⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_top.v

📁 利用FPGA实现浮点运算的verilog代码 希望能够给需要做这方面研究的同仁有所帮助
💻 V
字号:
/////////////////////////////////////////////////////////////////////////                                                             ////////  FPU                                                        ////////  Floating Point Unit (Single precision)                     ////////                                                             ////////  TEST BENCH                                                 ////////                                                             ////////  Author: Rudolf Usselmann                                   ////////          rudi@asics.ws                                      ////////                                                             /////////////////////////////////////////////////////////////////////////////                                                             //////// Copyright (C) 2000 Rudolf Usselmann                         ////////                    rudi@asics.ws                            ////////                                                             //////// This source file may be used and distributed without        //////// restriction provided that this copyright statement is not   //////// removed from the file and that any derivative work contains //////// the original copyright notice and the associated disclaimer.////////                                                             ////////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     //////// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   //////// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   //////// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      //////// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         //////// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    //////// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   //////// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        //////// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  //////// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  //////// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  //////// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         //////// POSSIBILITY OF SUCH DAMAGE.                                 ////////                                                             /////////////////////////////////////////////////////////////////////////`timescale 1ns / 100psmodule test;reg		clk;reg	[31:0]	opa;reg	[31:0]	opb;wire	[31:0]	sum;wire		inf, snan, qnan;wire		div_by_zero;reg	[31:0]	exp, exp1, exp2, exp3, exp4;reg	[31:0]	opa1, opa2, opa3, opa4;reg	[31:0]	opb1, opb2, opb3, opb4;reg	[2:0]	fpu_op, fpu_op1, fpu_op2, fpu_op3, fpu_op4, fpu_op5;reg	[3:0]	rmode, rmode1, rmode2, rmode3, rmode4, rmode5;reg		start, s1, s2, s3, s4;reg	[115:0]	tmem[0:500000];reg	[115:0]	tmp;reg	[7:0]	oper;reg	[7:0]	exc, exc1, exc2, exc3, exc4;integer		i;wire		ine;reg		match;wire		overflow, underflow;wire		zero;reg		exc_err;reg		m0, m1, m2;reg	[1:0]	fpu_rmode;reg	[3:0]	test_rmode;reg	[4:0]	test_sel;reg		fp_fasu;reg		fp_mul;reg		fp_div;reg		fp_combo;reg		fp_i2f;reg		fp_f2i;reg		test_exc;reg		show_prog;event		error_event;integer		error, vcount;always #50 clk = ~clk;initial   begin	$display ("\n\nFloating Point Unit Version 1.5\n\n");	clk = 0;	start = 0;	s1 = 0;	s2 = 0;	s3 = 0;	s4 = 0;	error = 0;	vcount = 0;	show_prog = 0;	fp_combo = 0;	fp_fasu  = 0;	fp_mul   = 0;	fp_div   = 0;	fp_i2f   = 1;	fp_f2i   = 1;	test_exc = 1;	test_sel   = 5'b01111;	test_rmode = 4'b1111;	//test_sel   = 5'b00110;	//test_rmode = 4'b01110;	fp_combo = 1;	fp_fasu  = 1;	fp_mul   = 1;	fp_div   = 1;	fp_i2f   = 1;	fp_f2i   = 1;	test_sel   = 5'b11111;	test_rmode = 4'b1111;	@(posedge clk);`include "test_bench/sel_test.vh"	repeat (4)	@(posedge clk);	$display("\n\n");	$display("\n\nAll test Done !\n\n");	$display("Run %0d vecors, found %0d errors.\n\n",vcount, error);	$finish;   endtask run_test;begin	@(posedge clk);	#1;	opa = 32'hx;	opb = 32'hx;	fpu_rmode = 2'hx;	fpu_op = 3'hx;	repeat(4) @(posedge clk);	#1;	oper = 1;	i=0;	while( |oper == 1'b1 )	   begin		@(posedge clk);		#1;		start = 1;		tmp   = tmem[i];		rmode = tmp[115:112];		exc   = tmp[111:104];		oper  = tmp[103:96];		opa   = tmp[95:64];		opb   = tmp[63:32];		exp   = tmp[31:00];		// FPU rounding mode		//  0:	float_round_nearest_even		//  1:	float_round_down		//  2:	float_round_up		//  3:	float_round_to_zero			case(rmode)		  0: fpu_rmode = 0;		  1: fpu_rmode = 3;		  2: fpu_rmode = 2;		  3: fpu_rmode = 1;		  default: fpu_rmode=2'hx;		endcase		// oper	fpu operation		//   1   add		//   2   sub		//   4   mul		//   8   div		//   ...		case(oper)		   8'b00000001:	fpu_op=3'b000;	// Add		   8'b00000010:	fpu_op=3'b001;	// Sub		   8'b00000100:	fpu_op=3'b010;	// Mul		   8'b00001000:	fpu_op=3'b011;	// Div		   8'b00010000:	fpu_op=3'b100;	// i2f		   8'b00100000:	fpu_op=3'b101;	// f2i		   8'b01000000:	fpu_op=3'b110;	// rem		   default: fpu_op=3'bx;		endcase		if(show_prog)	$write("Vector: %d\015",i);		//if(oper==1)	$write("+");		//else		//if(oper==2)	$write("-");		//else		//if(oper==4)	$write("*");		//else		//if(oper==8)	$write("/");		//else		$write("Unknown Operation (%d)",oper);		i= i+1;	   end	start = 0;   	@(posedge clk);	#1;	opa = 32'hx;	opb = 32'hx;	fpu_rmode = 2'hx;	fpu_op = 2'hx;	repeat(4) @(posedge clk);	#1;	for(i=0;i<500000;i=i+1)		// Clear Memory	   tmem[i] = 112'hxxxxxxxxxxxxxxxxx;   endendtaskalways @(posedge clk)   begin   	s1 <= #1 start;   	s2 <= #1 s1;   	s3 <= #1 s2;   	s4 <= #1 s3;	exp1 <= #1 exp;	exp2 <= #1 exp1;	exp3 <= #1 exp2;	exp4 <= #1 exp3;	opa1 <= #1 opa;	opa2 <= #1 opa1;	opa3 <= #1 opa2;	opa4 <= #1 opa3;	opb1 <= #1 opb;	opb2 <= #1 opb1;	opb3 <= #1 opb2;	opb4 <= #1 opb3;	fpu_op1 <= #1 fpu_op;	fpu_op2 <= #1 fpu_op1;	fpu_op3 <= #1 fpu_op2;	fpu_op4 <= #1 fpu_op3;	fpu_op5 <= #1 fpu_op4;	rmode1 <= #1 rmode;	rmode2 <= #1 rmode1;	rmode3 <= #1 rmode2;	rmode4 <= #1 rmode3;	rmode5 <= #1 rmode4;	exc1 <= #1 exc;	exc2 <= #1 exc1;	exc3 <= #1 exc2;	exc4 <= #1 exc3;	#3;		//	Floating Point Exceptions ( exc4 )	//	-------------------------	//	float_flag_invalid   =  1,	//	float_flag_divbyzero =  4,	//	float_flag_overflow  =  8,	//	float_flag_underflow = 16,	//	float_flag_inexact   = 32   	exc_err=0;	if(test_exc)	   begin		if(div_by_zero !== exc4[2])		   begin		   	exc_err=1;			$display("\nERROR: DIV_BY_ZERO Exception: Expected: %h, Got %h\n",exc4[2],div_by_zero);		   end		if(ine !== exc4[5])		   begin		   	exc_err=1;			$display("\nERROR: INE Exception: Expected: %h, Got %h\n",exc4[5],ine);		   end		if(overflow !== exc4[3])		   begin		   	exc_err=1;			$display("\nERROR: Overflow Exception Expected: %h, Got %h\n",exc4[3],overflow);		   end			if(underflow !== exc4[4])		   begin		   	exc_err=1;			$display("\nERROR: Underflow Exception Expected: %h, Got %h\n",exc4[4],underflow);		   end			if(zero !== !(|sum[30:0]))		   begin		   	exc_err=1;			$display("\nERROR: Zero Detection Failed. ZERO: %h, Sum: %h\n", zero, sum);		   end			if(inf !== ( (sum[30:23] == 8'hff) & ((|sum[22:0]) == 1'b0) ) )		   begin		   	exc_err=1;			$display("\nERROR: INF Detection Failed. INF: %h, Sum: %h\n", inf, sum);		   end			if(qnan !== ( &sum[30:23]  & |sum[22:0] )  & !(fpu_op4==5)   )		   begin		   	exc_err=1;			$display("\nERROR: QNAN Detection Failed. QNAN: %h, Sum: %h\n", qnan, sum);		   end		if(snan !== ( ( &opa4[30:23] & !opa4[22] & |opa4[21:0]) | ( &opb4[30:23] & !opb4[22] & |opb4[21:0]) ) )		   begin		   	exc_err=1;			$display("\nERROR: SNAN Detection Failed. SNAN: %h, OpA: %h, OpB: %h\n", snan, opa4, opb4);		   end	   end	m0 = ( (|sum) !== 1'b1) & ( (|sum) !== 1'b0);		// result unknown (ERROR)	//m0 = ( (|sum) === 1'bx) & 0;	m1 = (exp4 === sum);					// results are equal	// NAN   *** Ignore Fraction Detail ***	m2 =    (sum[31] == exp4[31]) &		(sum[30:23] == 8'hff)  & (exp4[30:23] == 8'hff) &		(sum[22] == exp4[22]) &		( (|sum[22:0]) == 1'b1) & ((|exp4[22:0]) == 1'b1);	match = m1 | m2;	if( (exc_err | !match | m0) & s4 )	   begin		-> error_event;		#0.6;		$display("\n%t: ERROR: output mismatch. Expected %h, Got %h (%h)", $time, exp4, sum, {opa4, opb4, exp4} );		$write("opa:\t");	disp_fp(opa4);		$display("opa:\t%h",opa4[30:0]);		case(fpu_op4)		   0: $display("\t+");		   1: $display("\t-");		   2: $display("\t*");		   3: $display("\t/");		   default: $display("\t Unknown Operation ");		endcase		$write("opb:\t");	disp_fp(opb4);		$write("EXP:\t");	disp_fp(exp4);		$write("GOT:\t");	disp_fp(sum);		$display("\nThis rmode: %h fpop: %h; Previous: rmode: %h fpop: %h; Next: rmode: %h fpop: %h\n",rmode4, fpu_op4, rmode5, fpu_op5, rmode3, fpu_op3);		$display("\n");		error = error + 1;	   end	if(s4)	vcount = vcount + 1;	if(error > 10)	   begin		@(posedge clk);	   	$display("\n\nFound to many errors, aborting ...\n\n");		$display("Run %0d vecors, found %0d errors.\n\n",vcount, error);		$finish;	   end   endfpu u0(clk, fpu_rmode, fpu_op, opa, opb, sum, inf, snan, qnan, ine, overflow, underflow, zero, div_by_zero);task disp_fp;input [31:0]	fp;reg 	[63:0]	x;reg	[7:0]	exp;   begin	exp = fp[30:23];	if(exp==8'h7f)	$write("(%h %h ( 00 ) %h) ",fp[31], exp, fp[22:0]);	else	if(exp>8'h7f)	$write("(%h %h (+%d ) %h) ",fp[31], exp, exp-8'h7f, fp[22:0]);	else		$write("(%h %h (-%d ) %h) ",fp[31], exp, 8'h7f-exp, fp[22:0]);			x[51:0] = {fp[22:0], 29'h0};	x[63] = fp[31];	x[62] = fp[30];	x[61:59] = {fp[29], fp[29], fp[29]};	x[58:52] = fp[29:23];		$display("\t%f",$bitstoreal(x));   endendtaskendmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -