FPGA Test Bench文件的编写

TB文件的编写

步骤

tb文件是为了对硬件描述语言 进行电路的仿真测试
主要有以下三部分
• 产生模拟激励(波形);
• 将产生的激励加入到被测试模块中并观察其响应;
• 将输出响应与期望值相比较。
一个完整的测试文件结构:

module tb_xxx();
//信号、变量声明(输入对应reg 输出对应wire)
...
//initial/always语句产生激励(时钟源)
...
//例化待测试模块 
...
//监控和比较输出响应
endmodule

1、 时钟激励设置:

//50%占空比时钟:
//方法一
parameter Clockperiod = 10;
parameter Times = 100;
initial 	
	begin
		clk_in = 0;
		forever
		 	#(ClockPeriod/2) clk_in=~clk_in;
	end
//方法二
initial 	
	begin
		clk_in = 0;
		 always#(ClockPeriod/2) clk_in=~clk_in;
	end
//方法三 产生固定数量时钟脉冲
initial 	
	begin
		clk_in = 0;
		repeat(Times)
		 	#(ClockPeriod/2) clk_in=~clk_in;
	end
//方法四 产生占空比非50%时钟
initial 	
	begin
		clk_in = 0;
		forever
		begin
		#((ClockPeriod/2)-2) clk_i=0;
		#((ClockPeriod/2)+2) clk_i=1;
		end
	end

2、复位信号的产生

//异步复位
initial
	begin
		rst_n = 1;//1'b1
		#100;
		rst_n = 0;
		#100;
		rst_n = 1;
	end
//同步复位
initial
	begin 
		rst_n <= 1;
		@(negedge clk_in)
			rst_n <= 0;
		#100;
		repeat(10)@(negedge clk_in);//延迟10个时钟周期
		@(negedge clk_in)//10个时钟周期过后 下一个下降沿 rst_n 置1
		rst_n <= 1;
	end

3、特殊信号设计

//一、封装函数进行特殊信号的输入
//send_data只是一位,根据data_en上升延来到时依次进行赋值
task data_in
input [7:0] dut_data;
input data_en;
output send_data;
begin
	@(posedge data_en);send_data = 0;//等待上升延
	@(posedge data_en); send_data = dut_data[0];
	@(posedge data_en); send_data = dut_data[1];
	@(posedge data_en); send_data = dut_data[2];
	@(posedge data_en); send_data = dut_data[3];
	@(posedge data_en); send_data = dut_data[4];
	@(posedge data_en); send_data = dut_data[5];
	@(posedge data_en); send_data = dut_data[6];
	@(posedge data_en); send_data = dut_data[7];
	@(posedge data_en); send_data = 1;
end
endtask
//调用:data_in(8'hXX,data_en,data_out);
//多输入任务封装
task more_input;
input [7:0] a;
input [7:0] b;
input [31:0] times;
output [8:0] c;
begin
repeat(times) //等待 times 个时钟上升沿
		@(posedge clk_in)
		c=a+b; //时钟上升沿 a,b 相加
end
endtask
//调用方法:more_input(x,y,t,z); //按声明顺序

//二、直接定义
//例如:SRAM 写信号产生
initial  
begin
	cs_n = 1;	//片选信号失效
	wr_n = 1;	//写信号失效
	rd_n = 1;	//读信号失效
	addr = 8'hxx; //地址无效,不定态
	data = 8'hzz; //数据无效,高阻态
	//不定态:这意味着这个信号的每一位都可以是0或1,但没有明确定义。
	//高阻态:类似于电路中的输入或输出未连接的状态
end
	#100;
//写入数据
	cs_n = 0;	
	wr_n = 0;	
	addr = 8'hF1; 
	data = 8'h2C; 
//结束写入
	#100;
	cs_n=1;
	wr_n=1;
	#10;
	addr=8'hxx;
	data=8'hzz;
	end

4、tb中的@和wait

