vivado中简单testbench测试代码的编写 - ZYNQ7021学习

首先要明白测试代码的作用,这点其实很重要!测试代码其实就是通过代码模拟产生测试的环境,然后测试自己编写的模块代码是否正确。这可以指导我们在编写代码过程中决定某一些控制信号该如何产生,比如用于控制产生测试信号的控制信号,可以在一个 initial 模块里去改变这个值,而测试信号中的控制信号,应该在时钟下产生。

1、 将测试代码模块命名为 sim_crc_to_ram, 并且不需要任何输入信号。

module sim_crc_to_ram;

2、 定义变量类型
       一般将输入信号定义为reg类型的;将输出信号定义为wire类型的;

	reg 	     clk_60M;
	reg 	     reset;
	reg 	     flag_din;
	reg 	     din;
	wire        clk_5k;
	wire        data_sys, data_inter;

3、例化模块,并将输入输出的信号和 2 中定义的变量进行关联。

crc_to_ram  uut (
                    .clk_60M(clk_60M),
                    .reset(reset),
                    .start(flag_din),
                    .din(din),
                    
                    .clk_5k(clk_5k),
                    .data_sys(data_sys),
                    .data_inter(data_inter)
               );

4、  产生时钟模块。
       根据需要产生一个或多个时钟。一般可以产生一个系统时钟即可,其他时钟由这个时钟分频产生即可。下面代码表示延迟8ns以后clk_60M信号取反,即周期为16ns的方波信号。

always #8 clk_60M = ~clk_60M; 

5、  时钟控制和reset信号的控制
       一般放在initial模块里,跟据具体需要对reset信号进行编辑;并注意时钟信号的初始化,否则无法产生正常的时钟信号(若不初始化,clk可能默认为x状态,~x状态仍为x,即不会产生时钟驱动)。

    reg	    data_ready;
    integer counti;                
    
    initial begin
            // Initialize Inputs
            clk_60M = 0;
            reset = 0;
            flag_din = 0;
            din = 0;
            
            counti = 0;
            $readmemb("C:/src.txt", mem);
            // Wait 100 ns for global reset to finish
            data_ready = 0;
            #100;
            reset = 1;
            #100;  
            data_ready = 1;  
            // Add stimulus here        
//          #(1600 * 10 * 1000);        // 4 frame 100k
            #(1600 * 1 * 1000);            // 4 frame 1M
//           #(400 * 1000);                // 1 frame 1MHz
            data_ready = 0;
        end 

6、  初始化文件操作

       基本的文件操作包括读和写,下面是我产生输入信号的代码附带其他标记信号,略显繁琐,自己写时采用一个for循环即可。

parameter 	        read_idle 	= 2'b00,
			read_begin	= 2'b01,
			read_end 	= 2'b10;

reg	[1 : 0]	state_read;
always@(posedge clk_5k or negedge reset)
begin
	if(!reset)
		state_read	<= read_idle;
	else
	begin
		case (state_read)
			read_idle:
			begin
				if(data_ready == 1'b1)
				begin
					counti		<= 0;
					state_read 	<= read_begin;		
				end
				else
					state_read 	<= read_idle;
			end
			
			read_begin:
			begin
				if (counti <= 1023)		// 1 frames
				begin
					din			<= mem[counti];
					counti		<= counti + 1;
					state_read 	<= read_begin; 
					
					if ((counti == 0) || (counti == 1024) || (counti == 2048) || (counti == 3072))	
						flag_din<= 1'b1;
					else
						flag_din<= 1'b0;
				end	
				else
					state_read	<= read_end;
			end
			
			read_end:
			begin
				state_read	<= read_idle;
		    end
				
			default: 
			begin
				state_read 	<= read_idle;	
			end
		endcase 
	end
end	

       写操作需要一个文件句柄,还要注意仿真结束前关闭文件操作,默认路径在.sim\sim_1\behav中(后仿在 .sim\sim_1\impl \timing中)。

integer fid;
fid = $fopen("resut.txt");
.........
$fclose(fid);

7、 控制信号和输出结果的编程
      根据具体的实例对控制信号进行编程,并采集其输出结果,分多个initial模块进行。要形成很强的时序观念,并尽量使每个initial模块结构相对单一,也可以在always块中随着时钟clk将数据写入文本文件中。一般调用文件写操作保存仿真结果,fid 是文件操作符,直接使用如下语句完成输出即可。

......
$fdisplay(fid,"%b",data_out);
......

8、 结束testbench程序的运行
       用$stop 或$finish结束程序的运行,另起一个initial。例如

  initial
        begin
             #(1000000*CYCLE);
             $ stop;
        end

 

  • 17
    点赞
  • 139
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值