diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rtl/modexpa7_factor.v | 178 | ||||
-rw-r--r-- | src/rtl/modexpa7_n_coeff.v | 3 |
2 files changed, 123 insertions, 58 deletions
diff --git a/src/rtl/modexpa7_factor.v b/src/rtl/modexpa7_factor.v index 9fe3bfe..7d8da72 100644 --- a/src/rtl/modexpa7_factor.v +++ b/src/rtl/modexpa7_factor.v @@ -142,13 +142,6 @@ module modexpa7_factor # n_num_words_latch <= n_num_words;
-
- //
- // Addresses
- //
- localparam [OPERAND_ADDR_WIDTH-1:0] bram_addr_zero = {OPERAND_ADDR_WIDTH{1'b0}};
- wire [OPERAND_ADDR_WIDTH-1:0] bram_addr_last = n_num_words_latch;
-
//
// Cycle Counters
//
@@ -158,8 +151,8 @@ module modexpa7_factor # wire [OPERAND_ADDR_WIDTH+5:0] cyc_cnt_last = {n_num_words, 1'b1, {5{1'b1}}};
wire [OPERAND_ADDR_WIDTH+5:0] cyc_cnt_next = cyc_cnt + 1'b1;
+ /* handy flag */
wire cyc_cnt_done = (cyc_cnt == cyc_cnt_last) ? 1'b1 : 1'b0;
-
always @(posedge clk)
//
@@ -170,15 +163,32 @@ module modexpa7_factor # FSM_STATE_SAVE_5: cyc_cnt <= cyc_cnt_done ? cyc_cnt : cyc_cnt_next;
endcase
-
-
-
+
+ //
+ // Handy Address Values
+ //
+ /* the very first address */
+ wire [OPERAND_ADDR_WIDTH-1:0] bram_addr_zero = {OPERAND_ADDR_WIDTH{1'b0}};
+
+ /* the very last address */
+ wire [OPERAND_ADDR_WIDTH-1:0] bram_addr_last = n_num_words_latch;
//
// Block Memories
//
+
+ /*
+ * This module uses 5 block memories:
+ * N - external input, stores modulus
+ * F - external output, stores Montgomery factor
+ * F0 - internal, stores intermediate result
+ * F1 - internal, stores quantity F0 << 1
+ * F2 - internal, stores quantity F1 - N
+ *
+ */
+
reg [OPERAND_ADDR_WIDTH-1:0] f_addr;
reg [OPERAND_ADDR_WIDTH-1:0] f0_addr;
reg [OPERAND_ADDR_WIDTH-1:0] f1_addr;
@@ -198,8 +208,8 @@ module modexpa7_factor # reg f1_wren;
reg f2_wren;
- assign n_bram_addr = f0_addr; // TODO: Make separate register for N maybe?
-
+ /* map top-level ports to internal registers */
+ assign n_bram_addr = f0_addr;
assign f_bram_addr = f_addr;
assign f_bram_in = f_data_in;
assign f_bram_wr = f_wren;
@@ -213,49 +223,59 @@ module modexpa7_factor # bram_1rw_readfirst #(.MEM_WIDTH(32), .MEM_ADDR_BITS(OPERAND_ADDR_WIDTH)) bram_f2 (.clk(clk), .a_addr(f2_addr), .a_wr(f2_wren), .a_in(f2_data_in), .a_out(f2_data_out));
-
+ /* handy values */
wire [OPERAND_ADDR_WIDTH-1:0] f_addr_next = f_addr + 1'b1;
wire [OPERAND_ADDR_WIDTH-1:0] f0_addr_next = f0_addr + 1'b1;
wire [OPERAND_ADDR_WIDTH-1:0] f1_addr_next = f1_addr + 1'b1;
wire [OPERAND_ADDR_WIDTH-1:0] f2_addr_next = f2_addr + 1'b1;
+ /* handy flags */
wire f_addr_done = (f_addr == bram_addr_last) ? 1'b1 : 1'b0;
wire f0_addr_done = (f0_addr == bram_addr_last) ? 1'b1 : 1'b0;
wire f1_addr_done = (f1_addr == bram_addr_last) ? 1'b1 : 1'b0;
wire f2_addr_done = (f2_addr == bram_addr_last) ? 1'b1 : 1'b0;
+ //
+ // Delayed Flags
+ //
reg f12_addr_done_dly;
always @(posedge clk)
//
f12_addr_done_dly <= f1_addr_done & f2_addr_done;
- reg f0_data_out_carry;
-
- wire [31: 0] f0_data_out_shifted = {f0_data_out[30:0], f0_data_out_carry};
+ //
+ // Modulus Delay Line
+ //
+ reg [31: 0] n_bram_out_dly;
+
+ /* delay block memory output by 1 clock cycle */
+ always @(posedge clk) n_bram_out_dly <= n_bram_out;
//
// Subtractor
//
- reg [31: 0] n_bram_out_dly;
-
- always @(posedge clk)
- n_bram_out_dly <= n_bram_out;
+
+ /*
+ * This subtractor calculated quantity F2 = F1 - N
+ *
+ */
wire [31: 0] sub_d;
wire sub_b_in;
reg sub_b_in_mask;
wire sub_b_out;
+ /* add masking into borrow feedback chain */
assign sub_b_in = sub_b_out & ~sub_b_in_mask;
always @(posedge clk)
- //
+
+ /* mask borrow into the very first word */
sub_b_in_mask <= (fsm_next_state == FSM_STATE_CALC_3) ? 1'b1 : 1'b0;
-
ip_sub32 sub_inst
(
.clk (clk),
@@ -266,10 +286,26 @@ module modexpa7_factor # .c_out (sub_b_out)
);
+
+ //
+ // F0 Shift Carry Logic
+ //
+ /*
+ * F0 value is repeatedly shifted to the left, so we need carry logic
+ * to save the MSB of the current output word and feed into the LSB
+ * of the next input word.
+ *
+ */
+ reg f0_data_out_carry;
+
+ /* shifted output */
+ wire [31: 0] f0_data_out_shifted = {f0_data_out[30:0], f0_data_out_carry};
+
always @(posedge clk)
- //
+
+ /* mask carry into the very first word, propagate carry otherwise */
case (fsm_next_state)
FSM_STATE_CALC_2: f0_data_out_carry <= 1'b0;
FSM_STATE_CALC_3,
@@ -280,32 +316,44 @@ module modexpa7_factor # endcase
-
+ //
+ // Delay Lines
+ //
reg sub_b_out_dly1;
reg f0_data_out_carry_dly1;
reg f0_data_out_carry_dly2;
- always @(posedge clk) sub_b_out_dly1 <= sub_b_out;
-
- always @(posedge clk) f0_data_out_carry_dly1 <= f0_data_out_carry;
- always @(posedge clk) f0_data_out_carry_dly2 <= f0_data_out_carry_dly1;
+ always @(posedge clk) begin
+ sub_b_out_dly1 <= sub_b_out;
+ f0_data_out_carry_dly1 <= f0_data_out_carry;
+ f0_data_out_carry_dly2 <= f0_data_out_carry_dly1;
+ end
+
+ //
+ // F Update Flag
+ //
reg flag_keep_f;
always @(posedge clk)
- //
+
+ /* update flag when new word of F2 is obtained */
if (fsm_next_state == FSM_STATE_SAVE_1)
flag_keep_f <= sub_b_out_dly1 & ~f0_data_out_carry_dly2;
+ //
+ // Block Memory Address Update Logic
+ //
always @(posedge clk) begin
//
+ // F0
+ //
case (fsm_next_state)
-
FSM_STATE_INIT_1,
FSM_STATE_CALC_1,
FSM_STATE_SAVE_3: f0_addr <= bram_addr_zero;
-
+ //
FSM_STATE_INIT_2,
FSM_STATE_CALC_2,
FSM_STATE_CALC_3,
@@ -314,50 +362,55 @@ module modexpa7_factor # FSM_STATE_CALC_6,
FSM_STATE_SAVE_4,
FSM_STATE_SAVE_5: f0_addr <= !f0_addr_done ? f0_addr_next : f0_addr;
-
endcase
//
+ // F1
+ //
case (fsm_next_state)
-
FSM_STATE_CALC_3,
FSM_STATE_SAVE_1: f1_addr <= bram_addr_zero;
-
+ //
FSM_STATE_CALC_4,
FSM_STATE_CALC_5,
FSM_STATE_CALC_6,
FSM_STATE_SAVE_2,
FSM_STATE_SAVE_3,
FSM_STATE_SAVE_4: f1_addr <= !f1_addr_done ? f1_addr_next : f1_addr;
-
endcase
//
+ // F2
+ //
case (fsm_next_state)
-
FSM_STATE_CALC_5,
FSM_STATE_SAVE_1: f2_addr <= bram_addr_zero;
-
+ //
FSM_STATE_CALC_6,
FSM_STATE_CALC_7,
FSM_STATE_CALC_8,
FSM_STATE_SAVE_2,
FSM_STATE_SAVE_3,
FSM_STATE_SAVE_4: f2_addr <= !f2_addr_done ? f2_addr_next : f2_addr;
-
endcase
//
- case (fsm_next_state)
-
+ // F
+ //
+ case (fsm_next_state)
FSM_STATE_SAVE_3: f_addr <= bram_addr_zero;
-
+ //
FSM_STATE_SAVE_4,
FSM_STATE_SAVE_5: f_addr <= !f_addr_done ? f_addr_next : f_addr;
-
endcase
//
end
+
+ //
+ // Block Memory Write Enable Logic
+ //
always @(posedge clk) begin
//
+ // F0
+ //
case (fsm_next_state)
FSM_STATE_INIT_1,
FSM_STATE_INIT_2,
@@ -367,6 +420,8 @@ module modexpa7_factor # default: f0_wren <= 1'b0;
endcase
//
+ // F1
+ //
case (fsm_next_state)
FSM_STATE_CALC_3,
FSM_STATE_CALC_4,
@@ -375,6 +430,8 @@ module modexpa7_factor # default: f1_wren <= 1'b0;
endcase
//
+ // F2
+ //
case (fsm_next_state)
FSM_STATE_CALC_5,
FSM_STATE_CALC_6,
@@ -383,6 +440,8 @@ module modexpa7_factor # default: f2_wren <= 1'b0;
endcase
//
+ // F
+ //
case (fsm_next_state)
FSM_STATE_SAVE_3,
FSM_STATE_SAVE_4,
@@ -391,18 +450,27 @@ module modexpa7_factor # endcase
//
end
-
+
+
+ //
+ // Block Memory Input Logic
+ //
always @(posedge clk) begin
//
+ // F0
+ //
case (fsm_next_state)
FSM_STATE_INIT_1: f0_data_in <= 32'd1;
FSM_STATE_INIT_2: f0_data_in <= 32'd0;
+ //
FSM_STATE_SAVE_3,
FSM_STATE_SAVE_4,
FSM_STATE_SAVE_5: f0_data_in <= flag_keep_f ? f1_data_out : f2_data_out;
default: f0_data_in <= {32{1'bX}};
endcase
//
+ // F1
+ //
case (fsm_next_state)
FSM_STATE_CALC_3,
FSM_STATE_CALC_4,
@@ -411,6 +479,8 @@ module modexpa7_factor # default: f1_data_in <= {32{1'bX}};
endcase
//
+ // F2
+ //
case (fsm_next_state)
FSM_STATE_CALC_5,
FSM_STATE_CALC_6,
@@ -419,6 +489,8 @@ module modexpa7_factor # default: f2_data_in <= {32{1'bX}};
endcase
//
+ // F
+ //
case (fsm_next_state)
FSM_STATE_SAVE_3,
FSM_STATE_SAVE_4,
@@ -430,13 +502,17 @@ module modexpa7_factor # //
- // FSM Transition Logic
+ // FSM Process
//
always @(posedge clk or negedge rst_n)
//
if (rst_n == 1'b0) fsm_state <= FSM_STATE_IDLE;
else fsm_state <= fsm_next_state;
+
+ //
+ // FSM Transition Logic
+ //
always @* begin
//
fsm_next_state = FSM_STATE_STOP;
@@ -447,36 +523,24 @@ module modexpa7_factor # else fsm_next_state = FSM_STATE_IDLE;
FSM_STATE_INIT_1: fsm_next_state = FSM_STATE_INIT_2;
-
FSM_STATE_INIT_2: if (f0_addr_done) fsm_next_state = FSM_STATE_CALC_1;
else fsm_next_state = FSM_STATE_INIT_2;
FSM_STATE_CALC_1: fsm_next_state = FSM_STATE_CALC_2;
-
FSM_STATE_CALC_2: fsm_next_state = FSM_STATE_CALC_3;
-
FSM_STATE_CALC_3: fsm_next_state = FSM_STATE_CALC_4;
-
FSM_STATE_CALC_4: fsm_next_state = FSM_STATE_CALC_5;
-
FSM_STATE_CALC_5: fsm_next_state = FSM_STATE_CALC_6;
-
FSM_STATE_CALC_6: if (f1_addr_done) fsm_next_state = FSM_STATE_CALC_7;
else fsm_next_state = FSM_STATE_CALC_6;
-
FSM_STATE_CALC_7: fsm_next_state = FSM_STATE_CALC_8;
-
FSM_STATE_CALC_8: fsm_next_state = FSM_STATE_SAVE_1;
FSM_STATE_SAVE_1: fsm_next_state = FSM_STATE_SAVE_2;
-
FSM_STATE_SAVE_2: fsm_next_state = FSM_STATE_SAVE_3;
-
FSM_STATE_SAVE_3: fsm_next_state = FSM_STATE_SAVE_4;
-
FSM_STATE_SAVE_4: if (f12_addr_done_dly) fsm_next_state = FSM_STATE_SAVE_5;
else fsm_next_state = FSM_STATE_SAVE_4;
-
FSM_STATE_SAVE_5: if (cyc_cnt_done) fsm_next_state = FSM_STATE_STOP;
else fsm_next_state = FSM_STATE_CALC_1;
diff --git a/src/rtl/modexpa7_n_coeff.v b/src/rtl/modexpa7_n_coeff.v index 2bed5cd..d416898 100644 --- a/src/rtl/modexpa7_n_coeff.v +++ b/src/rtl/modexpa7_n_coeff.v @@ -153,6 +153,7 @@ module modexpa7_n_coeff # * further investigation...
*
*/
+
reg [OPERAND_ADDR_WIDTH+4:0] cyc_cnt;
wire [OPERAND_ADDR_WIDTH+4:0] cyc_cnt_zero = {{OPERAND_ADDR_WIDTH{1'b0}}, {5{1'b0}}};
@@ -271,7 +272,7 @@ module modexpa7_n_coeff # wire rb_addr_done = (rb_addr == bram_addr_last) ? 1'b1 : 1'b0;
wire n_coeff_addr_done = (n_coeff_addr == bram_addr_last) ? 1'b1 : 1'b0;
- /* map top-level ports to internal register */
+ /* map top-level ports to internal registers */
assign n_bram_addr = n_addr;
assign n_coeff_bram_addr = n_coeff_addr;
assign n_coeff_bram_in = n_coeff_data_in;
|