mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Merge branch 'main' of https://github.com/openhwgroup/cvw into dev
This commit is contained in:
		
						commit
						35cd4e1d6c
					
				| @ -83,7 +83,7 @@ module testbenchfp; | ||||
|    logic [P.LOGCVTLEN-1:0] 	CvtShiftAmtE;               // how much to shift by
 | ||||
|    logic [P.DIVb:0] 		Quot; | ||||
|    logic                        CvtResSubnormUfE; | ||||
|    logic                        DivStart; | ||||
|    logic                        DivStart=0; | ||||
|    logic 			FDivBusyE; | ||||
|    logic 			OldFDivBusyE; | ||||
|    logic                        reset = 1'b0; | ||||
| @ -120,7 +120,11 @@ module testbenchfp; | ||||
|    logic 			ResMatch;                   // Check if result match
 | ||||
|    logic 			FlagMatch;                  // Check if IEEE flags match
 | ||||
|    logic 			CheckNow;                   // Final check
 | ||||
|    logic 			FMAop;                      // Is this a FMA operation?   
 | ||||
|    logic 			FMAop;                      // Is this a FMA operation?
 | ||||
| 
 | ||||
|    // FSM for testing each item per clock
 | ||||
|    typedef enum logic [2:0] {S0, Start, S2, Done} statetype; | ||||
|    statetype state, nextstate;    | ||||
|     | ||||
|    ///////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| @ -676,7 +680,7 @@ module testbenchfp; | ||||
|                                  .VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA,  | ||||
|                                  .Xs, .Ys, .Zs, .Unit(UnitVal), | ||||
|                                  .Xe, .Ye, .Ze, .TestNum, .OpCtrl(OpCtrlVal), | ||||
|                                  .Xm, .Ym, .Zm, .DivStart, | ||||
|                                  .Xm, .Ym, .Zm,  | ||||
|                                  .XNaN, .YNaN, .ZNaN, | ||||
|                                  .XSNaN, .YSNaN, .ZSNaN,  | ||||
|                                  .XSubnorm, .ZSubnorm,  | ||||
| @ -748,16 +752,6 @@ module testbenchfp; | ||||
|       clk = 1; #5; clk = 0; #5; | ||||
|    end | ||||
| 
 | ||||
|    // Provide reset for divsqrt to reset state to IDLE
 | ||||
|    // Previous version did not initiate a divide due to missing state
 | ||||
|    // information.  This starts the FSM by putting the fdivsqrt into
 | ||||
|    // the IDLE state.
 | ||||
|    initial | ||||
|      begin | ||||
| 	#0 reset = 1'b1; | ||||
| 	#25 reset = 1'b0;      | ||||
|      end   | ||||
|     | ||||
|    ///////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
|    //          |||||      |||  ||||||||||  |||||      |||
 | ||||
| @ -835,45 +829,64 @@ module testbenchfp; | ||||
| 	`CMPUNIT: ResFlg = CmpFlg; | ||||
| 	`CVTINTUNIT: ResFlg = Flg; | ||||
| 	`CVTFPUNIT: ResFlg = Flg; | ||||
|       endcase | ||||
|    end | ||||
|       endcase  | ||||
| 
 | ||||
|       // Use four state test sequence to handle div properly.
 | ||||
|       // Four states should allow other operations to finish
 | ||||
|       // properly and within time.
 | ||||
|       case (state) | ||||
| 	S0: begin | ||||
| 	   DivStart = 1'b0; | ||||
| 	   nextstate = Start; | ||||
| 	end | ||||
| 	Start: begin | ||||
| 	   if (UnitVal == `DIVUNIT)	   | ||||
| 	     DivStart = 1'b1; | ||||
| 	   else | ||||
| 	     DivStart = 1'b0;	   | ||||
| 	   nextstate = S2; | ||||
| 	end | ||||
| 	S2: begin | ||||
| 	   DivStart = 1'b0;	   | ||||
| 	   if ((FDivBusyE)|(~DivDone)) | ||||
| 	     nextstate = S2; | ||||
| 	   else | ||||
| 	     nextstate = Done; | ||||
| 	end | ||||
| 	Done: begin | ||||
| 	   DivStart = 1'b0; | ||||
| 	   nextstate = S0; | ||||
| 	end	 | ||||
|       endcase // case (state)
 | ||||
