diff options
Diffstat (limited to 'rtl/modular')
-rw-r--r-- | rtl/modular/modular_multiplier_256.v | 30 | ||||
-rw-r--r-- | rtl/modular/modular_reductor_256.v | 352 |
2 files changed, 204 insertions, 178 deletions
diff --git a/rtl/modular/modular_multiplier_256.v b/rtl/modular/modular_multiplier_256.v index 8487aee..c2f2661 100644 --- a/rtl/modular/modular_multiplier_256.v +++ b/rtl/modular/modular_multiplier_256.v @@ -293,8 +293,8 @@ module modular_multiplier_256 //
// Accumulators
//
- wire [46: 0] add48_cw0_s;
- wire [46: 0] add48_cw1_s;
+ wire [46: 0] add47_cw0_s;
+ wire [46: 0] add47_cw1_s;
//
@@ -314,26 +314,26 @@ module modular_multiplier_256 //
si_next_dly <= si_lsb[62:47];
- wire [46: 0] add48_cw0_a = si_lsb[46:0];
- wire [46: 0] add48_cw0_b = {{16{1'b0}}, si_prev_dly};
+ wire [46: 0] add47_cw0_a = si_lsb[46:0];
+ wire [46: 0] add47_cw0_b = {{16{1'b0}}, si_prev_dly};
- wire [46: 0] add48_cw1_a = add48_cw0_s;
- wire [46: 0] add48_cw1_b = {{15{1'b0}}, si_next_dly, mask_cw1_sum ? {16{1'b0}} : {1'b0, add48_cw1_s[46:32]}};
+ wire [46: 0] add47_cw1_a = add47_cw0_s;
+ wire [46: 0] add47_cw1_b = {{15{1'b0}}, si_next_dly, mask_cw1_sum ? {16{1'b0}} : {1'b0, add47_cw1_s[46:32]}};
- adder47_wrapper add48_cw0_inst
+ adder47_wrapper add47_cw0_inst
(
.clk (clk),
- .a (add48_cw0_a),
- .b (add48_cw0_b),
- .s (add48_cw0_s)
+ .a (add47_cw0_a),
+ .b (add47_cw0_b),
+ .s (add47_cw0_s)
);
- adder47_wrapper add48_cw1_inst
+ adder47_wrapper add47_cw1_inst
(
.clk (clk),
- .a (add48_cw1_a),
- .b (add48_cw1_b),
- .s (add48_cw1_s)
+ .a (add47_cw1_a),
+ .b (add47_cw1_b),
+ .s (add47_cw1_s)
);
@@ -364,7 +364,7 @@ module modular_multiplier_256 .a_addr (bram_c_addr),
.a_wr (store_c_word),
- .a_in (add48_cw1_s[31:0]),
+ .a_in (add47_cw1_s[31:0]),
.a_out (),
.b_addr (reduce_c_addr),
diff --git a/rtl/modular/modular_reductor_256.v b/rtl/modular/modular_reductor_256.v index 774f42e..e4b346a 100644 --- a/rtl/modular/modular_reductor_256.v +++ b/rtl/modular/modular_reductor_256.v @@ -1,39 +1,39 @@ -//------------------------------------------------------------------------------ -// -// modular_reductor_256.v -// ----------------------------------------------------------------------------- +//------------------------------------------------------------------------------
+//
+// modular_reductor_256.v
+// -----------------------------------------------------------------------------
// Modular reductor.
-// -// 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. -// +//
+// 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 modular_reductor_256
@@ -44,62 +44,62 @@ module modular_reductor_256 x_din, n_din, p_dout
);
- // - // Constants - // + //
+ // Constants
+ //
localparam OPERAND_NUM_WORDS = 8;
localparam WORD_COUNTER_WIDTH = 3;
- // - // Handy Numbers - // - localparam [WORD_COUNTER_WIDTH:0] WORD_INDEX_ZERO = 0; + //
+ // Handy Numbers
+ //
+ localparam [WORD_COUNTER_WIDTH:0] WORD_INDEX_ZERO = 0;
localparam [WORD_COUNTER_WIDTH:0] WORD_INDEX_LAST = 2 * OPERAND_NUM_WORDS - 1;
- // - // Handy Functions - // - function [WORD_COUNTER_WIDTH:0] WORD_INDEX_PREVIOUS_OR_LAST; - input [WORD_COUNTER_WIDTH:0] WORD_INDEX_CURRENT; - begin - WORD_INDEX_PREVIOUS_OR_LAST = (WORD_INDEX_CURRENT > WORD_INDEX_ZERO) ? - WORD_INDEX_CURRENT - 1'b1 : WORD_INDEX_LAST; - end + //
+ // Handy Functions
+ //
+ function [WORD_COUNTER_WIDTH:0] WORD_INDEX_PREVIOUS_OR_LAST;
+ input [WORD_COUNTER_WIDTH:0] WORD_INDEX_CURRENT;
+ begin
+ WORD_INDEX_PREVIOUS_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 + input wire rst_n; // active-low async reset
+
+ input wire ena; // enable input
output wire rdy; // ready output
- - output wire [WORD_COUNTER_WIDTH-0:0] x_addr; // index of current X word - output wire [WORD_COUNTER_WIDTH-1:0] n_addr; // index of current N word - output wire [WORD_COUNTER_WIDTH-1:0] p_addr; // index of current P word +
+ output wire [WORD_COUNTER_WIDTH-0:0] x_addr; // index of current X word
+ output wire [WORD_COUNTER_WIDTH-1:0] n_addr; // index of current N word
+ output wire [WORD_COUNTER_WIDTH-1:0] p_addr; // index of current P word
output wire p_wren; // store current P word now
- +
input wire [ 31:0] x_din; // X
input wire [ 31:0] n_din; // N (must be P-256!)
output wire [ 31:0] p_dout; // P = X mod N
- // - // Word Indices - // + //
+ // Word Indices
+ //
reg [WORD_COUNTER_WIDTH:0] index_x;
- - - /* map registers to output ports */ +
+
+ /* map registers to output ports */
assign x_addr = index_x;
- - // +
+ //
// FSM
//
localparam FSM_SHREG_WIDTH = (2 * OPERAND_NUM_WORDS + 1) + (5 * 2) + 1;
@@ -136,34 +136,34 @@ module modular_reductor_256 wire reduce_done_all = reduce_adder0_done & reduce_adder1_done & reduce_subtractor_done;
- always @(posedge clk or negedge rst_n) - // - if (rst_n == 1'b0) - // - fsm_shreg <= {{FSM_SHREG_WIDTH-1{1'b0}}, 1'b1}; - // - else begin - // + 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 if (!reduce_stop || reduce_done_all)
//
- fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]}; - // + fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]};
+ //
end
- // - // Word Index Increment Logic - // - always @(posedge clk) - // - if (rdy) - // - index_x <= WORD_INDEX_LAST; - // + //
+ // Word Index Increment Logic
+ //
+ always @(posedge clk)
+ //
+ if (rdy)
+ //
+ index_x <= WORD_INDEX_LAST;
+ //
else if (inc_index_x)
//
index_x <= WORD_INDEX_PREVIOUS_OR_LAST(index_x);
@@ -173,14 +173,27 @@ module modular_reductor_256 // Look-up Table
//
- // TODO: Explain s5!!!
+ //
+ // Take a look at the corresponding C model for more information
+ // on how exactly the math behind reduction works. The first step
+ // is to assemble nine 256-bit values ("z-words") from 32-bit parts
+ // of the full 512-bit product ("c-word"). The problem with z5 is
+ // that it contains c13 two times. This implementation scans from
+ // c15 to c0 and writes current part of c-word into corresponding
+ // parts of z-words. Since those 32-bit parts are stored in block
+ // memories, one source word can only be written to one location in
+ // every z-word at a time. The trick is to delay c13 and then write
+ // the delayed value at the corresponding location in z5 instead of
+ // the next c12. "z_save" flag is used to indicate that the current
+ // word should be delayed and written once again during the next cycle.
+ //
reg [9*WORD_COUNTER_WIDTH-1:0] z_addr; //
reg [9 -1:0] z_wren; //
reg [9 -1:0] z_mask; // mask input to store zero word
reg [9 -1:0] z_save; // save previous word once again
- always @(posedge clk) + always @(posedge clk)
//
if (inc_index_x)
//
@@ -204,9 +217,9 @@ module modular_reductor_256 4'd13: z_addr <= {3'd07, 3'd00, 3'd01, 3'd02, 3'd03, 3'd05, 3'd04, 3'd05, 3'dxx};
4'd14: z_addr <= {3'd00, 3'd01, 3'd02, 3'd04, 3'd04, 3'd06, 3'd05, 3'd06, 3'dxx};
4'd15: z_addr <= {3'd01, 3'd02, 3'd03, 3'd05, 3'd05, 3'd07, 3'd06, 3'd07, 3'dxx};
- // + //
default: z_addr <= {9*WORD_COUNTER_WIDTH{1'bX}};
- // + //
endcase
always @(posedge clk)
@@ -231,9 +244,9 @@ module modular_reductor_256 4'd13: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
4'd14: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
4'd15: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
- // + //
default: z_wren <= {9{1'b0}};
- // + //
endcase
always @(posedge clk)
@@ -260,11 +273,11 @@ module modular_reductor_256 4'd13: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0};
4'd14: z_mask <= {1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
4'd15: z_mask <= {1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- // + //
default: z_mask <= {9{1'bX}};
- // + //
endcase
- +
always @(posedge clk)
//
if (inc_index_x)
@@ -289,9 +302,9 @@ module modular_reductor_256 4'd13: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
4'd14: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
4'd15: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- // + //
default: z_save <= {9{1'bX}};
- // + //
endcase
@@ -312,18 +325,18 @@ module modular_reductor_256 //
begin : gen_z_bram
//
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_c_inst - ( - .clk (clk), - - .a_addr (z_addr[(z-1) * WORD_COUNTER_WIDTH +: WORD_COUNTER_WIDTH]), - .a_wr (z_wren[z-1] & store_word_z), - .a_in (z_mask[z-1] ? {32{1'b0}} : (z_save[z-1] ? x_din_dly : x_din)), - .a_out (), - - .b_addr (reduce_z_addr[z]), - .b_out (reduce_z_dout[z]) + bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
+ bram_c_inst
+ (
+ .clk (clk),
+
+ .a_addr (z_addr[(z-1) * WORD_COUNTER_WIDTH +: WORD_COUNTER_WIDTH]),
+ .a_wr (z_wren[z-1] & store_word_z),
+ .a_in (z_mask[z-1] ? {32{1'b0}} : (z_save[z-1] ? x_din_dly : x_din)),
+ .a_out (),
+
+ .b_addr (reduce_z_addr[z]),
+ .b_out (reduce_z_dout[z])
);
//
end
@@ -355,50 +368,49 @@ module modular_reductor_256 reg [WORD_COUNTER_WIDTH-1:0] bram_diff_rd_addr;
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_sum0_inst - ( - .clk (clk), - - .a_addr (bram_sum0_wr_addr), - .a_wr (bram_sum0_wr_wren), - .a_in (bram_sum0_wr_din), - .a_out (), - - .b_addr (bram_sum0_rd_addr), - .b_out (bram_sum0_rd_dout) + bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
+ bram_sum0_inst
+ (
+ .clk (clk),
+
+ .a_addr (bram_sum0_wr_addr),
+ .a_wr (bram_sum0_wr_wren),
+ .a_in (bram_sum0_wr_din),
+ .a_out (),
+
+ .b_addr (bram_sum0_rd_addr),
+ .b_out (bram_sum0_rd_dout)
);
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_sum1_inst - ( - .clk (clk), - - .a_addr (bram_sum1_wr_addr), - .a_wr (bram_sum1_wr_wren), - .a_in (bram_sum1_wr_din), - .a_out (), - - .b_addr (bram_sum1_rd_addr), - .b_out (bram_sum1_rd_dout) + bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
+ bram_sum1_inst
+ (
+ .clk (clk),
+
+ .a_addr (bram_sum1_wr_addr),
+ .a_wr (bram_sum1_wr_wren),
+ .a_in (bram_sum1_wr_din),
+ .a_out (),
+
+ .b_addr (bram_sum1_rd_addr),
+ .b_out (bram_sum1_rd_dout)
);
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_diff_inst - ( - .clk (clk), - - .a_addr (bram_diff_wr_addr), - .a_wr (bram_diff_wr_wren), - .a_in (bram_diff_wr_din), - .a_out (), - - .b_addr (bram_diff_rd_addr), - .b_out (bram_diff_rd_dout) + bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
+ bram_diff_inst
+ (
+ .clk (clk),
+
+ .a_addr (bram_diff_wr_addr),
+ .a_wr (bram_diff_wr_wren),
+ .a_in (bram_diff_wr_din),
+ .a_out (),
+
+ .b_addr (bram_diff_rd_addr),
+ .b_out (bram_diff_rd_dout)
);
-
wire [WORD_COUNTER_WIDTH-1:0] adder0_ab_addr;
wire [WORD_COUNTER_WIDTH-1:0] adder1_ab_addr;
wire [WORD_COUNTER_WIDTH-1:0] subtractor_ab_addr;
@@ -414,7 +426,12 @@ module modular_reductor_256 // n_addr - only 1 output, because all modules are in sync
- modular_adder adder_inst0
+ modular_adder #
+ (
+ .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS),
+ .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH)
+ )
+ adder_inst0
(
.clk (clk),
.rst_n (rst_n),
@@ -426,14 +443,19 @@ module modular_reductor_256 .n_addr (),
.s_addr (bram_sum0_wr_addr),
.s_wren (bram_sum0_wr_wren),
- +
.a_din (adder0_a_din),
.b_din (adder0_b_din),
.n_din (n_din),
.s_dout (bram_sum0_wr_din)
);
- modular_adder adder_inst1
+ modular_adder #
+ (
+ .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS),
+ .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH)
+ )
+ adder_inst1
(
.clk (clk),
.rst_n (rst_n),
@@ -445,14 +467,19 @@ module modular_reductor_256 .n_addr (),
.s_addr (bram_sum1_wr_addr),
.s_wren (bram_sum1_wr_wren),
- +
.a_din (adder1_a_din),
.b_din (adder1_b_din),
.n_din (n_din),
.s_dout (bram_sum1_wr_din)
);
- modular_subtractor subtractor_inst
+ modular_subtractor #
+ (
+ .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS),
+ .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH)
+ )
+ subtractor_inst
(
.clk (clk),
.rst_n (rst_n),
@@ -464,7 +491,7 @@ module modular_reductor_256 .n_addr (n_addr),
.d_addr (bram_diff_wr_addr),
.d_wren (bram_diff_wr_wren),
- +
.a_din (subtractor_a_din),
.b_din (subtractor_b_din),
.n_din (n_din),
@@ -473,7 +500,7 @@ module modular_reductor_256 //
- // address
+ // Address (Operand) Selector
//
always @(*)
//
@@ -572,7 +599,6 @@ module modular_reductor_256 endcase
-
//
// adder 0
//
@@ -650,17 +676,17 @@ module modular_reductor_256 end
-
-
- assign p_addr = bram_sum0_wr_addr; + //
+ // Address Mapping
+ //
+ assign p_addr = bram_sum0_wr_addr;
assign p_wren = bram_sum0_wr_wren & store_p;
assign p_dout = bram_sum0_wr_din;
-
-
+
endmodule
-//------------------------------------------------------------------------------ -// End-of-File +//------------------------------------------------------------------------------
+// End-of-File
//------------------------------------------------------------------------------
|