diff --git a/ip_cores/common/src/rtl/pipeline_if_single.sv b/ip_cores/common/src/rtl/pipeline_if_single.sv index 0d378a7..d6d6d7a 100644 --- a/ip_cores/common/src/rtl/pipeline_if_single.sv +++ b/ip_cores/common/src/rtl/pipeline_if_single.sv @@ -26,21 +26,17 @@ module pipeline_if_single #( if_axi_stream.source o_if ); - - - - // Need pipeline stage to store temp data if_axi_stream #(.DAT_BYTS(DAT_BYTS), .CTL_BITS(CTL_BITS)) if_r (i_if.i_clk); -always_ff @ (i_if.i_clk) begin +always_ff @ (posedge i_if.i_clk) begin if (i_rst) begin o_if.reset_source(); if_r.reset_source(); if_r.rdy <= 0; i_if.rdy <= 0; end else begin - i_if.rdy <= ~o_if.val || (o_if.val && o_if.rdy && ~if_r.val); + i_if.rdy <= ~o_if.val || (o_if.val && o_if.rdy); // Data transfer cases @@ -51,13 +47,14 @@ always_ff @ (i_if.i_clk) begin if_r.val <= 0; // Second case - second interface not valid end else begin - o_if.copy_if(i_if.dat, i_if.val, i_if.sop, i_if.eop, i_if.err, i_if.mod, i_if.ctl); + o_if.copy_if(i_if.dat, i_if.val && i_if.rdy, i_if.sop, i_if.eop, i_if.err, i_if.mod, i_if.ctl); end end // Check for case where input is valid so we need to store in second interface if (i_if.rdy && (o_if.val && ~o_if.rdy)) begin if_r.copy_if(i_if.dat, i_if.val, i_if.sop, i_if.eop, i_if.err, i_if.mod, i_if.ctl); + i_if.rdy <= 0; end end end diff --git a/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult.sv b/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult.sv index 5e3cdf6..5198571 100644 --- a/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult.sv +++ b/zcash_fpga/src/rtl/secp256k1/secp256k1_point_mult.sv @@ -56,7 +56,7 @@ logic [255:0] k_l; jb_point_t p_n, p_q, p_dbl, p_add; logic p_dbl_in_val, p_dbl_in_rdy, p_dbl_out_err, p_dbl_out_val, p_dbl_out_rdy, p_dbl_done; logic p_add_in_val, p_add_in_rdy, p_add_out_err, p_add_out_val, p_add_out_rdy, p_add_done; -logic special_dbl; +logic special_dbl, lookahead_dbl; enum {IDLE, DOUBLE_ADD, ADD_ONLY, FINISHED} state; @@ -77,14 +77,17 @@ always_ff @ (posedge i_clk) begin p_dbl_done <= 0; p_add_done <= 0; special_dbl <= 0; + lookahead_dbl <= 0; end else begin - p_dbl_out_rdy <= 1; - p_add_out_rdy <= 1; + case (state) {IDLE}: begin + p_dbl_out_rdy <= 1; + p_add_out_rdy <= 1; p_dbl_done <= 1; p_add_done <= 1; special_dbl <= 0; + lookahead_dbl <= 0; o_rdy <= 1; o_err <= 0; p_q <= 0; // p_q starts at 0 @@ -118,6 +121,12 @@ always_ff @ (posedge i_clk) begin special_dbl <= 0; end p_n <= p_dbl; + // We can look ahead and start the next double + if ((k_l >> 1) != 0 && ~lookahead_dbl && ~p_add_done) begin + p_dbl_in_val <= 1; + lookahead_dbl <= 1; + p_dbl_out_rdy <= 0; // Want to make sure we don't output while still waiting for add + end end if (p_add_out_val && p_add_out_rdy) begin p_add_done <= 1; @@ -126,6 +135,8 @@ always_ff @ (posedge i_clk) begin // Update variables and issue new commands if (p_add_done && p_dbl_done) begin + lookahead_dbl <= 0; + p_dbl_out_rdy <= 1; p_add_done <= 0; p_dbl_done <= 0; k_l <= k_l >> 1; @@ -143,7 +154,7 @@ always_ff @ (posedge i_clk) begin // Don't need to double on the final bit if ((k_l >> 1) != 0) - p_dbl_in_val <= 1; + p_dbl_in_val <= ~lookahead_dbl; // Don't do if we already started else p_dbl_done <= 1;