|        | ||||
|    end  | ||||
| 
 | ||||
|    // Provide reset for divsqrt to reset state
 | ||||
|    initial | ||||
|      begin | ||||
| 	#0  reset = 1'b1; | ||||
| 	#25 reset = 1'b0;      | ||||
|      end    | ||||
| 
 | ||||
|    // Left-over from before - will remove soon
 | ||||
|    always @(posedge clk)  | ||||
|      OldFDivBusyE = FDivDoneE; | ||||
| 
 | ||||
|    // For FP division this adds extra clock cycles to make sure the
 | ||||
|    // computation completes.  
 | ||||
|    // state machine to handle timing for testing due
 | ||||
|    // various cycle counts for different fp/int operations
 | ||||
|    // Adds vector at start of clock
 | ||||
|    always @(posedge clk) begin | ||||
|       // Add extra clock cycles in beginning for fdivsqrt to adequate reset state
 | ||||
|       if (~(FDivBusyE|DivStart)|(UnitVal != `DIVUNIT)) begin | ||||
| 	 // This allows specific number of clocks to allow each vector
 | ||||
| 	 // to complete for division or square root.  It is an
 | ||||
| 	 // arbitrary value and can be changed, if needed.
 | ||||
| 	 case (FmtVal) | ||||
| 	   // QP
 | ||||
| 	   2'b11: begin | ||||
| 	      repeat (20) | ||||
| 		@(posedge clk); | ||||
| 	   end | ||||
| 	   // HP
 | ||||
| 	   2'b10: begin | ||||
| 	      repeat (14) | ||||
| 		@(posedge clk); | ||||
| 	   end | ||||
| 	   // DP
 | ||||
| 	   2'b01: begin | ||||
| 	      repeat (18) | ||||
| 		@(posedge clk); | ||||
| 	   end | ||||
| 	   // SP
 | ||||
| 	   2'b00: begin | ||||
| 	      repeat (16) | ||||
| 		@(posedge clk); | ||||
| 	   end | ||||
| 	 endcase // case (FmtVal)	 
 | ||||
| 	 if (reset != 1'b1) | ||||
| 	   VectorNum += 1; // increment the vector
 | ||||
|       end | ||||
| 
 | ||||
|       // state machine element for testing
 | ||||
|       if (reset) | ||||
|         state <= S0; | ||||
|       else | ||||
| 	state <= nextstate;       | ||||
| 
 | ||||
|       // Increment the vector when Done with each test
 | ||||
|       if (state == Done) | ||||
| 	VectorNum += 1; // increment the vector
 | ||||
|        | ||||
|    end | ||||
| 
 | ||||
|    // check results on falling edge of clk
 | ||||
| @ -904,7 +917,7 @@ module testbenchfp; | ||||
|                               (YNaN&(Res[P.H_LEN-2:0] === {Y[P.H_LEN-2:P.H_NF],1'b1,Y[P.H_NF-2:0]})) | | ||||
|                               (ZNaN&(Res[P.H_LEN-2:0] === {Z[P.H_LEN-2:P.H_NF],1'b1,Z[P.H_NF-2:0]}))); | ||||
|          endcase | ||||
|       else if (UnitVal === `CVTFPUNIT) // if converting from floating point to floating point OpCtrl contains the final FP format
 | ||||
|       else if (UnitVal === `CVTFPUNIT) // if converting from FP to FP OpCtrl contains the final FP format
 | ||||
|          case (OpCtrlVal[1:0])  | ||||
|             2'b11: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res === {1'b0, {P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) | | ||||
|                               (AnsFlg[4]&(Res[P.Q_LEN-2:0] === {{P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) | | ||||
| @ -941,29 +954,22 @@ module testbenchfp; | ||||
|       ///////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
|       // check if result is correct
 | ||||
|       //  wait till the division result is done or one extra cylcle for early termination (to simulate the EM pipline stage)
 | ||||
|       assign ResMatch = ((Res === Ans) | NaNGood | (NaNGood === 1'bx)); | ||||
|       assign FlagMatch = ((ResFlg === AnsFlg) | (AnsFlg === 5'bx)); | ||||
|       assign divsqrtop = (OpCtrlVal == `SQRT_OPCTRL) | (OpCtrlVal == `DIV_OPCTRL); | ||||
|       assign FMAop = (OpCtrlVal == `FMAUNIT);   | ||||
|       assign DivDone = OldFDivBusyE & ~FDivBusyE; | ||||
| 
 | ||||
|       // Maybe change OpCtrl but for now just look at TEST for fma test
 | ||||
|       assign CheckNow = ((DivDone | ~divsqrtop) | (TEST == "add" | TEST == "fma" | TEST == "sub")) & (UnitVal !== `CVTINTUNIT) & (UnitVal !== `CMPUNIT); | ||||
|       if (~(ResMatch & FlagMatch) & CheckNow) begin | ||||
|       assign CheckNow = ((DivDone | ~divsqrtop) |  | ||||
| 			 (TEST == "all" | TEST == "add" | TEST == "fma" | TEST == "sub"))  | ||||
| 	& (UnitVal !== `CVTINTUNIT) & (UnitVal !== `CMPUNIT); | ||||
|        | ||||
|       if (~(ResMatch & FlagMatch) & CheckNow & (Ans[0] !== 1'bx)) begin | ||||
|          errors += 1; | ||||
|          $display("\nError in %s", Tests[TestNum]); | ||||
|          $display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]);	  | ||||
|          $display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Expected: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg); | ||||
|          $stop; | ||||
|       end else if (((UnitVal === `CVTINTUNIT) | (UnitVal === `CMPUNIT)) &  | ||||
|          ~(ResMatch & FlagMatch) & (Ans[0] !== 1'bx)) begin // Check for conversion and comparisons  
 | ||||
|             errors += 1; | ||||
|             $display("\nError in %s", Tests[TestNum]); | ||||
|             $display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]);	 	  | ||||
|             $display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Ans: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg); | ||||
|             $stop; | ||||
|       end | ||||
|       end             | ||||
| 
 | ||||
