diff options
-rw-r--r-- | src/rtl/residue.v | 369 |
1 files changed, 183 insertions, 186 deletions
diff --git a/src/rtl/residue.v b/src/rtl/residue.v index ccfaeda..f3d114c 100644 --- a/src/rtl/residue.v +++ b/src/rtl/residue.v @@ -47,97 +47,88 @@ module residue #(parameter OPW = 32, parameter ADW = 8) ( - input wire clk, - input wire reset_n, + input wire clk, + input wire reset_n, - input wire calculate, - output wire ready, + input wire calculate, + output wire ready, - input wire [14 : 0] nn, //MAX(2*N)=8192*2 (14 bit) - input wire [07 : 0] length, + input wire [14 : 0] nn, //MAX(2*N)=8192*2 (14 bit) + input wire [(ADW - 1) : 0] length, - output wire [07 : 0] opa_rd_addr, - input wire [31 : 0] opa_rd_data, - output wire [07 : 0] opa_wr_addr, - output wire [31 : 0] opa_wr_data, - output wire opa_wr_we, + output wire [(ADW - 1) : 0] opa_rd_addr, + input wire [(OPW - 1) : 0] opa_rd_data, + output wire [(ADW - 1) : 0] opa_wr_addr, + output wire [(OPW - 1) : 0] opa_wr_data, + output wire opa_wr_we, - output wire [07 : 0] opm_addr, - input wire [31 : 0] opm_data + output wire [(ADW - 1) : 0] opm_addr, + input wire [(OPW - 1) : 0] opm_data ); -//---------------------------------------------------------------- -// Internal constant and parameter definitions. -//---------------------------------------------------------------- + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + localparam CTRL_IDLE = 4'h0; + localparam CTRL_INIT = 4'h1; + localparam CTRL_INIT_STALL = 4'h2; + localparam CTRL_SHL = 4'h3; + localparam CTRL_SHL_STALL = 4'h4; + localparam CTRL_COMPARE = 4'h5; + localparam CTRL_COMPARE_STALL = 4'h6; + localparam CTRL_SUB = 4'h7; + localparam CTRL_SUB_STALL = 4'h8; + localparam CTRL_LOOP = 4'h9; -// m_residue_2_2N_array( N, M, Nr) -// Nr = 00...01 ; Nr = 1 == 2**(2N-2N) -// for (int i = 0; i < 2 * N; i++) -// Nr = Nr shift left 1 -// if (Nr less than M) continue; -// Nr = Nr - M -// return Nr -// -localparam CTRL_IDLE = 4'h0; -localparam CTRL_INIT = 4'h1; // Nr = 00...01 ; Nr = 1 == 2**(2N-2N) -localparam CTRL_INIT_STALL = 4'h2; -localparam CTRL_SHL = 4'h3; // Nr = Nr shift left 1 -localparam CTRL_SHL_STALL = 4'h4; -localparam CTRL_COMPARE = 4'h5; //if (Nr less than M) continue; -localparam CTRL_COMPARE_STALL = 4'h6; -localparam CTRL_SUB = 4'h7; //Nr = Nr - M -localparam CTRL_SUB_STALL = 4'h8; -localparam CTRL_LOOP = 4'h9; //for (int i = 0; i < 2 * N; i++) - -//---------------------------------------------------------------- -// Registers including update variables and write enable. -//---------------------------------------------------------------- - -reg [07 : 0] opa_rd_addr_reg; -reg [07 : 0] opa_wr_addr_reg; -reg [31 : 0] opa_wr_data_reg; -reg opa_wr_we_reg; -reg [07 : 0] opm_addr_reg; -reg ready_reg; -reg ready_new; -reg ready_we; -reg [03 : 0] residue_ctrl_reg; -reg [03 : 0] residue_ctrl_new; -reg residue_ctrl_we; -reg reset_word_index; -reg reset_n_counter; -reg [14 : 0] loop_counter_1_to_nn_reg; //for i = 1 to nn (2*N) -reg [14 : 0] loop_counter_1_to_nn_new; -reg loop_counter_1_to_nn_we; -reg [14 : 0] nn_reg; -reg nn_we; -reg [07 : 0] length_m1_reg; -reg [07 : 0] length_m1_new; -reg length_m1_we; -reg [07 : 0] word_index_reg; -reg [07 : 0] word_index_new; -reg word_index_we; - -reg [31 : 0] one_data; -wire [31 : 0] sub_data; -wire [31 : 0] shl_data; -reg sub_carry_in_new; -reg sub_carry_in_reg; -wire sub_carry_out; -reg shl_carry_in_new; -reg shl_carry_in_reg; -wire shl_carry_out; - -//---------------------------------------------------------------- -// Concurrent connectivity for ports etc. -//---------------------------------------------------------------- -assign opa_rd_addr = opa_rd_addr_reg; -assign opa_wr_addr = opa_wr_addr_reg; -assign opa_wr_data = opa_wr_data_reg; -assign opa_wr_we = opa_wr_we_reg; -assign opm_addr = opm_addr_reg; -assign ready = ready_reg; + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg [(ADW - 1) : 0] opa_rd_addr_reg; + reg [(ADW - 1) : 0] opa_wr_addr_reg; + reg [(OPW - 1) : 0] opa_wr_data_reg; + reg opa_wr_we_reg; + reg [(ADW - 1) : 0] opm_addr_reg; + reg ready_reg; + reg ready_new; + reg ready_we; + reg [03 : 0] residue_ctrl_reg; + reg [03 : 0] residue_ctrl_new; + reg residue_ctrl_we; + reg reset_word_index; + reg reset_n_counter; + reg [14 : 0] loop_counter_1_to_nn_reg; //for i = 1 to nn (2*N) + reg [14 : 0] loop_counter_1_to_nn_new; + reg loop_counter_1_to_nn_we; + reg [14 : 0] nn_reg; + reg nn_we; + reg [(ADW - 1) : 0] length_m1_reg; + reg [(ADW - 1) : 0] length_m1_new; + reg length_m1_we; + reg [(ADW - 1) : 0] word_index_reg; + reg [(ADW - 1) : 0] word_index_new; + reg word_index_we; + + reg [(OPW - 1) : 0] one_data; + wire [(OPW - 1) : 0] sub_data; + wire [(OPW - 1) : 0] shl_data; + reg sub_carry_in_new; + reg sub_carry_in_reg; + wire sub_carry_out; + reg shl_carry_in_new; + reg shl_carry_in_reg; + wire shl_carry_out; + + + //---------------------------------------------------------------- + // Concurrent connectivity for ports etc. + //---------------------------------------------------------------- + assign opa_rd_addr = opa_rd_addr_reg; + assign opa_wr_addr = opa_wr_addr_reg; + assign opa_wr_data = opa_wr_data_reg; + assign opa_wr_we = opa_wr_we_reg; + assign opm_addr = opm_addr_reg; + assign ready = ready_reg; //---------------------------------------------------------------- @@ -166,14 +157,14 @@ assign ready = ready_reg; begin if (!reset_n) begin - residue_ctrl_reg <= CTRL_IDLE; - word_index_reg <= 8'h0; - length_m1_reg <= 8'h0; - nn_reg <= 15'h0; + residue_ctrl_reg <= CTRL_IDLE; + word_index_reg <= {ADW{1'b1}}; + length_m1_reg <= {ADW{1'b1}}; + nn_reg <= 15'h0; loop_counter_1_to_nn_reg <= 15'h0; - ready_reg <= 1'b1; - sub_carry_in_reg <= 1'b0; - shl_carry_in_reg <= 1'b0; + ready_reg <= 1'b1; + sub_carry_in_reg <= 1'b0; + shl_carry_in_reg <= 1'b0; end else begin @@ -228,22 +219,24 @@ assign ready = ready_reg; loop_counter_1_to_nn_we = 1'b1; end + //---------------------------------------------------------------- // implements looping over words in a multiword operation //---------------------------------------------------------------- always @* begin : word_index_process - word_index_new = word_index_reg - 8'h1; + word_index_new = word_index_reg - 1'b1; word_index_we = 1'b1; if (reset_word_index) word_index_new = length_m1_reg; if (residue_ctrl_reg == CTRL_IDLE) - word_index_new = length_m1_new; //reduce a pipeline stage with early read - + //reduce a pipeline stage with early read + word_index_new = length_m1_new; end + //---------------------------------------------------------------- // writer process. implements: // Nr = 00...01 ; Nr = 1 == 2**(2N-2N) @@ -298,6 +291,7 @@ assign ready = ready_reg; opm_addr_reg = word_index_new; end + //---------------------------------------------------------------- // carry process. "Ripple carry awesomeness!" //---------------------------------------------------------------- @@ -320,6 +314,7 @@ assign ready = ready_reg; endcase end + //---------------------------------------------------------------- // Nr = 00...01 ; Nr = 1 == 2**(2N-2N) //---------------------------------------------------------------- @@ -328,128 +323,130 @@ assign ready = ready_reg; one_data = 32'h0; if (residue_ctrl_reg == CTRL_INIT) if (word_index_reg == length_m1_reg) - one_data = 32'h1; + one_data = {{(OPW - 1){1'b0}}, 1'b1}; end -//---------------------------------------------------------------- -// residue_ctrl -// -// Control FSM for residue -//---------------------------------------------------------------- -always @* - begin : residue_ctrl - ready_new = 1'b0; - ready_we = 1'b0; - - residue_ctrl_new = CTRL_IDLE; - residue_ctrl_we = 1'b0; - reset_word_index = 1'b0; - reset_n_counter = 1'b0; + //---------------------------------------------------------------- + // residue_ctrl + // + // Control FSM for residue + //---------------------------------------------------------------- + always @* + begin : residue_ctrl + ready_new = 1'b0; + ready_we = 1'b0; + reset_word_index = 1'b0; + reset_n_counter = 1'b0; + length_m1_new = length - 1'b1; + length_m1_we = 1'b0; + nn_we = 1'b0; + residue_ctrl_new = CTRL_IDLE; + residue_ctrl_we = 1'b0; - length_m1_new = length - 8'h1; - length_m1_we = 1'b0; + case (residue_ctrl_reg) + CTRL_IDLE: + if (calculate) + begin + ready_new = 1'b0; + ready_we = 1'b1; + reset_word_index = 1'b1; + length_m1_we = 1'b1; + nn_we = 1'b1; + residue_ctrl_new = CTRL_INIT; + residue_ctrl_we = 1'b1; + end - nn_we = 1'b0; + // Nr = 00...01 ; Nr = 1 == 2**(2N-2N) + CTRL_INIT: + if (word_index_reg == 0) + begin + residue_ctrl_new = CTRL_INIT_STALL; + residue_ctrl_we = 1'b1; + end - case (residue_ctrl_reg) - CTRL_IDLE: - if (calculate) + CTRL_INIT_STALL: begin - ready_new = 1'b0; - ready_we = 1'b1; - residue_ctrl_new = CTRL_INIT; - residue_ctrl_we = 1'b1; reset_word_index = 1'b1; - length_m1_we = 1'b1; - nn_we = 1'b1; + reset_n_counter = 1'b1; + residue_ctrl_new = CTRL_SHL; + residue_ctrl_we = 1'b1; end - CTRL_INIT: - if (word_index_reg == 8'h0) + // Nr = Nr shift left 1 + CTRL_SHL: begin - residue_ctrl_new = CTRL_INIT_STALL; - residue_ctrl_we = 1'b1; + if (word_index_reg == 0) + begin + residue_ctrl_new = CTRL_SHL_STALL; + residue_ctrl_we = 1'b1; + end end - CTRL_INIT_STALL: - begin - reset_word_index = 1'b1; - reset_n_counter = 1'b1; - residue_ctrl_new = CTRL_SHL; - residue_ctrl_we = 1'b1; - end - - CTRL_SHL: - begin - if (word_index_reg == 8'h0) + CTRL_SHL_STALL: begin - residue_ctrl_new = CTRL_SHL_STALL; + reset_word_index = 1'b1; + residue_ctrl_new = CTRL_COMPARE; residue_ctrl_we = 1'b1; end - end - CTRL_SHL_STALL: - begin - reset_word_index = 1'b1; - residue_ctrl_new = CTRL_COMPARE; - residue_ctrl_we = 1'b1; - end + //if (Nr less than M) continue + CTRL_COMPARE: + if (word_index_reg == 0) + begin + residue_ctrl_new = CTRL_COMPARE_STALL; + residue_ctrl_we = 1'b1; + end - CTRL_COMPARE: - if (word_index_reg == 8'h0) + CTRL_COMPARE_STALL: begin - residue_ctrl_new = CTRL_COMPARE_STALL; + reset_word_index = 1'b1; residue_ctrl_we = 1'b1; + if (sub_carry_in_reg == 1'b1) + //TODO: Bug! detect CF to detect less than, but no detect ZF to detect equal to. + residue_ctrl_new = CTRL_SUB; + else + residue_ctrl_new = CTRL_LOOP; end - CTRL_COMPARE_STALL: - begin - reset_word_index = 1'b1; - residue_ctrl_we = 1'b1; - if (sub_carry_in_reg == 1'b1) - //TODO: Bug! detect CF to detect less than, but no detect ZF to detect equal to. - residue_ctrl_new = CTRL_SUB; - else - residue_ctrl_new = CTRL_LOOP; - end + //Nr = Nr - M + CTRL_SUB: + if (word_index_reg == 0) + begin + residue_ctrl_new = CTRL_SUB_STALL; + residue_ctrl_we = 1'b1; + end - CTRL_SUB: - if (word_index_reg == 8'h0) + CTRL_SUB_STALL: begin - residue_ctrl_new = CTRL_SUB_STALL; + residue_ctrl_new = CTRL_LOOP; residue_ctrl_we = 1'b1; end - CTRL_SUB_STALL: - begin - residue_ctrl_new = CTRL_LOOP; - residue_ctrl_we = 1'b1; - end - - CTRL_LOOP: - begin - if (loop_counter_1_to_nn_reg == nn_reg) - begin - ready_new = 1'b1; - ready_we = 1'b1; - residue_ctrl_new = CTRL_IDLE; - residue_ctrl_we = 1'b1; - end - else - begin - reset_word_index = 1'b1; - residue_ctrl_new = CTRL_SHL; - residue_ctrl_we = 1'b1; - end - end + //for (int i = 0; i < 2 * N; i++) + CTRL_LOOP: + begin + if (loop_counter_1_to_nn_reg == nn_reg) + begin + ready_new = 1'b1; + ready_we = 1'b1; + residue_ctrl_new = CTRL_IDLE; + residue_ctrl_we = 1'b1; + end + else + begin + reset_word_index = 1'b1; + residue_ctrl_new = CTRL_SHL; + residue_ctrl_we = 1'b1; + end + end - default: - begin - end + default: + begin + end - endcase - end + endcase + end endmodule // residue |