aboutsummaryrefslogtreecommitdiff
path: root/src/rtl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rtl')
-rw-r--r--src/rtl/montprod.v214
1 files changed, 105 insertions, 109 deletions
diff --git a/src/rtl/montprod.v b/src/rtl/montprod.v
index 4af1069..ccf8341 100644
--- a/src/rtl/montprod.v
+++ b/src/rtl/montprod.v
@@ -79,9 +79,10 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
localparam CTRL_L_STALLPIPE_ES = 4'h9;
localparam CTRL_EMIT_S = 4'ha;
- localparam SMUX_0 = 2'h0;
- localparam SMUX_ADD = 2'h1;
- localparam SMUX_SHR = 2'h2;
+ localparam SMUX_ZERO = 2'h0;
+ localparam SMUX_ITER = 2'h1;
+ localparam SMUX_ADD = 2'h2;
+ localparam SMUX_SHR = 2'h3;
//----------------------------------------------------------------
@@ -98,12 +99,11 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
reg [1 : 0] s_mux_new;
reg [1 : 0] s_mux_reg;
- reg [(OPW - 1) : 0] s_mem_new;
reg s_mem_we_reg;
reg s_mem_we_new;
- reg [(ADW - 1) : 0] s_mem_addr;
- reg [(ADW - 1) : 0] s_mem_wr_addr_reg;
- wire [(OPW - 1) : 0] s_mem_read_data;
+
+ reg [(ADW - 1) : 0] s_mem_read_addr_reg;
+ reg [(ADW - 1) : 0] s_mem_write_addr_reg;
reg q_new;
reg q_reg;
@@ -117,8 +117,6 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
reg loop_ctr_set;
reg loop_ctr_dec;
- reg [(ADW - 1) : 0] b_word_index; //loop counter as a word index
-
reg [(13 - ADW - 1) : 0] b_bit_index_reg;
reg [(13 - ADW - 1) : 0] b_bit_index_new;
reg b_bit_index_we;
@@ -153,36 +151,42 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
wire [(OPW - 1) : 0] add_result_sm;
wire add_carry_out_sm;
+ reg [(ADW - 1) : 0] b_word_index; //loop counter as a word index
+
reg [(OPW - 1) : 0] shr_data_in;
wire shr_carry_out;
wire [(OPW - 1) : 0] shr_data_out;
reg [(ADW - 1) : 0] tmp_opa_addr;
- reg [(ADW - 1) : 0] tmp_opb_addr;
- reg [(ADW - 1) : 0] tmp_opm_addr;
- reg [(ADW - 1) : 0] tmp_result_addr;
- reg [(OPW - 1) : 0] tmp_result_data;
reg tmp_result_we;
+ reg [(ADW - 1) : 0] s_mem_read_addr;
+ wire [(OPW - 1) : 0] s_mem_read_data;
+ reg [(ADW - 1) : 0] s_mem_write_addr;
+ reg [(OPW - 1) : 0] s_mem_write_data;
+
reg [(OPW - 1) : 0] sa_adder_data_in;
reg [(OPW - 1) : 0] muxed_s_mem_read_data;
- reg [(ADW - 1) : 0] length_m1;
+ wire [(ADW - 1) : 0] length_m1;
// Temporary debug wires.
reg b_js;
reg pr_tt;
+ reg s_mem_we;
//----------------------------------------------------------------
// Concurrent connectivity for ports etc.
//----------------------------------------------------------------
+ assign length_m1 = length - 1'b1;
+
assign opa_addr = tmp_opa_addr;
- assign opb_addr = tmp_opb_addr;
- assign opm_addr = tmp_opm_addr;
+ assign opb_addr = b_word_index;
+ assign opm_addr = word_index_reg;
- assign result_addr = tmp_result_addr;
- assign result_data = tmp_result_data;
+ assign result_addr = word_index_prev_reg;
+ assign result_data = s_mem_read_data;
assign result_we = tmp_result_we;
assign ready = ready_reg;
@@ -193,11 +197,11 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
//----------------------------------------------------------------
blockmem1r1w #(.OPW(OPW), .ADW(ADW)) s_mem(
.clk(clk),
- .read_addr(s_mem_addr),
+ .read_addr(s_mem_read_addr),
.read_data(s_mem_read_data),
- .wr(s_mem_we_reg),
- .write_addr(s_mem_wr_addr_reg),
- .write_data(s_mem_new)
+ .wr(s_mem_we_reg | s_mem_we),
+ .write_addr(s_mem_write_addr),
+ .write_data(s_mem_write_data)
);
adder #(.OPW(OPW)) s_adder_sm(
@@ -245,16 +249,16 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
shr_carry_in_reg <= 1'b0;
b_reg <= 1'b0;
q_reg <= 1'b0;
- s_mux_reg <= SMUX_0;
+ s_mux_reg <= SMUX_ZERO;
s_mem_we_reg <= 1'b0;
- s_mem_wr_addr_reg <= {ADW{1'b0}};
+ s_mem_read_addr_reg <= {ADW{1'b0}};
b_bit_index_reg <= {(13 - ADW){1'b0}};
first_iteration_reg <= 1'b0;
montprod_ctrl_reg <= CTRL_IDLE;
end
else
begin
- s_mem_wr_addr_reg <= s_mem_addr;
+ s_mem_read_addr_reg <= s_mem_read_addr;
s_mem_we_reg <= s_mem_we_new;
s_mux_reg <= s_mux_new;
@@ -294,74 +298,10 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
//----------------------------------------------------------------
- // prodcalc
- //
- // Logic to generate addresses and data selection
- // for the OpA, OpM and Result memories.
- //----------------------------------------------------------------
- always @*
- begin : prodcalc
- tmp_opa_addr = word_index_reg;
- tmp_opb_addr = b_word_index;
- tmp_opm_addr = word_index_reg;
- tmp_result_addr = word_index_prev_reg;
- tmp_result_data = s_mem_read_data;
- tmp_result_we = 1'b0;
-
- if (montprod_ctrl_reg == CTRL_LOOP_ITER)
- begin
- tmp_opa_addr = length_m1;
- end
-
- if (montprod_ctrl_reg == CTRL_EMIT_S)
- tmp_result_we = 1'b1;
-
- end // prodcalc
-
-
- //----------------------------------------------------------------
- // word_index
- //
- // Logic that implements the word index used to drive
- // addresses for operands.
- //----------------------------------------------------------------
- always @*
- begin : word_index
- word_index_new = {ADW{1'b0}};
- word_index_we = 1'b0;
-
- if (reset_word_index_lsw)
- begin
- word_index_new = length_m1;
- word_index_we = 1'b1;
- end
-
- if (reset_word_index_msw)
- begin
- word_index_new = {ADW{1'b0}};
- word_index_we = 1'b1;
- end
-
- if (inc_word_index)
- begin
- word_index_new = word_index_reg + 1'b1;
- word_index_we = 1'b1;
- end
-
- if (dec_word_index)
- begin
- word_index_new = word_index_reg - 1'b1;
- word_index_we = 1'b1;
- end
- end // word_index
-
-
- //----------------------------------------------------------------
// s_logic
//
// Logic to calculate S memory updates including address
- // and write enable. This is where the main montprod
- // calculation is performed.
+ // and write enable. This is the main montprod datapath.
//----------------------------------------------------------------
always @*
begin : s_logic
@@ -370,9 +310,11 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
sa_adder_data_in = {OPW{1'b0}};
add_carry_in_sa_new = 1'b0;
add_carry_in_sm_new = 1'b0;
- s_mem_new = {OPW{1'b0}};
+ s_mem_read_addr = word_index_reg;
+ s_mem_write_addr = s_mem_read_addr_reg;
+ s_mem_write_data = {OPW{1'b0}};
s_mem_we_new = 1'b0;
- s_mem_addr = word_index_reg;
+ s_mem_we = 1'b0;
case (montprod_ctrl_reg)
CTRL_INIT_S:
@@ -382,7 +324,7 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
CTRL_LOOP_ITER:
begin
- s_mem_addr = length_m1;
+ s_mem_read_addr = length_m1;
end
CTRL_CALC_ADD:
@@ -404,8 +346,19 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
case (s_mux_reg)
+ SMUX_ZERO:
+ begin
+ s_mem_write_data = {OPW{1'b0}};
+ end
+
+ SMUX_ITER:
+ begin
+ end
+
SMUX_ADD:
begin
+ s_mem_we = b_reg | q_reg | first_iteration_reg;
+
if (first_iteration_reg)
muxed_s_mem_read_data = {OPW{1'b0}};
else
@@ -418,13 +371,13 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
sa_adder_data_in = muxed_s_mem_read_data;
if (b_reg)
- s_mem_new = add_result_sa;
+ s_mem_write_data = add_result_sa;
else if (q_reg)
- s_mem_new = add_result_sm;
+ s_mem_write_data = add_result_sm;
else if (first_iteration_reg)
- s_mem_new = {OPW{1'b0}};
+ s_mem_write_data = {OPW{1'b0}};
else
- s_mem_new = s_mem_read_data;
+ s_mem_write_data = s_mem_read_data;
add_carry_in_sa_new = add_carry_out_sa;
add_carry_in_sm_new = add_carry_out_sm;
@@ -432,8 +385,9 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
SMUX_SHR:
begin
+ s_mem_we = 1'b1;
shr_data_in = s_mem_read_data;
- s_mem_new = shr_data_out;
+ s_mem_write_data = shr_data_out;
shr_carry_in_new = shr_carry_out;
end
@@ -450,27 +404,63 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
// Extract b and q bits.
// b: current bit of B used.
// q = (s - b * A) & 1
+ // update the b bit and word indices based on loop counter.
//----------------------------------------------------------------
always @*
begin : bq
b_new = opb_data[b_bit_index_reg];
q_new = s_mem_read_data[0] ^ (opa_data[0] & b_new);
+
+ b_bit_index_new = (2**(13 - ADW) - 1) - loop_ctr_reg[(13 - ADW - 1) : 0];
+ b_word_index = loop_ctr_reg[12 : (13 - ADW)];
end // bq
//----------------------------------------------------------------
+ // word_index
+ //
+ // Logic that implements the word index used to drive
+ // addresses for operands.
+ //----------------------------------------------------------------
+ always @*
+ begin : word_index
+ word_index_new = {ADW{1'b0}};
+ word_index_we = 1'b0;
+
+ if (reset_word_index_lsw)
+ begin
+ word_index_new = length_m1;
+ word_index_we = 1'b1;
+ end
+
+ if (reset_word_index_msw)
+ begin
+ word_index_new = {ADW{1'b0}};
+ word_index_we = 1'b1;
+ end
+
+ if (inc_word_index)
+ begin
+ word_index_new = word_index_reg + 1'b1;
+ word_index_we = 1'b1;
+ end
+
+ if (dec_word_index)
+ begin
+ word_index_new = word_index_reg - 1'b1;
+ word_index_we = 1'b1;
+ end
+ end // word_index
+
+
+ //----------------------------------------------------------------
// loop_ctr
- // Logic for updating the loop counter and
- // setting related B indices.
+ // Logic for updating the loop counter.
//----------------------------------------------------------------
always @*
begin : loop_ctr
- loop_ctr_new = 13'h0;
- loop_ctr_we = 1'b0;
- length_m1 = length - 1'b1;
-
- b_bit_index_new = (2**(13 - ADW) - 1) - loop_ctr_reg[(13 - ADW - 1) : 0];
- b_word_index = loop_ctr_reg[12 : (13 - ADW)];
+ loop_ctr_new = 13'h0;
+ loop_ctr_we = 1'b0;
if (loop_ctr_set)
begin
@@ -499,16 +489,19 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
loop_ctr_dec = 1'b0;
b_bit_index_we = 1'b0;
bq_we = 1'b0;
- s_mux_new = SMUX_0;
+ s_mux_new = SMUX_ZERO;
dec_word_index = 1'b0;
inc_word_index = 1'b0;
reset_word_index_lsw = 1'b0;
reset_word_index_msw = 1'b0;
first_iteration_new = 1'b0;
first_iteration_we = 1'b0;
+ tmp_opa_addr = word_index_reg;
+ tmp_result_we = 1'b0;
montprod_ctrl_new = CTRL_IDLE;
montprod_ctrl_we = 1'b0;
+
case (montprod_ctrl_reg)
CTRL_IDLE:
begin
@@ -519,6 +512,7 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
ready_new = 1'b0;
ready_we = 1'b1;
reset_word_index_lsw = 1'b1;
+ loop_ctr_set = 1'b1;
montprod_ctrl_new = CTRL_INIT_S;
montprod_ctrl_we = 1'b1;
end
@@ -526,11 +520,11 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
CTRL_INIT_S:
begin
+ s_mux_new = SMUX_ZERO;
dec_word_index = 1'b1;
if (word_index_reg == 0)
begin
- loop_ctr_set = 1'b1;
montprod_ctrl_new = CTRL_WAIT;
montprod_ctrl_we = 1'b1;
end
@@ -538,7 +532,6 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
CTRL_WAIT:
begin
- loop_ctr_set = 1'b1;
montprod_ctrl_new = CTRL_LOOP_ITER;
montprod_ctrl_we = 1'b1;
end
@@ -547,6 +540,8 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
// Also abort loop if done.
CTRL_LOOP_ITER:
begin
+ s_mux_new = SMUX_ITER;
+ tmp_opa_addr = length_m1;
b_bit_index_we = 1'b1;
montprod_ctrl_new = CTRL_LOOP_BQ;
montprod_ctrl_we = 1'b1;
@@ -617,6 +612,7 @@ module montprod #(parameter OPW = 32, parameter ADW = 8)
CTRL_EMIT_S:
begin
dec_word_index = 1'b1;
+ tmp_result_we = 1'b1;
if (word_index_prev_reg == 0)
begin