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

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	

       写操作需要一个文件句柄,还要注意仿真结束前关闭文件操作。

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

7、 控制信号和输出结果的编程
      根据具体的实例对控制信号进行编程,并采集其输出结果,分多个initial模块进行。要形成很强的时序观念,并尽量使每个initial模块结构相对单一。一般调用文件写操作保存仿真结果,fid 是文件操作符。

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

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

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

猜你喜欢

转载自blog.csdn.net/yishuicanhong/article/details/81387849
今日推荐