diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rtl/montprod.v | 214 |
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 |