mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-20 03:57:18 -04:00
div interface refactor
This commit is contained in:
parent
7dba36573c
commit
0558c63557
22 changed files with 675 additions and 821 deletions
|
@ -64,6 +64,7 @@ module decode(
|
|||
output logic tr_branch_operand_stall,
|
||||
output logic tr_alu_operand_stall,
|
||||
output logic tr_ls_operand_stall,
|
||||
output logic tr_div_operand_stall,
|
||||
|
||||
output logic tr_instruction_issued_dec,
|
||||
output logic [31:0] tr_instruction_pc_dec,
|
||||
|
@ -374,7 +375,6 @@ module decode(
|
|||
assign div_inputs.rs2 = rf_decode.rs2_data;
|
||||
assign div_inputs.op = fn3[1:0];
|
||||
assign div_inputs.reuse_result = prev_div_result_valid_r & current_op_resuses_rs1_rs2;
|
||||
assign div_inputs.instruction_id = ti.issue_id;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
@ -426,6 +426,7 @@ module decode(
|
|||
assign tr_branch_operand_stall = tr_operand_stall & new_request[BRANCH_UNIT_ID];
|
||||
assign tr_alu_operand_stall = tr_operand_stall & new_request[ALU_UNIT_WB_ID] & ~new_request[BRANCH_UNIT_ID];
|
||||
assign tr_ls_operand_stall = tr_operand_stall & new_request[LS_UNIT_WB_ID];
|
||||
assign tr_div_operand_stall = tr_operand_stall & new_request[DIV_UNIT_WB_ID];
|
||||
|
||||
assign tr_instruction_issued_dec = instruction_issued;
|
||||
assign tr_instruction_pc_dec = fb.pc;
|
||||
|
|
|
@ -25,37 +25,27 @@ import taiga_config::*;
|
|||
import taiga_types::*;
|
||||
|
||||
module div_algorithm
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
generate
|
||||
case(DIV_ALGORITHM)
|
||||
RADIX_2 : div_radix2 #(XLEN) div (.*);
|
||||
RADIX_2_EARLY_TERMINATE : div_radix2_ET #(XLEN) div (.*);
|
||||
RADIX_2_EARLY_TERMINATE_FULL : div_radix2_ET_full #(XLEN) div (.*);
|
||||
RADIX_4 : div_radix4 #(XLEN) div (.*);
|
||||
RADIX_4_EARLY_TERMINATE : div_radix4_ET #(XLEN) div (.*);
|
||||
RADIX_4_EARLY_TERMINATE_FULL: div_radix4_ET_full #(XLEN) div (.*);
|
||||
RADIX_8 : div_radix8 #(XLEN) div (.*);
|
||||
RADIX_8_EARLY_TERMINATE : div_radix8_ET #(XLEN) div (.*);
|
||||
RADIX_16 : div_radix16 #(XLEN) div (.*);
|
||||
QUICK_NAIVE : div_quick_naive #(XLEN) div (.*);
|
||||
QUICK_CLZ : div_quick_clz #(XLEN) div (.*);
|
||||
QUICK_CLZ_MK2 : div_quick_clz_mk2 #(XLEN) div (.*);
|
||||
QUICK_RADIX_4 : div_quick_radix_4 #(XLEN) div (.*);
|
||||
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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -23,104 +23,106 @@
|
|||
|
||||
|
||||
module div_quick_clz
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)(
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
logic running;
|
||||
logic terminate;
|
||||
|
||||
logic [C_WIDTH-1:0] A_r;
|
||||
logic [C_WIDTH:0] A1;
|
||||
logic [C_WIDTH-1:0] A2;
|
||||
logic [div.DATA_WIDTH-1:0] normalized_divisor;
|
||||
|
||||
logic [C_WIDTH-1:0] new_R;
|
||||
logic [C_WIDTH-1:0] new_Q_bit;
|
||||
logic overflow;
|
||||
logic [div.DATA_WIDTH-1:0] subtraction1;
|
||||
logic [div.DATA_WIDTH-1:0] subtraction2;
|
||||
|
||||
logic [C_WIDTH-1:0] Q_bit1;
|
||||
logic [C_WIDTH-1:0] Q_bit2;
|
||||
logic [div.DATA_WIDTH-1:0] new_remainder;
|
||||
logic [div.DATA_WIDTH-1:0] new_quotient;
|
||||
|
||||
logic [C_WIDTH-1:0] B1;
|
||||
logic [C_WIDTH-1:0] B2;
|
||||
logic [C_WIDTH-1:0] B_r;
|
||||
logic [div.DATA_WIDTH-1:0] new_Q_bit1;
|
||||
logic [div.DATA_WIDTH-1:0] new_Q_bit2;
|
||||
|
||||
localparam CLZ_W = $clog2(C_WIDTH);
|
||||
logic [CLZ_W-1:0] R_CLZ;
|
||||
logic [CLZ_W-1:0] B_CLZ;
|
||||
logic [CLZ_W-1:0] B_CLZ_r;
|
||||
logic [div.DATA_WIDTH-1:0] test_multiple1;
|
||||
logic [div.DATA_WIDTH-1:0] test_multiple2;
|
||||
|
||||
localparam CLZ_W = $clog2(div.DATA_WIDTH);
|
||||
logic [CLZ_W-1:0] remainder_CLZ;
|
||||
logic [CLZ_W-1:0] divisor_CLZ;
|
||||
logic [CLZ_W-1:0] divisor_CLZ_r;
|
||||
logic [CLZ_W-1:0] CLZ_delta;
|
||||
////////////////////////////////////////////////////
|
||||
//Implementation
|
||||
clz remainder_clz_block (.clz_input(div.remainder), .clz(remainder_CLZ));
|
||||
clz divisor_clz_block (.clz_input(div.divisor), .clz(divisor_CLZ));
|
||||
|
||||
logic firstCycle;
|
||||
logic [C_WIDTH-1:0] shiftedB;
|
||||
//////////////////////////////////////////
|
||||
|
||||
clz clz_r (.clz_input(R), .clz(R_CLZ));
|
||||
clz clz_b (.clz_input(B), .clz(B_CLZ));
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
B_CLZ_r <= B_CLZ;
|
||||
shiftedB <= B << 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[C_WIDTH-1:1]};
|
||||
assign new_Q_bit = Q | (A1[C_WIDTH] ? Q_bit2 : Q_bit1);
|
||||
|
||||
assign B1 = shiftedB >> R_CLZ;
|
||||
assign A1 = R - B1;
|
||||
assign B2 = {1'b0, B1[C_WIDTH-1:1]};
|
||||
assign A2 = R - B2;
|
||||
|
||||
assign new_R = A1[C_WIDTH] ? A2[C_WIDTH-1:0] : A1[C_WIDTH-1:0];
|
||||
|
||||
assign B_is_zero = (&B_CLZ) & ~B[0];
|
||||
////////////////////////////////////////////////////
|
||||
//Control Signals
|
||||
assign div.divisor_is_zero = (&divisor_CLZ) & ~div.divisor[0];
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
running <= 0;
|
||||
else if (start & ~B_is_zero)
|
||||
else if (div.start & ~div.divisor_is_zero)
|
||||
running <= 1;
|
||||
else if (terminate)
|
||||
running <= 0;
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
complete <= (running & terminate) | (start & B_is_zero);
|
||||
div.done <= (running & terminate) | (div.start & div.divisor_is_zero);
|
||||
end
|
||||
|
||||
assign terminate = R < B;
|
||||
assign terminate = div.remainder < div.divisor;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Divisor Pre-processing
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start)
|
||||
Q <= B_is_zero ? '1 : '0;
|
||||
else if (~terminate & running)
|
||||
Q <= new_Q_bit;
|
||||
divisor_CLZ_r <= divisor_CLZ;
|
||||
normalized_divisor <= div.divisor << divisor_CLZ;
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Remainder Determination
|
||||
assign test_multiple1 = normalized_divisor >> remainder_CLZ;
|
||||
assign {overflow, subtraction1} = div.remainder - test_multiple1;
|
||||
|
||||
assign test_multiple2 = test_multiple1 >> 1;
|
||||
assign subtraction2 = div.remainder - test_multiple2;
|
||||
|
||||
assign new_remainder = overflow ? subtraction2 : subtraction1;
|
||||
|
||||
initial begin
|
||||
R = 0;
|
||||
div.remainder = 0;
|
||||
end
|
||||
always @ (posedge clk) begin
|
||||
if (start)
|
||||
R <= A;
|
||||
if (div.start)
|
||||
div.remainder <= div.dividend;
|
||||
else if (~terminate & running)
|
||||
R <= new_R;
|
||||
div.remainder <= new_remainder;
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Quotient Determination
|
||||
assign CLZ_delta = divisor_CLZ_r - remainder_CLZ;
|
||||
always_comb begin
|
||||
new_Q_bit1 = 0;
|
||||
new_Q_bit1[CLZ_delta] = 1;
|
||||
end
|
||||
assign new_Q_bit2 = new_Q_bit1 >> 1;
|
||||
assign new_quotient = div.quotient | (overflow ? new_Q_bit2 : new_Q_bit1);
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (div.start)
|
||||
div.quotient <= div.divisor_is_zero ? '1 : '0;
|
||||
else if (~terminate & running)
|
||||
div.quotient <= new_quotient;
|
||||
end
|
||||
////////////////////////////////////////////////////
|
||||
//End of Implementation
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Assertions
|
||||
endmodule
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -18,64 +18,49 @@
|
|||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
Alec Lu <alec_lu@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module div_quick_clz_mk2
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)(
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
logic running;
|
||||
logic terminate;
|
||||
|
||||
logic [C_WIDTH-1:0] A_r;
|
||||
logic [C_WIDTH:0] A0;
|
||||
logic [C_WIDTH:0] A1;
|
||||
logic [C_WIDTH-1:0] A2;
|
||||
logic [div.DATA_WIDTH:0] A0;
|
||||
logic [div.DATA_WIDTH:0] A1;
|
||||
logic [div.DATA_WIDTH-1:0] A2;
|
||||
|
||||
logic [C_WIDTH-1:0] new_R;
|
||||
logic [C_WIDTH-1:0] new_Q_bit;
|
||||
logic [C_WIDTH-1:0] new_R2;
|
||||
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 [C_WIDTH-1:0] Q_bit1;
|
||||
logic [C_WIDTH-1:0] Q_bit2;
|
||||
logic [div.DATA_WIDTH-1:0] Q_bit1;
|
||||
logic [div.DATA_WIDTH-1:0] Q_bit2;
|
||||
|
||||
logic [C_WIDTH-1:0] B1;
|
||||
logic [C_WIDTH-1:0] B2;
|
||||
logic [C_WIDTH-1:0] B_r;
|
||||
logic [div.DATA_WIDTH-1:0] B1;
|
||||
logic [div.DATA_WIDTH-1:0] B2;
|
||||
|
||||
localparam CLZ_W = $clog2(C_WIDTH);
|
||||
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 firstCycle;
|
||||
logic [C_WIDTH-1:0] shiftedB;
|
||||
logic [div.DATA_WIDTH-1:0] shiftedB;
|
||||
//////////////////////////////////////////
|
||||
|
||||
clz clz_r (.clz_input(R), .clz(R_CLZ));
|
||||
clz clz_b (.clz_input(B), .clz(B_CLZ));
|
||||
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
|
||||
firstCycle <= start;
|
||||
B_CLZ_r <= B_CLZ;
|
||||
A_r <= A;
|
||||
B_r <= B;
|
||||
shiftedB <= B_r << B_CLZ_r;
|
||||
shiftedB <= div.divisor << B_CLZ;
|
||||
end
|
||||
|
||||
assign CLZ_delta = B_CLZ_r - R_CLZ;
|
||||
|
@ -84,70 +69,65 @@ module div_quick_clz_mk2
|
|||
Q_bit1 = 0;
|
||||
Q_bit1[CLZ_delta] = 1;
|
||||
end
|
||||
assign Q_bit2 = {1'b0, Q_bit1[C_WIDTH-1:1]};
|
||||
assign Q_bit2 = {1'b0, Q_bit1[div.DATA_WIDTH-1:1]};
|
||||
|
||||
always_comb begin
|
||||
if (A1[C_WIDTH])
|
||||
if (A1[div.DATA_WIDTH])
|
||||
new_Q_bit = Q_bit2;
|
||||
else if (A0[C_WIDTH] || CLZ_delta == 0)
|
||||
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 = R - B1;
|
||||
assign B2 = {1'b0, B1[C_WIDTH-1:1]};
|
||||
assign A2 = R - B2;
|
||||
assign A1 = div.remainder - B1;
|
||||
assign B2 = {1'b0, B1[div.DATA_WIDTH-1:1]};
|
||||
assign A2 = div.remainder - B2;
|
||||
|
||||
assign A0 = R - (B1 + B2);
|
||||
assign A0 = div.remainder - (B1 + B2);
|
||||
|
||||
always_comb begin
|
||||
if (A1[C_WIDTH])
|
||||
new_R = A2[C_WIDTH-1:0];
|
||||
else if (A0[C_WIDTH] || CLZ_delta == 0)
|
||||
new_R = A1[C_WIDTH-1:0];
|
||||
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[C_WIDTH-1:0];
|
||||
new_R = A0[div.DATA_WIDTH-1:0];
|
||||
end
|
||||
|
||||
assign B_is_zero = (B_CLZ_r == 5'b11111 && ~B_r[0]);
|
||||
assign div.divisor_is_zero = (B_CLZ == 5'b11111 && ~div.divisor[0]);
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
running <= 0;
|
||||
else if (firstCycle & ~B_is_zero)
|
||||
else if (div.start & ~div.divisor_is_zero)
|
||||
running <= 1;
|
||||
else if (terminate)
|
||||
running <= 0;
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
complete <= 0;
|
||||
else if (ack)
|
||||
complete <= 0;
|
||||
else if ((running & terminate) | (firstCycle & B_is_zero))
|
||||
complete <= 1;
|
||||
div.done <= (running & terminate) | (div.start & div.divisor_is_zero);
|
||||
end
|
||||
|
||||
assign terminate = ({firstCycle, R} < {1'b0, B_r});
|
||||
assign terminate = div.remainder < div.divisor;
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (firstCycle)
|
||||
Q <= B_is_zero ? '1 : '0;
|
||||
if (div.start)
|
||||
div.quotient <= div.divisor_is_zero ? '1 : '0;
|
||||
else if (~terminate & running)
|
||||
Q <= Q | new_Q_bit;
|
||||
div.quotient <= div.quotient | new_Q_bit;
|
||||
end
|
||||
|
||||
initial begin
|
||||
R = 0;
|
||||
div.remainder = 0;
|
||||
end
|
||||
always @ (posedge clk) begin
|
||||
if (firstCycle)
|
||||
R <= A_r;
|
||||
if (div.start)
|
||||
div.remainder <= div.dividend;
|
||||
else if (~terminate & running)
|
||||
R <= new_R;
|
||||
div.remainder <= new_R;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -18,75 +18,63 @@
|
|||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
Alec Lu <alec_lu@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module div_quick_naive
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
|
||||
)
|
||||
(
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
);
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
logic running;
|
||||
logic terminate;
|
||||
|
||||
logic [C_WIDTH:0] A1;
|
||||
logic [C_WIDTH-1:0] A2;
|
||||
logic [div.DATA_WIDTH:0] A1;
|
||||
logic [div.DATA_WIDTH-1:0] A2;
|
||||
|
||||
logic [C_WIDTH-1:0] new_R;
|
||||
logic [C_WIDTH-1:0] new_Q_bit;
|
||||
logic [div.DATA_WIDTH-1:0] new_R;
|
||||
logic [div.DATA_WIDTH-1:0] new_Q_bit;
|
||||
|
||||
logic [C_WIDTH-1:0] Q_bit1;
|
||||
logic [C_WIDTH-1:0] Q_bit2;
|
||||
logic [div.DATA_WIDTH-1:0] Q_bit1;
|
||||
logic [div.DATA_WIDTH-1:0] Q_bit2;
|
||||
|
||||
logic [C_WIDTH-1:0] B1;
|
||||
logic [C_WIDTH-1:0] B2;
|
||||
logic [C_WIDTH-1:0] B_r;
|
||||
logic [div.DATA_WIDTH-1:0] B1;
|
||||
logic [div.DATA_WIDTH-1:0] B2;
|
||||
|
||||
localparam MSB_W = $clog2(C_WIDTH);
|
||||
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;
|
||||
|
||||
msb_naive msb_r (.msb_input(R), .msb(R_MSB));
|
||||
msb_naive msb_b (.msb_input(B), .msb(B_MSB));
|
||||
// msb msb_r (.msb_input(R), .msb(R_MSB));
|
||||
// msb msb_b (.msb_input(B_r), .msb(B_MSB));
|
||||
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[C_WIDTH-1:1]};
|
||||
assign new_Q_bit = Q | (A1[C_WIDTH] ? Q_bit2 : Q_bit1);
|
||||
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 = B_r << MSB_delta;
|
||||
assign A1 = R - B1;
|
||||
assign B2 = {1'b0,B1[C_WIDTH-1:1]};
|
||||
assign A2 = R - B2;
|
||||
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[C_WIDTH] ? A2 : A1[C_WIDTH-1:0];
|
||||
assign new_R = A1[div.DATA_WIDTH] ? A2 : A1[div.DATA_WIDTH-1:0];
|
||||
|
||||
assign B_is_zero = (B_MSB == 0 && ~B[0]);
|
||||
assign div.divisor_is_zero = (B_MSB == 0 && ~div.divisor[0]);
|
||||
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
running <= 0;
|
||||
else if (start & ~B_is_zero)
|
||||
else if (div.start & ~div.divisor_is_zero)
|
||||
running <= 1;
|
||||
else if (terminate)
|
||||
running <= 0;
|
||||
|
@ -94,25 +82,24 @@ module div_quick_naive
|
|||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
complete <= 0;
|
||||
else if (ack)
|
||||
complete <= 0;
|
||||
else if ((running & terminate) | (start & B_is_zero))
|
||||
complete <= 1;
|
||||
div.done <= 0;
|
||||
else if (div.done)
|
||||
div.done <= 0;
|
||||
else if ((running & terminate) | (div.start & div.divisor_is_zero))
|
||||
div.done <= 1;
|
||||
end
|
||||
|
||||
assign terminate = (R < B_r);
|
||||
assign terminate = (div.remainder < div.divisor);
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
B_r <= B;
|
||||
B_MSB_r <= B_MSB;
|
||||
if (start) begin
|
||||
Q <= B_is_zero ? '1 : 0;
|
||||
R <= A;
|
||||
if (div.start) begin
|
||||
div.quotient <= div.divisor_is_zero ? '1 : 0;
|
||||
div.remainder <= div.dividend;
|
||||
end
|
||||
else if (~terminate & running) begin
|
||||
Q <= new_Q_bit;
|
||||
R <= new_R;
|
||||
div.quotient <= new_Q_bit;
|
||||
div.remainder <= new_R;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -18,48 +18,40 @@
|
|||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module div_quick_radix_4
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)(
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
logic terminate;
|
||||
logic [C_WIDTH/2-1:0] shift_count;
|
||||
logic [div.DATA_WIDTH/2-1:0] shift_count;
|
||||
|
||||
logic [C_WIDTH+1:0] PR;
|
||||
logic [div.DATA_WIDTH+1:0] PR;
|
||||
logic [2:0] new_PR_sign;
|
||||
logic [C_WIDTH+2:0] new_PR_1;
|
||||
logic [C_WIDTH+2:0] new_PR_2;
|
||||
logic [C_WIDTH+2:0] new_PR_3;
|
||||
logic [C_WIDTH+1:0] B_1;
|
||||
logic [C_WIDTH+1:0] B_2;
|
||||
logic [C_WIDTH+1:0] B_3;
|
||||
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 [C_WIDTH-1:0] A_r;
|
||||
logic [C_WIDTH-1:0] B_r;
|
||||
logic [C_WIDTH-1:0] AR_r;
|
||||
logic [C_WIDTH-1:0] Q_temp;
|
||||
logic [div.DATA_WIDTH-1:0] A_r;
|
||||
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 [C_WIDTH*2:0] combined;
|
||||
logic [C_WIDTH*2:0] combined_normalized;
|
||||
logic [div.DATA_WIDTH*2+1:0] combined;
|
||||
logic [div.DATA_WIDTH*2+1:0] combined_normalized;
|
||||
logic terminate_early;
|
||||
|
||||
localparam CLZ_W = $clog2(C_WIDTH);
|
||||
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;
|
||||
|
@ -68,21 +60,21 @@ module div_quick_radix_4
|
|||
|
||||
logic firstCycle;
|
||||
logic greaterDivisor;
|
||||
logic [C_WIDTH-1:0] A_shifted;
|
||||
logic [C_WIDTH-1:0] B_shifted;
|
||||
logic [C_WIDTH-1:0] R_shifted;
|
||||
logic [div.DATA_WIDTH-1:0] A_shifted;
|
||||
logic [div.DATA_WIDTH-1:0] B_shifted;
|
||||
logic [div.DATA_WIDTH-1:0] R_shifted;
|
||||
|
||||
//implementation
|
||||
////////////////////////////////////////////////////
|
||||
clz clz_r (.clz_input(A), .clz(A_CLZ));
|
||||
clz clz_b (.clz_input(B), .clz(B_CLZ));
|
||||
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
|
||||
firstCycle <= start;
|
||||
firstCycle <= div.start;
|
||||
A_CLZ_r <= A_CLZ;
|
||||
B_CLZ_r <= B_CLZ;
|
||||
A_r <= A;
|
||||
B_r <= B;
|
||||
A_r <= div.dividend;
|
||||
B_r <= div.divisor;
|
||||
end
|
||||
assign A_shifted = A_r << A_CLZ_r;
|
||||
assign B_shifted = B_r << A_CLZ_r;
|
||||
|
@ -90,12 +82,12 @@ module div_quick_radix_4
|
|||
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[C_WIDTH+2], new_PR_2[C_WIDTH+2], new_PR_1[C_WIDTH+2]};
|
||||
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 (firstCycle)
|
||||
shift_count <= 32'd1;
|
||||
shift_count <= 1;
|
||||
else
|
||||
shift_count <= {shift_count[14:0], firstCycle};
|
||||
end
|
||||
|
@ -112,57 +104,53 @@ module div_quick_radix_4
|
|||
end
|
||||
|
||||
assign combined_normalized = {PR, AR_r} >> (shift_num_R + A_CLZ_r);
|
||||
assign R = combined_normalized[C_WIDTH-1:0];
|
||||
assign div.remainder = combined_normalized[div.DATA_WIDTH-1:0];
|
||||
|
||||
assign combined = {PR, AR_r} >> shift_num_R;
|
||||
assign R_shifted = combined[C_WIDTH-1:0];
|
||||
assign R_shifted = combined[div.DATA_WIDTH-1:0];
|
||||
|
||||
assign terminate_early = (B_shifted > R_shifted) | greaterDivisor;
|
||||
assign Q = terminate_early ? (Q_temp << shift_num_Q) : Q_temp;
|
||||
assign div.quotient = terminate_early ? (Q_temp << shift_num_Q) : Q_temp;
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (firstCycle) begin
|
||||
PR <= {{(C_WIDTH-1){1'b0}}, A_shifted[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q_temp <= B_is_zero ? '1 : '0;
|
||||
AR_r <= {A_shifted[C_WIDTH-3:0], 2'b00};
|
||||
PR <= {{(div.DATA_WIDTH){1'b0}}, A_shifted[div.DATA_WIDTH-1:div.DATA_WIDTH-2]};
|
||||
Q_temp <= div.divisor_is_zero ? '1 : '0;
|
||||
AR_r <= {A_shifted[div.DATA_WIDTH-3:0], 2'b00};
|
||||
greaterDivisor <= B_r > A_r;
|
||||
B_1 <= {2'b0, B_shifted}; //1xB
|
||||
B_2 <= {1'b0, B_shifted, 1'b0}; //2xB
|
||||
B_3 <= {1'b0, B_shifted, 1'b0} + B_shifted; //3xB
|
||||
B_3 <= {1'b0, B_shifted, 1'b0} + {2'b0, B_shifted}; //3xB
|
||||
end else if (~terminate & ~terminate_early) begin
|
||||
AR_r <= {AR_r[C_WIDTH-3:0], 2'b00};
|
||||
casex (new_PR_sign)
|
||||
AR_r <= {AR_r[div.DATA_WIDTH-3:0], 2'b00};
|
||||
case (new_PR_sign)
|
||||
3'b111 : begin
|
||||
PR <= {PR[C_WIDTH-1:0], AR_r[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q_temp <= {Q[C_WIDTH-3:0], 2'b00};
|
||||
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[C_WIDTH-1:0], AR_r[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q_temp <= {Q[C_WIDTH-3:0], 2'b01};
|
||||
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[C_WIDTH-1:0], AR_r[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q_temp <= {Q[C_WIDTH-3:0], 2'b10};
|
||||
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
|
||||
3'b000 : begin
|
||||
PR <= {new_PR_3[C_WIDTH-1:0], AR_r[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q_temp <= {Q[C_WIDTH-3:0], 2'b11};
|
||||
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
|
||||
default begin
|
||||
PR <= 'x;
|
||||
Q_temp <= 'x;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// always_ff @ (posedge clk) begin
|
||||
// if (firstCycle)
|
||||
// B_is_zero <= ~B_r[0];
|
||||
// div.divisor_is_zero <= ~B_r[0];
|
||||
// else if (~terminate)
|
||||
// B_is_zero <= B_is_zero & ~(|new_PR_sign);
|
||||
// div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign);
|
||||
// end
|
||||
assign B_is_zero = (&B_CLZ_r) & ~B_r[0];
|
||||
assign div.divisor_is_zero = (&B_CLZ_r) & ~B_r[0];
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
|
@ -177,13 +165,13 @@ module div_quick_radix_4
|
|||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
complete <= 0;
|
||||
div.done <= 0;
|
||||
else begin
|
||||
if ((~firstCycle & (shift_count[15] | terminate_early) & ~complete & ~terminate) | (firstCycle & B_is_zero))
|
||||
complete <= 1;
|
||||
else if (ack)
|
||||
complete <= 0;
|
||||
if ((~firstCycle & (shift_count[15] | terminate_early) & ~div.done & ~terminate) | (firstCycle & div.divisor_is_zero))
|
||||
div.done <= 1;
|
||||
else if (div.done)
|
||||
div.done <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -18,126 +18,114 @@
|
|||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
Alec Lu <alec_lu@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module div_radix16
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)(
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
);
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
|
||||
logic terminate;
|
||||
logic [C_WIDTH-1:0] shift_count;
|
||||
logic [div.DATA_WIDTH-1:0] shift_count;
|
||||
|
||||
logic [C_WIDTH+3:0] PR;
|
||||
logic [C_WIDTH+3:0] PR_lower;
|
||||
logic [C_WIDTH+3:0] PR_upper;
|
||||
logic [C_WIDTH-1:0] Q_lower;
|
||||
logic [C_WIDTH-1:0] Q_upper;
|
||||
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 [C_WIDTH+4:0] new_PR_8;
|
||||
logic [C_WIDTH+4:0] new_PR [6:0];
|
||||
logic [div.DATA_WIDTH+4:0] new_PR_8;
|
||||
logic [div.DATA_WIDTH+4:0] new_PR [6:0];
|
||||
|
||||
logic [C_WIDTH+3:0] B_6;
|
||||
logic [C_WIDTH+3:0] B_10;
|
||||
logic [C_WIDTH+3:0] B_12;
|
||||
logic [C_WIDTH+3:0] B_14;
|
||||
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] <= start;
|
||||
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, B, 3'b000}};
|
||||
assign new_PR[0] = new_PR_8[C_WIDTH+4] ? {1'b0, PR} - {1'b0, {4'b0000, B}} : {1'b0, PR} - {1'b0, {1'b0, B, 3'b000}} - {4'b0000, B};
|
||||
assign new_PR[1] = new_PR_8[C_WIDTH+4] ? {1'b0, PR} - {1'b0, {3'b000, B, 1'b0}} : {1'b0, PR} - {1'b0, B_10};
|
||||
assign new_PR[2] = new_PR_8[C_WIDTH+4] ? {1'b0, PR} - {1'b0, {3'b000, B, 1'b0}} - {4'b0000, B} : {1'b0, PR} - {1'b0, B_10} - {4'b0000, B};
|
||||
assign new_PR[3] = new_PR_8[C_WIDTH+4] ? {1'b0, PR} - {1'b0, {2'b00, B, 2'b00}} : {1'b0, PR} - {1'b0, B_12};
|
||||
assign new_PR[4] = new_PR_8[C_WIDTH+4] ? {1'b0, PR} - {1'b0, {2'b00, B, 2'b00}} - {4'b0000, B} : {1'b0, PR} - {1'b0, B_12} - {4'b0000, B};
|
||||
assign new_PR[5] = new_PR_8[C_WIDTH+4] ? {1'b0, PR} - {1'b0, B_6} : {1'b0, PR} - {1'b0, B_14};
|
||||
assign new_PR[6] = new_PR_8[C_WIDTH+4] ? {1'b0, PR} - {1'b0, B_6} - {4'b0000, B} : {1'b0, PR} - {1'b0, B_14} - {4'b0000, B};
|
||||
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][C_WIDTH+4], new_PR[5][C_WIDTH+4], new_PR[4][C_WIDTH+4],
|
||||
new_PR[3][C_WIDTH+4], new_PR[2][C_WIDTH+4], new_PR[1][C_WIDTH+4],
|
||||
new_PR[0][C_WIDTH+4]};
|
||||
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[C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-4]} & {(C_WIDTH+4){(new_PR_sign[0])}});
|
||||
Q_lower = ({Q[C_WIDTH-5:0], 4'b0000} & {C_WIDTH{(new_PR_sign[0])}});
|
||||
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][C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-4]} & {(C_WIDTH+4){(~new_PR_sign[i-1] & new_PR_sign[i])}});
|
||||
Q_lower = Q_lower | ({Q[C_WIDTH-5:0], i[3:0]} & {C_WIDTH{(~new_PR_sign[i-1] & new_PR_sign[i])}});
|
||||
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][C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-4]} & {(C_WIDTH+4){(~new_PR_sign[6])}});
|
||||
Q_lower = Q_lower | ({Q[C_WIDTH-5:0], 4'b0111} & {C_WIDTH{(~new_PR_sign[6])}});
|
||||
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[C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-4]} & {(C_WIDTH+4){new_PR_sign[0]}};
|
||||
Q_upper = {Q[C_WIDTH-5:0], 4'b1000} & {C_WIDTH{new_PR_sign[0]}};
|
||||
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][C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-4]} & {(C_WIDTH+4){(~new_PR_sign[i-1] & new_PR_sign[i])}});
|
||||
Q_upper = Q_upper | ({Q[C_WIDTH-5:0], (i[3:0] | 4'b1000)} & {C_WIDTH{(~new_PR_sign[i-1] & new_PR_sign[i])}});
|
||||
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][C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-4]} & {(C_WIDTH+4){(~new_PR_sign[6])}});
|
||||
Q_upper = Q_upper | ({Q[C_WIDTH-5:0], 4'b1111} & {C_WIDTH{(~new_PR_sign[6])}});
|
||||
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 (start) begin
|
||||
B_6 <= {2'b00, B, 2'b00} + {3'b000, B, 1'b0};
|
||||
B_10 <= {1'b0, B, 3'b000} + {3'b000, B, 1'b0};
|
||||
B_12 <= {1'b0, B, 3'b000} + {2'b00, B, 2'b00};
|
||||
B_14 <= {1'b0, B, 3'b000} + {2'b00, B, 2'b00} + {3'b000, B, 1'b0};
|
||||
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 <= {{(C_WIDTH){1'b0}}, A[C_WIDTH-1:C_WIDTH-4]};
|
||||
Q <= {A[C_WIDTH-5:0], 4'b0000};
|
||||
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
|
||||
casez (new_PR_8[C_WIDTH+4])
|
||||
case (new_PR_8[div.DATA_WIDTH+4])
|
||||
1'b1 : begin
|
||||
PR <= PR_lower;
|
||||
Q <= Q_lower;
|
||||
div.quotient <= Q_lower;
|
||||
end
|
||||
1'b0 : begin
|
||||
PR <= PR_upper;
|
||||
Q <= Q_upper;
|
||||
end
|
||||
default : begin
|
||||
PR <= 'x;
|
||||
Q <= 'x;
|
||||
div.quotient <= Q_upper;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign R = PR[C_WIDTH+3:4];
|
||||
assign div.remainder = PR[div.DATA_WIDTH+3:4];
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start)
|
||||
B_is_zero <= ~B[0];
|
||||
if (div.start)
|
||||
div.divisor_is_zero <= ~div.divisor[0];
|
||||
else if (~terminate)
|
||||
B_is_zero <= B_is_zero & ~(|new_PR_sign);
|
||||
div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign);
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
terminate <= 0;
|
||||
else begin
|
||||
if (start)
|
||||
if (div.start)
|
||||
terminate <= 0;
|
||||
if (shift_count[7])
|
||||
terminate <= 1;
|
||||
|
@ -146,12 +134,12 @@ module div_radix16
|
|||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
complete <= 0;
|
||||
div.done <= 0;
|
||||
else begin
|
||||
if (shift_count[7])
|
||||
complete <= 1;
|
||||
else if (ack)
|
||||
complete <= 0;
|
||||
div.done <= 1;
|
||||
else if (div.done)
|
||||
div.done <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -18,71 +18,59 @@
|
|||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module div_radix2
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)(
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
logic terminate;
|
||||
|
||||
logic [C_WIDTH:0] new_PR;
|
||||
logic [C_WIDTH:0] PR;
|
||||
|
||||
logic [C_WIDTH-1:0] shift_count;
|
||||
logic [C_WIDTH-1:0] B_r;
|
||||
|
||||
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, B_r};
|
||||
assign negative_sub_rst = new_PR[C_WIDTH];
|
||||
assign new_PR = PR - {1'b0, div.divisor};
|
||||
assign negative_sub_rst = new_PR[div.DATA_WIDTH];
|
||||
|
||||
//Shift reg for
|
||||
always_ff @ (posedge clk) begin
|
||||
shift_count <= {shift_count[30:0], start};
|
||||
shift_count <= {shift_count[30:0], div.start};
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start) begin
|
||||
PR <= {{(C_WIDTH){1'b0}}, A[C_WIDTH-1]};
|
||||
Q <= {A[C_WIDTH-2:0], 1'b0};
|
||||
B_r <= B;
|
||||
if (div.start) 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
|
||||
else if (~terminate) begin
|
||||
PR <= negative_sub_rst ? {PR[C_WIDTH-1:0], Q[C_WIDTH-1]} : {new_PR[C_WIDTH-1:0], Q[C_WIDTH-1]};
|
||||
Q <= {Q[C_WIDTH-2:0], ~negative_sub_rst};
|
||||
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 R = PR[C_WIDTH:1];
|
||||
assign div.remainder = PR[div.DATA_WIDTH:1];
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start)
|
||||
B_is_zero <= ~B[0];
|
||||
if (div.start)
|
||||
div.divisor_is_zero <= ~div.divisor[0];
|
||||
else if (~terminate)
|
||||
B_is_zero <= B_is_zero & ~negative_sub_rst;
|
||||
div.divisor_is_zero <= div.divisor_is_zero & ~negative_sub_rst;
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
terminate <= 0;
|
||||
else begin
|
||||
if (start)
|
||||
if (div.start)
|
||||
terminate <= 0;
|
||||
if (shift_count[31])
|
||||
terminate <= 1;
|
||||
|
@ -91,12 +79,12 @@ module div_radix2
|
|||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
complete <= 0;
|
||||
div.done <= 0;
|
||||
else begin
|
||||
if (shift_count[31])
|
||||
complete <= 1;
|
||||
else if (ack)
|
||||
complete <= 0;
|
||||
div.done <= 1;
|
||||
else if (div.done)
|
||||
div.done <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -18,78 +18,67 @@
|
|||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
Alec Lu <alec_lu@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module div_radix2_ET
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)(
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
);
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
logic terminate;
|
||||
logic terminate_early;
|
||||
|
||||
logic [C_WIDTH:0] new_PR;
|
||||
logic [C_WIDTH:0] PR;
|
||||
logic [div.DATA_WIDTH:0] new_PR;
|
||||
logic [div.DATA_WIDTH:0] PR;
|
||||
|
||||
logic [C_WIDTH-1:0] shift_count;
|
||||
logic [div.DATA_WIDTH-1:0] shift_count;
|
||||
|
||||
logic [C_WIDTH-1:0] B_r;
|
||||
logic negative_sub_rst;
|
||||
|
||||
//implementation
|
||||
////////////////////////////////////////////////////
|
||||
assign new_PR = PR - {1'b0, B_r};
|
||||
assign negative_sub_rst = new_PR[C_WIDTH];
|
||||
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], start & ~terminate_early};
|
||||
shift_count <= {shift_count[30:0], div.start & ~terminate_early};
|
||||
end
|
||||
|
||||
assign terminate_early = B > A;
|
||||
assign terminate_early = div.divisor > div.dividend;
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start) begin
|
||||
if (div.start) begin
|
||||
if (terminate_early) begin
|
||||
PR <= {A, 1'b0};
|
||||
Q <= '0;
|
||||
PR <= {div.dividend, 1'b0};
|
||||
div.quotient <= '0;
|
||||
end else begin
|
||||
PR <= {{(C_WIDTH-2){1'b0}}, A[C_WIDTH-1]};
|
||||
Q <= {A[C_WIDTH-2:0], 1'b0};
|
||||
PR <= {(div.DATA_WIDTH)'(1'b0), div.dividend[div.DATA_WIDTH-1]};
|
||||
div.quotient <= {div.dividend[div.DATA_WIDTH-2:0], 1'b0};
|
||||
end
|
||||
B_r <= B;
|
||||
end else if (~terminate) begin
|
||||
PR <= negative_sub_rst ? {PR[C_WIDTH-1:0], Q[C_WIDTH-1]} : {new_PR[C_WIDTH-1:0], Q[C_WIDTH-1]};
|
||||
Q <= {Q[C_WIDTH-2:0], ~negative_sub_rst};
|
||||
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 R = PR[C_WIDTH:1];
|
||||
assign div.remainder = PR[div.DATA_WIDTH:1];
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start)
|
||||
B_is_zero <= ~B[0];
|
||||
if (div.start)
|
||||
div.divisor_is_zero <= ~div.divisor[0];
|
||||
else if (~terminate)
|
||||
B_is_zero <= B_is_zero & ~negative_sub_rst;
|
||||
div.divisor_is_zero <= div.divisor_is_zero & ~negative_sub_rst;
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
terminate <= 0;
|
||||
else begin
|
||||
if (start) begin
|
||||
if (div.start) begin
|
||||
if (terminate_early) begin
|
||||
terminate <= 1;
|
||||
end else begin
|
||||
|
@ -103,12 +92,12 @@ module div_radix2_ET
|
|||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
complete <= 0;
|
||||
div.done <= 0;
|
||||
else begin
|
||||
if (ack)
|
||||
complete <= 0;
|
||||
else if ((~start & (shift_count[31])) | (start & terminate_early))
|
||||
complete <= 1;
|
||||
if (div.done)
|
||||
div.done <= 0;
|
||||
else if ((~div.start & (shift_count[31])) | (div.start & terminate_early))
|
||||
div.done <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -18,58 +18,48 @@
|
|||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
Alec Lu <alec_lu@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module div_radix2_ET_full
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
);
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
logic terminate;
|
||||
|
||||
logic [C_WIDTH:0] new_PR;
|
||||
logic [C_WIDTH:0] PR;
|
||||
logic [div.DATA_WIDTH:0] new_PR;
|
||||
logic [div.DATA_WIDTH:0] PR;
|
||||
|
||||
logic [C_WIDTH-1:0] shift_count;
|
||||
logic [div.DATA_WIDTH-1:0] shift_count;
|
||||
|
||||
logic negative_sub_rst;
|
||||
logic [C_WIDTH-1:0] B_r;
|
||||
logic [C_WIDTH-1:0] AR_r;
|
||||
logic [C_WIDTH-1:0] Q_temp;
|
||||
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 [C_WIDTH*2:0] combined;
|
||||
logic [C_WIDTH*2:0] combined_r;
|
||||
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, B_r};
|
||||
assign negative_sub_rst = new_PR[C_WIDTH];
|
||||
assign new_PR = PR - {1'b0, div.divisor};
|
||||
assign negative_sub_rst = new_PR[div.DATA_WIDTH];
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start)
|
||||
if (div.start)
|
||||
shift_count <= 32'd1;
|
||||
else
|
||||
shift_count <= {shift_count[30:0], start};
|
||||
shift_count <= {shift_count[30:0], div.start};
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start) begin
|
||||
if (div.start) begin
|
||||
shift_num_R <= 1;
|
||||
shift_num_Q <= 32;
|
||||
end
|
||||
|
@ -81,37 +71,36 @@ module div_radix2_ET_full
|
|||
|
||||
assign combined = {PR, AR_r} >> shift_num_R;
|
||||
|
||||
assign R = combined[C_WIDTH-1:0];
|
||||
assign terminate_early = B_r > R;
|
||||
assign Q = terminate_early ? (Q_temp << shift_num_Q) : Q_temp;
|
||||
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 (start) begin
|
||||
PR <= {{(C_WIDTH-2){1'b0}}, A[C_WIDTH-1]};
|
||||
if (div.start) begin
|
||||
PR <= {(div.DATA_WIDTH)'(1'b0), div.dividend[div.DATA_WIDTH-1]};
|
||||
Q_temp <= '0;
|
||||
AR_r <= {A[C_WIDTH-2:0], 1'b0};
|
||||
B_r <= B;
|
||||
AR_r <= {div.dividend[div.DATA_WIDTH-2:0], 1'b0};
|
||||
end
|
||||
else if (~terminate & ~terminate_early) begin
|
||||
PR <= negative_sub_rst ? {PR[C_WIDTH-1:0], AR_r[C_WIDTH-1]} :
|
||||
{new_PR[C_WIDTH-1:0], AR_r[C_WIDTH-1]};
|
||||
Q_temp <= {Q_temp[C_WIDTH-2:0], ~negative_sub_rst};
|
||||
AR_r <= {AR_r[C_WIDTH-2:0], 1'b0};
|
||||
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 (start)
|
||||
B_is_zero <= ~B[0];
|
||||
if (div.start)
|
||||
div.divisor_is_zero <= ~div.divisor[0];
|
||||
else if (~terminate)
|
||||
B_is_zero <= B_is_zero & ~negative_sub_rst;
|
||||
div.divisor_is_zero <= div.divisor_is_zero & ~negative_sub_rst;
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
terminate <= 0;
|
||||
else begin
|
||||
if (start)
|
||||
if (div.start)
|
||||
terminate <= 0;
|
||||
//if (shift_count[31])
|
||||
else if (shift_count[31] | terminate_early)
|
||||
|
@ -121,14 +110,14 @@ module div_radix2_ET_full
|
|||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
complete <= 0;
|
||||
div.done <= 0;
|
||||
else begin
|
||||
// if (shift_count[31])
|
||||
if (~start & (shift_count[31] | terminate_early) & ~complete & ~terminate)
|
||||
complete <= 1;
|
||||
else if (ack)
|
||||
complete <= 0;
|
||||
if (~div.start & (shift_count[31] | terminate_early) & ~div.done & ~terminate)
|
||||
div.done <= 1;
|
||||
else if (div.done)
|
||||
div.done <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -18,97 +18,85 @@
|
|||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module div_radix4
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)(
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
);
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
logic terminate;
|
||||
logic [C_WIDTH/2-1:0] shift_count;
|
||||
logic [div.DATA_WIDTH/2-1:0] shift_count;
|
||||
|
||||
logic [C_WIDTH+1:0] PR;
|
||||
logic [div.DATA_WIDTH+1:0] PR;
|
||||
logic [2:0] new_PR_sign;
|
||||
logic [C_WIDTH+2:0] new_PR_1;
|
||||
logic [C_WIDTH+2:0] new_PR_2;
|
||||
logic [C_WIDTH+2:0] new_PR_3;
|
||||
logic [C_WIDTH+1:0] B_1;
|
||||
logic [C_WIDTH+1:0] B_2;
|
||||
logic [C_WIDTH+1:0] B_3;
|
||||
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[C_WIDTH+2], new_PR_2[C_WIDTH+2], new_PR_1[C_WIDTH+2]};
|
||||
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], start};
|
||||
shift_count <= {shift_count[14:0], div.start};
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start) begin
|
||||
PR <= {{(C_WIDTH-1){1'b0}}, A[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q <= {A[C_WIDTH-3:0], 2'b00};
|
||||
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, B}; //1xB
|
||||
B_2 <= {1'b0, B, 1'b0}; //2xB
|
||||
B_3 <= {1'b0, B, 1'b0} + B; //3xB
|
||||
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
|
||||
casex (new_PR_sign)
|
||||
case (new_PR_sign)
|
||||
3'b111 : begin
|
||||
PR <= {PR[C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q <= {Q[C_WIDTH-3:0], 2'b00};
|
||||
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[C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q <= {Q[C_WIDTH-3:0], 2'b01};
|
||||
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[C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q <= {Q[C_WIDTH-3:0], 2'b10};
|
||||
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
|
||||
3'b000 : begin
|
||||
PR <= {new_PR_3[C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q <= {Q[C_WIDTH-3:0], 2'b11};
|
||||
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
|
||||
default begin
|
||||
PR <= 'x;
|
||||
Q <= 'x;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign R = PR[C_WIDTH+1:2];
|
||||
assign div.remainder = PR[div.DATA_WIDTH+1:2];
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start)
|
||||
B_is_zero <= ~B[0];
|
||||
if (div.start)
|
||||
div.divisor_is_zero <= ~div.divisor[0];
|
||||
else if (~terminate)
|
||||
B_is_zero <= B_is_zero & ~(|new_PR_sign);
|
||||
div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign);
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
terminate <= 0;
|
||||
else begin
|
||||
if (start)
|
||||
if (div.start)
|
||||
terminate <= 0;
|
||||
if (shift_count[15])
|
||||
terminate <= 1;
|
||||
|
@ -117,13 +105,13 @@ module div_radix4
|
|||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
complete <= 0;
|
||||
div.done <= 0;
|
||||
else begin
|
||||
if (shift_count[15])
|
||||
complete <= 1;
|
||||
else if (ack)
|
||||
complete <= 0;
|
||||
div.done <= 1;
|
||||
else if (div.done)
|
||||
div.done <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -18,107 +18,94 @@
|
|||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module div_radix4_ET
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
logic terminate;
|
||||
logic terminate_early;
|
||||
logic [C_WIDTH/2-1:0] shift_count;
|
||||
logic [div.DATA_WIDTH/2-1:0] shift_count;
|
||||
|
||||
logic [C_WIDTH+1:0] PR;
|
||||
logic [div.DATA_WIDTH+1:0] PR;
|
||||
logic [2:0] new_PR_sign;
|
||||
logic [C_WIDTH+2:0] new_PR_1;
|
||||
logic [C_WIDTH+2:0] new_PR_2;
|
||||
logic [C_WIDTH+2:0] new_PR_3;
|
||||
logic [C_WIDTH+1:0] B_1;
|
||||
logic [C_WIDTH+1:0] B_2;
|
||||
logic [C_WIDTH+1:0] B_3;
|
||||
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[C_WIDTH+2], new_PR_2[C_WIDTH+2], new_PR_1[C_WIDTH+2]};
|
||||
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], start & ~terminate_early};
|
||||
shift_count <= {shift_count[14:0], div.start & ~terminate_early};
|
||||
end
|
||||
|
||||
assign terminate_early = B > A;
|
||||
assign terminate_early = div.divisor > div.dividend;
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start) begin
|
||||
if (div.start) begin
|
||||
if (terminate_early) begin
|
||||
PR <= {A, 2'b00};
|
||||
Q <= '0;
|
||||
PR <= {div.dividend, 2'b00};
|
||||
div.quotient <= '0;
|
||||
end
|
||||
else begin
|
||||
PR <= {{(C_WIDTH-1){1'b0}}, A[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q <= {A[C_WIDTH-3:0], 2'b00};
|
||||
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, B}; //1xB
|
||||
B_2 <= {1'b0, B, 1'b0}; //2xB
|
||||
B_3 <= {1'b0, B, 1'b0} + B; //3xB
|
||||
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
|
||||
casex (new_PR_sign)
|
||||
case (new_PR_sign)
|
||||
3'b111 : begin
|
||||
PR <= {PR[C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q <= {Q[C_WIDTH-3:0], 2'b00};
|
||||
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[C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q <= {Q[C_WIDTH-3:0], 2'b01};
|
||||
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[C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q <= {Q[C_WIDTH-3:0], 2'b10};
|
||||
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
|
||||
3'b000 : begin
|
||||
PR <= {new_PR_3[C_WIDTH-1:0], Q[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q <= {Q[C_WIDTH-3:0], 2'b11};
|
||||
end
|
||||
default begin
|
||||
PR <= 'x;
|
||||
Q <= 'x;
|
||||
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 R = PR[C_WIDTH+1:2];
|
||||
assign div.remainder = PR[div.DATA_WIDTH+1:2];
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start)
|
||||
B_is_zero <= ~B[0];
|
||||
if (div.start)
|
||||
div.divisor_is_zero <= ~div.divisor[0];
|
||||
else if (~terminate)
|
||||
B_is_zero <= B_is_zero & ~(|new_PR_sign);
|
||||
div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign);
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
terminate <= 0;
|
||||
else begin
|
||||
if (start)
|
||||
if (div.start)
|
||||
if (terminate_early) begin
|
||||
terminate <= 1;
|
||||
end else begin
|
||||
|
@ -131,12 +118,12 @@ module div_radix4_ET
|
|||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
complete <= 0;
|
||||
div.done <= 0;
|
||||
else begin
|
||||
if (ack)
|
||||
complete <= 0;
|
||||
else if ((~start & (shift_count[15])) | (start & terminate_early))
|
||||
complete <= 1;
|
||||
if (div.done)
|
||||
div.done <= 0;
|
||||
else if ((~div.start & (shift_count[15])) | (div.start & terminate_early))
|
||||
div.done <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -18,44 +18,35 @@
|
|||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module div_radix4_ET_full
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)(
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
);
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
logic terminate;
|
||||
logic [C_WIDTH/2-1:0] shift_count;
|
||||
logic [div.DATA_WIDTH/2-1:0] shift_count;
|
||||
|
||||
logic [C_WIDTH+1:0] PR;
|
||||
logic [div.DATA_WIDTH+1:0] PR;
|
||||
logic [2:0] new_PR_sign;
|
||||
logic [C_WIDTH+2:0] new_PR_1;
|
||||
logic [C_WIDTH+2:0] new_PR_2;
|
||||
logic [C_WIDTH+2:0] new_PR_3;
|
||||
logic [C_WIDTH+1:0] B_1;
|
||||
logic [C_WIDTH+1:0] B_2;
|
||||
logic [C_WIDTH+1:0] B_3;
|
||||
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 [C_WIDTH-1:0] B_r;
|
||||
logic [C_WIDTH-1:0] AR_r;
|
||||
logic [C_WIDTH-1:0] Q_temp;
|
||||
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 [C_WIDTH*2:0] combined;
|
||||
logic [div.DATA_WIDTH*2:0] combined;
|
||||
logic terminate_early;
|
||||
|
||||
//implementation
|
||||
|
@ -63,18 +54,18 @@ module div_radix4_ET_full
|
|||
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[C_WIDTH+2], new_PR_2[C_WIDTH+2], new_PR_1[C_WIDTH+2]};
|
||||
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 (start)
|
||||
shift_count <= 32'd1;
|
||||
if (div.start)
|
||||
shift_count <= 1;
|
||||
else
|
||||
shift_count <= {shift_count[14:0], start};
|
||||
shift_count <= {shift_count[14:0], div.start};
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start) begin
|
||||
if (div.start) begin
|
||||
shift_num_R <= 2;
|
||||
shift_num_Q <= 32;
|
||||
end
|
||||
|
@ -84,59 +75,55 @@ module div_radix4_ET_full
|
|||
end
|
||||
end
|
||||
|
||||
assign combined = {PR, AR_r} >> shift_num_R;
|
||||
assign R = combined[C_WIDTH-1:0];
|
||||
assign terminate_early = B_r > R;
|
||||
assign Q = terminate_early ? (Q_temp << shift_num_Q) : Q_temp;
|
||||
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 (start) begin
|
||||
PR <= {{(C_WIDTH-1){1'b0}}, A[C_WIDTH-1:C_WIDTH-2]};
|
||||
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 <= {A[C_WIDTH-3:0], 2'b00};
|
||||
B_r <= B;
|
||||
B_1 <= {2'b0, B}; //1xB
|
||||
B_2 <= {1'b0, B, 1'b0}; //2xB
|
||||
B_3 <= {1'b0, B, 1'b0} + B; //3xB
|
||||
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[C_WIDTH-3:0], 2'b00};
|
||||
casex (new_PR_sign)
|
||||
AR_r <= {AR_r[div.DATA_WIDTH-3:0], 2'b00};
|
||||
case (new_PR_sign)
|
||||
3'b111 : begin
|
||||
PR <= {PR[C_WIDTH-1:0], AR_r[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q_temp <= {Q[C_WIDTH-3:0], 2'b00};
|
||||
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[C_WIDTH-1:0], AR_r[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q_temp <= {Q[C_WIDTH-3:0], 2'b01};
|
||||
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[C_WIDTH-1:0], AR_r[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q_temp <= {Q[C_WIDTH-3:0], 2'b10};
|
||||
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
|
||||
3'b000 : begin
|
||||
PR <= {new_PR_3[C_WIDTH-1:0], AR_r[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q_temp <= {Q[C_WIDTH-3:0], 2'b11};
|
||||
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
|
||||
default begin
|
||||
PR <= 'x;
|
||||
Q_temp <= 'x;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start)
|
||||
B_is_zero <= ~B[0];
|
||||
if (div.start)
|
||||
div.divisor_is_zero <= ~div.divisor[0];
|
||||
else if (~terminate)
|
||||
B_is_zero <= B_is_zero & ~(|new_PR_sign);
|
||||
div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign);
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
terminate <= 0;
|
||||
else begin
|
||||
if (start)
|
||||
if (div.start)
|
||||
terminate <= 0;
|
||||
else if (shift_count[15] | terminate_early)
|
||||
terminate <= 1;
|
||||
|
@ -145,13 +132,13 @@ module div_radix4_ET_full
|
|||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
complete <= 0;
|
||||
div.done <= 0;
|
||||
else begin
|
||||
if (~start & (shift_count[15] | terminate_early) & ~complete & ~terminate)
|
||||
complete <= 1;
|
||||
else if (ack)
|
||||
complete <= 0;
|
||||
if (~div.start & (shift_count[15] | terminate_early) & ~div.done & ~terminate)
|
||||
div.done <= 1;
|
||||
else if (div.done)
|
||||
div.done <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -18,56 +18,48 @@
|
|||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module div_radix8
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)(
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
);
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
logic terminate;
|
||||
logic [10:0] shift_count;
|
||||
|
||||
logic [C_WIDTH+2:0] PR;
|
||||
logic [C_WIDTH:0] Q_33;
|
||||
logic [div.DATA_WIDTH+2:0] PR;
|
||||
logic [div.DATA_WIDTH:0] Q_33;
|
||||
logic [6:0] new_PR_sign;
|
||||
|
||||
logic [C_WIDTH+3:0] new_PR_1;
|
||||
logic [C_WIDTH+3:0] new_PR_2;
|
||||
logic [C_WIDTH+3:0] new_PR_3;
|
||||
logic [C_WIDTH+3:0] new_PR_4;
|
||||
logic [C_WIDTH+3:0] new_PR_5;
|
||||
logic [C_WIDTH+3:0] new_PR_6;
|
||||
logic [C_WIDTH+3:0] new_PR_7;
|
||||
logic [C_WIDTH+2:0] B_1;
|
||||
logic [C_WIDTH+2:0] B_2;
|
||||
logic [C_WIDTH+2:0] B_3;
|
||||
logic [C_WIDTH+2:0] B_4;
|
||||
logic [C_WIDTH+2:0] B_5;
|
||||
logic [C_WIDTH+2:0] B_6;
|
||||
logic [C_WIDTH+2:0] B_7;
|
||||
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} - B;
|
||||
// assign new_PR_2 = {1'b0, PR} - {B, 1'b0};
|
||||
// assign new_PR_3 = {1'b0, PR} - {B, 1'b0} - B;
|
||||
// assign new_PR_4 = {1'b0, PR} - {B, 2'b0};
|
||||
// assign new_PR_5 = {1'b0, PR} - {B, 2'b0} - B;
|
||||
// assign new_PR_6 = {1'b0, PR} - {B, 2'b0} - {B, 1'b0};
|
||||
// assign new_PR_7 = {1'b0, PR} - {B, 2'b0} - {B, 1'b0} - B;
|
||||
// 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;
|
||||
|
@ -75,85 +67,81 @@ module div_radix8
|
|||
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[C_WIDTH+3], new_PR_6[C_WIDTH+3], new_PR_5[C_WIDTH+3],
|
||||
new_PR_4[C_WIDTH+3], new_PR_3[C_WIDTH+3], new_PR_2[C_WIDTH+3],
|
||||
new_PR_1[C_WIDTH+3]};
|
||||
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], start};
|
||||
shift_count <= {shift_count[9:0], div.start};
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start) begin
|
||||
PR <= {{(C_WIDTH){1'b0}}, 1'b0, A[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q_33 <= {A[C_WIDTH-3:0], 3'b000};
|
||||
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, B};
|
||||
B_2 <= {2'b00, B, 1'b0};
|
||||
B_3 <= {2'b00, B, 1'b0} + B;
|
||||
B_4 <= {1'b0, B, 2'b00};
|
||||
B_5 <= {1'b0, B, 2'b00} + B;
|
||||
B_6 <= {1'b0, B, 2'b00} + {2'b00, B, 1'b0};
|
||||
B_7 <= {1'b0, B, 2'b00} + {2'b00, B, 1'b0} + B;
|
||||
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
|
||||
casex (new_PR_sign)
|
||||
case (new_PR_sign)
|
||||
7'b1111111 : begin
|
||||
PR <= {PR[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b000};
|
||||
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[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b001};
|
||||
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[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b010};
|
||||
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[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b011};
|
||||
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[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b100};
|
||||
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[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b101};
|
||||
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[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b110};
|
||||
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
|
||||
7'b0000000 : begin
|
||||
PR <= {new_PR_7[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b111};
|
||||
end
|
||||
default begin
|
||||
PR <= 'x;
|
||||
Q_33 <= 'x;
|
||||
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 R = PR[C_WIDTH+2:3];
|
||||
assign Q = Q_33[C_WIDTH-1:0];
|
||||
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 (start)
|
||||
B_is_zero <= ~B[0];
|
||||
if (div.start)
|
||||
div.divisor_is_zero <= ~div.divisor[0];
|
||||
else if (~terminate)
|
||||
B_is_zero <= B_is_zero & ~(|new_PR_sign);
|
||||
div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign);
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
terminate <= 0;
|
||||
else begin
|
||||
if (start)
|
||||
if (div.start)
|
||||
terminate <= 0;
|
||||
if (shift_count[10])
|
||||
terminate <= 1;
|
||||
|
@ -162,13 +150,13 @@ module div_radix8
|
|||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
complete <= 0;
|
||||
div.done <= 0;
|
||||
else begin
|
||||
if (shift_count[10])
|
||||
complete <= 1;
|
||||
else if (ack)
|
||||
complete <= 0;
|
||||
div.done <= 1;
|
||||
else if (div.done)
|
||||
div.done <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* 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.
|
||||
|
@ -18,128 +18,116 @@
|
|||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
* Alec Lu <alec_lu@sfu.ca>
|
||||
*/
|
||||
|
||||
|
||||
module div_radix8_ET
|
||||
#(
|
||||
parameter C_WIDTH = 32
|
||||
)(
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic start,
|
||||
input logic ack,
|
||||
input logic [C_WIDTH-1:0] A,
|
||||
input logic [C_WIDTH-1:0] B,
|
||||
output logic [C_WIDTH-1:0] Q,
|
||||
output logic [C_WIDTH-1:0] R,
|
||||
output logic complete,
|
||||
output logic B_is_zero
|
||||
);
|
||||
unsigned_division_interface.divider div
|
||||
);
|
||||
|
||||
logic terminate;
|
||||
logic terminate_early;
|
||||
logic [10:0] shift_count;
|
||||
|
||||
logic [C_WIDTH+2:0] PR;
|
||||
logic [C_WIDTH:0] Q_33;
|
||||
logic [div.DATA_WIDTH+2:0] PR;
|
||||
logic [div.DATA_WIDTH:0] Q_33;
|
||||
logic [6:0] new_PR_sign;
|
||||
|
||||
logic [C_WIDTH+3:0] new_PR_1;
|
||||
logic [C_WIDTH+3:0] new_PR_2;
|
||||
logic [C_WIDTH+3:0] new_PR_3;
|
||||
logic [C_WIDTH+3:0] new_PR_4;
|
||||
logic [C_WIDTH+3:0] new_PR_5;
|
||||
logic [C_WIDTH+3:0] new_PR_6;
|
||||
logic [C_WIDTH+3:0] new_PR_7;
|
||||
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} - B;
|
||||
assign new_PR_2 = {1'b0, PR} - {B, 1'b0};
|
||||
assign new_PR_3 = {1'b0, PR} - {B, 1'b0} - B;
|
||||
assign new_PR_4 = {1'b0, PR} - {B, 2'b0};
|
||||
assign new_PR_5 = {1'b0, PR} - {B, 2'b0} - B;
|
||||
assign new_PR_6 = {1'b0, PR} - {B, 2'b0} - {B, 1'b0};
|
||||
assign new_PR_7 = {1'b0, PR} - {B, 2'b0} - {B, 1'b0} - B;
|
||||
assign new_PR_sign = {new_PR_7[C_WIDTH+3], new_PR_6[C_WIDTH+3], new_PR_5[C_WIDTH+3],
|
||||
new_PR_4[C_WIDTH+3], new_PR_3[C_WIDTH+3], new_PR_2[C_WIDTH+3],
|
||||
new_PR_1[C_WIDTH+3]};
|
||||
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], start & ~terminate_early};
|
||||
shift_count <= {shift_count[9:0], div.start & ~terminate_early};
|
||||
end
|
||||
|
||||
assign terminate_early = B > A;
|
||||
assign terminate_early = div.divisor > div.dividend;
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (start) begin
|
||||
if (div.start) begin
|
||||
if (terminate_early) begin
|
||||
PR <= {A, 3'b000};
|
||||
PR <= {div.dividend, 3'b000};
|
||||
Q_33 <= '0;
|
||||
end else begin
|
||||
PR <= {{(C_WIDTH){1'b0}}, 1'b0, A[C_WIDTH-1:C_WIDTH-2]};
|
||||
Q_33 <= {A[C_WIDTH-3:0], 3'b000};
|
||||
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
|
||||
casex (new_PR_sign)
|
||||
case (new_PR_sign)
|
||||
7'b1111111 : begin
|
||||
PR <= {PR[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b000};
|
||||
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[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b001};
|
||||
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[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b010};
|
||||
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[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b011};
|
||||
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[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b100};
|
||||
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[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b101};
|
||||
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[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b110};
|
||||
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
|
||||
7'b0000000 : begin
|
||||
PR <= {new_PR_7[C_WIDTH-1:0], Q_33[C_WIDTH:C_WIDTH-2]};
|
||||
Q_33 <= {Q_33[C_WIDTH-3:0], 3'b111};
|
||||
end
|
||||
default begin
|
||||
PR <= 'x;
|
||||
Q_33 <= 'x;
|
||||
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 R = PR[C_WIDTH+2:3];
|
||||
assign Q = Q_33[C_WIDTH-1:0];
|
||||
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 (start)
|
||||
B_is_zero <= ~B[0];
|
||||
if (div.start)
|
||||
div.divisor_is_zero <= ~div.divisor[0];
|
||||
else if (~terminate)
|
||||
B_is_zero <= B_is_zero & ~(|new_PR_sign);
|
||||
div.divisor_is_zero <= div.divisor_is_zero & ~(|new_PR_sign);
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
terminate <= 0;
|
||||
else begin
|
||||
if (start)
|
||||
if (div.start)
|
||||
if (terminate_early) begin
|
||||
terminate <= 1;
|
||||
end else begin
|
||||
|
@ -152,13 +140,13 @@ module div_radix8_ET
|
|||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst)
|
||||
complete <= 0;
|
||||
div.done <= 0;
|
||||
else begin
|
||||
if (ack)
|
||||
complete <= 0;
|
||||
else if ((~start & (shift_count[10])) | (start & terminate_early))
|
||||
complete <= 1;
|
||||
if (div.done)
|
||||
div.done <= 0;
|
||||
else if ((~div.start & (shift_count[10])) | (div.start & terminate_early))
|
||||
div.done <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
@ -58,15 +58,10 @@ module div_unit
|
|||
div_fifo_inputs_t fifo_inputs;
|
||||
div_fifo_inputs_t div_op;
|
||||
|
||||
logic start_algorithm;
|
||||
unsigned_division_interface #(.DATA_WIDTH(32)) div_core();
|
||||
|
||||
logic in_progress;
|
||||
logic computation_complete;
|
||||
logic div_done;
|
||||
|
||||
logic [31:0] unsigned_quotient;
|
||||
logic [31:0] unsigned_remainder;
|
||||
|
||||
logic divisor_zero;
|
||||
logic negate_result;
|
||||
|
||||
fifo_interface #(.DATA_WIDTH($bits(div_fifo_inputs_t))) input_fifo();
|
||||
|
@ -114,27 +109,29 @@ module div_unit
|
|||
|
||||
////////////////////////////////////////////////////
|
||||
//Control Signals
|
||||
assign start_algorithm = input_fifo.valid & (~in_progress) & ~div_op.reuse_result;
|
||||
assign div_done = computation_complete | (input_fifo.valid & div_op.reuse_result);
|
||||
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);
|
||||
|
||||
//If more than one cycle, set in_progress so that multiple start_algorithm signals are not sent to the div unit.
|
||||
//If more than one cycle, set in_progress so that multiple div.start signals are not sent to the div unit.
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst)
|
||||
in_progress <= 0;
|
||||
else if (start_algorithm)
|
||||
else if (div_core.start)
|
||||
in_progress <= 1;
|
||||
else if (computation_complete)
|
||||
else if (div_core.done)
|
||||
in_progress <= 0;
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Div core
|
||||
div_algorithm #(XLEN) div (.*, .start(start_algorithm), .A(div_op.unsigned_dividend), .B(div_op.unsigned_divisor), .Q(unsigned_quotient), .R(unsigned_remainder), .complete(computation_complete), .ack(computation_complete), .B_is_zero(divisor_zero));
|
||||
assign div_core.dividend = div_op.unsigned_dividend;
|
||||
assign div_core.divisor = div_op.unsigned_divisor;
|
||||
div_algorithm divider_block (.*, .div(div_core));
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Output
|
||||
assign negate_result = div_op.remainder_op ? div_op.negate_remainder : (~divisor_zero & div_op.negate_quotient);
|
||||
assign wb.rd = negate_if (div_op.remainder_op ? unsigned_remainder : unsigned_quotient, negate_result);
|
||||
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 : div_core.quotient, negate_result);
|
||||
assign wb.done = div_done;
|
||||
assign wb.id = div_op.instruction_id;
|
||||
////////////////////////////////////////////////////
|
||||
|
|
|
@ -239,6 +239,19 @@ interface fetch_sub_unit_interface;
|
|||
|
||||
endinterface
|
||||
|
||||
//start and done are cycle cycle pulses
|
||||
interface unsigned_division_interface #(parameter DATA_WIDTH = 32);
|
||||
logic start;
|
||||
logic [DATA_WIDTH-1:0] dividend;
|
||||
logic [DATA_WIDTH-1:0] divisor;
|
||||
logic [DATA_WIDTH-1:0] remainder;
|
||||
logic [DATA_WIDTH-1:0] quotient;
|
||||
logic done;
|
||||
logic divisor_is_zero;
|
||||
modport requester (input remainder, quotient, done, divisor_is_zero, output dividend, divisor, start);
|
||||
modport divider (output remainder, quotient, done, divisor_is_zero, input dividend, divisor, start);
|
||||
endinterface
|
||||
|
||||
//request and ack are single cycle pulses
|
||||
//request should be high when the instruction is issued
|
||||
//data_valid is held high until an ack is received
|
||||
|
|
|
@ -128,6 +128,7 @@ module taiga (
|
|||
logic tr_branch_operand_stall;
|
||||
logic tr_alu_operand_stall;
|
||||
logic tr_ls_operand_stall;
|
||||
logic tr_div_operand_stall;
|
||||
|
||||
logic tr_instruction_issued_dec;
|
||||
logic [31:0] tr_instruction_pc_dec;
|
||||
|
@ -227,6 +228,7 @@ module taiga (
|
|||
tr.events.branch_operand_stall <= tr_branch_operand_stall;
|
||||
tr.events.alu_operand_stall <= tr_alu_operand_stall;
|
||||
tr.events.ls_operand_stall <= tr_ls_operand_stall;
|
||||
tr.events.div_operand_stall <= tr_div_operand_stall;
|
||||
tr.events.branch_correct <= tr_branch_correct;
|
||||
tr.events.branch_misspredict <= tr_branch_misspredict;
|
||||
tr.events.return_misspredict <= tr_return_misspredict;
|
||||
|
|
|
@ -64,7 +64,7 @@ package taiga_config;
|
|||
QUICK_CLZ_MK2,
|
||||
QUICK_RADIX_4
|
||||
} div_type;
|
||||
parameter div_type DIV_ALGORITHM = QUICK_CLZ;
|
||||
parameter div_type DIV_ALGORITHM = RADIX_2;
|
||||
|
||||
//Enable Atomic extension (cache operations only)
|
||||
parameter USE_AMO = 0;
|
||||
|
|
|
@ -394,7 +394,6 @@ package taiga_types;
|
|||
logic [XLEN-1:0] rs2;
|
||||
logic [1:0] op;
|
||||
logic reuse_result;
|
||||
instruction_id_t instruction_id;
|
||||
} div_inputs_t;
|
||||
|
||||
typedef struct packed{
|
||||
|
@ -454,6 +453,7 @@ package taiga_types;
|
|||
logic branch_operand_stall;
|
||||
logic alu_operand_stall;
|
||||
logic ls_operand_stall;
|
||||
logic div_operand_stall;
|
||||
|
||||
//Branch Unit
|
||||
logic branch_correct;
|
||||
|
|
|
@ -46,6 +46,7 @@ static const char * const eventNames[] = {
|
|||
"branch_operand_stall",
|
||||
"alu_operand_stall",
|
||||
"ls_operand_stall",
|
||||
"div_operand_stall",
|
||||
"branch_correct",
|
||||
"branch_misspredict",
|
||||
"return_misspredict",
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
../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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue