Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
testbench教程_verilog testbench怎么写,希望能够帮助你!!!。
1 编写testbench目的
编写testbench的主要目的是为了对使用硬件描述语言(HDL)设计的电路进行仿真验证,测试设计电路的功能、部分性能是否与预期的目标相符。
编写testbench进行测试的过程如下:
1) 产生模拟激励(波形);
2) 将产生的激励加入到被测试模块并观察其输出响应;
3) 将输出响应与期望进行比较,从而判断设计的正确性。
2 基本的testbench结构
module test_bench;
// 通常testbench没有输入与输出端口
信号或变量定义声明
使用initial或always语句来产生激励波形
例化设计模块
监控和比较输出响应
endmodule
简单的testbench的结构通常需要建立一个顶层文件,顶层文件没有输入和输出端口。在顶层文件里,把被测模块和激励产生模块实例化进来,并且把被测模块的端口与激励模块的端口进行对应连接,使得激励可以输入到被测模块。端口连接的方式有名称和位置关联两种方式,我们常常使用“名称关联”方式。
3 产生激励的一些描写方式
3.1 产生时钟的几种方式
1)使用initial方式产生占空比50﹪的时钟
initial begin CLK = 0; #delay; forever #(period/2) CLK = ~CLK; end
注意:一定要给时钟赋初始值,因为信号的缺省值为z,如果不赋初值,则反相后还是z,时钟就一直处于高阻z状态。
产生的时钟信号如下图所示:
2)使用always方式
initial CLK = 0; always #(period/2) CLK = ~CLK;
3)使用repeat产生确定数目的时钟脉冲
initial begin CLK = 0; repeat(6) #(period/2) CLK = ~CLK; end
4)产生占空比非50﹪的时钟
initial CLK = 0; always begin #3 CLK = ~CLK; #2 CLK = ~CLK; end
3.2 产生复位信号的几种形式
1)异步复位
initial begin Rst = 1; #100; Rst = 0; #500; Rst = 1; end
2)同步复位1
initial begin Rst = 1; @(negedge CLK); // 等待时钟下降沿 Rst = 0; #30; @(negedge CLK); // 等待时钟下降沿 Rst = 1; end
2)同步复位2
initial begin Rst = 1; @(negedge CLK); // 等待时钟下降沿 repeat (3) @(negedge CLK); // 经过3个时钟下降沿 Rst = 1; end
4 testbench实例
4.1 2-4解码器实例
module dec2x4(A, B, Enable, Z); input A, B, Enable; output[3:0] Z; reg [3:0] Z_o; assign Z = Z_o; always@(A or B or Enable) begin if(Enable == 1'b0) Z_o = 4'b1111; else case({A, B}) 2'b00: Z_o = 4'b1110; 2'b01: Z_o = 4'b1101; 2'b10: Z_o = 4'b1011; 2'b11: Z_o = 4'b0111; default: Z_o = 4'b1111; endcase end endmodule
测试模块:
`timescale 1ns/100ps module testbench; reg a, b, en; wire [3:0] z;
//例化被测试模块
dec2x4 DUT(.A(a),.B(b),.Enable(en),.Z(z));
//产生输入激励
initial begin en = 0; a = 0; b = 0; #10 en = 1; #10 b = 1; #10 a = 1; #10 b = 0; #10 a = 0; #10 $stop;
end
//显示输出结果
always@(en or a or b or z) begin $display("At time %t, input is %b%b%b, output is %b", $time, a, b, en, z); end
endmodule
4.2 时序检测器
下面是一个时序检测器的验证实例。被测模型用于检测数据线上连续三个1的序列。在时钟的每个上升沿检查数据。
module Count3_1s(Data, Clock, Detect3_1s); input Data, Clock; output Detect3_1s; integer Count; reg Detect3_1s; initial begin Count = 0; Detect3_1s = 0; end always@(posedge Clock) begin if(Data == 1) Count = Count + 1; else Count = 0; if(Count>=3) Detect3_1s = 1; else Detect3_1s = 0; end endmodule
测试模块:
`timescale 1ns/100ps module testbench; reg Data, Clock; wire Detect; integer Out_file;
// 待测试模块的应用实例
Count3_1s DUT(Data,Clock,Detect); // 位置关联方式 initial begin Clock = 0; forever #5 Clock = ~Clock; end initial begin Data = 0; #5 Data = 1; #40 Data = 0; #10 Data = 1; #40 Data = 0; #20 $stop; // 仿真结束 end
// 创建一个记录文件:
initial Out_file = $fopen("results.txt");
// 在文件中保存监控信息
always@(posedge Clock) begin if(Detect == 1'b1) $fwrite(Out_file,"At time %t, Detect out is 1\n", $time); end endmodule
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章