前言
Verilog中的延迟控制有两种类型–延迟和事件表达式。
下面一一道来。
正文
延迟控制语句
如果延迟表达式的值为未知值或高阻抗值,将被解释为零延迟。对于这个语句会用即可,用于仿真延时使用嘛,例如:
`timescale 1ns/1ps
module tb;
reg [3:0] a, b;
initial begin
{
a,b} = 0;
$display ("T=%0t a=%0d b=%0d", $realtime, a, b);
#10
a = 10;
$display ("T=%0t a=%0d b=%0d", $realtime, a, b);
#(2*10)
b = 8;
$display ("T=%0t a=%0d b=%0d", $realtime, a, b);
#('dz)
a = 2;
b = 2;
$display ("T=%0t a=%0d b=%0d", $realtime, a, b);
#('h10)
a = 3;
b = 3;
$display ("T=%0t a=%0d b=%0d", $realtime, a, b);
end
endmodule
# run 1000ns
T=0 a=0 b=0
T=10000 a=10 b=0
T=30000 a=10 b=8
T=30000 a=2 b=2
T=46000 a=3 b=3
事件控制语句
线网和变量的值变化可以作为同步事件来触发执行其他程序语句,是一个隐含事件。该事件也可以基于变化的方向,比如朝0的变化使其成为negedge,朝1的变化使其成为posedge。(并不一定非要是时钟)
- negedge是指从1到X、Z或0,以及从X或Z到0的过渡。
- posedge是指从0到X、Z或1,以及从X或Z到1的过渡。
module tb;
reg a, b;
initial begin
a <= 0;
#10 a <= 1;
#10 b <= 1;
#10 a <= 0;
#15 a <= 1;
end
// Start another procedural block that waits for an update to
// signals made in the above procedural block
initial begin
@(posedge a); $display ("T=%0t Posedge of a detected for 0->1", $time);
@(posedge b); $display ("T=%0t Posedge of b detected for X->1", $time);
@(posedge (a + b)) $display ("T=%0t Posedge of a+b", $time);
@(a) $display ("T=%0t Change in a found", $time);
end
endmodule
Time resolution is 1 ps
T=10000 Posedge of a detected for 0->1
T=20000 Posedge of b detected for X->1
T=30000 Posedge of a+b
T=45000 Change in a found
如果是这样:
module tb;
reg a, b;
initial begin
a <= 0;
$display ("T=%0t a=%0d b=%0d", $realtime, a, b);
#10 a <= 1;
$display ("T=%0t a=%0d b=%0d", $realtime, a, b);
#10 b <= 1;
$display ("T=%0t a=%0d b=%0d", $realtime, a, b);
#10 a <= 0;
$display ("T=%0t a=%0d b=%0d", $realtime, a, b);
#15 a <= 1;
end
// Start another procedural block that waits for an update to
// signals made in the above procedural block
initial begin
@(posedge a); $display ("T=%0t Posedge of a detected for 0->1", $time);
@(posedge b); $display ("T=%0t Posedge of b detected for X->1", $time);
@(posedge (a + b)) $display ("T=%0t Posedge of a+b", $time);
@(a) $display ("T=%0t Change in a found", $time);
end
endmodule
则仿真log为:
Time resolution is 1 ps
T=0 a=x b=x
T=10000 a=0 b=x
T=10000 Posedge of a detected for 0->1
T=20000 a=1 b=x
T=20000 Posedge of b detected for X->1
T=30000 a=1 b=1
T=30000 Posedge of a+b
T=45000 Change in a found
Named Events
关键字event可以用来声明一个可以明确触发的命名事件。一个事件不能保存任何数据,没有时间长度,可以在任何特定的时间发生。命名的事件可以通过在命名的事件句柄前加上->操作符来触发。命名事件可以通过使用上面描述的@操作符来等待。
module tb;
event a_event;
event b_event;
initial begin
#20 -> a_event;
#30;
->a_event;
#50 ->a_event;
#10 ->b_event;
end
always @ (a_event) $display ("T=%0t [always] a_event is triggered", $time);
initial begin
#25;
@(a_event) $display ("T=%0t [initial] a_event is triggered", $time);
#10 @(b_event) $display ("T=%0t [initial] b_event is triggered", $time);
end
endmodule
Time resolution is 1 ps
T=20000 [always] a_event is triggered
T=50000 [initial] a_event is triggered
T=50000 [always] a_event is triggered
T=100000 [always] a_event is triggered
T=110000 [initial] b_event is triggered
Event or operator
或操作符可以用来等待,直到表达式中的任何一个事件被触发。也可以用逗号 ,代替or操作符。
module tb;
reg a, b;
initial begin
$monitor ("T=%0t a=%0d b=%0d", $time, a, b);
{
a, b} <= 0;
#10 a <= 1;
#5 b <= 1;
#5 b <= 0;
end
// Use "or" between events
always @ (posedge a or posedge b)
$display ("T=%0t posedge of a or b found", $time);
// Use a comma between
always @ (posedge a, negedge b)
$display ("T=%0t posedge of a or negedge of b found", $time);
always @ (a, b)
$display ("T=%0t Any change on a or b", $time);
endmodule
Time resolution is 1 ps
T=0 Any change on a or b
T=0 posedge of a or negedge of b found
T=0 a=0 b=0
T=10000 Any change on a or b
T=10000 posedge of a or b found
T=10000 posedge of a or negedge of b found
T=10000 a=1 b=0
T=15000 Any change on a or b
T=15000 posedge of a or b found
T=15000 a=1 b=1
T=20000 Any change on a or b
T=20000 posedge of a or negedge of b found
T=20000 a=1 b=0
好了,不再多说,其实最常用还是:
@(posedge a)
...
@(b)
...
#10
....
往期回顾
Verilog初级教程(20)Verilog中的`ifdef 条件编译语句
Verilog初级教程(17)Verilog中的case语句
Verilog初级教程(15)Verilog中的阻塞与非阻塞语句
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?
参考资料及推荐关注
Verilog `ifdef Conditional Compilation
个人微信公众号: FPGA LAB
今天的文章Verilog初级教程(21)Verilog中的延迟控制语句分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/29697.html