aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rtl/residue.v369
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