aboutsummaryrefslogtreecommitdiff
path: root/rtl/modular/modular_adder.v
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2017-03-07 19:46:44 -0500
committerRob Austein <sra@hactrn.net>2017-03-07 19:46:44 -0500
commitab4638f70ee846de7398a3d78d467a9551e508cf (patch)
tree61c330bb0be48daa4faf3830abfa84c9e5f400d7 /rtl/modular/modular_adder.v
parent9fa6e368879d30835880b3bb0e87c8cf13dd9874 (diff)
Promote code common to both ECDSA* cores to separate repository in core/ tree.
Pavel's two ECDSA base point multiplier cores share a fair amount of code. Maintenance issues aside, the duplication confused the Xilinx synthesis tools if one tried to build a single bitstream containing both cores, so we've separated the common code out into this library. The selection of files in this library was done by comparing the rtl trees of the two original core repositories using "diff -rqws" and selecting the files which diff reported as being identical. Also dealt with some cosmetic issues (indentation, Windows-isms, etc).
Diffstat (limited to 'rtl/modular/modular_adder.v')
-rw-r--r--rtl/modular/modular_adder.v522
1 files changed, 261 insertions, 261 deletions
diff --git a/rtl/modular/modular_adder.v b/rtl/modular/modular_adder.v
index 5641feb..189059d 100644
--- a/rtl/modular/modular_adder.v
+++ b/rtl/modular/modular_adder.v
@@ -2,7 +2,7 @@
//
// modular_adder.v
// -----------------------------------------------------------------------------
-// Modular adder.
+// Modular adder.
//
// Authors: Pavel Shatov
//
@@ -34,265 +34,265 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
-//------------------------------------------------------------------------------
-
-module modular_adder
- (
- clk, rst_n,
- ena, rdy,
- ab_addr, n_addr, s_addr, s_wren,
- a_din, b_din, n_din, s_dout
- );
-
-
- //
- // Parameters
- //
- parameter OPERAND_NUM_WORDS = 8;
- parameter WORD_COUNTER_WIDTH = 3;
-
-
- //
- // 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_NEXT_OR_ZERO;
- input [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_CURRENT;
- begin
- WORD_INDEX_NEXT_OR_ZERO = (WORD_INDEX_CURRENT < WORD_INDEX_LAST) ?
- WORD_INDEX_CURRENT + 1'b1 : WORD_INDEX_ZERO;
- 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] ab_addr; // index of current A and B words
- output wire [WORD_COUNTER_WIDTH-1:0] n_addr; // index of current N word
- output wire [WORD_COUNTER_WIDTH-1:0] s_addr; // index of current S word
- output wire s_wren; // store current S word now
-
- input wire [ 31:0] a_din; // A
- input wire [ 31:0] b_din; // B
- input wire [ 31:0] n_din; // N
- output wire [ 31:0] s_dout; // S = (A + B) mod N
-
-
- //
- // Word Indices
- //
- reg [WORD_COUNTER_WIDTH-1:0] index_ab;
- reg [WORD_COUNTER_WIDTH-1:0] index_n;
- reg [WORD_COUNTER_WIDTH-1:0] index_s;
-
- /* map registers to output ports */
- assign ab_addr = index_ab;
- assign n_addr = index_n;
- assign s_addr = index_s;
-
-
- //
- // Adder
- //
- wire [31: 0] add32_s;
- wire add32_c_in;
- wire add32_c_out;
-
- adder32_wrapper adder32
- (
- .clk (clk),
- .a (a_din),
- .b (b_din),
- .s (add32_s),
- .c_in (add32_c_in),
- .c_out (add32_c_out)
- );
-
-
- //
- // Subtractor
- //
- wire [31: 0] sub32_d;
- wire sub32_b_in;
- wire sub32_b_out;
-
- subtractor32_wrapper subtractor32
- (
- .clk (clk),
- .a (add32_s),
- .b (n_din),
- .d (sub32_d),
- .b_in (sub32_b_in),
- .b_out (sub32_b_out)
- );
-
-
- //
- // FSM
- //
-
- localparam FSM_SHREG_WIDTH = 2*OPERAND_NUM_WORDS + 5;
-
- reg [FSM_SHREG_WIDTH-1:0] fsm_shreg;
-
- assign rdy = fsm_shreg[0];
-
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_ab = 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_inc_index_n = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 2) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 1)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_store_sum_ab = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 3) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_store_sum_ab_n = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 4) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 3)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_store_data_s = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 4) : FSM_SHREG_WIDTH - (2 * OPERAND_NUM_WORDS + 3)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_s = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 5) : FSM_SHREG_WIDTH - (2 * OPERAND_NUM_WORDS + 4)];
-
- wire fsm_latch_msb_carry = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2)];
- wire fsm_latch_msb_borrow = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 3)];
-
- wire inc_index_ab = |fsm_shreg_inc_index_ab;
- wire inc_index_n = |fsm_shreg_inc_index_n;
- wire store_sum_ab = |fsm_shreg_store_sum_ab;
- wire store_sum_ab_n = |fsm_shreg_store_sum_ab_n;
- wire store_data_s = |fsm_shreg_store_data_s;
- wire inc_index_s = |fsm_shreg_inc_index_s;
-
- 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
-
-
-
-
-
-
-
- //
- // Carry & Borrow Masking Logic
- //
- reg add32_c_mask;
- reg sub32_b_mask;
-
- always @(posedge clk) begin
- //
- add32_c_mask <= (index_ab == WORD_INDEX_ZERO) ? 1'b1 : 1'b0;
- sub32_b_mask <= (index_n == WORD_INDEX_ZERO) ? 1'b1 : 1'b0;
- //
- end
-
- assign add32_c_in = add32_c_out & ~add32_c_mask;
- assign sub32_b_in = sub32_b_out & ~sub32_b_mask;
-
-
- //
- // Carry & Borrow Latch Logic
- //
- reg add32_carry_latch;
- reg sub32_borrow_latch;
-
- always @(posedge clk) begin
- //
- if (fsm_latch_msb_carry) add32_carry_latch <= add32_c_out;
- if (fsm_latch_msb_borrow) sub32_borrow_latch <= sub32_b_out;
- //
- end
-
-
- //
- // Intermediate Results
- //
- reg [32*OPERAND_NUM_WORDS-1:0] s_ab;
- reg [32*OPERAND_NUM_WORDS-1:0] s_ab_n;
-
- always @(posedge clk)
- //
- if (store_data_s) begin
- //
- s_ab <= {{32{1'bX}}, s_ab[32*OPERAND_NUM_WORDS-1:32]};
- s_ab_n <= {{32{1'bX}}, s_ab_n[32*OPERAND_NUM_WORDS-1:32]};
- //
- end else begin
- //
- if (store_sum_ab) s_ab <= {add32_s, s_ab[32*OPERAND_NUM_WORDS-1:32]};
- if (store_sum_ab_n) s_ab_n <= {sub32_d, s_ab_n[32*OPERAND_NUM_WORDS-1:32]};
- //
- end
-
-
- //
- // Word Index Increment Logic
- //
- always @(posedge clk)
- //
- if (rdy) begin
- //
- index_ab <= WORD_INDEX_ZERO;
- index_n <= WORD_INDEX_ZERO;
- index_s <= WORD_INDEX_ZERO;
- //
- end else begin
- //
- if (inc_index_ab) index_ab <= WORD_INDEX_NEXT_OR_ZERO(index_ab);
- if (inc_index_n) index_n <= WORD_INDEX_NEXT_OR_ZERO(index_n);
- if (inc_index_s) index_s <= WORD_INDEX_NEXT_OR_ZERO(index_s);
- //
- end
-
-
- //
- // Output Sum Selector
- //
- wire mux_select_ab = sub32_borrow_latch && !add32_carry_latch;
-
-
- //
- // Output Data and Write Enable Logic
- //
- reg s_wren_reg;
- reg [31: 0] s_dout_reg;
- wire [31: 0] s_dout_mux = mux_select_ab ? s_ab[31:0] : s_ab_n[31:0];
-
- assign s_wren = s_wren_reg;
- assign s_dout = s_dout_reg;
-
- always @(posedge clk)
- //
- if (rdy) begin
- //
- s_wren_reg <= 1'b0;
- s_dout_reg <= {32{1'bX}};
- //
- end else begin
- //
- s_wren_reg <= store_data_s;
- s_dout_reg <= store_data_s ? s_dout_mux : {32{1'bX}};
- //
- end
-
-
-endmodule
-
-
+//------------------------------------------------------------------------------
+
+module modular_adder
+ (
+ clk, rst_n,
+ ena, rdy,
+ ab_addr, n_addr, s_addr, s_wren,
+ a_din, b_din, n_din, s_dout
+ );
+
+
+ //
+ // Parameters
+ //
+ parameter OPERAND_NUM_WORDS = 8;
+ parameter WORD_COUNTER_WIDTH = 3;
+
+
+ //
+ // 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_NEXT_OR_ZERO;
+ input [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_CURRENT;
+ begin
+ WORD_INDEX_NEXT_OR_ZERO = (WORD_INDEX_CURRENT < WORD_INDEX_LAST) ?
+ WORD_INDEX_CURRENT + 1'b1 : WORD_INDEX_ZERO;
+ 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] ab_addr; // index of current A and B words
+ output wire [WORD_COUNTER_WIDTH-1:0] n_addr; // index of current N word
+ output wire [WORD_COUNTER_WIDTH-1:0] s_addr; // index of current S word
+ output wire s_wren; // store current S word now
+
+ input wire [ 31:0] a_din; // A
+ input wire [ 31:0] b_din; // B
+ input wire [ 31:0] n_din; // N
+ output wire [ 31:0] s_dout; // S = (A + B) mod N
+
+
+ //
+ // Word Indices
+ //
+ reg [WORD_COUNTER_WIDTH-1:0] index_ab;
+ reg [WORD_COUNTER_WIDTH-1:0] index_n;
+ reg [WORD_COUNTER_WIDTH-1:0] index_s;
+
+ /* map registers to output ports */
+ assign ab_addr = index_ab;
+ assign n_addr = index_n;
+ assign s_addr = index_s;
+
+
+ //
+ // Adder
+ //
+ wire [31: 0] add32_s;
+ wire add32_c_in;
+ wire add32_c_out;
+
+ adder32_wrapper adder32
+ (
+ .clk (clk),
+ .a (a_din),
+ .b (b_din),
+ .s (add32_s),
+ .c_in (add32_c_in),
+ .c_out (add32_c_out)
+ );
+
+
+ //
+ // Subtractor
+ //
+ wire [31: 0] sub32_d;
+ wire sub32_b_in;
+ wire sub32_b_out;
+
+ subtractor32_wrapper subtractor32
+ (
+ .clk (clk),
+ .a (add32_s),
+ .b (n_din),
+ .d (sub32_d),
+ .b_in (sub32_b_in),
+ .b_out (sub32_b_out)
+ );
+
+
+ //
+ // FSM
+ //
+
+ localparam FSM_SHREG_WIDTH = 2*OPERAND_NUM_WORDS + 5;
+
+ reg [FSM_SHREG_WIDTH-1:0] fsm_shreg;
+
+ assign rdy = fsm_shreg[0];
+
+ wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_ab = 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_inc_index_n = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 2) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 1)];
+ wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_store_sum_ab = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 3) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2)];
+ wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_store_sum_ab_n = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 4) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 3)];
+ wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_store_data_s = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 4) : FSM_SHREG_WIDTH - (2 * OPERAND_NUM_WORDS + 3)];
+ wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_s = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 5) : FSM_SHREG_WIDTH - (2 * OPERAND_NUM_WORDS + 4)];
+
+ wire fsm_latch_msb_carry = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2)];
+ wire fsm_latch_msb_borrow = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 3)];
+
+ wire inc_index_ab = |fsm_shreg_inc_index_ab;
+ wire inc_index_n = |fsm_shreg_inc_index_n;
+ wire store_sum_ab = |fsm_shreg_store_sum_ab;
+ wire store_sum_ab_n = |fsm_shreg_store_sum_ab_n;
+ wire store_data_s = |fsm_shreg_store_data_s;
+ wire inc_index_s = |fsm_shreg_inc_index_s;
+
+ 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
+
+
+
+
+
+
+
+ //
+ // Carry & Borrow Masking Logic
+ //
+ reg add32_c_mask;
+ reg sub32_b_mask;
+
+ always @(posedge clk) begin
+ //
+ add32_c_mask <= (index_ab == WORD_INDEX_ZERO) ? 1'b1 : 1'b0;
+ sub32_b_mask <= (index_n == WORD_INDEX_ZERO) ? 1'b1 : 1'b0;
+ //
+ end
+
+ assign add32_c_in = add32_c_out & ~add32_c_mask;
+ assign sub32_b_in = sub32_b_out & ~sub32_b_mask;
+
+
+ //
+ // Carry & Borrow Latch Logic
+ //
+ reg add32_carry_latch;
+ reg sub32_borrow_latch;
+
+ always @(posedge clk) begin
+ //
+ if (fsm_latch_msb_carry) add32_carry_latch <= add32_c_out;
+ if (fsm_latch_msb_borrow) sub32_borrow_latch <= sub32_b_out;
+ //
+ end
+
+
+ //
+ // Intermediate Results
+ //
+ reg [32*OPERAND_NUM_WORDS-1:0] s_ab;
+ reg [32*OPERAND_NUM_WORDS-1:0] s_ab_n;
+
+ always @(posedge clk)
+ //
+ if (store_data_s) begin
+ //
+ s_ab <= {{32{1'bX}}, s_ab[32*OPERAND_NUM_WORDS-1:32]};
+ s_ab_n <= {{32{1'bX}}, s_ab_n[32*OPERAND_NUM_WORDS-1:32]};
+ //
+ end else begin
+ //
+ if (store_sum_ab) s_ab <= {add32_s, s_ab[32*OPERAND_NUM_WORDS-1:32]};
+ if (store_sum_ab_n) s_ab_n <= {sub32_d, s_ab_n[32*OPERAND_NUM_WORDS-1:32]};
+ //
+ end
+
+
+ //
+ // Word Index Increment Logic
+ //
+ always @(posedge clk)
+ //
+ if (rdy) begin
+ //
+ index_ab <= WORD_INDEX_ZERO;
+ index_n <= WORD_INDEX_ZERO;
+ index_s <= WORD_INDEX_ZERO;
+ //
+ end else begin
+ //
+ if (inc_index_ab) index_ab <= WORD_INDEX_NEXT_OR_ZERO(index_ab);
+ if (inc_index_n) index_n <= WORD_INDEX_NEXT_OR_ZERO(index_n);
+ if (inc_index_s) index_s <= WORD_INDEX_NEXT_OR_ZERO(index_s);
+ //
+ end
+
+
+ //
+ // Output Sum Selector
+ //
+ wire mux_select_ab = sub32_borrow_latch && !add32_carry_latch;
+
+
+ //
+ // Output Data and Write Enable Logic
+ //
+ reg s_wren_reg;
+ reg [31: 0] s_dout_reg;
+ wire [31: 0] s_dout_mux = mux_select_ab ? s_ab[31:0] : s_ab_n[31:0];
+
+ assign s_wren = s_wren_reg;
+ assign s_dout = s_dout_reg;
+
+ always @(posedge clk)
+ //
+ if (rdy) begin
+ //
+ s_wren_reg <= 1'b0;
+ s_dout_reg <= {32{1'bX}};
+ //
+ end else begin
+ //
+ s_wren_reg <= store_data_s;
+ s_dout_reg <= store_data_s ? s_dout_mux : {32{1'bX}};
+ //
+ end
+
+
+endmodule
+
+
//------------------------------------------------------------------------------
// End-of-File
-//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------