时间:2025-04-12 来源:FPGA_UCY 关于我们 0
目录
之所以重开一个,是怕记不过来,记性不好的苦恼。写完代码之后除了软件自带的功能去检验语法是否正确外,还得去自己验证代码功能能不能实现,总不能每次都上板子试验,那样既麻烦,又没法知道错误出在哪,所以编一个仿真文件很有必要哈。
编写仿真激励 激励与被测对象的链接
这个比较简单,就是跟例化一样,把那些脚一一链接就行,例化应该会吧。下面是上一个状态机进行仿真时候激励文件中例化部分,该定义定义,该连就连,括号里面写那个就是跟那个连。
module tb_a111;
reg clk;
reg rst_n;
reg i1;
reg i2;
wire o1;
wire o2;
wire err;
a111 uut (
.clk(clk),
.rst_n(rst_n),
.i1(i1),
.i2(i2),
.o1(o1),
.o2(o2),
.err(err)
);
endmodule
常用语句
在仿真中最常见的就是语句和语句,有时候也有for语句,之前就说过for循环基本使用在激励文件中。语句和语句是两种基本的过程语句,在刚开始仿真的时候就开始并行执行,但是一般情况下,用进行主动激励,被动启动。另一个区别就是,只执行一次,可以不断重复执行。但是只要思想不滑坡,办法总比困难多,想在语句能重复执行,可以在里面添加循环语句,例如for语句,while语句,语句等。语句被动触发,跟正常代码中一样,需要某种情况,例如时钟的上升或者下降沿触发。
时钟、复位的写法 普通时钟
我直接用了最常见的一种时钟出现方法,
parameter FAST_PERLOD = 10;
initial
clk = 0;
always
#(FAST_PERLOD/2) clk = ~clk;
出现的结果如下,明细看出来哈,5ns一循环。
非50%占空比的时钟
在一些设计中时钟不是规律的,所以在极力中需要模拟这种时钟。
parameter Hi_TIME = 10,
Lo_TIME = 5 ;
always
begin
#Hi_TIME clk = 0;
#Lo_TIME clk = 1;
end
从代码可以看出,是自己定义了两个变量去控制时钟周期变化,变化如图:
但从图中也可以明显的看出初始状态为x,这是因为代码中并未规定初始时钟是多少。
固定数目时钟
如果想产生固定数目的时钟,就可以用语句中用语句实现,代码如下
parameter PulseCount = 4 ,
FAST_FERIOD = 10 ;
initial begin
clk = 0 ;
repeat(PulseCount)
#(FAST_FERIOD/2)clk = ~clk ;
end
从图可以看出进行了两次循环就一直为零了;
相移时钟信号
这种我确实没咋见过,也学一学,从图上就能看出来,两个始终是有些不一样的。
代码如下:这是先生成了一个时钟,再生成了一个相移为2的时钟;
parameter HI_TIME = 5 ,
LO_TIME = 10,
PHASE_SHIFT = 2 ;
reg Abslute_clk ;
wire Dedrive_clk ;
always begin
#HI_TIME Abslute_clk = 0 ;
#LO_TIME Abslute_clk = 1 ;
end
assign #PHASE_SHIFT Dedrive_clk = Abslute_clk;
异步复位信号
我直接用书上教的没成功,自己编了一个,效果是一样的,代码如下:
initial begin
clk = 0 ;
rst_n = 1 ;
#10 rst_n = 0;
#50 rst_n = 1 ;
end
always #2 clk = ~clk ;
效果图很明显哈
同步复位信号
代码如下
initial begin
clk = 0 ;
rst_n = 1 ;
@(negedge clk) ;
rst_n = 0 ;
# 30 ;
@(negedge clk);
rst_n = 1 ;
end
always #2 clk = ~clk ;
从仿真图上可以看出。从第一时钟的下降沿开始复位,直到30ns后撤销复位。
利用系统函数和系统任务
我就不举例子了,直接看这个链接,挺全的;FPGA基础设计(11)任务、函数、系统任务、系统函数_fpga系统函数-CSDN博客
编写仿真文件要注意的问题
1、不是硬件!在编写正常代码的时候要用硬件思维,但编写不用综合,所以只要能完成相应功能就行,不过需要尽可能选择抽象层次较高的语句。
书上说的有点墨迹,我看网上有个学习笔记写的也挺完善。学习笔记 - 工匠小建 - 博客园
ok,的内容就这些,实践是检验真理的唯一标准。