From f913305993ed06ef0d103cf77ffa1c6f50fbc8ab Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 2 Oct 2021 20:55:37 -0400 Subject: [PATCH] Partial divider cleanup --- .../regression/wave-dos/peripheral-waves.do | 7 ++-- wally-pipelined/src/muldiv/intdivrestoring.sv | 35 +++++++++---------- wally-pipelined/src/muldiv/muldiv.sv | 12 +++---- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/wally-pipelined/regression/wave-dos/peripheral-waves.do b/wally-pipelined/regression/wave-dos/peripheral-waves.do index 9ff6e4fe2..57eb5babc 100644 --- a/wally-pipelined/regression/wave-dos/peripheral-waves.do +++ b/wally-pipelined/regression/wave-dos/peripheral-waves.do @@ -38,9 +38,9 @@ add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE add wave /testbench/dut/hart/mdu/genblk1/div/StartDivideE add wave /testbench/dut/hart/mdu/DivBusyE add wave /testbench/dut/hart/mdu/DivDoneE -add wave -hex /testbench/dut/hart/mdu/genblk1/div/D +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/X +add wave -hex /testbench/dut/hart/mdu/genblk1/div/XE add wave -hex /testbench/dut/hart/mdu/genblk1/div/Win add wave -hex /testbench/dut/hart/mdu/genblk1/div/XQin add wave -hex /testbench/dut/hart/mdu/genblk1/div/Wshift @@ -50,7 +50,8 @@ add wave -hex /testbench/dut/hart/mdu/genblk1/div/qi add wave -hex /testbench/dut/hart/mdu/genblk1/div/Wprime add wave -hex /testbench/dut/hart/mdu/genblk1/div/W add wave -hex /testbench/dut/hart/mdu/genblk1/div/XQ -add wave -hex /testbench/dut/hart/mdu/genblk1/div/REM +add wave -hex /testbench/dut/hart/mdu/genblk1/div/RemM +add wave -hex /testbench/dut/hart/mdu/genblk1/div/QuotM add wave -divider add wave -hex /testbench/dut/hart/ifu/PCM diff --git a/wally-pipelined/src/muldiv/intdivrestoring.sv b/wally-pipelined/src/muldiv/intdivrestoring.sv index f9c8a735f..45ffbfb58 100644 --- a/wally-pipelined/src/muldiv/intdivrestoring.sv +++ b/wally-pipelined/src/muldiv/intdivrestoring.sv @@ -31,12 +31,12 @@ module intdivrestoring ( input logic StallM, FlushM, input logic SignedDivideE, input logic StartDivideE, - input logic [`XLEN-1:0] X, D, + input logic [`XLEN-1:0] XE, DE, output logic BusyE, done, - output logic [`XLEN-1:0] Q, REM + output logic [`XLEN-1:0] QuotM, RemM ); - logic [`XLEN-1:0] W, W2, Win, Wshift, Wprime, Wn, Wnn, Wnext, XQ, XQin, XQshift, XQn, XQnn, XQnext, Dsaved, Din, Dabs, D2, Dn, Xn, Xabs, X2, Xsaved, Xinit, DAbsB, W1, XQ1; + logic [`XLEN-1:0] W, W2, Win, Wshift, Wprime, Wn, Wnn, Wnext, XQ, XQin, XQshift, XQn, XQnn, XQnext, DSavedE, Din, Dabs, D2, Dn, Xn, Xabs, X2, XSavedE, Xinit, DAbsB, W1, XQ1; logic qi, qib; // curent quotient bit localparam STEPBITS = $clog2(`XLEN)-1; logic [STEPBITS:0] step; @@ -48,17 +48,18 @@ module intdivrestoring ( // save inputs on the negative edge of the execute clock. // This is unusual practice, but the inputs are not guaranteed to be stable due to some hazard and forwarding logic. // Saving the inputs is the most hardware-efficient way to fix the issue. - flopen #(`XLEN) dsavereg(~clk, StartDivideE, D, Dsaved); - flopen #(`XLEN) xsavereg(~clk, StartDivideE, X, Xsaved); - assign SignD = Dsaved[`XLEN-1]; // *** do some of these need pipelining for consecutive divides? - assign SignX = Xsaved[`XLEN-1]; - assign div0 = (Dsaved == 0); // *** eventually replace with just the negedge saved D + flopen #(`XLEN) dsavereg(~clk, StartDivideE, DE, DSavedE); + flopen #(`XLEN) xsavereg(~clk, StartDivideE, XE, XSavedE); + flopenrc #(1) SignedDivideMReg(clk, reset, FlushM, ~StallM, SignedDivideE, SignedDivideM); + assign SignD = DSavedE[`XLEN-1]; // *** do some of these need pipelining for consecutive divides? + assign SignX = XSavedE[`XLEN-1]; + assign div0 = (DSavedE == 0); // *** eventually replace with just the negedge saved D // Take absolute value for signed operations - neg #(`XLEN) negd(Dsaved, Dn); - mux2 #(`XLEN) dabsmux(Dsaved, Dn, SignedDivideE & SignD, Din); // take absolute value for signed operations - neg #(`XLEN) negx(Xsaved, Xn); - mux2 #(`XLEN) xabsmux(Xsaved, Xn, SignedDivideE & SignX, Xinit); // need original X as remainder if doing divide by 0 + neg #(`XLEN) negd(DSavedE, Dn); + mux2 #(`XLEN) dabsmux(DSavedE, Dn, SignedDivideE & SignD, Din); // take absolute value for signed operations + neg #(`XLEN) negx(XSavedE, Xn); + mux2 #(`XLEN) xabsmux(XSavedE, Xn, SignedDivideE & SignX, Xinit); // need original X as remainder if doing divide by 0 // Negate D for subtraction assign DAbsB = ~Din; @@ -71,8 +72,8 @@ module intdivrestoring ( intdivrestoringstep step1(Win, XQin, DAbsB, W1, XQ1); intdivrestoringstep step2(W1, XQ1, DAbsB, Wnext, XQnext); - flopen #(`XLEN) wreg(clk, /*StartDivideE | */BusyE, Wnext, W); // *** could become just busy once start moves to its own cycle - flopen #(`XLEN) xreg(clk, /*StartDivideE | */BusyE, XQnext, XQ); + flopen #(`XLEN) wreg(clk, BusyE, Wnext, W); // *** could become just busy once start moves to its own cycle + flopen #(`XLEN) xreg(clk, BusyE, XQnext, XQ); // Output selection logic in Memory Stage // On final setp of signed operations, negate outputs as needed @@ -81,8 +82,8 @@ module intdivrestoring ( neg #(`XLEN) wneg(W, Wn); neg #(`XLEN) qneg(XQ, XQn); // Select appropriate output: normal, negated, or for divide by zero - mux3 #(`XLEN) qmux(XQ, XQn, {`XLEN{1'b1}}, {div0, NegQ}, Q); // Q taken from XQ register, negated if necessary, or all 1s when dividing by zero - mux3 #(`XLEN) remmux(W, Wn, Xsaved, {div0, NegW}, REM); // REM taken from W register, negated if necessary, or from X when dividing 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) remmux(W, Wn, XSavedE, {div0, NegW}, RemM); // REM taken from W register, negated if necessary, or from X when dividing by zero // busy logic always_ff @(posedge clk) @@ -106,8 +107,6 @@ module intdivrestoring ( end assign init = (step == 0); - // save signs of original inputs - flopenrc #(1) SignedDivideMReg(clk, reset, FlushM, ~StallM, SignedDivideE, SignedDivideM); endmodule // muldiv diff --git a/wally-pipelined/src/muldiv/muldiv.sv b/wally-pipelined/src/muldiv/muldiv.sv index be49bf057..734965195 100644 --- a/wally-pipelined/src/muldiv/muldiv.sv +++ b/wally-pipelined/src/muldiv/muldiv.sv @@ -52,7 +52,7 @@ module muldiv ( logic enable_q; //logic [2:0] Funct3E_Q; logic div0error; // ***unused - logic [`XLEN-1:0] X, D; + logic [`XLEN-1:0] XE, DE; //logic [`XLEN-1:0] Num0, Den0; // logic gclk; @@ -69,17 +69,17 @@ module muldiv ( // Handle sign extension for W-type instructions if (`XLEN == 64) begin // RV64 has W-type instructions - assign X = W64E ? {{32{SrcAE[31]&SignedDivideE}}, SrcAE[31:0]} : SrcAE; - assign D = W64E ? {{32{SrcBE[31]&SignedDivideE}}, SrcBE[31:0]} : SrcBE; + assign XE = W64E ? {{32{SrcAE[31]&SignedDivideE}}, SrcAE[31:0]} : SrcAE; + assign DE = W64E ? {{32{SrcBE[31]&SignedDivideE}}, SrcBE[31:0]} : SrcBE; end else begin // RV32 has no W-type instructions - assign X = SrcAE; - assign D = SrcBE; + assign XE = SrcAE; + assign DE = SrcBE; end 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); intdivrestoring div(.clk, .reset, .StallM, .FlushM, - .SignedDivideE, .StartDivideE, .X(X), .D(D), .BusyE, .done(DivDoneE), .Q(QuotM), .REM(RemM)); + .SignedDivideE, .StartDivideE, .XE, .DE, .BusyE, .done(DivDoneE), .QuotM, .RemM); // 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