diff options
Diffstat (limited to 'rtl/multiword/mw_comparator.v')
-rw-r--r-- | rtl/multiword/mw_comparator.v | 440 |
1 files changed, 220 insertions, 220 deletions
diff --git a/rtl/multiword/mw_comparator.v b/rtl/multiword/mw_comparator.v index b97a6cf..756ee83 100644 --- a/rtl/multiword/mw_comparator.v +++ b/rtl/multiword/mw_comparator.v @@ -1,220 +1,220 @@ -//------------------------------------------------------------------------------
-//
-// mw_comparator.v
-// -----------------------------------------------------------------------------
-// Multi-word comparator.
-//
-// Authors: Pavel Shatov
-//
-// Copyright (c) 2015-2016, NORDUnet A/S
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// - Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// - Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-//
-// - Neither the name of the NORDUnet nor the names of its contributors may be
-// used to endorse or promote products derived from this software without
-// specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-//------------------------------------------------------------------------------
-
-module mw_comparator
- (
- clk, rst_n,
- ena, rdy,
- xy_addr, x_din, y_din,
- cmp_l, cmp_e, cmp_g
- );
-
-
- //
- // Parameters
- //
- parameter WORD_COUNTER_WIDTH = 3;
- parameter OPERAND_NUM_WORDS = 8;
-
-
- // - // Handy Numbers - // - localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_ZERO = 0; - localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_LAST = OPERAND_NUM_WORDS - 1;
-
-
- // - // Handy Functions - // - function [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_PREV_OR_LAST; - input [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_CURRENT; - begin - WORD_INDEX_PREV_OR_LAST = (WORD_INDEX_CURRENT > WORD_INDEX_ZERO) ? - WORD_INDEX_CURRENT - 1'b1 : WORD_INDEX_LAST; - end - endfunction
-
-
- //
- // Ports
- //
- input wire clk; // system clock
- input wire rst_n; // active-low async reset
-
- input wire ena; // enable input
- output wire rdy; // ready output
-
- output wire [WORD_COUNTER_WIDTH-1:0] xy_addr; // address of current X and Y words
- input wire [ 32-1:0] x_din; // current X word
- input wire [ 32-1:0] y_din; // current Y word
-
- output wire cmp_l; // X < Y ?
- output wire cmp_e; // X = Y ?
- output wire cmp_g; // X > Y ?
-
-
- // - // Word Indices - // - reg [WORD_COUNTER_WIDTH-1:0] index_xy;
-
- reg reg_cmp_l;
- reg reg_cmp_e;
- reg reg_cmp_g;
-
-
- // - // Output Mapping
- // - assign xy_addr = index_xy;
- - assign cmp_l = reg_cmp_l; - assign cmp_e = reg_cmp_e;
- assign cmp_g = reg_cmp_g;
-
-
- // - // FSM - // - localparam FSM_SHREG_WIDTH = 1 * OPERAND_NUM_WORDS + 3; - - reg [FSM_SHREG_WIDTH-1:0] fsm_shreg; - - assign rdy = fsm_shreg[0]; - - wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_dec_index_xy = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 1) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 0)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_calc_leg = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 3) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2)];
- wire fsm_shreg_calc_leg_last = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2)]; - - wire dec_index_xy = |fsm_shreg_dec_index_xy;
- wire calc_leg = |fsm_shreg_calc_leg;
- wire calc_leg_last = fsm_shreg_calc_leg_last; - - - always @(posedge clk or negedge rst_n) - // - if (rst_n == 1'b0) - // - fsm_shreg <= {{FSM_SHREG_WIDTH-1{1'b0}}, 1'b1}; - // - else begin - // - if (rdy) fsm_shreg <= {ena, {FSM_SHREG_WIDTH-2{1'b0}}, ~ena}; - // - else fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]}; - // - end
-
-
- // - // Word Index Increment Logic - // - always @(posedge clk) - // - if (rdy) index_xy <= WORD_INDEX_LAST; - else if (dec_index_xy) index_xy <= WORD_INDEX_PREV_OR_LAST(index_xy);
-
-
- //
- // 32-bit Subtractor
- //
- wire [31: 0] sub32_d_out;
- wire sub32_b_in;
- wire sub32_b_out;
-
- subtractor32_wrapper subtractor32_inst
- (
- .clk (clk),
-
- .a (x_din),
- .b (y_din),
-
- .d (sub32_d_out),
-
- .b_in (sub32_b_in),
- .b_out (sub32_b_out)
- );
-
-
- // - // Borrow Masking Logic - // - reg sub32_b_mask; - - always @(posedge clk) - // - sub32_b_mask <= (index_xy == WORD_INDEX_LAST) ? 1'b1 : 1'b0;
- - assign sub32_b_in = sub32_b_out & ~sub32_b_mask;
-
- //
- // Output Logic
- //
- wire cmp_unresolved = !(cmp_l || cmp_g);
-
- wire cmp_borrow_is_set = (sub32_b_out == 1'b1) ? 1'b1 : 1'b0;
- wire cmp_difference_is_nonzero = (sub32_d_out != 32'd0) ? 1'b1 : 1'b0;
-
- always @(posedge clk)
- //
- if (rdy) begin
- //
- if (ena) begin
- //
- reg_cmp_l <= 1'b0;
- reg_cmp_e <= 1'b0;
- reg_cmp_g <= 1'b0;
- //
- end
- //
- end else if (cmp_unresolved && calc_leg) begin
- //
- if ( cmp_borrow_is_set) reg_cmp_l <= 1'b1;
- if (!cmp_borrow_is_set && cmp_difference_is_nonzero) reg_cmp_g <= 1'b1;
- if (!cmp_borrow_is_set && !cmp_difference_is_nonzero && calc_leg_last) reg_cmp_e <= 1'b1;
- //
- end
-
-
-endmodule
-
-
-//------------------------------------------------------------------------------
-// End-of-File
-//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------ +// +// mw_comparator.v +// ----------------------------------------------------------------------------- +// Multi-word comparator. +// +// Authors: Pavel Shatov +// +// Copyright (c) 2015-2016, NORDUnet A/S +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// - Neither the name of the NORDUnet nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +//------------------------------------------------------------------------------ + +module mw_comparator + ( + clk, rst_n, + ena, rdy, + xy_addr, x_din, y_din, + cmp_l, cmp_e, cmp_g + ); + + + // + // Parameters + // + parameter WORD_COUNTER_WIDTH = 3; + parameter OPERAND_NUM_WORDS = 8; + + + // + // Handy Numbers + // + localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_ZERO = 0; + localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_LAST = OPERAND_NUM_WORDS - 1; + + + // + // Handy Functions + // + function [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_PREV_OR_LAST; + input [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_CURRENT; + begin + WORD_INDEX_PREV_OR_LAST = (WORD_INDEX_CURRENT > WORD_INDEX_ZERO) ? + WORD_INDEX_CURRENT - 1'b1 : WORD_INDEX_LAST; + end + endfunction + + + // + // Ports + // + input wire clk; // system clock + input wire rst_n; // active-low async reset + + input wire ena; // enable input + output wire rdy; // ready output + + output wire [WORD_COUNTER_WIDTH-1:0] xy_addr; // address of current X and Y words + input wire [ 32-1:0] x_din; // current X word + input wire [ 32-1:0] y_din; // current Y word + + output wire cmp_l; // X < Y ? + output wire cmp_e; // X = Y ? + output wire cmp_g; // X > Y ? + + + // + // Word Indices + // + reg [WORD_COUNTER_WIDTH-1:0] index_xy; + + reg reg_cmp_l; + reg reg_cmp_e; + reg reg_cmp_g; + + + // + // Output Mapping + // + assign xy_addr = index_xy; + + assign cmp_l = reg_cmp_l; + assign cmp_e = reg_cmp_e; + assign cmp_g = reg_cmp_g; + + + // + // FSM + // + localparam FSM_SHREG_WIDTH = 1 * OPERAND_NUM_WORDS + 3; + + reg [FSM_SHREG_WIDTH-1:0] fsm_shreg; + + assign rdy = fsm_shreg[0]; + + wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_dec_index_xy = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 1) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 0)]; + wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_calc_leg = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 3) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2)]; + wire fsm_shreg_calc_leg_last = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2)]; + + wire dec_index_xy = |fsm_shreg_dec_index_xy; + wire calc_leg = |fsm_shreg_calc_leg; + wire calc_leg_last = fsm_shreg_calc_leg_last; + + + always @(posedge clk or negedge rst_n) + // + if (rst_n == 1'b0) + // + fsm_shreg <= {{FSM_SHREG_WIDTH-1{1'b0}}, 1'b1}; + // + else begin + // + if (rdy) fsm_shreg <= {ena, {FSM_SHREG_WIDTH-2{1'b0}}, ~ena}; + // + else fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]}; + // + end + + + // + // Word Index Increment Logic + // + always @(posedge clk) + // + if (rdy) index_xy <= WORD_INDEX_LAST; + else if (dec_index_xy) index_xy <= WORD_INDEX_PREV_OR_LAST(index_xy); + + + // + // 32-bit Subtractor + // + wire [31: 0] sub32_d_out; + wire sub32_b_in; + wire sub32_b_out; + + subtractor32_wrapper subtractor32_inst + ( + .clk (clk), + + .a (x_din), + .b (y_din), + + .d (sub32_d_out), + + .b_in (sub32_b_in), + .b_out (sub32_b_out) + ); + + + // + // Borrow Masking Logic + // + reg sub32_b_mask; + + always @(posedge clk) + // + sub32_b_mask <= (index_xy == WORD_INDEX_LAST) ? 1'b1 : 1'b0; + + assign sub32_b_in = sub32_b_out & ~sub32_b_mask; + + // + // Output Logic + // + wire cmp_unresolved = !(cmp_l || cmp_g); + + wire cmp_borrow_is_set = (sub32_b_out == 1'b1) ? 1'b1 : 1'b0; + wire cmp_difference_is_nonzero = (sub32_d_out != 32'd0) ? 1'b1 : 1'b0; + + always @(posedge clk) + // + if (rdy) begin + // + if (ena) begin + // + reg_cmp_l <= 1'b0; + reg_cmp_e <= 1'b0; + reg_cmp_g <= 1'b0; + // + end + // + end else if (cmp_unresolved && calc_leg) begin + // + if ( cmp_borrow_is_set) reg_cmp_l <= 1'b1; + if (!cmp_borrow_is_set && cmp_difference_is_nonzero) reg_cmp_g <= 1'b1; + if (!cmp_borrow_is_set && !cmp_difference_is_nonzero && calc_leg_last) reg_cmp_e <= 1'b1; + // + end + + +endmodule + + +//------------------------------------------------------------------------------ +// End-of-File +//------------------------------------------------------------------------------ |