mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Renamed variables, moved output handling to postprocessor, added remainder handling
This commit is contained in:
		
							parent
							
								
									a17361870f
								
							
						
					
					
						commit
						abe1ff906e
					
				
										
											Binary file not shown.
										
									
								
							| @ -35,33 +35,35 @@ module srt ( | ||||
|   input  logic Start,  | ||||
|   input  logic Stall, // *** multiple pipe stages
 | ||||
|   input  logic Flush, // *** multiple pipe stages
 | ||||
|   // Floating Point Inputs
 | ||||
|   // later add exponents, signs, special cases
 | ||||
|   // Floating Point
 | ||||
|   input  logic       XSign, YSign, | ||||
|   input  logic [`NE-1:0] XExp, YExp, | ||||
|   input  logic [`NF-1:0] SrcXFrac, SrcYFrac, | ||||
|   // Integer
 | ||||
|   input  logic [`XLEN-1:0] SrcA, SrcB, | ||||
|   // Customization
 | ||||
|   input  logic [1:0] Fmt, // Floats: 00 = 16 bit, 01 = 32 bit, 10 = 64 bit, 11 = 128 bit
 | ||||
|   input  logic       W64, // 32-bit ints on XLEN=64
 | ||||
|   // Selection
 | ||||
|   input  logic       Signed, // Interpret integers as signed 2's complement
 | ||||
|   input  logic       Int, // Choose integer inputs
 | ||||
|   input  logic       Sqrt, // perform square root, not divide
 | ||||
|   output logic       rsign, done, | ||||
|   output logic [`DIVLEN-2:0] Rem, Quot, // *** later handle integers
 | ||||
|   output logic [`DIVLEN-1:0] Rem, Result, | ||||
|   output logic [`NE-1:0] rExp, | ||||
|   output logic [3:0] Flags | ||||
| ); | ||||
| 
 | ||||
|   logic                       qp, qz, qn; // quotient is +1, 0, or -1
 | ||||
|   logic                       qp, qz, qn; // result bits are +1, 0, or -1
 | ||||
