Verilog初级教程(13)Verilog中的块语句
前言
所谓的块语句,无非就是一组语句,例如在initial或者always中,使用begin…end或者fork…join包裹的语句,都可以称为块语句。块语句有两种:
- 串行语句
- 并行语句
下面分别介绍。
正文
串行语句
语句使用begin和end关键字进行包装,并将按照给定的顺序,一个接一个地依次执行。
延迟值相对于前一条语句的执行时间进行处理。在块内的所有语句执行完毕后,控制权可以传递到其他地方。
例如:
module design0;
reg [31:0] data;
// "initial" block starts at time 0
initial begin
// After 10 time units, data becomes 0xfe
#10 data = 8'hfe;
$display ("[Time=%0t] data=0x%0h", $time, data);
// After 20 time units, data becomes 0x11
#20 data = 8'h11;
$display ("[Time=%0t] data=0x%0h", $time, data);
end
endmodule
如上例,第一条语句从begin处开始,经过10个单位的延迟,执行第一条语句;
在经过20个时间单位的延迟,执行第二条语句。这就是串行执行的语句。
上述仿真log文件为:
[Time=10] data=0xfe
[Time=30] data=0x11
并行语句
并行块可以并发执行语句,延迟控制可以用来提供赋值的时间顺序。通过将语句包装在fork和join关键字中来并行启动。
例如:
initial begin
#10 data = 8'hfe;
fork
#20 data = 8'h11;
#10 data = 8'h00;
join
end
其执行示意图如下:
位于fork…join中的语句是并行语句块,里面的每一条语句(使用分号或者begin…end分割)都并行执行,例如上例中的fork…join内部的语句,即使:
#20 data = 8'h11;
位于前面,但是它是要在语句:
#10 data = 8'h00;
后面执行。
上图也很明显地说明了,fork开始,10个时间单位时,执行:
#10 data = 8'h00;
在过10个时间单位执行:
#20 data = 8'h11;
这就是并行执行。
并行块内包含串行块的情况
上面举了这个例子:
initial begin
#10 data = 8'hfe;
fork
#20 data = 8'h11;
#10 data = 8'h00;
join
end
在上面的例子中,fork-join块将在以10个时间单位执行语句后启动。在这个块中的语句将被并行执行,第一个被启动的语句将是数据被赋值为8’h00的语句,因为延迟是在fork-join启动后的10个时间单位。再过10个时间单位后,第一条语句将被启动,数据将得到8’h11的值。
我们上面也说了,并行块内的每一条语句都并行执行,我们对这里的每一条语句进行说明,使用begin…end包裹的语句块也属于一条语句,即块语句。
而begin…end中的语句是串行执行的,因此就存在并行中包含串行的情况,如下例:
initial begin
#10 data = 8'hfe;
fork
#10 data = 8'h11;
begin
#20 data = 8'h00;
#30 data = 8'haa;
end
join
end
很好理解,如下图:
语句:
#10 data = 8'h11;
与:
begin
#20 data = 8'h00;
#30 data = 8'haa;
end
是并行的关系。
fork开始后的10个时间单位执行语句:
#10 data = 8'h11;
与
begin
#20 data = 8'h00;
#30 data = 8'haa;
end
因为块本身(块内的第一条语句)与其他语句一同并行启动;
之后块内部的语句串行执行:
也就是说fork后的20个时间单位执行:
//begin
#20 data = 8'h00;
// #30 data = 8'haa;
//end
不言而喻,在过30个时间单位,也就是fork后的50时间单位执行:
//begin
// #20 data = 8'h00;
#30 data = 8'haa;
// end
注:这里强调的都是fork后的时间点,而不是initial begin后的,如果强调initial后的,需要算上第一条语句的10个时间单位。
块名称
顺串行块和并行块都可以通过在关键字begin和fork后面添加:name_of_block
来命名。这样,就可以在disable
语句中引用该块。
例如:
begin : name_seq
[statements]
end
fork : name_fork
[statements]
join
往期文章回顾
Verilog初级教程(12)Verilog中的generate块
Verilog初级教程(11)Verilog中的initial块
Verilog初级教程(10)Verilog的always块
Verilog初级教程(8)Verilog中的assign语句
Verilog初级教程(7)Verilog模块例化以及悬空端口的处理
Verilog初级教程(5)Verilog中的多维数组和存储器
Verilog初级教程(2)Verilog HDL的初级语法
FPGA/ASIC初学者应该学习Verilog还是VHDL?
- 个人微信公众号: FPGA LAB
上一篇: Django Ajax请求实例
下一篇: Python学习笔记——Django视图