diff --git a/wally-pipelined/regression/wave-dos/peripheral-waves.do b/wally-pipelined/regression/wave-dos/peripheral-waves.do index 2da82b869..2362b0511 100644 --- a/wally-pipelined/regression/wave-dos/peripheral-waves.do +++ b/wally-pipelined/regression/wave-dos/peripheral-waves.do @@ -35,6 +35,23 @@ add wave -hex /testbench/dut/hart/ieu/dp/SrcAE add wave -hex /testbench/dut/hart/ieu/dp/SrcBE add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE #add wave /testbench/dut/hart/ieu/dp/PCSrcE +add wave /testbench/dut/hart/mdu/genblk1/div/start +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/Din +add wave -hex /testbench/dut/hart/mdu/genblk1/div/X +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 +add wave -hex /testbench/dut/hart/mdu/genblk1/div/XQshift +add wave -hex /testbench/dut/hart/mdu/genblk1/div/Wnext +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 -divider add wave -hex /testbench/dut/hart/ifu/PCM add wave -hex /testbench/dut/hart/ifu/InstrM @@ -48,9 +65,9 @@ add wave -hex /testbench/dut/hart/lsu/dcache/ReadDataM add wave -hex /testbench/dut/hart/ebu/ReadDataM add wave -divider add wave -hex /testbench/PCW -add wave -hex /testbench/InstrW +#add wave -hex /testbench/InstrW add wave -hex /testbench/dut/hart/ieu/c/InstrValidW -add wave /testbench/InstrWName +#add wave /testbench/InstrWName add wave -hex /testbench/dut/hart/ReadDataW add wave -hex /testbench/dut/hart/ieu/dp/ResultW add wave -hex /testbench/dut/hart/ieu/dp/RegWriteW diff --git a/wally-pipelined/src/muldiv/intdivrestoring.sv b/wally-pipelined/src/muldiv/intdivrestoring.sv index ed78718cf..831fe9d02 100644 --- a/wally-pipelined/src/muldiv/intdivrestoring.sv +++ b/wally-pipelined/src/muldiv/intdivrestoring.sv @@ -28,9 +28,9 @@ module intdivrestoring ( input logic clk, input logic reset, - input logic StallM, - input logic signedDivide, - input logic start, + input logic StallM, FlushM, + input logic SignedDivideE, + input logic StartDivideE, input logic [`XLEN-1:0] X, D, output logic busy, done, output logic [`XLEN-1:0] Q, REM @@ -41,78 +41,84 @@ module intdivrestoring ( localparam STEPBITS = $clog2(`XLEN)-1; logic [STEPBITS:0] step; logic div0; - logic negate, init, startd, SignX, SignD, NegW, NegQ; + logic init, startd, SignX, SignD, NegW, NegQ; + logic SignedDivideM; + // *** add pipe stages to everything // Setup for signed division abs #(`XLEN) absd(D, Dabs); - mux2 #(`XLEN) dabsmux(D, Dabs, signedDivide, D2); - flopen #(`XLEN) dsavereg(clk, start, D2, Dsaved); - mux2 #(`XLEN) dfirstmux(Dsaved, D, start, Din); + mux2 #(`XLEN) dabsmux(D, Dabs, SignedDivideE, D2); + flopen #(`XLEN) dsavereg(clk, StartDivideE, D2, Dsaved); + mux2 #(`XLEN) dfirstmux(Dsaved, D, StartDivideE, Din); abs #(`XLEN) absx(X, Xabs); - mux2 #(`XLEN) xabsmux(X, Xabs, signedDivide & ~div0, X2); // need original X as remainder if doing divide by 0 - flopen #(`XLEN) xsavereg(clk, start, X2, Xsaved); - mux2 #(`XLEN) xfirstmux(Xsaved, X, start, Xinit); + mux2 #(`XLEN) xabsmux(X, Xabs, SignedDivideE & ~div0, X2); // need original X as remainder if doing divide by 0 + flopen #(`XLEN) xsavereg(clk, StartDivideE, X2, Xsaved); + mux2 #(`XLEN) xfirstmux(Xsaved, X, StartDivideE, Xinit); mux2 #(`XLEN) wmux(W, {`XLEN{1'b0}}, init, Win); mux2 #(`XLEN) xmux(XQ, Xinit, init, XQin); assign DAbsB = ~Din; + assign div0 = (Din == 0); // *** eventually replace with just the negedge saved D // *** parameterize steps per cycle intdivrestoringstep step1(Win, XQin, DAbsB, W1, XQ1); - intdivrestoringstep step2(W1, XQ1, DAbsB, W2, XQshift); +// intdivrestoringstep step2(W1, XQ1, DAbsB, W2, XQshift); + intdivrestoringstep step2(W1, XQ1, DAbsB, Wnext, XQnext); // conditionally negate outputs at end of signed operation - // *** move into M stage - neg #(`XLEN) wneg(W, Wn); - mux2 #(`XLEN) wnextmux(W2, Wn, NegW, Wnext); //*** - neg #(`XLEN) qneg(XQ, XQn); - mux2 #(`XLEN) qnextmux(XQshift, XQn, NegQ, XQnext); - flopen #(`XLEN) wreg(clk, start | (busy & (~negate | NegW)), Wnext, W); - flopen #(`XLEN) xreg(clk, start | (busy & (~negate | NegQ)), XQnext, XQ); + +// flopen #(`XLEN) wreg(clk, StartDivideE | (busy & (~negate | NegW)), Wnext, W); +// flopen #(`XLEN) xreg(clk, StartDivideE | (busy & (~negate | NegQ)), XQnext, XQ); + flopen #(`XLEN) wreg(clk, StartDivideE | busy, Wnext, W); // *** could become just busy once start moves to its own cycle + flopen #(`XLEN) xreg(clk, StartDivideE | busy, XQnext, XQ); // outputs - assign div0 = (Din == 0); - mux2 #(`XLEN) qmux(XQ, {`XLEN{1'b1}}, div0, Q); // Q taken from XQ register, or all 1s when dividing by zero - mux2 #(`XLEN) remmux(W, Xsaved, div0, REM); // REM taken from W register, or from X when dividing by zero + neg #(`XLEN) wneg(W, Wn); +// mux2 #(`XLEN) wnextmux(W2, Wn, NegW, Wnext); //*** + neg #(`XLEN) qneg(XQ, XQn); +// mux2 #(`XLEN) qnextmux(XQshift, XQn, NegQ, XQnext); + mux3 #(`XLEN) qmux(XQ, XQn, {`XLEN{1'b1}}, {div0, NegQ}, Q); // Q taken from XQ register, or all 1s when dividing by zero *** + mux3 #(`XLEN) remmux(W, Wn, Xsaved, {div0, NegW}, REM); // REM taken from W register, or from X when dividing by zero // busy logic always_ff @(posedge clk) if (reset) begin - busy = 0; done = 0; step = 0; negate = 0; - end else if (start & ~StallM) begin + busy = 0; done = 0; step = 0; //negate = 0; + end else if (StartDivideE & ~StallM) begin if (div0) done = 1; else begin busy = 1; step = 1; end - end else if (busy & ~done & ~(startd & signedDivide)) begin // pause one cycle at beginning of signed operations for absolute value + end else if (busy & ~done & ~(startd & SignedDivideE)) begin // pause one cycle at beginning of signed operations for absolute value step = step + 1; if (step[STEPBITS]) begin // *** early terminate on division by 0 - if (signedDivide & ~negate) begin +/* if (SignedDivideE & ~negate) begin negate = 1; - end else begin + end else begin*/ step = 0; busy = 0; - negate = 0; + //negate = 0; done = 1; - end + //end end end else if (done) begin done = 0; busy = 0; - negate = 0; + //negate = 0; end // initialize on the start cycle for unsigned operations, or one cycle later for signed operations (giving time for abs) - flop #(1) initflop(clk, start, startd); - mux2 #(1) initmux(start, startd, signedDivide, init); + flop #(1) initflop(clk, StartDivideE, startd); + mux2 #(1) initmux(StartDivideE, startd, SignedDivideE, init); // save signs of original inputs - flopen #(2) signflops(clk, start, {D[`XLEN-1], X[`XLEN-1]}, {SignD, SignX}); + flopenrc #(1) SignedDivideMReg(clk, reset, FlushM, ~StallM, SignedDivideE, SignedDivideM); + flopen #(2) signflops(clk, StartDivideE, {D[`XLEN-1], X[`XLEN-1]}, {SignD, SignX}); // On final setp of signed operations, negate outputs as needed - assign NegW = SignX & negate; - assign NegQ = (SignX ^ SignD) & negate; + assign NegW = SignedDivideM & SignX; // & negate; + assign NegQ = SignedDivideM & (SignX ^ SignD); // & negate; endmodule // muldiv diff --git a/wally-pipelined/src/muldiv/muldiv.sv b/wally-pipelined/src/muldiv/muldiv.sv index 03df97e7c..17e943490 100644 --- a/wally-pipelined/src/muldiv/muldiv.sv +++ b/wally-pipelined/src/muldiv/muldiv.sv @@ -56,7 +56,7 @@ module muldiv ( //logic [`XLEN-1:0] Num0, Den0; // logic gclk; - logic startDivideE, busy; + logic StartDivideE, busy; logic SignedDivideE; logic W64M; @@ -77,12 +77,13 @@ module muldiv ( 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, .signedDivide(SignedDivideE), .start(startDivideE), .X(X), .D(D), .busy(busy), .done(DivDoneE), .Q(QuotM), .REM(RemM)); + //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), .busy(busy), .done(DivDoneE), .Q(QuotM), .REM(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] & ~busy & ~DivDoneE; // *** mabye DivDone should be M stage - assign DivBusyE = startDivideE | busy; + assign StartDivideE = MulDivE & Funct3E[2] & ~busy & ~DivDoneE; // *** mabye DivDone should be M stage + assign DivBusyE = StartDivideE | busy; // Select result always_comb