|   logic [`NE-1:0]             calcExp; | ||||
|   logic                       calcSign; | ||||
|   logic [`DIVLEN+3:0]         X, Dpreproc, C, F, S, SM, AddIn; | ||||
|   logic [`DIVLEN+3:0]         WS, WSA, WSN, WC, WCA, WCN, D, Db, Dsel; | ||||
|   logic [$clog2(`XLEN+1)-1:0] intExp, dur, calcDur; | ||||
|   logic [$clog2(`XLEN+1)-1:0] zeroCntD, intExp, dur, calcDur; | ||||
|   logic                       intSign; | ||||
|   logic                       cin; | ||||
|   | ||||
|   srtpreproc preproc(SrcA, SrcB, SrcXFrac, SrcYFrac, XExp, Fmt, W64, Signed, Int, Sqrt, X, Dpreproc, intExp, calcDur, intSign); | ||||
|   srtpreproc preproc(SrcA, SrcB, SrcXFrac, SrcYFrac, XExp, Fmt, W64, Signed, Int, Sqrt, X, Dpreproc, zeroCntD, intExp, calcDur, intSign); | ||||
| 
 | ||||
|   // Top Muxes and Registers
 | ||||
|   // When start is asserted, the inputs are loaded into the divider.
 | ||||
| @ -91,7 +93,7 @@ module srt ( | ||||
|   // otfc2  #(`DIVLEN) otfc2(clk, Start, qp, qz, qn, Quot);
 | ||||
|   // otherwise use sotfc
 | ||||
|   creg   sotfcC(clk, Start, Sqrt, C); | ||||
|   sotfc2 sotfc2(clk, Start, qp, qn, Sqrt, C, Quot, S, SM); | ||||
|   sotfc2 sotfc2(clk, Start, qp, qn, Sqrt, C, S, SM); | ||||
|   fsel2 fsel(qp, qn, C, S, SM, F); | ||||
| 
 | ||||
|   // Adder input selection
 | ||||
| @ -103,7 +105,7 @@ module srt ( | ||||
|    | ||||
|   expcalc expcalc(.XExp, .YExp, .calcExp, .Sqrt); | ||||
| 
 | ||||
|   signcalc signcalc(.XSign, .YSign, .calcSign); | ||||
|   srtpostproc postproc(.WS, .WC, .X, .D, .S, .SM, .dur, .zeroCntD, .XSign, .YSign, .Signed, .Int, .Result, .Rem, .calcSign); | ||||
| endmodule | ||||
| 
 | ||||
| ////////////////
 | ||||
| @ -123,11 +125,11 @@ module srtpreproc ( | ||||
|   input  logic       Int, // Choose integer inputs
 | ||||
|   input  logic       Sqrt, // perform square root, not divide
 | ||||
|   output logic [`DIVLEN+3:0] X, D, | ||||
|   output logic [$clog2(`XLEN+1)-1:0] intExp, dur, // Quotient integer exponent
 | ||||
|   output logic [$clog2(`XLEN+1)-1:0] zeroCntB, intExp, dur, // Quotient integer exponent
 | ||||
|   output logic       intSign // Quotient integer sign
 | ||||
| ); | ||||
| 
 | ||||
|   logic  [$clog2(`XLEN+1)-1:0] zeroCntA, zeroCntB; | ||||
|   logic  [$clog2(`XLEN+1)-1:0] zeroCntA; | ||||
|   logic  [`XLEN-1:0] PosA, PosB; | ||||
|   logic  [`DIVLEN-1:0] ExtraA, ExtraB, PreprocA, PreprocB, PreprocX, PreprocY, DivX; | ||||
|   logic  [`NF+4:0] SqrtX; | ||||
| @ -235,7 +237,7 @@ module otfc2 #(parameter N=66) ( | ||||
|   input  logic         clk, | ||||
|   input  logic         Start, | ||||
|   input  logic         qp, qz, qn, | ||||
|   output logic [N-3:0] r | ||||
|   output logic [N-3:0] Result | ||||
| ); | ||||
|   //  The on-the-fly converter transfers the quotient 
 | ||||
|   //  bits to the quotient as they come.
 | ||||
| @ -261,7 +263,7 @@ module otfc2 #(parameter N=66) ( | ||||
|       QMNext = {QMR, 1'b0}; | ||||
|     end  | ||||
|   end | ||||
|   assign r = Q[N] ? Q[N-1:2] : Q[N-2:1]; | ||||
|   assign Result = Q[N] ? Q[N-1:2] : Q[N-2:1]; | ||||
| 
 | ||||
| endmodule | ||||
| 
 | ||||
| @ -274,7 +276,6 @@ module sotfc2( | ||||
|   input  logic         sp, sn, | ||||
|   input  logic         Sqrt, | ||||
|   input  logic [`DIVLEN+3:0] C, | ||||
|   output logic [`DIVLEN-2:0] Sq, | ||||
|   output logic [`DIVLEN+3:0] S, SM | ||||
| ); | ||||
|   //  The on-the-fly converter transfers the square root 
 | ||||
| @ -298,7 +299,6 @@ module sotfc2( | ||||
|       SMNext = SM | (C & ~(C << 1)); | ||||
|     end  | ||||
|   end | ||||
|   assign Sq = S[`DIVLEN] ? S[`DIVLEN-1:1] : S[`DIVLEN-2:0]; | ||||
| endmodule | ||||
| 
 | ||||
| //////////////////////////
 | ||||
| @ -395,14 +395,74 @@ module expcalc( | ||||
| 
 | ||||
| endmodule | ||||
| 
 | ||||
| //////////////
 | ||||
| // signcalc //
 | ||||
| //////////////
 | ||||
| module signcalc( | ||||
|   input logic  XSign, YSign, | ||||
| module srtpostproc( | ||||
|   input  logic [`DIVLEN+3:0] WS, WC, X, D, S, SM, | ||||
|   input  logic [$clog2(`XLEN+1)-1:0] dur, zeroCntD, | ||||
|   input  logic XSign, YSign, Signed, Int, | ||||
|   output logic [`DIVLEN-1:0]   Result, Rem, | ||||
|   output logic calcSign | ||||
| ); | ||||
|   logic [`DIVLEN+3:0] W, shiftRem, intRem, intS;  | ||||
|   logic [`DIVLEN-1:0] floatRes, intRes; | ||||
|   logic               WSign; | ||||
| 
 | ||||
|   assign W = WS + WC; | ||||
|   assign WSign = W[`DIVLEN+3]; | ||||
|   // Remainder handling
 | ||||
|   always_comb begin | ||||
|     if (zeroCntD == ($clog2(`XLEN+1))'(`XLEN)) begin | ||||
|       intRem = X; | ||||
|       intS = -1; | ||||
|     end | ||||
|     else if (~Signed) begin | ||||
|       if (WSign) begin | ||||
|         intRem = W + D; | ||||
|         intS = SM; | ||||
|       end else begin  | ||||
|         intRem = W; | ||||
|         intS = S; | ||||
|       end | ||||
|     end | ||||
|     else case ({YSign, XSign, WSign}) | ||||
|       3'b000: begin | ||||
|         intRem = W;  | ||||
|         intS = S;  | ||||
|       end | ||||
|       3'b001: begin | ||||
|         intRem = W + D; | ||||
|         intS = SM; | ||||
|       end | ||||
|       3'b010: begin | ||||
|         intRem = W - D; | ||||
|         intS = ~S; | ||||
|       end | ||||
|       3'b011: begin | ||||
|         intRem = W; | ||||
|         intS = ~SM; | ||||
|       end | ||||
|       3'b100: begin | ||||
|         intRem = W; | ||||
|         intS = ~SM; | ||||
|       end | ||||
|       3'b101: begin | ||||
|         intRem = W + D; | ||||
|         intS = ~SM + 1; | ||||
|       end  | ||||
|       3'b110: begin | ||||
|         intRem = W - D; | ||||
|         intS = S + 1; | ||||
|       end  | ||||
|       3'b111: begin | ||||
|         intRem = W; | ||||
|         intS = S; | ||||
|       end | ||||
|     endcase | ||||
|   end | ||||
|   assign floatRes = S[`DIVLEN] ? S[`DIVLEN:1] : S[`DIVLEN-1:0]; | ||||
|   assign intRes = intS[`DIVLEN] ? intS[`DIVLEN:1] : intS[`DIVLEN-1:0]; | ||||
|   assign Result = Int ? intRes : floatRes; | ||||
|   assign calcSign = XSign ^ YSign; | ||||
|   assign shiftRem = intRem >>> dur; | ||||
|   assign Rem = shiftRem[`DIVLEN-1:0]; | ||||
| endmodule | ||||
| 
 | ||||
| endmodule | ||||
| @ -49,7 +49,7 @@ module testbench; | ||||
|   logic               asign, bsign; | ||||
|   logic [`NF-1:0]     r; | ||||
|   logic [`XLEN-1:0]   rInt; | ||||
|   logic [`DIVLEN-2:0] Quot; | ||||
|   logic [`DIVLEN-1:0] Quot, Rem; | ||||
|   | ||||
|   // Test parameters
 | ||||
|   parameter MEM_SIZE = 40000; | ||||
| @ -72,7 +72,7 @@ module testbench; | ||||
| 
 | ||||
|   // Equip Int test or Sqrt test
 | ||||
|   assign Int = 1'b0; | ||||
|   assign Sqrt = 1'b0; | ||||
|   assign Sqrt = 1'b1; | ||||
| 
 | ||||
|   // Divider
 | ||||
|   srt srt(.clk, .Start(req),  | ||||
| @ -82,7 +82,7 @@ module testbench; | ||||
|                 .SrcXFrac(afrac), .SrcYFrac(bfrac),  | ||||
|                 .SrcA(a), .SrcB(b), .Fmt(2'b00),  | ||||
|                 .W64(1'b1), .Signed(1'b0), .Int, .Sqrt,  | ||||
|                 .Quot, .Rem(), .Flags(), .done); | ||||
|                 .Result(Quot), .Rem, .Flags(), .done); | ||||
| 
 | ||||
|   // Counter
 | ||||
|   // counter counter(clk, req, done);
 | ||||
| @ -101,7 +101,7 @@ module testbench; | ||||
|     begin | ||||
|       testnum = 0;  | ||||
|       errors = 0; | ||||
|       $readmemh ("testvectors", Tests); | ||||
|       $readmemh ("sqrttestvectors", Tests); | ||||
|       Vec = Tests[testnum]; | ||||
|       a = Vec[`mema]; | ||||
|       {asign, aExp, afrac} = a; | ||||
| @ -117,7 +117,7 @@ module testbench; | ||||
| 
 | ||||
|   always @(posedge clk) begin | ||||
|     r = Quot[(`DIVLEN - 2):(`DIVLEN - `NF - 1)]; | ||||
|     rInt = {1'b1, Quot}; | ||||
|     rInt = Quot; | ||||
|     if (done) begin | ||||
|       if (~Int & ~Sqrt) begin | ||||
|         req <= #5 1; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user