在这里,我们从一个最简单的程序入手,看一看最简单的仿真文件该怎么写。
我们将测试一个具有同步清零功能的D型触发器。
首先这里是触发器的代码:
module SyncResetFF(
D, Clock, Reset,Q
);
input D, Clock, Reset;
output reg Q;
//时钟正边沿触发的前提下, reset仍然是低电平触发
always@(posedge Clock)
if(!Reset)
Q<= 0;
else
Q<= D;
endmodule
接下来为这个器件编写仿真程序。可以参考其他教程,在正确的位置添加仿真文件。
接下来打开仿真程序,开始编辑。
先说这一部分:
reg data, clk, reset;
wire q;
SyncResetFF srf1(data, clk, reset, q);
在这里我们将原来的触发器的输入设置成reg型,将输出设置成wire型,之后我们实例化一个触发器,并且把变量填到指定的地方去(就像我们实例化模块那样)。
下一部分:
//设置时钟 每50ns修改一次,也就是100ns为一个周期
initial begin
clk=1;
forever #50 clk = ~clk;
end
在这里我们声明时钟。vivado的测试本身就有一个时钟;而我们在这里定义一个我们用的,依赖于vivado测试时钟的时钟。
#50表示vivado测试的时间轴每向前跑50ns, clk就会取反,也就是我们定义了一个周期为100ns的时钟。
vivado时钟就是上面的时间轴,而我们定义的clk就是红色的那一条。它们之间是有差异的。
下一部分就很好解释了, vivado轴经过#后面的数值,变量们执行相应的修改。
//设置输入信号
initial begin//初始状态的值
reset= 0; data=0;
#100 reset=1; data=1;//100ns时修改这些值
#100 data=0;//过了100ns再作修改
#110 data=1;//再过110ns
#90 data=1;//再过90ns
#200 reset=0;data=1;//...
end
Run Simulation后, 这将是最终的效果(如果提示只输出transcript请参考数字逻辑板块的另一篇博文, 这个问题困扰了我一周)
总得来说,时序电路的clk设置需要依赖于vivado测试时钟,而在不同时间修改输入数据也是通过vivado时钟进行标记的。尽管输入数据与clk本身看上去独立了,但它们之间通过vivado时钟联系了起来(达到了和而不同的效果), 这样也实现了仿真测试的功能。
需要指出的是,这篇博文的描述方法和用词或许不大专业和准确,操作方法也挺简单粗暴。但对于实现第一个仿真,我想还是能有些帮助的。谢谢。