diff --git a/wally-pipelined/regression/wave-dos/peripheral-waves.do b/wally-pipelined/regression/wave-dos/peripheral-waves.do index 2362b0511..9ff6e4fe2 100644 --- a/wally-pipelined/regression/wave-dos/peripheral-waves.do +++ b/wally-pipelined/regression/wave-dos/peripheral-waves.do @@ -35,7 +35,7 @@ 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/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 diff --git a/wally-pipelined/src/muldiv/intdivrestoring.sv b/wally-pipelined/src/muldiv/intdivrestoring.sv index 831fe9d02..79a978ef0 100644 --- a/wally-pipelined/src/muldiv/intdivrestoring.sv +++ b/wally-pipelined/src/muldiv/intdivrestoring.sv @@ -32,7 +32,7 @@ module intdivrestoring ( input logic SignedDivideE, input logic StartDivideE, input logic [`XLEN-1:0] X, D, - output logic busy, done, + output logic BusyE, done, output logic [`XLEN-1:0] Q, REM ); @@ -64,49 +64,39 @@ module intdivrestoring ( // *** parameterize steps per cycle intdivrestoringstep step1(Win, XQin, DAbsB, W1, XQ1); -// intdivrestoringstep step2(W1, XQ1, DAbsB, W2, XQshift); intdivrestoringstep step2(W1, XQ1, DAbsB, Wnext, XQnext); - // conditionally negate outputs at end of signed operation - -// 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); + 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); // outputs + // On final setp of signed operations, negate outputs as needed + assign NegW = SignedDivideM & SignX; + assign NegQ = SignedDivideM & (SignX ^ SignD); 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 + 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 // busy logic always_ff @(posedge clk) if (reset) begin - busy = 0; done = 0; step = 0; //negate = 0; + BusyE = 0; done = 0; step = 0; end else if (StartDivideE & ~StallM) begin if (div0) done = 1; else begin - busy = 1; step = 1; + BusyE = 1; step = 1; end - end else if (busy & ~done & ~(startd & SignedDivideE)) begin // pause one cycle at beginning of signed operations for absolute value + end else if (BusyE & ~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 (SignedDivideE & ~negate) begin - negate = 1; - end else begin*/ + if (step[STEPBITS]) begin step = 0; - busy = 0; - //negate = 0; + BusyE = 0; done = 1; - //end end end else if (done) begin done = 0; - busy = 0; - //negate = 0; + BusyE = 0; end // initialize on the start cycle for unsigned operations, or one cycle later for signed operations (giving time for abs) @@ -115,10 +105,7 @@ module intdivrestoring ( // save signs of original inputs 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 = SignedDivideM & SignX; // & negate; - assign NegQ = SignedDivideM & (SignX ^ SignD); // & negate; + flopen #(2) signflops(clk, StartDivideE, {D[`XLEN-1], X[`XLEN-1]}, {SignD, SignX}); // *** shouldn't be necessary when capturing inputs properly endmodule // muldiv diff --git a/wally-pipelined/src/muldiv/muldiv.sv b/wally-pipelined/src/muldiv/muldiv.sv index 17e943490..be49bf057 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, BusyE; logic SignedDivideE; logic W64M; @@ -79,11 +79,11 @@ module muldiv ( 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), .busy(busy), .done(DivDoneE), .Q(QuotM), .REM(RemM)); + .SignedDivideE, .StartDivideE, .X(X), .D(D), .BusyE, .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] & ~BusyE & ~DivDoneE; // *** mabye DivDone should be M stage + assign DivBusyE = StartDivideE | BusyE; // Select result always_comb