相关阅读
Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm=1001.2014.3001.5482
always和initial是Verilog中的核心,它们被称为结构(construct),用于组织语句的执行方式。下面将分别对这两者进行阐述。
always结构
图1是always结构的BNF范式语法(有关BNF范式,可以参考以往文章)。
图1 always结构的语法
它看起来非常简单,即always关键词后面跟着一条语句(statement)即可。always结构代表了在仿真时其后面的这条语句会一直循环执行。
语句是什么?这是个好问题,下面来看Verilog中语句的定义,如图2所示,它依旧是以BNF范式的形式给出的。
图2 语句的定义
可以看出,语句可以是众多类语句中的一种,比如阻塞赋值语句(blocking_assignment) 、选择语句(case_statement),块语句(par_block、seq_clock)被视作一条语句,用于将多条语句以某种方式组织起来,它们在之前的文章中讨论过Verilog基础:块语句。
由于always结构会持续执行后面的语句,因此该语句应有“过程语句前置时序控制”,这在之前的文章中也讨论过Verilog基础:延时模型。
下面就是因为没有时序控制而出现死锁(仿真时间无法推进)的情况。
always clk = !clk //由于赋值语句一直执行,仿真时间停止在0,而无法推进
下面通过添加延迟时序控制(delay control),正确地使用了always结构,产生了一个时钟信号。
always #5 clk = !clk //赋值语句每5时间单位执行一次,因此该时钟周期为10个时间单位
更常见的情况下,always结构后面会跟一个语句块,比如顺序块begin-end,而更常见的时序控制会使用事件控制(event control)。
always @(a, b) begin //语句前的@后使得该过程被挂起,直到a或b之一的值发生改变
c = a | b;
d = a & b;
end
一个好的建议是,当使用always结构时,不论后面是否只有一条语句,都使用顺序块begin-end,这样能防止出现错误。
initial结构
图3是initial结构的BNF范式语法。
图3 initial结构的语法
它与always结构非常相似,唯一不同的就是initial结构使用的是initial关键词加一条语句。initial结构代表着其后面的语句只会执行一次,一旦执行完毕后,initial结构就被销毁。从它这抽象的描述中,就可知它是不可综合的,它常用于仿真时使用的testbench中。
下面是一个initial结构,它在特定的时间将信号赋特定值,可以看做描述了一段波形。
initial begin
a=1'b1; //在开始时,a是1
#5 a=1'b0; //在5时间单位,a变为0
#10 a=1'b1; //在15时间单位,a变为1
end