diff --git a/core/div_algorithms/div_algorithm.sv b/core/div_algorithms/div_algorithm.sv index 735f861..904dd8d 100644 --- a/core/div_algorithms/div_algorithm.sv +++ b/core/div_algorithms/div_algorithm.sv @@ -34,19 +34,7 @@ module div_algorithm generate case(DIV_ALGORITHM) RADIX_2 : div_radix2 div_block (.*); - RADIX_2_EARLY_TERMINATE : div_radix2_ET div_block (.*); - RADIX_2_EARLY_TERMINATE_FULL : div_radix2_ET_full div_block (.*); - RADIX_4 : div_radix4 div_block (.*); - RADIX_4_EARLY_TERMINATE : div_radix4_ET div_block (.*); - RADIX_4_EARLY_TERMINATE_FULL: div_radix4_ET_full div_block (.*); - RADIX_8 : div_radix8 div_block (.*); - RADIX_8_EARLY_TERMINATE : div_radix8_ET div_block (.*); - RADIX_16 : div_radix16 div_block (.*); - QUICK_NAIVE : div_quick_naive div_block (.*); QUICK_CLZ : div_quick_clz div_block (.*); - QUICK_CLZ_MK2 : div_quick_clz_mk2 div_block (.*); - QUICK_RADIX_4 : div_quick_radix_4 div_block (.*); - default : $error("invalid div selection"); endcase endgenerate diff --git a/core/div_algorithms/div_quick_clz.sv b/core/div_algorithms/div_quick_clz.sv index 61e88e4..c958b34 100644 --- a/core/div_algorithms/div_quick_clz.sv +++ b/core/div_algorithms/div_quick_clz.sv @@ -31,6 +31,7 @@ module div_quick_clz logic running; logic terminate; + logic [div.DATA_WIDTH-1:0] divisor_r; logic [div.DATA_WIDTH-1:0] normalized_divisor; @@ -79,13 +80,16 @@ module div_quick_clz div.done <= (running & terminate) | (div.start & divisor_is_zero_first_cycle); end - assign terminate = div.remainder < div.divisor; + assign terminate = div.remainder < divisor_r; //////////////////////////////////////////////////// //Divisor Pre-processing always_ff @ (posedge clk) begin - divisor_CLZ_r <= divisor_CLZ; - normalized_divisor <= div.divisor << divisor_CLZ; + if (div.start) begin + divisor_r <= div.divisor; + divisor_CLZ_r <= divisor_CLZ; + normalized_divisor <= div.divisor << divisor_CLZ; + end end //////////////////////////////////////////////////// diff --git a/core/div_algorithms/div_quick_clz_mk2.sv b/core/div_algorithms/div_quick_clz_mk2.sv deleted file mode 100644 index fbfe414..0000000 --- a/core/div_algorithms/div_quick_clz_mk2.sv +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright © 2017-2019 Eric Matthews, Lesley Shannon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Initial code developed under the supervision of Dr. Lesley Shannon, - * Reconfigurable Computing Lab, Simon Fraser University. - * - * Author(s): - * Eric Matthews - * Alec Lu - */ - - -module div_quick_clz_mk2 - ( - input logic clk, - input logic rst, - unsigned_division_interface.divider div - ); - - logic running; - logic terminate; - - logic [div.DATA_WIDTH:0] A0; - logic [div.DATA_WIDTH:0] A1; - logic [div.DATA_WIDTH-1:0] A2; - - logic [div.DATA_WIDTH-1:0] new_R; - logic [div.DATA_WIDTH-1:0] new_Q_bit; - logic [div.DATA_WIDTH-1:0] new_R2; - - logic [div.DATA_WIDTH-1:0] Q_bit1; - logic [div.DATA_WIDTH-1:0] Q_bit2; - - logic [div.DATA_WIDTH-1:0] B1; - logic [div.DATA_WIDTH-1:0] B2; - - localparam CLZ_W = $clog2(div.DATA_WIDTH); - logic [CLZ_W-1:0] R_CLZ; - logic [CLZ_W-1:0] B_CLZ; - logic [CLZ_W-1:0] B_CLZ_r; - logic [CLZ_W-1:0] CLZ_delta; - logic divisor_is_zero_first_cycle; - - logic [div.DATA_WIDTH-1:0] shiftedB; - ////////////////////////////////////////// - - clz clz_r (.clz_input(div.remainder), .clz(R_CLZ)); - clz clz_b (.clz_input(div.divisor), .clz(B_CLZ)); - - always_ff @ (posedge clk) begin - B_CLZ_r <= B_CLZ; - shiftedB <= div.divisor << B_CLZ; - end - - assign CLZ_delta = B_CLZ_r - R_CLZ; - - always_comb begin - Q_bit1 = 0; - Q_bit1[CLZ_delta] = 1; - end - assign Q_bit2 = {1'b0, Q_bit1[div.DATA_WIDTH-1:1]}; - - always_comb begin - if (A1[div.DATA_WIDTH]) - new_Q_bit = Q_bit2; - else if (A0[div.DATA_WIDTH] || CLZ_delta == 0) - new_Q_bit = Q_bit1; - else - new_Q_bit = (Q_bit1 | Q_bit2); - end - - assign B1 = shiftedB >> R_CLZ; - assign A1 = div.remainder - B1; - assign B2 = {1'b0, B1[div.DATA_WIDTH-1:1]}; - assign A2 = div.remainder - B2; - - assign A0 = div.remainder - (B1 + B2); - - always_comb begin - if (A1[div.DATA_WIDTH]) - new_R = A2[div.DATA_WIDTH-1:0]; - else if (A0[div.DATA_WIDTH] || CLZ_delta == 0) - new_R = A1[div.DATA_WIDTH-1:0]; - else - new_R = A0[div.DATA_WIDTH-1:0]; - end - - assign divisor_is_zero_first_cycle = (B_CLZ == 5'b11111 && ~div.divisor[0]); - always @ (posedge clk) begin - if (div.start) - div.divisor_is_zero <= divisor_is_zero_first_cycle; - end - - always_ff @ (posedge clk) begin - if (rst) - running <= 0; - else if (div.start & ~divisor_is_zero_first_cycle) - running <= 1; - else if (terminate) - running <= 0; - end - - always_ff @ (posedge clk) begin - div.done <= (running & terminate) | (div.start & divisor_is_zero_first_cycle); - end - - assign terminate = div.remainder < div.divisor; - - always_ff @ (posedge clk) begin - if (div.start) - div.quotient <= '0; - else if (~terminate & running) - div.quotient <= div.quotient | new_Q_bit; - end - - initial begin - div.remainder = 0; - end - always @ (posedge clk) begin - if (div.start) - div.remainder <= div.dividend; - else if (~terminate & running) - div.remainder <= new_R; - end - -endmodule diff --git a/core/div_algorithms/div_quick_naive.sv b/core/div_algorithms/div_quick_naive.sv deleted file mode 100644 index ee481d4..0000000 --- a/core/div_algorithms/div_quick_naive.sv +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright © 2017-2019 Eric Matthews, Lesley Shannon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Initial code developed under the supervision of Dr. Lesley Shannon, - * Reconfigurable Computing Lab, Simon Fraser University. - * - * Author(s): - * Eric Matthews - * Alec Lu - */ - - -module div_quick_naive - ( - input logic clk, - input logic rst, - unsigned_division_interface.divider div - ); - - logic running; - logic terminate; - - logic [div.DATA_WIDTH:0] A1; - logic [div.DATA_WIDTH-1:0] A2; - - logic [div.DATA_WIDTH-1:0] new_R; - logic [div.DATA_WIDTH-1:0] new_Q_bit; - - logic [div.DATA_WIDTH-1:0] Q_bit1; - logic [div.DATA_WIDTH-1:0] Q_bit2; - - logic [div.DATA_WIDTH-1:0] B1; - logic [div.DATA_WIDTH-1:0] B2; - - localparam MSB_W = $clog2(div.DATA_WIDTH); - logic [MSB_W-1:0] R_MSB; - logic [MSB_W-1:0] B_MSB; - logic [MSB_W-1:0] B_MSB_r; - logic [MSB_W-1:0] MSB_delta; - logic divisor_is_zero_first_cycle; - - msb_naive msb_r (.msb_input(div.remainder), .msb(R_MSB)); - msb_naive msb_b (.msb_input(div.divisor), .msb(B_MSB)); - // msb msb_r (.msb_input(div.remainder), .msb(R_MSB)); - // msb msb_b (.msb_input(div.divisor), .msb(B_MSB)); - - assign MSB_delta = R_MSB - B_MSB_r; - - assign Q_bit1 = 2**MSB_delta; - assign Q_bit2 = {1'b0, Q_bit1[div.DATA_WIDTH-1:1]}; - assign new_Q_bit = div.quotient | (A1[div.DATA_WIDTH] ? Q_bit2 : Q_bit1); - - assign B1 = div.divisor << MSB_delta; - assign A1 = div.remainder - B1; - assign B2 = {1'b0,B1[div.DATA_WIDTH-1:1]}; - assign A2 = div.remainder - B2; - - assign new_R = A1[div.DATA_WIDTH] ? A2 : A1[div.DATA_WIDTH-1:0]; - - assign divisor_is_zero_first_cycle = (B_MSB == 0 && ~div.divisor[0]); - always @ (posedge clk) begin - if (div.start) - div.divisor_is_zero <= divisor_is_zero_first_cycle; - end - - always_ff @ (posedge clk) begin - if (rst) - running <= 0; - else if (div.start & ~divisor_is_zero_first_cycle) - running <= 1; - else if (terminate) - running <= 0; - end - - always_ff @ (posedge clk) begin - if (rst) - div.done <= 0; - else if (div.done) - div.done <= 0; - else if ((running & terminate) | (div.start & divisor_is_zero_first_cycle)) - div.done <= 1; - end - - assign terminate = (div.remainder < div.divisor); - - always_ff @ (posedge clk) begin - B_MSB_r <= B_MSB; - if (div.start) begin - div.quotient <= 0; - div.remainder <= div.dividend; - end - else if (~terminate & running) begin - div.quotient <= new_Q_bit; - div.remainder <= new_R; - end - end - -endmodule diff --git a/core/div_algorithms/div_quick_radix4.sv b/core/div_algorithms/div_quick_radix4.sv deleted file mode 100644 index 67a7dba..0000000 --- a/core/div_algorithms/div_quick_radix4.sv +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright © 2017-2019 Eric Matthews, Lesley Shannon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Initial code developed under the supervision of Dr. Lesley Shannon, - * Reconfigurable Computing Lab, Simon Fraser University. - * - * Author(s): - * Eric Matthews - * Alec Lu - */ - - -module div_quick_radix_4 - ( - input logic clk, - input logic rst, - unsigned_division_interface.divider div - ); - - logic terminate; - logic [div.DATA_WIDTH/2-1:0] shift_count; - - logic [div.DATA_WIDTH+1:0] PR; - logic [2:0] new_PR_sign; - logic [div.DATA_WIDTH+2:0] new_PR_1; - logic [div.DATA_WIDTH+2:0] new_PR_2; - logic [div.DATA_WIDTH+2:0] new_PR_3; - logic [div.DATA_WIDTH+1:0] B_1; - logic [div.DATA_WIDTH+1:0] B_2; - logic [div.DATA_WIDTH+1:0] B_3; - - logic [div.DATA_WIDTH-1:0] AR_r; - logic [div.DATA_WIDTH-1:0] Q_temp; - logic [5:0] shift_num_R; - logic [6:0] shift_num_R_normalized; - logic [5:0] shift_num_Q; - logic [div.DATA_WIDTH*2+1:0] combined; - logic [div.DATA_WIDTH*2+1:0] combined_normalized; - logic terminate_early; - - localparam CLZ_W = $clog2(div.DATA_WIDTH); - logic [CLZ_W-1:0] A_CLZ; - logic [CLZ_W-1:0] B_CLZ; - logic [CLZ_W-1:0] A_CLZ_r; - logic [CLZ_W-1:0] B_CLZ_r; - logic [CLZ_W-1:0] CLZ_delta; - - logic firstCycle; - logic greaterDivisor; - logic [div.DATA_WIDTH-1:0] A_shifted; - logic [div.DATA_WIDTH-1:0] B_shifted; - logic [div.DATA_WIDTH-1:0] R_shifted; - logic [div.DATA_WIDTH-1:0] B_shifted_r; - - //implementation - //////////////////////////////////////////////////// - clz clz_r (.clz_input(div.dividend), .clz(A_CLZ)); - clz clz_b (.clz_input(div.divisor), .clz(B_CLZ)); - - always_ff @ (posedge clk) begin - if (rst) begin - firstCycle <= 0; - A_CLZ_r <= 0; - B_CLZ_r <= 0; - A_shifted <= 0; - B_shifted <= 0; - end else begin - if (div.start) begin - firstCycle <= 1; - A_CLZ_r <= A_CLZ; - B_CLZ_r <= B_CLZ; - greaterDivisor <= div.divisor > div.dividend; - A_shifted <= div.dividend << A_CLZ; - B_shifted <= div.divisor << A_CLZ; - end else begin - firstCycle <= 0; - end - end - end - - assign new_PR_1 = {1'b0, PR} - {1'b0, B_1}; - assign new_PR_2 = {1'b0, PR} - {1'b0, B_2}; - assign new_PR_3 = {1'b0, PR} - {1'b0, B_3}; - assign new_PR_sign = {new_PR_3[div.DATA_WIDTH+2], new_PR_2[div.DATA_WIDTH+2], new_PR_1[div.DATA_WIDTH+2]}; - - //Shift reg for - always_ff @ (posedge clk) begin - if (rst) begin - shift_count <= 0; - end else if (firstCycle) begin - shift_count <= 1; - end else if (terminate) begin - shift_count <= 0; - end else begin - shift_count <= {shift_count[14:0], firstCycle}; - end - end - - always_ff @ (posedge clk) begin - if (firstCycle) begin - shift_num_R <= 2; - shift_num_R_normalized <= 2 + {2'b0, A_CLZ_r}; - shift_num_Q <= 32; - end - else if (~terminate & ~terminate_early) begin - shift_num_R <= shift_num_R + 2; - shift_num_R_normalized <= shift_num_R_normalized + 2; - shift_num_Q <= shift_num_Q - 2; - end - end - - assign combined_normalized = {PR, AR_r} >> shift_num_R_normalized; - assign div.remainder = combined_normalized[div.DATA_WIDTH-1:0]; - - assign combined = {PR, AR_r} >> shift_num_R; - assign R_shifted = combined[div.DATA_WIDTH-1:0]; - - assign terminate_early = ~firstCycle & ((B_shifted_r > R_shifted) | greaterDivisor); - assign div.quotient = terminate_early ? (Q_temp << shift_num_Q) : Q_temp; - - always_ff @ (posedge clk) begin - if (firstCycle) begin - PR <= {{(div.DATA_WIDTH){1'b0}}, A_shifted[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - Q_temp <= '0; - AR_r <= {A_shifted[div.DATA_WIDTH-3:0], 2'b00}; - B_shifted_r <= B_shifted; - B_1 <= {2'b0, B_shifted}; //1xB - B_2 <= {1'b0, B_shifted, 1'b0}; //2xB - B_3 <= {1'b0, B_shifted, 1'b0} + {2'b0, B_shifted}; //3xB - end else if (~terminate & ~terminate_early) begin - AR_r <= {AR_r[div.DATA_WIDTH-3:0], 2'b00}; - case (new_PR_sign) - 3'b111 : begin - PR <= {PR[div.DATA_WIDTH-1:0], AR_r[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - Q_temp <= {div.quotient[div.DATA_WIDTH-3:0], 2'b00}; - end - 3'b110 : begin - PR <= {new_PR_1[div.DATA_WIDTH-1:0], AR_r[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - Q_temp <= {div.quotient[div.DATA_WIDTH-3:0], 2'b01}; - end - 3'b100 : begin - PR <= {new_PR_2[div.DATA_WIDTH-1:0], AR_r[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - Q_temp <= {div.quotient[div.DATA_WIDTH-3:0], 2'b10}; - end - default : begin //3'b000 : begin - PR <= {new_PR_3[div.DATA_WIDTH-1:0], AR_r[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - Q_temp <= {div.quotient[div.DATA_WIDTH-3:0], 2'b11}; - end - endcase - end - end - - always_ff @ (posedge clk) begin - if (div.start) - div.divisor_is_zero <= ~(|div.divisor); - else if (~terminate & ~terminate_early) - div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign); - end - - always_ff @ (posedge clk) begin - if (rst) - terminate <= 0; - else begin - if (firstCycle) - terminate <= 0; - else if (shift_count[15] | terminate_early) - terminate <= 1; - end - end - - always_ff @ (posedge clk) begin - if (rst) - div.done <= 0; - else begin - if (firstCycle) - div.done <= 0; - else if ((shift_count[15] | terminate_early) & ~div.done & ~terminate) - div.done <= 1; - else if (div.done) - div.done <= 0; - end - end - -endmodule diff --git a/core/div_algorithms/div_radix16.sv b/core/div_algorithms/div_radix16.sv deleted file mode 100644 index 35da949..0000000 --- a/core/div_algorithms/div_radix16.sv +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright © 2017-2019 Eric Matthews, Lesley Shannon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Initial code developed under the supervision of Dr. Lesley Shannon, - * Reconfigurable Computing Lab, Simon Fraser University. - * - * Author(s): - * Eric Matthews - * Alec Lu - */ - - -module div_radix16 - ( - input logic clk, - input logic rst, - unsigned_division_interface.divider div - ); - - - logic terminate; - logic [div.DATA_WIDTH-1:0] shift_count; - - logic [div.DATA_WIDTH+3:0] PR; - logic [div.DATA_WIDTH+3:0] PR_lower; - logic [div.DATA_WIDTH+3:0] PR_upper; - logic [div.DATA_WIDTH-1:0] Q_lower; - logic [div.DATA_WIDTH-1:0] Q_upper; - - logic [6:0] new_PR_sign; - logic [div.DATA_WIDTH+4:0] new_PR_8; - logic [div.DATA_WIDTH+4:0] new_PR [6:0]; - - logic [div.DATA_WIDTH+3:0] B_6; - logic [div.DATA_WIDTH+3:0] B_10; - logic [div.DATA_WIDTH+3:0] B_12; - logic [div.DATA_WIDTH+3:0] B_14; - - - //Shift reg for - always_ff @ (posedge clk) begin - shift_count[0] <= div.start; - shift_count[31:1] <= shift_count[30:0]; - end - - assign new_PR_8 = {1'b0, PR} - {1'b0, {1'b0, div.divisor, 3'b000}}; - assign new_PR[0] = new_PR_8[div.DATA_WIDTH+4] ? {1'b0, PR} - {1'b0, {4'b0000, div.divisor}} : {1'b0, PR} - {1'b0, {1'b0, div.divisor, 3'b000}} - {4'b0000, div.divisor}; - assign new_PR[1] = new_PR_8[div.DATA_WIDTH+4] ? {1'b0, PR} - {1'b0, {3'b000, div.divisor, 1'b0}} : {1'b0, PR} - {1'b0, B_10}; - assign new_PR[2] = new_PR_8[div.DATA_WIDTH+4] ? {1'b0, PR} - {1'b0, {3'b000, div.divisor, 1'b0}} - {4'b0000, div.divisor} : {1'b0, PR} - {1'b0, B_10} - {4'b0000, div.divisor}; - assign new_PR[3] = new_PR_8[div.DATA_WIDTH+4] ? {1'b0, PR} - {1'b0, {2'b00, div.divisor, 2'b00}} : {1'b0, PR} - {1'b0, B_12}; - assign new_PR[4] = new_PR_8[div.DATA_WIDTH+4] ? {1'b0, PR} - {1'b0, {2'b00, div.divisor, 2'b00}} - {4'b0000, div.divisor} : {1'b0, PR} - {1'b0, B_12} - {4'b0000, div.divisor}; - assign new_PR[5] = new_PR_8[div.DATA_WIDTH+4] ? {1'b0, PR} - {1'b0, B_6} : {1'b0, PR} - {1'b0, B_14}; - assign new_PR[6] = new_PR_8[div.DATA_WIDTH+4] ? {1'b0, PR} - {1'b0, B_6} - {4'b0000, div.divisor} : {1'b0, PR} - {1'b0, B_14} - {4'b0000, div.divisor}; - - assign new_PR_sign = {new_PR[6][div.DATA_WIDTH+4], new_PR[5][div.DATA_WIDTH+4], new_PR[4][div.DATA_WIDTH+4], - new_PR[3][div.DATA_WIDTH+4], new_PR[2][div.DATA_WIDTH+4], new_PR[1][div.DATA_WIDTH+4], - new_PR[0][div.DATA_WIDTH+4]}; - - always_comb begin - PR_lower = ({PR[div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-4]} & {(div.DATA_WIDTH+4){(new_PR_sign[0])}}); - Q_lower = ({div.quotient[div.DATA_WIDTH-5:0], 4'b0000} & {div.DATA_WIDTH{(new_PR_sign[0])}}); - for (int i = 1; i < 7; i = i+1) begin - PR_lower = PR_lower | ({new_PR[i-1][div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-4]} & {(div.DATA_WIDTH+4){(~new_PR_sign[i-1] & new_PR_sign[i])}}); - Q_lower = Q_lower | ({div.quotient[div.DATA_WIDTH-5:0], i[3:0]} & {div.DATA_WIDTH{(~new_PR_sign[i-1] & new_PR_sign[i])}}); - end - PR_lower = PR_lower | ({new_PR[6][div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-4]} & {(div.DATA_WIDTH+4){(~new_PR_sign[6])}}); - Q_lower = Q_lower | ({div.quotient[div.DATA_WIDTH-5:0], 4'b0111} & {div.DATA_WIDTH{(~new_PR_sign[6])}}); - - PR_upper = {new_PR_8[div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-4]} & {(div.DATA_WIDTH+4){new_PR_sign[0]}}; - Q_upper = {div.quotient[div.DATA_WIDTH-5:0], 4'b1000} & {div.DATA_WIDTH{new_PR_sign[0]}}; - for (int i = 1; i < 7; i = i+1) begin - PR_upper = PR_upper | ({new_PR[i-1][div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-4]} & {(div.DATA_WIDTH+4){(~new_PR_sign[i-1] & new_PR_sign[i])}}); - Q_upper = Q_upper | ({div.quotient[div.DATA_WIDTH-5:0], (i[3:0] | 4'b1000)} & {div.DATA_WIDTH{(~new_PR_sign[i-1] & new_PR_sign[i])}}); - end - PR_upper = PR_upper | ({new_PR[6][div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-4]} & {(div.DATA_WIDTH+4){(~new_PR_sign[6])}}); - Q_upper = Q_upper | ({div.quotient[div.DATA_WIDTH-5:0], 4'b1111} & {div.DATA_WIDTH{(~new_PR_sign[6])}}); - end - - always_ff @ (posedge clk) begin - if (div.start) begin - B_6 <= {2'b00, div.divisor, 2'b00} + {3'b000, div.divisor, 1'b0}; - B_10 <= {1'b0, div.divisor, 3'b000} + {3'b000, div.divisor, 1'b0}; - B_12 <= {1'b0, div.divisor, 3'b000} + {2'b00, div.divisor, 2'b00}; - B_14 <= {1'b0, div.divisor, 3'b000} + {2'b00, div.divisor, 2'b00} + {3'b000, div.divisor, 1'b0}; - - PR <= {{(div.DATA_WIDTH){1'b0}}, div.dividend[div.DATA_WIDTH-1:div.DATA_WIDTH-4]}; - div.quotient <= {div.dividend[div.DATA_WIDTH-5:0], 4'b0000}; - end - else if (~terminate) begin - case (new_PR_8[div.DATA_WIDTH+4]) - 1'b1 : begin - PR <= PR_lower; - div.quotient <= Q_lower; - end - 1'b0 : begin - PR <= PR_upper; - div.quotient <= Q_upper; - end - endcase - end - end - - assign div.remainder = PR[div.DATA_WIDTH+3:4]; - - always_ff @ (posedge clk) begin - if (div.start) - div.divisor_is_zero <= ~div.divisor[0]; - else if (~terminate) - div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign); - end - - always_ff @ (posedge clk) begin - if (rst) - terminate <= 0; - else begin - if (div.start) - terminate <= 0; - if (shift_count[7]) - terminate <= 1; - end - end - - always_ff @ (posedge clk) begin - if (rst) - div.done <= 0; - else begin - if (shift_count[7]) - div.done <= 1; - else if (div.done) - div.done <= 0; - end - end - -endmodule diff --git a/core/div_algorithms/div_radix2.sv b/core/div_algorithms/div_radix2.sv index 63fb33b..7eb40ef 100644 --- a/core/div_algorithms/div_radix2.sv +++ b/core/div_algorithms/div_radix2.sv @@ -31,6 +31,7 @@ module div_radix2 logic terminate; + logic [div.DATA_WIDTH-1:0] divisor_r; logic [div.DATA_WIDTH:0] new_PR; logic [div.DATA_WIDTH:0] PR; logic [div.DATA_WIDTH-1:0] shift_count; @@ -38,7 +39,7 @@ module div_radix2 //implementation //////////////////////////////////////////////////// - assign new_PR = PR - {1'b0, div.divisor}; + assign new_PR = PR - {1'b0, divisor_r}; assign negative_sub_rst = new_PR[div.DATA_WIDTH]; //Shift reg for @@ -48,6 +49,7 @@ module div_radix2 always_ff @ (posedge clk) begin if (div.start) begin + divisor_r <= div.divisor; PR <= {(div.DATA_WIDTH)'(1'b0), div.dividend[div.DATA_WIDTH-1]}; div.quotient <= {div.dividend[div.DATA_WIDTH-2:0], 1'b0}; end diff --git a/core/div_algorithms/div_radix2_ET.sv b/core/div_algorithms/div_radix2_ET.sv deleted file mode 100644 index fd30d24..0000000 --- a/core/div_algorithms/div_radix2_ET.sv +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright © 2017-2019 Eric Matthews, Lesley Shannon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Initial code developed under the supervision of Dr. Lesley Shannon, - * Reconfigurable Computing Lab, Simon Fraser University. - * - * Author(s): - * Eric Matthews - * Alec Lu - */ - - -module div_radix2_ET - ( - input logic clk, - input logic rst, - unsigned_division_interface.divider div - ); - - logic terminate; - logic terminate_early; - - logic [div.DATA_WIDTH:0] new_PR; - logic [div.DATA_WIDTH:0] PR; - - logic [div.DATA_WIDTH-1:0] shift_count; - - logic negative_sub_rst; - - //implementation - //////////////////////////////////////////////////// - assign new_PR = PR - {1'b0, div.divisor}; - assign negative_sub_rst = new_PR[div.DATA_WIDTH]; - - always_ff @ (posedge clk) begin - shift_count <= {shift_count[30:0], div.start & ~terminate_early}; - end - - assign terminate_early = div.divisor > div.dividend; - - always_ff @ (posedge clk) begin - if (div.start) begin - if (terminate_early) begin - PR <= {div.dividend, 1'b0}; - div.quotient <= '0; - end else begin - PR <= {(div.DATA_WIDTH)'(1'b0), div.dividend[div.DATA_WIDTH-1]}; - div.quotient <= {div.dividend[div.DATA_WIDTH-2:0], 1'b0}; - end - end else if (~terminate) begin - PR <= negative_sub_rst ? {PR[div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1]} : {new_PR[div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1]}; - div.quotient <= {div.quotient[div.DATA_WIDTH-2:0], ~negative_sub_rst}; - end - end - - assign div.remainder = PR[div.DATA_WIDTH:1]; - - always_ff @ (posedge clk) begin - if (div.start) - div.divisor_is_zero <= ~div.divisor[0]; - else if (~terminate) - div.divisor_is_zero <= div.divisor_is_zero & ~negative_sub_rst; - end - - always_ff @ (posedge clk) begin - if (rst) - terminate <= 0; - else begin - if (div.start) begin - if (terminate_early) begin - terminate <= 1; - end else begin - terminate <= 0; - end - end - if (shift_count[31]) - terminate <= 1; - end - end - - always_ff @ (posedge clk) begin - if (rst) - div.done <= 0; - else begin - if (div.done) - div.done <= 0; - else if ((~div.start & (shift_count[31])) | (div.start & terminate_early)) - div.done <= 1; - end - end - -endmodule diff --git a/core/div_algorithms/div_radix2_ET_full.sv b/core/div_algorithms/div_radix2_ET_full.sv deleted file mode 100644 index fecda31..0000000 --- a/core/div_algorithms/div_radix2_ET_full.sv +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright © 2017-2019 Eric Matthews, Lesley Shannon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Initial code developed under the supervision of Dr. Lesley Shannon, - * Reconfigurable Computing Lab, Simon Fraser University. - * - * Author(s): - * Eric Matthews - * Alec Lu - */ - - -module div_radix2_ET_full - ( - input logic clk, - input logic rst, - unsigned_division_interface.divider div - ); - - logic terminate; - - logic [div.DATA_WIDTH:0] new_PR; - logic [div.DATA_WIDTH:0] PR; - - logic [div.DATA_WIDTH-1:0] shift_count; - - logic negative_sub_rst; - logic [div.DATA_WIDTH-1:0] AR_r; - logic [div.DATA_WIDTH-1:0] Q_temp; - logic [5:0] shift_num_R; - logic [5:0] shift_num_Q; - logic [div.DATA_WIDTH*2:0] combined; - logic [div.DATA_WIDTH*2:0] combined_r; - logic terminate_early; - logic terminate_early_r; - - //implementation - //////////////////////////////////////////////////// - assign new_PR = PR - {1'b0, div.divisor}; - assign negative_sub_rst = new_PR[div.DATA_WIDTH]; - - always_ff @ (posedge clk) begin - if (div.start) - shift_count <= 32'd1; - else - shift_count <= {shift_count[30:0], div.start}; - end - - always_ff @ (posedge clk) begin - if (div.start) begin - shift_num_R <= 1; - shift_num_Q <= 32; - end - else if (~terminate & ~terminate_early) begin - shift_num_R <= shift_num_R + 1; - shift_num_Q <= shift_num_Q - 1; - end - end - - assign combined = {PR, AR_r} >> shift_num_R; - - assign div.remainder = combined[div.DATA_WIDTH-1:0]; - assign terminate_early = div.divisor > div.remainder; - assign div.quotient = terminate_early ? (Q_temp << shift_num_Q) : Q_temp; - - always_ff @ (posedge clk) begin - if (div.start) begin - PR <= {(div.DATA_WIDTH)'(1'b0), div.dividend[div.DATA_WIDTH-1]}; - Q_temp <= '0; - AR_r <= {div.dividend[div.DATA_WIDTH-2:0], 1'b0}; - end - else if (~terminate & ~terminate_early) begin - PR <= negative_sub_rst ? {PR[div.DATA_WIDTH-1:0], AR_r[div.DATA_WIDTH-1]} : - {new_PR[div.DATA_WIDTH-1:0], AR_r[div.DATA_WIDTH-1]}; - Q_temp <= {Q_temp[div.DATA_WIDTH-2:0], ~negative_sub_rst}; - AR_r <= {AR_r[div.DATA_WIDTH-2:0], 1'b0}; - end - end - - always_ff @ (posedge clk) begin - if (div.start) - div.divisor_is_zero <= ~div.divisor[0]; - else if (~terminate) - div.divisor_is_zero <= div.divisor_is_zero & ~negative_sub_rst; - end - - always_ff @ (posedge clk) begin - if (rst) - terminate <= 0; - else begin - if (div.start) - terminate <= 0; - //if (shift_count[31]) - else if (shift_count[31] | terminate_early) - terminate <= 1; - end - end - - always_ff @ (posedge clk) begin - if (rst) - div.done <= 0; - else begin - // if (shift_count[31]) - if (~div.start & (shift_count[31] | terminate_early) & ~div.done & ~terminate) - div.done <= 1; - else if (div.done) - div.done <= 0; - end - end - -endmodule diff --git a/core/div_algorithms/div_radix4.sv b/core/div_algorithms/div_radix4.sv deleted file mode 100644 index 460ef7e..0000000 --- a/core/div_algorithms/div_radix4.sv +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright © 2017-2019 Eric Matthews, Lesley Shannon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Initial code developed under the supervision of Dr. Lesley Shannon, - * Reconfigurable Computing Lab, Simon Fraser University. - * - * Author(s): - * Eric Matthews - * Alec Lu - */ - - -module div_radix4 - ( - input logic clk, - input logic rst, - unsigned_division_interface.divider div - ); - - logic terminate; - logic [div.DATA_WIDTH/2-1:0] shift_count; - - logic [div.DATA_WIDTH+1:0] PR; - logic [2:0] new_PR_sign; - logic [div.DATA_WIDTH+2:0] new_PR_1; - logic [div.DATA_WIDTH+2:0] new_PR_2; - logic [div.DATA_WIDTH+2:0] new_PR_3; - logic [div.DATA_WIDTH+1:0] B_1; - logic [div.DATA_WIDTH+1:0] B_2; - logic [div.DATA_WIDTH+1:0] B_3; - - //implementation - //////////////////////////////////////////////////// - assign new_PR_1 = {1'b0, PR} - {1'b0, B_1}; - assign new_PR_2 = {1'b0, PR} - {1'b0, B_2}; - assign new_PR_3 = {1'b0, PR} - {1'b0, B_3}; - assign new_PR_sign = {new_PR_3[div.DATA_WIDTH+2], new_PR_2[div.DATA_WIDTH+2], new_PR_1[div.DATA_WIDTH+2]}; - - //Shift reg for - always_ff @ (posedge clk) begin - shift_count <= {shift_count[14:0], div.start}; - end - - always_ff @ (posedge clk) begin - if (div.start) begin - PR <= {{(div.DATA_WIDTH){1'b0}}, div.dividend[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - div.quotient <= {div.dividend[div.DATA_WIDTH-3:0], 2'b00}; - - B_1 <= {2'b0, div.divisor}; //1xB - B_2 <= {1'b0, div.divisor, 1'b0}; //2xB - B_3 <= {1'b0, div.divisor, 1'b0} + {2'b0, div.divisor}; //3xB - end else if (~terminate) begin - case (new_PR_sign) - 3'b111 : begin - PR <= {PR[div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - div.quotient <= {div.quotient[div.DATA_WIDTH-3:0], 2'b00}; - end - 3'b110 : begin - PR <= {new_PR_1[div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - div.quotient <= {div.quotient[div.DATA_WIDTH-3:0], 2'b01}; - end - 3'b100 : begin - PR <= {new_PR_2[div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - div.quotient <= {div.quotient[div.DATA_WIDTH-3:0], 2'b10}; - end - default: begin //3'b000 : begin - PR <= {new_PR_3[div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - div.quotient <= {div.quotient[div.DATA_WIDTH-3:0], 2'b11}; - end - endcase - end - end - - assign div.remainder = PR[div.DATA_WIDTH+1:2]; - - always_ff @ (posedge clk) begin - if (div.start) - div.divisor_is_zero <= ~div.divisor[0]; - else if (~terminate) - div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign); - end - - always_ff @ (posedge clk) begin - if (rst) - terminate <= 0; - else begin - if (div.start) - terminate <= 0; - if (shift_count[15]) - terminate <= 1; - end - end - - always_ff @ (posedge clk) begin - if (rst) - div.done <= 0; - else begin - if (shift_count[15]) - div.done <= 1; - else if (div.done) - div.done <= 0; - end - end - -endmodule diff --git a/core/div_algorithms/div_radix4_ET.sv b/core/div_algorithms/div_radix4_ET.sv deleted file mode 100644 index dcfa4b9..0000000 --- a/core/div_algorithms/div_radix4_ET.sv +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright © 2017-2019 Eric Matthews, Lesley Shannon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Initial code developed under the supervision of Dr. Lesley Shannon, - * Reconfigurable Computing Lab, Simon Fraser University. - * - * Author(s): - * Eric Matthews - * Alec Lu - */ - - -module div_radix4_ET - ( - input logic clk, - input logic rst, - unsigned_division_interface.divider div - ); - - logic terminate; - logic terminate_early; - logic [div.DATA_WIDTH/2-1:0] shift_count; - - logic [div.DATA_WIDTH+1:0] PR; - logic [2:0] new_PR_sign; - logic [div.DATA_WIDTH+2:0] new_PR_1; - logic [div.DATA_WIDTH+2:0] new_PR_2; - logic [div.DATA_WIDTH+2:0] new_PR_3; - logic [div.DATA_WIDTH+1:0] B_1; - logic [div.DATA_WIDTH+1:0] B_2; - logic [div.DATA_WIDTH+1:0] B_3; - - //implementation - //////////////////////////////////////////////////// - assign new_PR_1 = {1'b0, PR} - {1'b0, B_1}; - assign new_PR_2 = {1'b0, PR} - {1'b0, B_2}; - assign new_PR_3 = {1'b0, PR} - {1'b0, B_3}; - assign new_PR_sign = {new_PR_3[div.DATA_WIDTH+2], new_PR_2[div.DATA_WIDTH+2], new_PR_1[div.DATA_WIDTH+2]}; - - //Shift reg for - always_ff @ (posedge clk) begin - shift_count <= {shift_count[14:0], div.start & ~terminate_early}; - end - - assign terminate_early = div.divisor > div.dividend; - - always_ff @ (posedge clk) begin - if (div.start) begin - if (terminate_early) begin - PR <= {div.dividend, 2'b00}; - div.quotient <= '0; - end - else begin - PR <= {{(div.DATA_WIDTH){1'b0}}, div.dividend[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - div.quotient <= {div.dividend[div.DATA_WIDTH-3:0], 2'b00}; - end - B_1 <= {2'b0, div.divisor}; //1xB - B_2 <= {1'b0, div.divisor, 1'b0}; //2xB - B_3 <= {1'b0, div.divisor, 1'b0} + {2'b0, div.divisor}; //3xB - end - else if (~terminate) begin - case (new_PR_sign) - 3'b111 : begin - PR <= {PR[div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - div.quotient <= {div.quotient[div.DATA_WIDTH-3:0], 2'b00}; - end - 3'b110 : begin - PR <= {new_PR_1[div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - div.quotient <= {div.quotient[div.DATA_WIDTH-3:0], 2'b01}; - end - 3'b100 : begin - PR <= {new_PR_2[div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - div.quotient <= {div.quotient[div.DATA_WIDTH-3:0], 2'b10}; - end - default: begin //3'b000 : begin - PR <= {new_PR_3[div.DATA_WIDTH-1:0], div.quotient[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - div.quotient <= {div.quotient[div.DATA_WIDTH-3:0], 2'b11}; - end - endcase - end - end - - assign div.remainder = PR[div.DATA_WIDTH+1:2]; - - always_ff @ (posedge clk) begin - if (div.start) - div.divisor_is_zero <= ~div.divisor[0]; - else if (~terminate) - div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign); - end - - always_ff @ (posedge clk) begin - if (rst) - terminate <= 0; - else begin - if (div.start) - if (terminate_early) begin - terminate <= 1; - end else begin - terminate <= 0; - end - if (shift_count[15]) - terminate <= 1; - end - end - - always_ff @ (posedge clk) begin - if (rst) - div.done <= 0; - else begin - if (div.done) - div.done <= 0; - else if ((~div.start & (shift_count[15])) | (div.start & terminate_early)) - div.done <= 1; - end - end - -endmodule diff --git a/core/div_algorithms/div_radix4_ET_full.sv b/core/div_algorithms/div_radix4_ET_full.sv deleted file mode 100644 index 441ffd7..0000000 --- a/core/div_algorithms/div_radix4_ET_full.sv +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright © 2017-2019 Eric Matthews, Lesley Shannon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Initial code developed under the supervision of Dr. Lesley Shannon, - * Reconfigurable Computing Lab, Simon Fraser University. - * - * Author(s): - * Eric Matthews - * Alec Lu - */ - - -module div_radix4_ET_full - ( - input logic clk, - input logic rst, - unsigned_division_interface.divider div - ); - - logic terminate; - logic [div.DATA_WIDTH/2-1:0] shift_count; - - logic [div.DATA_WIDTH+1:0] PR; - logic [2:0] new_PR_sign; - logic [div.DATA_WIDTH+2:0] new_PR_1; - logic [div.DATA_WIDTH+2:0] new_PR_2; - logic [div.DATA_WIDTH+2:0] new_PR_3; - logic [div.DATA_WIDTH+1:0] B_1; - logic [div.DATA_WIDTH+1:0] B_2; - logic [div.DATA_WIDTH+1:0] B_3; - - logic [div.DATA_WIDTH-1:0] B_r; - logic [div.DATA_WIDTH-1:0] AR_r; - logic [div.DATA_WIDTH-1:0] Q_temp; - logic [5:0] shift_num_R; - logic [5:0] shift_num_Q; - logic [div.DATA_WIDTH*2:0] combined; - logic terminate_early; - - //implementation - //////////////////////////////////////////////////// - assign new_PR_1 = {1'b0, PR} - {1'b0, B_1}; - assign new_PR_2 = {1'b0, PR} - {1'b0, B_2}; - assign new_PR_3 = {1'b0, PR} - {1'b0, B_3}; - assign new_PR_sign = {new_PR_3[div.DATA_WIDTH+2], new_PR_2[div.DATA_WIDTH+2], new_PR_1[div.DATA_WIDTH+2]}; - - //Shift reg for - always_ff @ (posedge clk) begin - if (div.start) - shift_count <= 1; - else - shift_count <= {shift_count[14:0], div.start}; - end - - always_ff @ (posedge clk) begin - if (div.start) begin - shift_num_R <= 2; - shift_num_Q <= 32; - end - else if (~terminate & ~terminate_early) begin - shift_num_R <= shift_num_R + 2; - shift_num_Q <= shift_num_Q - 2; - end - end - - assign combined = {PR[div.DATA_WIDTH:0], AR_r} >> shift_num_R; - assign div.remainder = combined[div.DATA_WIDTH-1:0]; - assign terminate_early = B_r > div.remainder; - assign div.quotient = terminate_early ? (Q_temp << shift_num_Q) : Q_temp; - - always_ff @ (posedge clk) begin - if (div.start) begin - PR <= {{(div.DATA_WIDTH){1'b0}}, div.dividend[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - Q_temp <= '0; - AR_r <= {div.dividend[div.DATA_WIDTH-3:0], 2'b00}; - B_r <= div.divisor; - B_1 <= {2'b0, div.divisor}; //1xB - B_2 <= {1'b0, div.divisor, 1'b0}; //2xB - B_3 <= {1'b0, div.divisor, 1'b0} + {2'b0, div.divisor}; //3xB - end else if (~terminate & ~terminate_early) begin - AR_r <= {AR_r[div.DATA_WIDTH-3:0], 2'b00}; - case (new_PR_sign) - 3'b111 : begin - PR <= {PR[div.DATA_WIDTH-1:0], AR_r[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - Q_temp <= {div.quotient[div.DATA_WIDTH-3:0], 2'b00}; - end - 3'b110 : begin - PR <= {new_PR_1[div.DATA_WIDTH-1:0], AR_r[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - Q_temp <= {div.quotient[div.DATA_WIDTH-3:0], 2'b01}; - end - 3'b100 : begin - PR <= {new_PR_2[div.DATA_WIDTH-1:0], AR_r[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - Q_temp <= {div.quotient[div.DATA_WIDTH-3:0], 2'b10}; - end - default: begin //3'b000 : begin - PR <= {new_PR_3[div.DATA_WIDTH-1:0], AR_r[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - Q_temp <= {div.quotient[div.DATA_WIDTH-3:0], 2'b11}; - end - endcase - end - end - - always_ff @ (posedge clk) begin - if (div.start) - div.divisor_is_zero <= ~div.divisor[0]; - else if (~terminate) - div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign); - end - - always_ff @ (posedge clk) begin - if (rst) - terminate <= 0; - else begin - if (div.start) - terminate <= 0; - else if (shift_count[15] | terminate_early) - terminate <= 1; - end - end - - always_ff @ (posedge clk) begin - if (rst) - div.done <= 0; - else begin - if (~div.start & (shift_count[15] | terminate_early) & ~div.done & ~terminate) - div.done <= 1; - else if (div.done) - div.done <= 0; - end - end - -endmodule diff --git a/core/div_algorithms/div_radix8.sv b/core/div_algorithms/div_radix8.sv deleted file mode 100644 index d9bdf38..0000000 --- a/core/div_algorithms/div_radix8.sv +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright © 2017-2019 Eric Matthews, Lesley Shannon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Initial code developed under the supervision of Dr. Lesley Shannon, - * Reconfigurable Computing Lab, Simon Fraser University. - * - * Author(s): - * Eric Matthews - * Alec Lu - */ - - -module div_radix8 - ( - input logic clk, - input logic rst, - unsigned_division_interface.divider div - ); - - logic terminate; - logic [10:0] shift_count; - - logic [div.DATA_WIDTH+2:0] PR; - logic [div.DATA_WIDTH:0] Q_33; - logic [6:0] new_PR_sign; - - logic [div.DATA_WIDTH+3:0] new_PR_1; - logic [div.DATA_WIDTH+3:0] new_PR_2; - logic [div.DATA_WIDTH+3:0] new_PR_3; - logic [div.DATA_WIDTH+3:0] new_PR_4; - logic [div.DATA_WIDTH+3:0] new_PR_5; - logic [div.DATA_WIDTH+3:0] new_PR_6; - logic [div.DATA_WIDTH+3:0] new_PR_7; - logic [div.DATA_WIDTH+2:0] B_1; - logic [div.DATA_WIDTH+2:0] B_2; - logic [div.DATA_WIDTH+2:0] B_3; - logic [div.DATA_WIDTH+2:0] B_4; - logic [div.DATA_WIDTH+2:0] B_5; - logic [div.DATA_WIDTH+2:0] B_6; - logic [div.DATA_WIDTH+2:0] B_7; - - //implementation - //////////////////////////////////////////////////// -// assign new_PR_1 = {1'b0, PR} - div.divisor; -// assign new_PR_2 = {1'b0, PR} - {div.divisor, 1'b0}; -// assign new_PR_3 = {1'b0, PR} - {div.divisor, 1'b0} - div.divisor; -// assign new_PR_4 = {1'b0, PR} - {div.divisor, 2'b0}; -// assign new_PR_5 = {1'b0, PR} - {div.divisor, 2'b0} - div.divisor; -// assign new_PR_6 = {1'b0, PR} - {div.divisor, 2'b0} - {div.divisor, 1'b0}; -// assign new_PR_7 = {1'b0, PR} - {div.divisor, 2'b0} - {div.divisor, 1'b0} - div.divisor; - assign new_PR_1 = {1'b0, PR} - B_1; - assign new_PR_2 = {1'b0, PR} - B_2; - assign new_PR_3 = {1'b0, PR} - B_3; - assign new_PR_4 = {1'b0, PR} - B_4; - assign new_PR_5 = {1'b0, PR} - B_5; - assign new_PR_6 = {1'b0, PR} - B_6; - assign new_PR_7 = {1'b0, PR} - B_7; - assign new_PR_sign = {new_PR_7[div.DATA_WIDTH+3], new_PR_6[div.DATA_WIDTH+3], new_PR_5[div.DATA_WIDTH+3], - new_PR_4[div.DATA_WIDTH+3], new_PR_3[div.DATA_WIDTH+3], new_PR_2[div.DATA_WIDTH+3], - new_PR_1[div.DATA_WIDTH+3]}; - - //Shift reg for - always_ff @ (posedge clk) begin - shift_count <= {shift_count[9:0], div.start}; - end - - always_ff @ (posedge clk) begin - if (div.start) begin - PR <= {{(div.DATA_WIDTH){1'b0}}, 1'b0, div.dividend[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - Q_33 <= {div.dividend[div.DATA_WIDTH-3:0], 3'b000}; - - B_1 <= {3'b000, div.divisor}; - B_2 <= {2'b00, div.divisor, 1'b0}; - B_3 <= {2'b00, div.divisor, 1'b0} + {3'b0, div.divisor}; - B_4 <= {1'b0, div.divisor, 2'b00}; - B_5 <= {1'b0, div.divisor, 2'b00} + {3'b0, div.divisor}; - B_6 <= {1'b0, div.divisor, 2'b00} + {2'b00, div.divisor, 1'b0}; - B_7 <= {1'b0, div.divisor, 2'b00} + {2'b00, div.divisor, 1'b0} + {3'b0, div.divisor}; - end - else if (~terminate) begin - case (new_PR_sign) - 7'b1111111 : begin - PR <= {PR[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b000}; - end - 7'b1111110 : begin - PR <= {new_PR_1[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b001}; - end - 7'b1111100 : begin - PR <= {new_PR_2[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b010}; - end - 7'b1111000 : begin - PR <= {new_PR_3[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b011}; - end - 7'b1110000 : begin - PR <= {new_PR_4[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b100}; - end - 7'b1100000 : begin - PR <= {new_PR_5[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b101}; - end - 7'b1000000 : begin - PR <= {new_PR_6[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b110}; - end - default: begin //7'b0000000 : begin - PR <= {new_PR_7[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b111}; - end - endcase - end - end - - assign div.remainder = PR[div.DATA_WIDTH+2:3]; - assign div.quotient = Q_33[div.DATA_WIDTH-1:0]; - - always_ff @ (posedge clk) begin - if (div.start) - div.divisor_is_zero <= ~div.divisor[0]; - else if (~terminate) - div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign); - end - - always_ff @ (posedge clk) begin - if (rst) - terminate <= 0; - else begin - if (div.start) - terminate <= 0; - if (shift_count[10]) - terminate <= 1; - end - end - - always_ff @ (posedge clk) begin - if (rst) - div.done <= 0; - else begin - if (shift_count[10]) - div.done <= 1; - else if (div.done) - div.done <= 0; - end - end - -endmodule diff --git a/core/div_algorithms/div_radix8_ET.sv b/core/div_algorithms/div_radix8_ET.sv deleted file mode 100644 index 9818be6..0000000 --- a/core/div_algorithms/div_radix8_ET.sv +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright © 2017-2019 Eric Matthews, Lesley Shannon - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Initial code developed under the supervision of Dr. Lesley Shannon, - * Reconfigurable Computing Lab, Simon Fraser University. - * - * Author(s): - * Eric Matthews - * Alec Lu - */ - - -module div_radix8_ET - ( - input logic clk, - input logic rst, - unsigned_division_interface.divider div - ); - - logic terminate; - logic terminate_early; - logic [10:0] shift_count; - - logic [div.DATA_WIDTH+2:0] PR; - logic [div.DATA_WIDTH:0] Q_33; - logic [6:0] new_PR_sign; - - logic [div.DATA_WIDTH+3:0] new_PR_1; - logic [div.DATA_WIDTH+3:0] new_PR_2; - logic [div.DATA_WIDTH+3:0] new_PR_3; - logic [div.DATA_WIDTH+3:0] new_PR_4; - logic [div.DATA_WIDTH+3:0] new_PR_5; - logic [div.DATA_WIDTH+3:0] new_PR_6; - logic [div.DATA_WIDTH+3:0] new_PR_7; - - //implementation - //////////////////////////////////////////////////// - assign new_PR_1 = {1'b0, PR} - {4'b0, div.divisor}; - assign new_PR_2 = {1'b0, PR} - {3'b0, div.divisor, 1'b0}; - assign new_PR_3 = {1'b0, PR} - {3'b0, div.divisor, 1'b0} - {4'b0, div.divisor}; - assign new_PR_4 = {1'b0, PR} - {2'b0, div.divisor, 2'b0}; - assign new_PR_5 = {1'b0, PR} - {2'b0, div.divisor, 2'b0} - {4'b0, div.divisor}; - assign new_PR_6 = {1'b0, PR} - {2'b0, div.divisor, 2'b0} - {3'b0, div.divisor, 1'b0}; - assign new_PR_7 = {1'b0, PR} - {2'b0, div.divisor, 2'b0} - {3'b0, div.divisor, 1'b0} - {4'b0, div.divisor}; - assign new_PR_sign = {new_PR_7[div.DATA_WIDTH+3], new_PR_6[div.DATA_WIDTH+3], new_PR_5[div.DATA_WIDTH+3], - new_PR_4[div.DATA_WIDTH+3], new_PR_3[div.DATA_WIDTH+3], new_PR_2[div.DATA_WIDTH+3], - new_PR_1[div.DATA_WIDTH+3]}; - - //Shift reg for - always_ff @ (posedge clk) begin - shift_count <= {shift_count[9:0], div.start & ~terminate_early}; - end - - assign terminate_early = div.divisor > div.dividend; - - always_ff @ (posedge clk) begin - if (div.start) begin - if (terminate_early) begin - PR <= {div.dividend, 3'b000}; - Q_33 <= '0; - end else begin - PR <= {{(div.DATA_WIDTH){1'b0}}, 1'b0, div.dividend[div.DATA_WIDTH-1:div.DATA_WIDTH-2]}; - Q_33 <= {div.dividend[div.DATA_WIDTH-3:0], 3'b000}; - end - end - else if (~terminate) begin - case (new_PR_sign) - 7'b1111111 : begin - PR <= {PR[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b000}; - end - 7'b1111110 : begin - PR <= {new_PR_1[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b001}; - end - 7'b1111100 : begin - PR <= {new_PR_2[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b010}; - end - 7'b1111000 : begin - PR <= {new_PR_3[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b011}; - end - 7'b1110000 : begin - PR <= {new_PR_4[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b100}; - end - 7'b1100000 : begin - PR <= {new_PR_5[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b101}; - end - 7'b1000000 : begin - PR <= {new_PR_6[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b110}; - end - default: begin //7'b0000000 : begin - PR <= {new_PR_7[div.DATA_WIDTH-1:0], Q_33[div.DATA_WIDTH:div.DATA_WIDTH-2]}; - Q_33 <= {Q_33[div.DATA_WIDTH-3:0], 3'b111}; - end - endcase - end - end - - assign div.remainder = PR[div.DATA_WIDTH+2:3]; - assign div.quotient = Q_33[div.DATA_WIDTH-1:0]; - - always_ff @ (posedge clk) begin - if (div.start) - div.divisor_is_zero <= ~div.divisor[0]; - else if (~terminate) - div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign); - end - - always_ff @ (posedge clk) begin - if (rst) - terminate <= 0; - else begin - if (div.start) - if (terminate_early) begin - terminate <= 1; - end else begin - terminate <= 0; - end - if (shift_count[10]) - terminate <= 1; - end - end - - always_ff @ (posedge clk) begin - if (rst) - div.done <= 0; - else begin - if (div.done) - div.done <= 0; - else if ((~div.start & (shift_count[10])) | (div.start & terminate_early)) - div.done <= 1; - end - end - -endmodule diff --git a/core/div_unit.sv b/core/div_unit.sv index ea3f97f..87f0b63 100755 --- a/core/div_unit.sv +++ b/core/div_unit.sv @@ -47,17 +47,22 @@ module div_unit logic remainder_op; typedef struct packed{ - logic [XLEN-1:0] unsigned_dividend; - logic [XLEN-1:0] unsigned_divisor; logic remainder_op; logic negate_quotient; logic negate_remainder; logic reuse_result; id_t id; + } div_attributes_t; + + typedef struct packed{ + logic [XLEN-1:0] unsigned_dividend; + logic [XLEN-1:0] unsigned_divisor; + div_attributes_t attr; } div_fifo_inputs_t; div_fifo_inputs_t fifo_inputs; div_fifo_inputs_t div_op; + div_attributes_t in_progress_attr; unsigned_division_interface #(.DATA_WIDTH(32)) div_core(); @@ -90,36 +95,40 @@ module div_unit assign fifo_inputs.unsigned_dividend = unsigned_dividend; assign fifo_inputs.unsigned_divisor = unsigned_divisor; - assign fifo_inputs.remainder_op = div_inputs.op[1]; - assign fifo_inputs.negate_quotient = negate_quotient; - assign fifo_inputs.negate_remainder = negate_remainder; - assign fifo_inputs.reuse_result = div_inputs.reuse_result; - assign fifo_inputs.id = issue.id; + assign fifo_inputs.attr.remainder_op = div_inputs.op[1]; + assign fifo_inputs.attr.negate_quotient = negate_quotient; + assign fifo_inputs.attr.negate_remainder = negate_remainder; + assign fifo_inputs.attr.reuse_result = div_inputs.reuse_result; + assign fifo_inputs.attr.id = issue.id; //////////////////////////////////////////////////// //Input FIFO - taiga_fifo #(.DATA_WIDTH($bits(div_fifo_inputs_t)), .FIFO_DEPTH(MAX_IDS)) + taiga_fifo #(.DATA_WIDTH($bits(div_fifo_inputs_t)), .FIFO_DEPTH(1)) div_input_fifo (.fifo(input_fifo), .*); assign input_fifo.data_in = fifo_inputs; assign input_fifo.push = issue.new_request; assign input_fifo.potential_push = issue.possible_issue; - assign issue.ready = 1; //As FIFO depth is the same as MAX_INFLIGHT_COUNT - assign input_fifo.pop = wb.done & wb.ack; + assign issue.ready = ~input_fifo.full | input_fifo.pop; //As FIFO depth is the same as MAX_INFLIGHT_COUNT + assign input_fifo.pop = input_fifo.valid & (~in_progress);//wb.done & wb.ack; assign div_op = input_fifo.data_out; //////////////////////////////////////////////////// //Control Signals - assign div_core.start = input_fifo.valid & (~in_progress) & ~div_op.reuse_result; - assign div_done = div_core.done | (input_fifo.valid & div_op.reuse_result); + assign div_core.start = input_fifo.valid & (~in_progress) & ~div_op.attr.reuse_result; + assign div_done = div_core.done | (in_progress & in_progress_attr.reuse_result); //If more than one cycle, set in_progress so that multiple div.start signals are not sent to the div unit. set_clr_reg_with_rst #(.SET_OVER_CLR(1), .WIDTH(1), .RST_VALUE('0)) in_progress_m ( .clk, .rst, - .set(div_core.start), + .set(input_fifo.valid & (~in_progress)), .clr(wb.ack), .result(in_progress) ); + always_ff @ (posedge clk) begin + if (input_fifo.pop) + in_progress_attr <= div_op.attr; + end //////////////////////////////////////////////////// //Div core @@ -130,8 +139,8 @@ module div_unit //////////////////////////////////////////////////// //Output logic done_r; - assign negate_result = div_op.remainder_op ? div_op.negate_remainder : (~div_core.divisor_is_zero & div_op.negate_quotient); - assign wb.rd = negate_if (div_op.remainder_op ? div_core.remainder : ({32{div_core.divisor_is_zero}} | div_core.quotient), negate_result); + assign negate_result = in_progress_attr.remainder_op ? in_progress_attr.negate_remainder : (~div_core.divisor_is_zero & in_progress_attr.negate_quotient); + assign wb.rd = negate_if (in_progress_attr.remainder_op ? div_core.remainder : ({32{div_core.divisor_is_zero}} | div_core.quotient), negate_result); always_ff @ (posedge clk) begin if (wb.ack) @@ -140,7 +149,7 @@ module div_unit done_r <= 1; end assign wb.done = div_done | done_r; - assign wb.id = div_op.id; + assign wb.id = in_progress_attr.id; //////////////////////////////////////////////////// //Assertions diff --git a/core/taiga_config.sv b/core/taiga_config.sv index 2775b18..dcdc128 100755 --- a/core/taiga_config.sv +++ b/core/taiga_config.sv @@ -51,19 +51,8 @@ package taiga_config; //Division algorithm selection typedef enum { - RADIX_2, - RADIX_2_EARLY_TERMINATE, - RADIX_2_EARLY_TERMINATE_FULL, - RADIX_4, - RADIX_4_EARLY_TERMINATE, - RADIX_4_EARLY_TERMINATE_FULL, - RADIX_8, - RADIX_8_EARLY_TERMINATE, - RADIX_16, - QUICK_NAIVE, - QUICK_CLZ, - QUICK_CLZ_MK2, - QUICK_RADIX_4 + RADIX_2,//Smallest + QUICK_CLZ//Highest performance and best performance per LUT } div_type; parameter div_type DIV_ALGORITHM = QUICK_CLZ; diff --git a/tools/taiga_compile_order b/tools/taiga_compile_order index e9df627..f19cbb4 100644 --- a/tools/taiga_compile_order +++ b/tools/taiga_compile_order @@ -62,21 +62,8 @@ ../core/div_algorithms/div_radix2.sv -../core/div_algorithms/div_radix2_ET.sv -../core/div_algorithms/div_radix2_ET_full.sv -../core/div_algorithms/div_radix4.sv -../core/div_algorithms/div_radix8.sv -../core/div_algorithms/div_radix8_ET.sv -../core/div_algorithms/div_radix4_ET.sv -../core/div_algorithms/div_radix4_ET_full.sv -../core/div_algorithms/div_radix16.sv -../core/msb.sv -../core/msb_naive.sv ../core/clz.sv -../core/div_algorithms/div_quick_clz_mk2.sv ../core/div_algorithms/div_quick_clz.sv -../core/div_algorithms/div_quick_radix4.sv -../core/div_algorithms/div_quick_naive.sv ../core/div_algorithms/div_algorithm.sv ../core/div_unit.sv