|       if (TestVectors[VectorNum][0] === 1'bx & Tests[TestNum] !== "") begin // if reached the eof
 | ||||
|          // increment the test
 | ||||
| @ -979,11 +985,12 @@ module testbenchfp; | ||||
|          // increment the rounding mode or loop back to rne 
 | ||||
|          if (FrmNum < 4) FrmNum += 1; | ||||
|          else begin | ||||
|             FrmNum = 0; | ||||
| 	    FrmNum = 0; | ||||
|             // Add some time as a buffer between tests at the end of each test
 | ||||
|             repeat (10) | ||||
|                @(posedge clk); | ||||
|          end	  | ||||
| 	    // (to be removed)
 | ||||
| 	    repeat (10) | ||||
|               @(posedge clk); | ||||
| 	 end | ||||
|          // if no more Tests - finish
 | ||||
|          if (Tests[TestNum] === "") begin | ||||
|                   $display("\nAll Tests completed with %d errors\n", errors); | ||||
| @ -996,28 +1003,27 @@ endmodule | ||||
| 
 | ||||
| 
 | ||||
| module readvectors import cvw::*; #(parameter cvw_t P) ( | ||||
| 		    input logic 	        clk, | ||||
| 		    input logic [P.FLEN*4+7:0]  TestVector, | ||||
| 		    input logic 		clk, | ||||
| 		    input logic [P.FLEN*4+7:0] 	TestVector, | ||||
| 		    input logic [P.FMTBITS-1:0] ModFmt, | ||||
| 		    input logic [1:0] 	        Fmt, | ||||
| 		    input logic [2:0] 	        Unit, | ||||
| 		    input logic [31:0] 	        VectorNum, | ||||
| 		    input logic [31:0] 	        TestNum, | ||||
| 		    input logic [2:0] 	        OpCtrl, | ||||
| 		    output logic [P.FLEN-1:0]   Ans, | ||||
| 		    output logic [P.XLEN-1:0]   SrcA, | ||||
| 		    output logic [4:0] 	        AnsFlg, | ||||
| 		    output logic 	        Xs, Ys, Zs, // sign bits of XYZ
 | ||||
| 		    output logic [P.NE-1:0]     Xe, Ye, Ze, // exponents of XYZ (converted to largest supported precision)
 | ||||
| 		    output logic [P.NF:0]       Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision)
 | ||||
