mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			233 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			Systemverilog
		
	
	
	
	
	
			
		
		
	
	
			233 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			Systemverilog
		
	
	
	
	
	
 | 
						|
//`include "../../../config/old/rv64icfd/wally-config.vh"
 | 
						|
 | 
						|
`define FLEN 64//(`Q_SUPPORTED ? 128 : `D_SUPPORTED ? 64 : 32)
 | 
						|
`define NE   11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
 | 
						|
`define NF   52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
 | 
						|
`define XLEN 64
 | 
						|
module testbench3();
 | 
						|
 | 
						|
 logic [31:0] errors=0;
 | 
						|
 logic [31:0] vectornum=0;
 | 
						|
 logic [`FLEN*4+7:0] testvectors[6133248:0];
 | 
						|
 | 
						|
//  logic 	[63:0]		X,Y,Z;
 | 
						|
 logic 	[`FLEN-1:0]		ans;
 | 
						|
 logic 	[7:0]	 	flags;
 | 
						|
 logic 	[2:0]		FrmE;
 | 
						|
 logic				FmtE;
 | 
						|
 logic  [`FLEN-1:0]      FMAResM;
 | 
						|
 logic  [4:0]       FMAFlgM;
 | 
						|
integer fp;
 | 
						|
logic 	[2:0]		FOpCtrlE;
 | 
						|
logic 		[2*`NF+1:0]		ProdManE; 
 | 
						|
logic 		[3*`NF+5:0]		AlignedAddendE;	
 | 
						|
logic 		[`NE+1:0]		ProdExpE; 
 | 
						|
logic 					AddendStickyE;
 | 
						|
logic 					KillProdE; 
 | 
						|
// logic					XZeroE;
 | 
						|
// logic					YZeroE;
 | 
						|
// logic					ZZeroE;
 | 
						|
// logic					XDenormE;
 | 
						|
// logic					YDenormE;
 | 
						|
// logic					ZDenormE;
 | 
						|
// logic					XInfE;
 | 
						|
// logic					YInfE;
 | 
						|
// logic					ZInfE;
 | 
						|
// logic					XNaNE;
 | 
						|
// logic					YNaNE;
 | 
						|
// logic					ZNaNE;
 | 
						|
 | 
						|
logic wnan;
 | 
						|
// logic XNaNE;
 | 
						|
// logic YNaNE;
 | 
						|
// logic ZNaNE;
 | 
						|
logic ansnan, clk;
 | 
						|
 | 
						|
 | 
						|
assign FOpCtrlE = 3'b0;  
 | 
						|
 | 
						|
// nearest even - 000
 | 
						|
// twords zero - 001
 | 
						|
// down - 010
 | 
						|
// up - 011
 | 
						|
// nearest max mag - 100  
 | 
						|
assign FrmE = 3'b000;
 | 
						|
