mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	moved lzc to generic and small optimizations on fcvt
This commit is contained in:
		
							parent
							
								
									c6d79cd718
								
							
						
					
					
						commit
						1be91753fe
					
				| @ -32,7 +32,7 @@ vlib work | ||||
| # start and run simulation | ||||
| # remove +acc flag for faster sim during regressions if there is no need to access internal signals | ||||
| # $num = the added words after the call | ||||
| vlog +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-fp.sv ../src/fpu/*.sv -suppress 2583,7063,8607,2697  | ||||
| vlog +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-fp.sv ../src/fpu/*.sv ../src/generic/*.sv -suppress 2583,7063,8607,2697  | ||||
| 
 | ||||
| vsim -voptargs=+acc work.testbenchfp -G TEST=$2 | ||||
| 
 | ||||
|  | ||||
| @ -39,9 +39,10 @@ module fcvt ( | ||||
| 
 | ||||
|     logic [`FPSIZES/3:0]    OutFmt;     // format of the output
 | ||||
|     logic [`XLEN-1:0]       PosInt;     // the positive integer input
 | ||||
|     logic [`XLEN-1:0]       TrimInt;    // integer trimmed to the correct size
 | ||||
|     logic [`LGLEN-1:0]      LzcIn;      // input to the Leading Zero Counter (priority encoder)
 | ||||
|     logic [`NE:0]           CalcExp;    // the calculated expoent
 | ||||
| 	logic [$clog2(`LGLEN):0] ShiftAmt;  // how much to shift by
 | ||||
| 	logic [$clog2(`LGLEN)-1:0] ShiftAmt;  // how much to shift by
 | ||||
|     logic [`LGLEN+`NF:0]    ShiftIn;    // number to be shifted
 | ||||
|     logic                   ResDenormUf;// does the result underflow or is denormalized
 | ||||
|     logic                   ResUf;      // does the result underflow
 | ||||
| @ -71,6 +72,7 @@ module fcvt ( | ||||
|     logic                   Int64;      // is the integer 64 bits?
 | ||||
|     logic                   IntToFp;       // is the opperation an int->fp conversion?
 | ||||
|     logic                   ToInt;      // is the opperation an fp->int conversion?
 | ||||
|     logic [$clog2(`LGLEN)-1:0] ZeroCnt; // output from the LZC
 | ||||
| 
 | ||||
| 
 | ||||
|     // seperate OpCtrl for code readability
 | ||||
| @ -91,18 +93,11 @@ module fcvt ( | ||||
|     ///////////////////////////////////////////////////////////////////////////
 | ||||
|     // negation
 | ||||
|     ///////////////////////////////////////////////////////////////////////////
 | ||||
|     // negate the input if the input is a negitive singed integer
 | ||||
|     //      - remove leading ones if the input is a unsigned 32-bit integer
 | ||||
|     //
 | ||||
|     //              Negitive input
 | ||||
|     //                      64-bit input : negate the input
 | ||||
|     //                      32-bit input : trim to 32-bits and negate the input
 | ||||
|     //              Positive input
 | ||||
|     //                      64-bit input : do nothing
 | ||||
|     //                      32-bit input : trim to 32-bits
 | ||||
|     // 1) negate the input if the input is a negitive singed integer
 | ||||
|     // 2) trim the input to the proper size (kill the 32 most significant zeroes if needed)
 | ||||
| 
 | ||||
|     assign PosInt = ResSgn ? Int64 ? -ForwardedSrcAE : {{`XLEN-32{1'b0}}, -ForwardedSrcAE[31:0]} :  | ||||
|                              Int64 ? ForwardedSrcAE : {{`XLEN-32{1'b0}}, ForwardedSrcAE[31:0]}; | ||||
|     assign PosInt = ResSgn ? -ForwardedSrcAE : ForwardedSrcAE; | ||||
|     assign TrimInt = {{`XLEN-32{Int64}}, {32{1'b1}}} & PosInt; | ||||
| 
 | ||||
|     ///////////////////////////////////////////////////////////////////////////
 | ||||
|     // lzc 
 | ||||
| @ -111,16 +106,10 @@ module fcvt ( | ||||
|     // choose the input to the leading zero counter i.e. priority encoder
 | ||||
|     //             int -> fp : | positive integer | 00000... (if needed) | 
 | ||||
|     //             fp  -> fp : | fraction         | 00000... (if needed) | 
 | ||||
|     assign LzcIn = IntToFp ? {PosInt, {`LGLEN-`XLEN{1'b0}}} :      // I->F
 | ||||
|                              {XManE[`NF-1:0], {`LGLEN-`NF{1'b0}}}; // F->F
 | ||||
|     assign LzcIn = IntToFp ? {TrimInt, {`LGLEN-`XLEN{1'b0}}} : | ||||
|                              {XManE[`NF-1:0], {`LGLEN-`NF{1'b0}}}; | ||||
|      | ||||
|     // lglen is the largest possible value of ZeroCnt (NF or XLEN) hence normcnt must be log2(lglen) bits
 | ||||
| 	logic [$clog2(`LGLEN):0]	i, ZeroCnt; | ||||
| 	always_comb begin | ||||
| 			i = 0; | ||||
| 			while (~LzcIn[`LGLEN-1-i] & i <= `LGLEN-1) i = i+1;  // search for leading one 
 | ||||
| 			ZeroCnt = i; | ||||
| 	end | ||||
|     lzc #(`LGLEN) lzc (.num(LzcIn), .ZeroCnt); | ||||
| 
 | ||||
| 
 | ||||
|     ///////////////////////////////////////////////////////////////////////////
 | ||||
| @ -154,9 +143,9 @@ module fcvt ( | ||||
|     //              - only shift fp -> fp if the intital value is denormalized
 | ||||
|     //                  - this is a problem because the input to the lzc was the fraction rather than the mantissa
 | ||||
|     //                  - rather have a few and-gates than an extra bit in the priority encoder??? *** is this true?
 | ||||
|     assign ShiftAmt = ToInt ? CalcExp[$clog2(`LGLEN):0]&{$clog2(`LGLEN)+1{~CalcExp[`NE]}} : | ||||
|                     ResDenormUf&~IntToFp ? ($clog2(`LGLEN)+1)'(`NF-1)+CalcExp[$clog2(`LGLEN):0] :  | ||||
|                               (ZeroCnt+1)&{$clog2(`LGLEN)+1{XOrigDenormE|IntToFp}}; | ||||
|     assign ShiftAmt = ToInt ? CalcExp[$clog2(`LGLEN)-1:0]&{$clog2(`LGLEN){~CalcExp[`NE]}} : | ||||
|                     ResDenormUf&~IntToFp ? ($clog2(`LGLEN))'(`NF-1)+CalcExp[$clog2(`LGLEN)-1:0] :  | ||||
|                               (ZeroCnt+1)&{$clog2(`LGLEN){XOrigDenormE|IntToFp}}; | ||||
|      | ||||
|     // shift
 | ||||
|     //      fp -> int: |  `XLEN  zeros |     Mantissa      | 0's if nessisary | << CalcExp
 | ||||
| @ -568,7 +557,7 @@ module fcvt ( | ||||
|     //      - do so if the result underflows, is zero (the exp doesnt calculate correctly). or the integer input is 0
 | ||||
|     //      - dont set to zero if fp input is zero but not using the fp input
 | ||||
|     //      - dont set to zero if int input is zero but not using the int input
 | ||||
|     assign KillRes = (ResUf|(XZeroE&~IntToFp)|(~|PosInt&IntToFp)); | ||||
|     assign KillRes = (ResUf|(XZeroE&~IntToFp)|(~|TrimInt&IntToFp)); | ||||
| 
 | ||||
|     if (`FPSIZES == 1) begin         | ||||
|         // IEEE sends a payload while Riscv says to send a canonical quiet NaN
 | ||||
|  | ||||
| @ -409,22 +409,10 @@ module loa( //https://ieeexplore.ieee.org/abstract/document/930098 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     lzc lzc(.f, .NormCntE); | ||||
|     lzc #(3*`NF+7) lzc (.num(f), .ZeroCnt(NormCntE)); | ||||
|    | ||||
| endmodule | ||||
| 
 | ||||
| module lzc( | ||||
|     input logic  [3*`NF+6:0]            f, | ||||
|     output logic [$clog2(3*`NF+7)-1:0]    NormCntE    // normalization shift
 | ||||
| ); | ||||
|      | ||||
|     logic [$clog2(3*`NF+7)-1:0] i; | ||||
|     always_comb begin | ||||
|         i = 0; | ||||
|         while (~f[3*`NF+6-i] & $unsigned(i) <= $unsigned($clog2(3*`NF+7)'(3)*($clog2(3*`NF+7))'(`NF)+($clog2(3*`NF+7))'(6))) i = i+1;  // search for leading one
 | ||||
|         NormCntE = i; | ||||
|     end | ||||
| endmodule | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										13
									
								
								pipelined/src/generic/lzc.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								pipelined/src/generic/lzc.sv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| //leading zero counter i.e. priority encoder
 | ||||
| module lzc #(parameter WIDTH=1) ( | ||||
|     input logic  [WIDTH-1:0]            num, | ||||
|     output logic [$clog2(WIDTH)-1:0]  ZeroCnt | ||||
| ); | ||||
|      | ||||
|     logic [$clog2(WIDTH)-1:0] i; | ||||
|     always_comb begin | ||||
|         i = 0; | ||||
|         while (~num[WIDTH-1-i] & $unsigned(i) <= $unsigned(WIDTH-1)) i = i+1;  // search for leading one
 | ||||
|         ZeroCnt = i; | ||||
|     end | ||||
| endmodule | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user