Added more pipeline stage suffixes to divider

This commit is contained in:
David Harris 2021-10-02 22:54:01 -04:00
parent 3441991d93
commit 24bb3f4baf
8 changed files with 35 additions and 31 deletions

View File

@ -176,7 +176,7 @@ add wave -noupdate -group muldiv /testbench/dut/hart/mdu/FlushM
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/FlushW add wave -noupdate -group muldiv /testbench/dut/hart/mdu/FlushW
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/MulDivResultW add wave -noupdate -group muldiv /testbench/dut/hart/mdu/MulDivResultW
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/genblk1/div/start add wave -noupdate -group muldiv /testbench/dut/hart/mdu/genblk1/div/start
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/DivDoneE add wave -noupdate -group muldiv /testbench/dut/hart/mdu/DivDoneM
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/DivBusyE add wave -noupdate -group muldiv /testbench/dut/hart/mdu/DivBusyE
add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/fsm1/CURRENT_STATE add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/fsm1/CURRENT_STATE
add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/N add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/N

View File

@ -37,7 +37,6 @@ add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE
#add wave /testbench/dut/hart/ieu/dp/PCSrcE #add wave /testbench/dut/hart/ieu/dp/PCSrcE
add wave /testbench/dut/hart/mdu/genblk1/div/StartDivideE add wave /testbench/dut/hart/mdu/genblk1/div/StartDivideE
add wave /testbench/dut/hart/mdu/DivBusyE add wave /testbench/dut/hart/mdu/DivBusyE
add wave /testbench/dut/hart/mdu/DivDoneE
add wave -hex /testbench/dut/hart/mdu/genblk1/div/DE add wave -hex /testbench/dut/hart/mdu/genblk1/div/DE
add wave -hex /testbench/dut/hart/mdu/genblk1/div/Din add wave -hex /testbench/dut/hart/mdu/genblk1/div/Din
add wave -hex /testbench/dut/hart/mdu/genblk1/div/XE add wave -hex /testbench/dut/hart/mdu/genblk1/div/XE

View File

@ -179,7 +179,7 @@ add wave -noupdate -group muldiv /testbench/dut/hart/mdu/FlushM
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/FlushW add wave -noupdate -group muldiv /testbench/dut/hart/mdu/FlushW
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/MulDivResultW add wave -noupdate -group muldiv /testbench/dut/hart/mdu/MulDivResultW
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/genblk1/div/start add wave -noupdate -group muldiv /testbench/dut/hart/mdu/genblk1/div/start
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/DivDoneE add wave -noupdate -group muldiv /testbench/dut/hart/mdu/DivDoneM
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/DivBusyE add wave -noupdate -group muldiv /testbench/dut/hart/mdu/DivBusyE
add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/fsm1/CURRENT_STATE add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/fsm1/CURRENT_STATE
add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/N add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/N

View File