assign FmtE = 1'b1;
 | 
						|
 | 
						|
    logic  [`FLEN-1:0] X, Y, Z;
 | 
						|
    // logic         FmtE;
 | 
						|
    // logic  [2:0]  FOpCtrlE;
 | 
						|
    logic        XSgnE, YSgnE, ZSgnE;
 | 
						|
    logic [`NE-1:0] XExpE, YExpE, ZExpE;
 | 
						|
    logic [`NF-1:0] XFracE, YFracE, ZFracE;
 | 
						|
    logic        XAssumed1E, YAssumed1E, ZAssumed1E;
 | 
						|
    logic XNormE;
 | 
						|
    logic XNaNE, YNaNE, ZNaNE;
 | 
						|
    logic XSNaNE, YSNaNE, ZSNaNE;
 | 
						|
    logic XDenormE, YDenormE, ZDenormE;
 | 
						|
    logic XZeroE, YZeroE, ZZeroE;
 | 
						|
    logic [`NE-1:0] BiasE;
 | 
						|
    logic XInfE, YInfE, ZInfE;
 | 
						|
    logic XExpMaxE;
 | 
						|
 //***rename to make significand = 1.frac m = significand
 | 
						|
    logic           XFracZero, YFracZero, ZFracZero; // input fraction zero
 | 
						|
    logic           XExpZero, YExpZero, ZExpZero; // input exponent zero
 | 
						|
    logic [`FLEN-1:0]    Addend; // value to add (Z or zero)
 | 
						|
    logic           YExpMaxE, ZExpMaxE;  // input exponent all 1s
 | 
						|
 | 
						|
    assign Addend = FOpCtrlE[2] ? (`FLEN)'(0) : Z; // Z is only used in the FMA, and is set to Zero if a multiply opperation
 | 
						|
    assign XSgnE = FmtE ? X[`FLEN-1] : X[31];
 | 
						|
    assign YSgnE = FmtE ? Y[`FLEN-1] : Y[31];
 | 
						|
    assign ZSgnE = FmtE ? Addend[`FLEN-1] : Addend[31];
 | 
						|
 | 
						|
    assign XExpE = FmtE ? X[62:52] : {X[30], {3{~X[30]&~XExpZero|XExpMaxE}}, X[29:23]}; 
 | 
						|
    assign YExpE = FmtE ? Y[62:52] : {Y[30], {3{~Y[30]&~YExpZero|YExpMaxE}}, Y[29:23]}; 
 | 
						|
    assign ZExpE = FmtE ? Addend[62:52] : {Addend[30], {3{~Addend[30]&~ZExpZero|ZExpMaxE}}, Addend[29:23]}; 
 | 
						|
 | 
						|
    assign XFracE = FmtE ? X[`NF-1:0] : {X[22:0], 29'b0};
 | 
						|
    assign YFracE = FmtE ? Y[`NF-1:0] : {Y[22:0], 29'b0};
 | 
						|
    assign ZFracE = FmtE ? Addend[`NF-1:0] : {Addend[22:0], 29'b0};
 | 
						|
 | 
						|
    assign XAssumed1E = FmtE ? |X[62:52] : |X[30:23]; 
 | 
						|
    assign YAssumed1E = FmtE ? |Y[62:52] : |Y[30:23];
 | 
						|
    assign ZAssumed1E = FmtE ? |Z[62:52] : |Z[30:23];
 | 
						|
 | 
						|
    assign XExpZero = ~XAssumed1E;
 | 
						|
    assign YExpZero = ~YAssumed1E;
 | 
						|
    assign ZExpZero = ~ZAssumed1E;
 | 
						|
   
 | 
						|
    assign XFracZero = ~|XFracE;
 | 
						|
    assign YFracZero = ~|YFracE;
 | 
						|
    assign ZFracZero = ~|ZFracE;
 | 
						|
 | 
						|
    assign XExpMaxE = FmtE ? &X[62:52] : &X[30:23];
 | 
						|
    assign YExpMaxE = FmtE ? &Y[62:52] : &Y[30:23];
 | 
						|
    assign ZExpMaxE = FmtE ? &Z[62:52] : &Z[30:23];
 | 
						|
   
 | 
						|
    assign XNormE = ~(XExpMaxE|XExpZero);
 | 
						|
    
 | 
						|
    assign XNaNE = XExpMaxE & ~XFracZero;
 | 
						|
    assign YNaNE = YExpMaxE & ~YFracZero;
 | 
						|
    assign ZNaNE = ZExpMaxE & ~ZFracZero;
 | 
						|
 | 
						|
    assign XSNaNE = XNaNE&~XFracE[`NF-1];
 | 
						|
    assign YSNaNE = YNaNE&~YFracE[`NF-1];
 | 
						|
    assign ZSNaNE = ZNaNE&~ZFracE[`NF-1];
 | 
						|
 | 
						|
    assign XDenormE = XExpZero & ~XFracZero;
 | 
						|
    assign YDenormE = YExpZero & ~YFracZero;
 | 
						|
    assign ZDenormE = ZExpZero & ~ZFracZero;
 | 
						|
 | 
						|
    assign XInfE = XExpMaxE & XFracZero;
 | 
						|
    assign YInfE = YExpMaxE & YFracZero;
 | 
						|
    assign ZInfE = ZExpMaxE & ZFracZero;
 | 
						|
 | 
						|
    assign XZeroE = XExpZero & XFracZero;
 | 
						|
    assign YZeroE = YExpZero & YFracZero;
 | 
						|
    assign ZZeroE = ZExpZero & ZFracZero;
 | 
						|
 | 
						|
    assign BiasE = 13'h3ff;
 | 
						|
 | 
						|
assign	wnan = FmtE ? &FMAResM[`FLEN-2:`NF] & |FMAResM[`NF-1:0] : &FMAResM[30:23] & |FMAResM[22:0]; 
 | 
						|
// assign	XNaNE = FmtE ? &X[62:52] & |X[51:0] : &X[62:55] & |X[54:32]; 
 | 
						|
// assign	YNaNE = FmtE ? &Y[62:52] & |Y[51:0] : &Y[62:55] & |Y[54:32]; 
 | 
						|
// assign	ZNaNE = FmtE ? &Z[62:52] & |Z[51:0] : &Z[62:55] & |Z[54:32]; 
 | 
						|
assign	ansnan = FmtE ? &ans[`FLEN-2:`NF] & |ans[`NF-1:0] : &ans[30:23] & |ans[22:0]; 
 | 
						|
 // instantiate device under test
 | 
						|
 | 
						|
    logic [3*`NF+5:0]	SumE, SumM;       
 | 
						|
    logic 			    InvZE, InvZM;
 | 
						|
    logic 			    NegSumE, NegSumM;
 | 
						|
    logic 			    ZSgnEffE, ZSgnEffM;
 | 
						|
    logic 			    PSgnE, PSgnM;
 | 
						|
    logic [8:0]			NormCntE, NormCntM;
 | 
						|
    
 | 
						|
    fma1 fma1 (.XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE({XAssumed1E,XFracE}), .YManE({YAssumed1E,YFracE}), .ZManE({ZAssumed1E,ZFracE}),
 | 
						|
                 .XDenormE, .YDenormE, .ZDenormE,  .XZeroE, .YZeroE, .ZZeroE,
 | 
						|
                .FOpCtrlE, .FmtE, .SumE, .NegSumE, .InvZE, .NormCntE, .ZSgnEffE, .PSgnE,
 | 
						|
                .ProdExpE, .AddendStickyE, .KillProdE); 
 | 
						|
fma2 UUT2(.XSgnM(XSgnE), .YSgnM(YSgnE), .XExpM(XExpE), .YExpM(YExpE), .ZExpM(ZExpE), .XManM({XAssumed1E,XFracE}), .YManM({YAssumed1E,YFracE}), .ZManM({ZAssumed1E,ZFracE}), .XNaNM(XNaNE), .YNaNM(YNaNE), .ZNaNM(ZNaNE), .XZeroM(XZeroE), .YZeroM(YZeroE), .ZZeroM(ZZeroE), .XInfM(XInfE), .YInfM(YInfE), .ZInfM(ZInfE), .XSNaNM(XSNaNE), .YSNaNM(YSNaNE), .ZSNaNM(ZSNaNE),
 | 
						|
              //  .FSrcXE, .FSrcYE, .FSrcZE, .FSrcXM, .FSrcYM, .FSrcZM, 
 | 
						|
                .KillProdM(KillProdE), .AddendStickyM(AddendStickyE), .ProdExpM(ProdExpE), .SumM(SumE), .NegSumM(NegSumE), .InvZM(InvZE), .NormCntM(NormCntE), .ZSgnEffM(ZSgnEffE), .PSgnM(PSgnE),
 | 
						|
               .FmtM(FmtE), .FrmM(FrmE), .FMAFlgM, .FMAResM);
 | 
						|
 | 
						|
 | 
						|
 // produce clock
 | 
						|
 always
 | 
						|
 begin
 | 
						|
 clk = 1; #5; clk = 0; #5;
 | 
						|
 end
 | 
						|
 // at start of test, load vectors
 | 
						|
 // and pulse reset
 | 
						|
 initial
 | 
						|
 begin
 | 
						|
    $readmemh("testFloatNoSpace", testvectors);
 | 
						|
 end
 | 
						|
 // apply test vectors on rising edge of clk
 | 
						|
always @(posedge clk)
 | 
						|
 begin
 | 
						|
  #1; 
 | 
						|
  if (FmtE==1'b1) {X, Y, Z, ans, flags} = testvectors[vectornum];
 | 
						|
  else	begin	  X = {{32{1'b1}}, testvectors[vectornum][135:104]};
 | 
						|
  		  Y = {{32{1'b1}}, testvectors[vectornum][103:72]};
 | 
						|
  		  Z = {{32{1'b1}}, testvectors[vectornum][71:40]};
 | 
						|
  		  ans = {{32{1'b1}}, testvectors[vectornum][39:8]};
 | 
						|
  		  flags = testvectors[vectornum][7:0];
 | 
						|
  end
 | 
						|
 end
 | 
						|
 // check results on falling edge of clk
 | 
						|
  always @(negedge clk) begin
 | 
						|
 
 | 
						|
	if((FmtE==1'b1) & (FMAFlgM != flags[4:0] | (!wnan & (FMAResM != ans)) | (wnan & ansnan & ~((XNaNE & (FMAResM[`FLEN-2:0] == {XExpE,1'b1,X[`NF-2:0]})) | (YNaNE & (FMAResM[`FLEN-2:0] == {YExpE,1'b1,Y[`NF-2:0]}))  | (ZNaNE & (FMAResM[`FLEN-2:0] == {ZExpE,1'b1,Z[`NF-2:0]})) | (FMAResM[`FLEN-2:0] == ans[`FLEN-2:0]))))) begin
 | 
						|
  //  fp = $fopen("/home/kparry/riscv-wally/pipelined/src/fpu/FMA/tbgen/results.dat","w");
 | 
						|
	// if((FmtE==1'b1) & (FMAFlgM != flags[4:0] | (FMAResM != ans))) begin
 | 
						|
        $display( "%h %h %h %h %h %h %h  Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags);
 | 
						|
		if(FMAResM == 64'h8000000000000000) $display( "FMAResM=-zero ");
 | 
						|
		if(XDenormE) $display( "xdenorm ");
 | 
						|
		if(YDenormE) $display( "ydenorm ");
 | 
						|
		if(ZDenormE) $display( "zdenorm ");
 | 
						|
		if(FMAFlgM[4] != 0) $display( "invld ");
 | 
						|
		if(FMAFlgM[2] != 0) $display( "ovrflw ");
 | 
						|
		if(FMAFlgM[1] != 0) $display( "unflw ");
 | 
						|
		if(FMAResM[`FLEN] & FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} & FMAResM[`NF-1:0] == 0) $display( "FMAResM=-inf ");
 | 
						|
		if(~FMAResM[`FLEN] & FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} & FMAResM[`NF-1:0] == 0) $display( "FMAResM=+inf ");
 | 
						|
		if(FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} & FMAResM[`NF-1:0] != 0 & ~FMAResM[`NF-1]) $display( "FMAResM=sigNaN ");
 | 
						|
		if(FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} & FMAResM[`NF-1:0] != 0 & FMAResM[`NF-1]) $display( "FMAResM=qutNaN ");
 | 
						|
		if(ans[`FLEN] & ans[`FLEN-2:`NF] == {`NE{1'b1}} & ans[`NF-1:0] == 0) $display( "ans=-inf ");
 | 
						|
		if(~ans[`FLEN] & ans[`FLEN-2:`NF] == {`NE{1'b1}} & ans[`NF-1:0] == 0) $display( "ans=+inf ");
 | 
						|
		if(ans[`FLEN-2:`NF] == {`NE{1'b1}} & ans[`NF-1:0] != 0 & ~ans[`NF-1]) $display( "ans=sigNaN ");
 | 
						|
		if(ans[`FLEN-2:`NF] == {`NE{1'b1}} & ans[`NF-1:0] != 0 & ans[`NF-1]) $display( "ans=qutNaN ");
 | 
						|
        errors = errors + 1;
 | 
						|
	  //if (errors == 10)
 | 
						|
		$stop;
 | 
						|
    end
 | 
						|
    if((FmtE==1'b0)&(FMAFlgM != flags[4:0] | (!wnan & (FMAResM != ans)) | (wnan & ansnan & ~(((XNaNE & (FMAResM[30:0] == {X[30:23],1'b1,X[21:0]})) | (YNaNE & (FMAResM[30:0] == {Y[30:23],1'b1,Y[21:0]}))  | (ZNaNE & (FMAResM[30:0] == {Z[30:23],1'b1,Z[21:0]})) | (FMAResM[30:0] == ans[30:0]))) ))) begin
 | 
						|
        $display( "%h %h %h %h %h %h %h  Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags);
 | 
						|
		if(FMAResM == 64'h8000000000000000) $display( "FMAResM=-zero ");
 | 
						|
		if(~(|X[30:23]) & |X[22:0]) $display( "xdenorm ");
 | 
						|
		if(~(|Y[30:23]) & |Y[22:0]) $display( "ydenorm ");
 | 
						|
		if(~(|Z[30:23]) & |Z[22:0]) $display( "zdenorm ");
 | 
						|
		if(FMAFlgM[4] != 0) $display( "invld ");
 | 
						|
		if(FMAFlgM[2] != 0) $display( "ovrflw ");
 | 
						|
		if(FMAFlgM[1] != 0) $display( "unflw ");
 | 
						|
		if(FMAResM == 64'hFF80000000000000) $display( "FMAResM=-inf ");
 | 
						|
		if(FMAResM == 64'h7F80000000000000) $display( "FMAResM=+inf ");
 | 
						|
		if(&FMAResM[30:23] & |FMAResM[22:0] & ~FMAResM[22]) $display( "FMAResM=sigNaN ");
 | 
						|
		if(&FMAResM[30:23] & |FMAResM[22:0] & FMAResM[22] ) $display( "FMAResM=qutNaN ");
 | 
						|
		if(ans == 64'hFF80000000000000) $display( "ans=-inf ");
 | 
						|
		if(ans == 64'h7F80000000000000) $display( "ans=+inf ");
 | 
						|
		if(&ans[30:23] & |ans[22:0] & ~ans[22] ) $display( "ans=sigNaN ");
 | 
						|
		if(&ans[30:23] & |ans[22:0] & ans[22]) $display( "ans=qutNaN ");
 | 
						|
        errors = errors + 1;
 | 
						|
	  if (errors == 10)
 | 
						|
		$stop;
 | 
						|
    end
 | 
						|
 vectornum = vectornum + 1;
 | 
						|
 if (testvectors[vectornum] === 194'bx) begin
 | 
						|
 $display("%d tests completed with %d errors", vectornum, errors);
 | 
						|
 $stop;
 | 
						|
 end
 | 
						|
 end
 | 
						|
endmodule
 |