forked from Github_Repos/cvw
		
	Divider code cleanup
This commit is contained in:
		
							parent
							
								
									852eb24731
								
							
						
					
					
						commit
						4926ae343a
					
				| @ -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 | ||||
|  | ||||
| @ -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
 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user