| 		    output logic 	        XNaN, YNaN, ZNaN, // is XYZ a NaN
 | ||||
| 		    output logic 	        XSNaN, YSNaN, ZSNaN, // is XYZ a signaling NaN
 | ||||
| 		    output logic 	        XSubnorm, ZSubnorm, // is XYZ denormalized
 | ||||
| 		    output logic 	        XZero, YZero, ZZero, // is XYZ zero
 | ||||
| 		    output logic 	        XInf, YInf, ZInf, // is XYZ infinity
 | ||||
| 		    output logic 	        XExpMax, | ||||
| 		    output logic 	        DivStart, | ||||
| 		    output logic [P.FLEN-1:0]   X, Y, Z, XPostBox | ||||
| 		    input logic [1:0] 		Fmt, | ||||
| 		    input logic [2:0] 		Unit, | ||||
| 		    input logic [31:0] 		VectorNum, | ||||
| 		    input logic [31:0] 		TestNum, | ||||
| 		    input logic [2:0] 		OpCtrl, | ||||
| 		    output logic [P.FLEN-1:0] 	Ans, | ||||
| 		    output logic [P.XLEN-1:0] 	SrcA, | ||||
| 		    output logic [4:0] 		AnsFlg, | ||||
| 		    output logic 		Xs, Ys, Zs, // sign bits of XYZ
 | ||||
| 		    output logic [P.NE-1:0] 	Xe, Ye, Ze, // exponents of XYZ (converted to largest supported precision)
 | ||||
| 		    output logic [P.NF:0] 	Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision)
 | ||||
| 		    output logic 		XNaN, YNaN, ZNaN, // is XYZ a NaN
 | ||||
| 		    output logic 		XSNaN, YSNaN, ZSNaN, // is XYZ a signaling NaN
 | ||||
| 		    output logic 		XSubnorm, ZSubnorm, // is XYZ denormalized
 | ||||
| 		    output logic 		XZero, YZero, ZZero, // is XYZ zero
 | ||||
| 		    output logic 		XInf, YInf, ZInf, // is XYZ infinity
 | ||||
| 		    output logic 		XExpMax, | ||||
| 		    output logic [P.FLEN-1:0] 	X, Y, Z, XPostBox | ||||
| 		    ); | ||||
| 
 | ||||