@ -30,7 +30,7 @@ module forward(
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
input logic MemReadE, MulDivE, CSRReadE, input logic MemReadE, MulDivE, CSRReadE,
input logic RegWriteM, RegWriteW, input logic RegWriteM, RegWriteW,
input logic DivDoneE, DivBusyE, input logic DivBusyE,
input logic FWriteIntE, FWriteIntM, FWriteIntW, input logic FWriteIntE, FWriteIntM, FWriteIntW,
input logic SCE, input logic SCE,
input logic StallD, input logic StallD,
@ -54,7 +54,7 @@ module forward(
// Stall on dependent operations that finish in Mem Stage and can't bypass in time // Stall on dependent operations that finish in Mem Stage and can't bypass in time
assign FPUStallD = FWriteIntE & ((Rs1D == RdE) | (Rs2D == RdE)); assign FPUStallD = FWriteIntE & ((Rs1D == RdE) | (Rs2D == RdE));
assign LoadStallD = (MemReadE|SCE) & ((Rs1D == RdE) | (Rs2D == RdE)); assign LoadStallD = (MemReadE|SCE) & ((Rs1D == RdE) | (Rs2D == RdE));
assign MulDivStallD = MulDivE & ((Rs1D == RdE) | (Rs2D == RdE)) /*| DivBusyE */; // *** extend with stalls for divide assign MulDivStallD = MulDivE & ((Rs1D == RdE) | (Rs2D == RdE));
assign CSRRdStallD = CSRReadE & ((Rs1D == RdE) | (Rs2D == RdE)); assign CSRRdStallD = CSRReadE & ((Rs1D == RdE) | (Rs2D == RdE));
endmodule endmodule

View File

@ -73,7 +73,6 @@ module ieu (
input logic FlushD, FlushE, FlushM, FlushW, input logic FlushD, FlushE, FlushM, FlushW,
output logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD, output logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD,
output logic PCSrcE, output logic PCSrcE,
input logic DivDoneE,
input logic DivBusyE, input logic DivBusyE,
output logic CSRReadM, CSRWriteM, PrivilegedM, output logic CSRReadM, CSRWriteM, PrivilegedM,
output logic CSRWritePendingDEM, output logic CSRWritePendingDEM,

View File

@ -32,7 +32,7 @@ module intdivrestoring (
input logic SignedDivideE, input logic SignedDivideE,
input logic StartDivideE, input logic StartDivideE,
input logic [`XLEN-1:0] XE, DE, input logic [`XLEN-1:0] XE, DE,
output logic BusyE, done, output logic BusyE, DivDoneM,
output logic [`XLEN-1:0] QuotM, RemM output logic [`XLEN-1:0] QuotM, RemM
); );
@ -40,8 +40,8 @@ module intdivrestoring (
logic qi, qib; // curent quotient bit logic qi, qib; // curent quotient bit
localparam STEPBITS = $clog2(`XLEN)-1; localparam STEPBITS = $clog2(`XLEN)-1;
logic [STEPBITS:0] step; logic [STEPBITS:0] step;
logic div0; logic Div0E, Div0M;
logic init, startd, SignX, SignD, NegW, NegQ; logic init, startd, SignXE, SignXM, SignDE, SignDM, NegWM, NegQM;
logic SignedDivideM; logic SignedDivideM;
// *** add pipe stages to everything // *** add pipe stages to everything
@ -50,19 +50,27 @@ module intdivrestoring (
// Saving the inputs is the most hardware-efficient way to fix the issue. // Saving the inputs is the most hardware-efficient way to fix the issue.
flopen #(`XLEN) dsavereg(~clk, StartDivideE, DE, DSavedE); flopen #(`XLEN) dsavereg(~clk, StartDivideE, DE, DSavedE);
flopen #(`XLEN) xsavereg(~clk, StartDivideE, XE, XSavedE); flopen #(`XLEN) xsavereg(~clk, StartDivideE, XE, XSavedE);
assign SignDE = DSavedE[`XLEN-1]; // *** do some of these need pipelining for consecutive divides?
assign SignXE = XSavedE[`XLEN-1];
assign Div0E = (DSavedE == 0);
// pipeline registers
flopenrc #(1) SignedDivideMReg(clk, reset, FlushM, ~StallM, SignedDivideE, SignedDivideM); flopenrc #(1) SignedDivideMReg(clk, reset, FlushM, ~StallM, SignedDivideE, SignedDivideM);
assign SignD = DSavedE[`XLEN-1]; // *** do some of these need pipelining for consecutive divides? flopenrc #(1) Div0eMReg(clk, reset, FlushM, ~StallM, Div0E, Div0M);
assign SignX = XSavedE[`XLEN-1]; flopenrc #(1) SignDMReg(clk, reset, FlushM, ~StallM, SignDE, SignDM);
assign div0 = (DSavedE == 0); flopenrc #(1) SignXMReg(clk, reset, FlushM, ~StallM, SignXE, SignXM);
flopenrc #(`XLEN) XSavedMReg(clk, reset, FlushM, ~StallM, XSavedE, XSavedM); // is this truly necessary?
// Take absolute value for signed operations // Take absolute value for signed operations
neg #(`XLEN) negd(DSavedE, DnE); neg #(`XLEN) negd(DSavedE, DnE);
mux2 #(`XLEN) dabsmux(DSavedE, DnE, SignedDivideE & SignD, Din); // take absolute value for signed operations mux2 #(`XLEN) dabsmux(DSavedE, DnE, SignedDivideE & SignDE, Din); // take absolute value for signed operations
neg #(`XLEN) negx(XSavedE, XnE); neg #(`XLEN) negx(XSavedE, XnE);
mux2 #(`XLEN) xabsmux(XSavedE, XnE, SignedDivideE & SignX, Xinit); // need original X as remainder if doing divide by 0 mux2 #(`XLEN) xabsmux(XSavedE, XnE, SignedDivideE & SignXE, Xinit); // need original X as remainder if doing divide by 0
// Negate D for subtraction // Negate D for subtraction
assign DAbsB = ~Din; assign DAbsB = ~Din;
// *** merge this into dabsmux if possible
// Put suffixes on Xinit, init->DivInitE, Wn, XQn
// initialization multiplexers on first cycle of operation (one cycle after start is asserted) // initialization multiplexers on first cycle of operation (one cycle after start is asserted)
mux2 #(`XLEN) wmux(W, {`XLEN{1'b0}}, init, Win); mux2 #(`XLEN) wmux(W, {`XLEN{1'b0}}, init, Win);
@ -77,33 +85,34 @@ module intdivrestoring (
// Output selection logic in Memory Stage // Output selection logic in Memory Stage
// On final setp of signed operations, negate outputs as needed // On final setp of signed operations, negate outputs as needed
assign NegW = SignedDivideM & SignX; assign NegWM = SignedDivideM & SignXM;
assign NegQ = SignedDivideM & (SignX ^ SignD); assign NegQM = SignedDivideM & (SignXM ^ SignDM);
neg #(`XLEN) wneg(W, Wn); neg #(`XLEN) wneg(W, Wn);
neg #(`XLEN) qneg(XQ, XQn); neg #(`XLEN) qneg(XQ, XQn);
// Select appropriate output: normal, negated, or for divide by zero // Select appropriate output: normal, negated, or for divide by zero
mux3 #(`XLEN) qmux(XQ, XQn, {`XLEN{1'b1}}, {div0, NegQ}, QuotM); // Q taken from XQ register, negated if necessary, or all 1s when dividing by zero mux3 #(`XLEN) qmux(XQ, XQn, {`XLEN{1'b1}}, {Div0M, NegQM}, QuotM); // Q taken from XQ register, negated if necessary, or all 1s when dividing by zero
mux3 #(`XLEN) remmux(W, Wn, XSavedE, {div0, NegW}, RemM); // REM taken from W register, negated if necessary, or from X when dividing by zero mux3 #(`XLEN) remmux(W, Wn, XSavedM, {Div0M, NegWM}, RemM); // REM taken from W register, negated if necessary, or from X when dividing by zero
// verify it's really necessary to have XSavedM
// busy logic // busy logic
always_ff @(posedge clk) always_ff @(posedge clk)
if (reset) begin if (reset) begin
BusyE = 0; done = 0; step = 0; init = 0; BusyE = 0; DivDoneM = 0; step = 0; init = 0;
end else if (StartDivideE & ~StallM) begin end else if (StartDivideE & ~StallM) begin
if (div0) done = 1; if (Div0E) DivDoneM = 1;
else begin else begin
BusyE = 1; step = 0; init = 1; BusyE = 1; step = 0; init = 1;
end end
end else if (BusyE & ~done) begin // pause one cycle at beginning of signed operations for absolute value end else if (BusyE & ~DivDoneM) begin // pause one cycle at beginning of signed operations for absolute value
init = 0; init = 0;
step = step + 1; step = step + 1;
if (step[STEPBITS]) begin if (step[STEPBITS]) begin
step = 0; step = 0;
BusyE = 0; BusyE = 0;
done = 1; DivDoneM = 1;
end end
end else if (done) begin end else if (DivDoneM) begin
done = 0; DivDoneM = 0;
BusyE = 0; BusyE = 0;
end end

View File

@ -36,7 +36,6 @@ module muldiv (
// Writeback stage // Writeback stage
output logic [`XLEN-1:0] MulDivResultW, output logic [`XLEN-1:0] MulDivResultW,
// Divide Done // Divide Done
output logic DivDoneE,
output logic DivBusyE, output logic DivBusyE,
// hazards // hazards
input logic StallE, StallM, StallW, FlushM, FlushW input logic StallE, StallM, StallW, FlushM, FlushW
@ -56,7 +55,7 @@ module muldiv (
//logic [`XLEN-1:0] Num0, Den0; //logic [`XLEN-1:0] Num0, Den0;
// logic gclk; // logic gclk;
logic StartDivideE, BusyE; logic StartDivideE, BusyE, DivDoneM;
logic SignedDivideE; logic SignedDivideE;
logic W64M; logic W64M;
@ -79,10 +78,10 @@ module muldiv (
assign SignedDivideE = ~Funct3E[0]; // simplified from (Funct3E[2]&~Funct3E[1]&~Funct3E[0]) | (Funct3E[2]&Funct3E[1]&~Funct3E[0]); assign SignedDivideE = ~Funct3E[0]; // simplified from (Funct3E[2]&~Funct3E[1]&~Funct3E[0]) | (Funct3E[2]&Funct3E[1]&~Funct3E[0]);
//intdiv #(`XLEN) div (QuotE, RemE, DivDoneE, DivBusyE, div0error, N, D, gclk, reset, StartDivideE, SignedDivideE); //intdiv #(`XLEN) div (QuotE, RemE, DivDoneE, DivBusyE, div0error, N, D, gclk, reset, StartDivideE, SignedDivideE);
intdivrestoring div(.clk, .reset, .StallM, .FlushM, intdivrestoring div(.clk, .reset, .StallM, .FlushM,
.SignedDivideE, .StartDivideE, .XE, .DE, .BusyE, .done(DivDoneE), .QuotM, .RemM); .SignedDivideE, .StartDivideE, .XE, .DE, .BusyE, .DivDoneM, .QuotM, .RemM);
// Start a divide when a new division instruction is received and the divider isn't already busy or finishing // Start a divide when a new division instruction is received and the divider isn't already busy or finishing
assign StartDivideE = MulDivE & Funct3E[2] & ~BusyE & ~DivDoneE; // *** mabye DivDone should be M stage assign StartDivideE = MulDivE & Funct3E[2] & ~BusyE & ~DivDoneM;
assign DivBusyE = StartDivideE | BusyE; assign DivBusyE = StartDivideE | BusyE;
// Select result // Select result
@ -111,7 +110,6 @@ module muldiv (
end else begin // no M instructions supported end else begin // no M instructions supported
assign MulDivResultW = 0; assign MulDivResultW = 0;
assign DivBusyE = 0; assign DivBusyE = 0;
assign DivDoneE = 0;
end end
endgenerate endgenerate

View File

@ -88,7 +88,6 @@ module wallypipelinedhart
logic InvalidateICacheM, FlushDCacheM; logic InvalidateICacheM, FlushDCacheM;
logic PCSrcE; logic PCSrcE;
logic CSRWritePendingDEM; logic CSRWritePendingDEM;
logic DivDoneE;
logic DivBusyE; logic DivBusyE;
logic RegWriteD; logic RegWriteD;
logic LoadStallD, StoreStallD, MulDivStallD, CSRRdStallD; logic LoadStallD, StoreStallD, MulDivStallD, CSRRdStallD;