//@使用沿触发
//wait 语句都是使用电平触发
initial
begin
start=1'b1;
wait(en=1'b1);
#10;
start=1'b0;
end

5、仿真控制语句及系统任务描述

$stop //停止运行仿真,modelsim 中可继续仿真
$stop(n) //带参数系统任务,根据参数 0,1 或 2 不同,输出仿真信息
$finish //结束运行仿真,不可继续仿真
$finish(n) //带参数系统任务,根据参数 0,1 或 2 不同,输出仿真信息
//0:不输出任何信息
//1:输出当前仿真时刻和位置
//2:输出当前仿真时刻、位置和仿真过程中用到的 memory 以及 CPU 时间的
统计
$random //产生随机数
$random % n //产生范围-n 到 n 之间的随机数
{$random} % n //产生范围 0 到 n 之间的随机数
/*---------------------------------------------------------------- 仿真终端显示描述
----------------------------------------------------------------*/
$monitor //仿真打印输出,大印出仿真过程中的变量,使其终端显示
/*
$monitor($time,,,"clk=%d reset=%d out=%d",clk,reset,out);
*/
$display //终端打印字符串,显示仿真结果等
/*
$display(” Simulation start ! ");
$display(” At time %t,input is %b%b%b,output is %b",$time,a,b,en,z);
*/
$time //返回 64 位整型时间
$stime //返回 32 位整型时间
$realtime //实行实型模拟时间

//激励具有复杂的数据结构
//verilog 提供了读入文本的系统函数
$readmemb/$readmemh("<数据文件名>",<存储器名>);
$readmemb/$readmemh("<数据文件名>",<存储器名>,<起始地址>);
$readmemb/$readmemh("<数据文件名>",<存储器名>,<起始地址>,<结束地址>);
$readmemb:/*读取二进制数据,读取文件内容只能包含:空白位置,注释行,二进制数
数据中不能包含位宽说明和格式说明,每个数字必须是二进制数字。*/
$readmemh:/*读取十六进制数据,读取文件内容只能包含:空白位置,注释行,十六进
制数
数据中不能包含位宽说明和格式说明,每个数字必须是十六进制数字。*/
/*当地址出现在数据文件中,格式为@hh...h,地址与数字之间不允许空白位
置,
可出现多个地址*/
module
reg [7:0] memory[0:3];//声明 8 个 8 位存储单元
integer i;
initial
begin
$readmemh("mem.dat",memory);//读取系统文件到存储器中的给定地址
//显示此时存储器内容
for(i=0;i<4;i=i+1)
$display("Memory[%d]=%h",i,memory[i]);
end
endmodule
/*mem.dat 文件内容
@001
AB CD
@003
A1
*/

下面是一个具体例子:

module add(
input [5:0] a,
input [5:0] b,
input [5:0] c,
input [5:0] d,
output [7:0]e
);

wire [6:0] outa1,outa2;
assign e = outa1 + outa2;

adder add1(
.ina(a),
.inb(b),
.outa(outa1)
);

adder add2(
.ina(c),
.inb(d),
.outa(outa2)
);

endmodule
module adder(
input [5:0] ina,
input [5:0] inb,
output [6:0] outa
);
assign outa = ina + inb;
endmodule

tb文件

module tb_adder();
reg [5:0] a;
reg [5:0] b;
reg [5:0] c;
reg [5:0] d;
wire [7:0] e;
reg [5:0] i;

add uut(
.a(a),
.b(b),
.c(c),
.d(d),
.e(e)
);
initial begin
for (i=1;i<31;i=i+1)
	begin
	#10;
	a = i;
	b = i;
	c = i;
	d = i;
	end
end
initial begin
$monitor($time,,,"%d + %d + %d + %d = {%d}",a,b,c,d,e);
#500 $finish;
end
endmodule

在这里插入图片描述

在这里插入图片描述

  • 11
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值