|    localparam Q_LEN = 32'd128; | ||||
| @ -1030,8 +1036,6 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( | ||||
|    // apply test vectors on rising edge of clk
 | ||||
|    // Format of vectors Inputs(1/2/3)_AnsFlg
 | ||||
|    always @(VectorNum) begin | ||||
|       DivStart = 1'b0;       | ||||
|       #1; | ||||
|       AnsFlg = TestVector[4:0]; | ||||
|       case (Unit) | ||||
| 	`FMAUNIT: | ||||
| @ -1101,30 +1105,18 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( | ||||
|               2'b11: begin // quad
 | ||||
| 		 X = TestVector[8+2*(P.Q_LEN)-1:8+(P.Q_LEN)]; | ||||
| 		 Ans = TestVector[8+(P.Q_LEN-1):8]; | ||||
| 		 if (~clk) #5; | ||||
| 		 DivStart = 1'b1; #10 // one clk cycle
 | ||||
| 		   DivStart = 1'b0; | ||||
|               end | ||||
|               2'b01: if (P.D_SUPPORTED) begin // double
 | ||||
| 		 X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+2*(P.D_LEN)-1:8+(P.D_LEN)]}; | ||||
| 		 Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; | ||||
| 		 if (~clk) #5; | ||||
| 		 DivStart = 1'b1; #10 | ||||
| 		   DivStart = 1'b0; | ||||
|               end | ||||
|               2'b00: if (P.S_SUPPORTED) begin // single
 | ||||
| 		 X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+2*(P.S_LEN)-1:8+1*(P.S_LEN)]}; | ||||
| 		 Ans = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; | ||||
| 		 if (~clk) #5; | ||||
| 		 DivStart = 1'b1; #10 | ||||
| 		   DivStart = 1'b0; | ||||
|               end | ||||
|               2'b10: begin // half
 | ||||
| 		 X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+2*(P.H_LEN)-1:8+(P.H_LEN)]}; | ||||
| 		 Ans = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; | ||||
| 		 if (~clk) #5; | ||||
| 		 DivStart = 1'b1; #10 | ||||
| 		   DivStart = 1'b0; | ||||
|               end | ||||
|             endcase | ||||
|           else | ||||
| @ -1133,33 +1125,21 @@ module readvectors import cvw::*; #(parameter cvw_t P) ( | ||||
| 		 X = TestVector[8+3*(P.Q_LEN)-1:8+2*(P.Q_LEN)]; | ||||
| 		 Y = TestVector[8+2*(P.Q_LEN)-1:8+(P.Q_LEN)]; | ||||
| 		 Ans = TestVector[8+(P.Q_LEN-1):8]; | ||||
| 		 if (~clk) #5; | ||||
| 		 DivStart = 1'b1; #10 // one clk cycle
 | ||||
| 		   DivStart = 1'b0; | ||||
|               end | ||||
|               2'b01: if (P.D_SUPPORTED) begin // double
 | ||||
| 		 X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+3*(P.D_LEN)-1:8+2*(P.D_LEN)]}; | ||||
| 		 Y = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+2*(P.D_LEN)-1:8+(P.D_LEN)]}; | ||||
| 		 Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; | ||||
| 		 if (~clk) #5; | ||||
| 		 DivStart = 1'b1; #10 | ||||
| 		   DivStart = 1'b0; | ||||
|               end | ||||
|               2'b00: if (P.S_SUPPORTED) begin // single
 | ||||
| 		 X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+3*(P.S_LEN)-1:8+2*(P.S_LEN)]}; | ||||
| 		 Y = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+2*(P.S_LEN)-1:8+1*(P.S_LEN)]}; | ||||
| 		 Ans = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; | ||||
| 		 if (~clk) #5; | ||||
| 		 DivStart = 1'b1; #10 | ||||
| 		   DivStart = 1'b0; | ||||
|               end | ||||
|               2'b10: begin // half
 | ||||
| 		 X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+3*(P.H_LEN)-1:8+2*(P.H_LEN)]}; | ||||
| 		 Y = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+2*(P.H_LEN)-1:8+(P.H_LEN)]}; | ||||
| 		 Ans = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; | ||||
| 		 if (~clk) #5; | ||||
| 		 DivStart = 1'b1; #10 | ||||
| 		   DivStart = 1'b0; | ||||
|               end | ||||
|             endcase | ||||
| 	`CMPUNIT: | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user