相关阅读
Verilog基础专栏https://blog.csdn.net/weixin_45791458/category_12263729.html?spm=1001.2014.3001.5482
1、块语句
块语句(block statements)是一种把语句组织在一起,这样他们在语法上就像单个语句一样工作。Verilog HDL中有两种类型的块:
- 顺序块,也叫begin-end块
- 并行块,也叫fork-join块
顺序块应该由关键词begin和end分隔,顺序块中的过程语句应该按照它们在块中给出的顺序依次执行。
并行块应该由关键词fork和join分隔,并行块中的过程语句并发执行(这里的并发执行不是指严格在同时有两个语句执行,而是指在同一个仿真时间同时执行,因为实际上仿真器永远是串行执行语句,在这里指语句的执行顺序不确定)。
1.1、顺序块
顺序块具有以下特性:
- 语句应按顺序执行,一条语句执行完后才会执行下一条语句。
- 每条语句的延迟是相对于前一条语句完成的仿真时间而言的。
- 控制流应该在最后一条语句完成后从块内传出。
下图给出了顺序块语法的BNF表示。
例1:顺序块使以下的两个赋值有确定性结果。
beginareg = breg;creg = areg; //creg存储了breg的值
end
第一条语句对areg的赋值一定会在控制转移到执行第二条语句前完成,因此creg获得的是areg也即是breg的值。
例2:可以在顺序块中使用时序控制来在时间上分离两个赋值。
beginareg = breg; @(posedge clock) creg = areg; //只有posedge上升沿事件发生,第二条语句才会执行
end
例3:以下示例显示了如何使用顺序块和时序控制的组合来指定时序波形:
parameter d = 50; // 一个参数声明
reg [7:0] r; // 声明一个8位reg变量
begin // 一个由时序控制的波形#d r = 'h35;#d r = 'hE2;#d r = 'h00;#d r = 'hF7;#d -> end_wave; //触发一个叫end_wave的事件
end
1.2、并行块
并行块具有以下特性:
- 语句并发执行。
- 每个语句的延迟是相对于进入并行块的仿真时间而言的。
- 时序控制可用于为赋值提供时间顺序。
- 时序上最后一条语句执行完成后,控制从块内传出。
下图给出了并行块语法的BNF表示。
例子:以下示例通过使用并行块而不是顺序块对1.1例3中所示的波形进行重新描述。reg上产生的波形对于两种实现方式来说完全相同。
fork#50 r = 'h35;#100 r = 'hE2;#150 r = 'h00;#200 r = 'hF7;#250 -> end_wave;
join
1.3、块名字
顺序块和并行块都可以通过在关键字begin或fork后面添加:name_of_block来命名。块的命名有几个目的:
- 它使得能为块声明局部变量(variables)、参数(parameter)和命名事件(named event)。
- 它允许在诸如disable语句之类的语句中引用块。(即允许层次引用)
所有变量应为静态变量;也就是说,所有变量都存在一个唯一的位置,离开或进入块不应对变量有任何影响。
命名块创建了一个新的结构层次,从而允许在任何位置对命名块内的变量进行访问。
1.4、开始和结束时间
顺序块和并行块都有开始和结束时间的概念。对于顺序块,开始时间是执行第一条语句时,结束时间是执行完最后一条语句时。对于并行块,所有语句的开始时间(仿真时间)都相同,而结束时间是执行完最后一个被调度语句的时间。
顺序块和并行块可以相互嵌入,从而使复杂的控制结构能够容易地表达并具有高度的结构。当块相互嵌入时,块开始和结束的时间很重要。直到达到块的完成时间,也就是说,直到块完全完成执行,才应继续执行块后面的语句。
例1:以下示例是1.1例3的语句,但这些语句以相反的顺序编写,但仍产生相同的波形
fork#250 -> end_wave;#200 r = 'hF7;#150 r = 'h00;#100 r = 'hE2;#50 r = 'h35;
join
例2:当在发生两个单独的事件(称为事件的连接)之后进行赋值时,fork-join块可能很有用。
beginfork@Aevent;@Bevent;joinareg = breg;
end
这两个事件可以按任何顺序发生(甚至在同一仿真时间发生),fork-join块将完成并退出,对areg进行赋值。相反,如果fork-join块是begin-end块,并且Bevent发生在Aevent之前,那么该块将等待下一个Bevent才会跳出begin-end块。
例3:此示例显示了两个顺序块,每个块将在其控制事件发生时执行。因为事件控制在fork-join块中,所以它们是并行执行的,因此这两个顺序块之间是可以并行执行的。
fork@enable_a begin#ta wa = 0;#ta wa = 1;#ta wa = 0;end@enable_b begin#tb wb = 1;#tb wb = 0;#tb wb = 1;end
join
以上内容来源于《IEEE Standard for Verilog® Hardware Description Language 2005》,有删改