仿真就是借助一个软件来真实模拟设计行为,帮助验证代码是否正确,当代码出现问题时帮助定位问题、解决问题。
硬件调试的前提是有开发板,且它依赖于fpga的片上资源,当fpga资源 被消耗得差不多时,就很难再添加调试的代码进行硬件调试。此时,通过仿真来调试代码就显得很有必要。仿真区别于硬件调试的缺点是需要编写激励文件TestBench。
仿真分为功能仿真和时序仿真。
设计输入、功能仿真RTL、时序仿真(走线延迟,不常用,通常通过时序分析来看是否满足时序要求)、系统级验证。
以led_twinkle工程为例,简单说明仿真文件的编写
.v文件如下:
module led_twinkle(
input sys_clk,
input sys_rst_n, //低电平有效
output [1:0] led
);
reg [25:0] cnt;
//reg pulse_led;
assign led = (cnt < 26'd2500_0000)? 2'b01:2'b10; //小于0.5秒点亮led[0],大于0.5秒点亮led[1]
//assign led = pulse_led;
//计数器
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
cnt <= 26'd0;
// pulse_led <= 1'b0;
else if(cnt < 26'd5000_0000)
cnt <= cnt + 1'b1;
else
cnt <= 26'd0;
//pulse_led <= ~pulse_led;
end
// ila_0 your_instance_name (
// .clk(sys_clk), // input wire clk
//
//
// .probe0(sys_rst_n), // input wire [0:0] probe0
// .probe1(led), // input wire [1:0] probe1
// .probe2(cnt) // input wire [25:0] probe2
// );
endmodule
.tb文件如下:
`timescale 1ns / 1ps //仿真单位、仿真精度
module tb_led_twinkle();
reg sys_clk;
reg sys_rst_n;
wire [1:0] led;
initial begin
sys_clk = 1'b0;
sys_rst_n = 1'b0;
#200
sys_rst_n = 1'b1; //表示结束复位
end
always #10 sys_clk = ~sys_clk; //周期是20ns,对应频率就是50MHz
//模块例化
led_twinkle u_led_twinkle(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.led (led)
);
endmodule
编写完仿真文件后,进行仿真,运行行为仿真。
可以看到仿真波形
仿真的时间可以在setting中设置