赞
踩
前言:在SystemVerilog中,用来触发事件时,使用->;用来等待事件使用@或者wait。那么@和wait有什么区别呢?在Verilog中当一个线程在一个事件上发生阻塞的同时,正好另一个线程触发了这个事件,则竞争就出现了。如果触发线程先于阻塞线程,则触发无效(触发是一个零宽度的脉冲)。
Systemverilog 引入了triggered()函数,用于检测某个事件是否已被触发过,包括正在触发。线程可以等待这个结果,而不用在@操作符上阻塞。
- `timescale 1ns/10fs
-
- module event_test();
- event a; //使用关键字event来声明一个事件a
-
- initial begin
- #50ns;
- ->a;
- end
-
- initial begin
- #50ns;
- @a; //第一个进程在50ns后触发了事件a,第二个进程在1ns的时候等待a,有可能等的到,有可能等不到,产生竞争
- end
-
- endmodule
- module event_test();
- event a; //使用关键字event来声明一个事件a
-
- initial begin
- #50;
- ->a;
- $display("Event a is being triggered!");
- end
-
-
- initial begin
- #20;
- wait(a.triggered); //使用wait来等待事件a,这种方式是一定可以等到a的
- $display("#20 a.triggered!");
- end
-
- initial begin
- #50;
- wait(a.triggered); //使用wait来等待事件a,这种方式是一定可以等到a的,这是和使用@来等待的区别
- $display("#50 a.triggered!");
- end
-
- initial begin
- #60;
- wait(a.triggered); //使用wait来等待事件a,a會被trigger一次,並且並且發生在wait之前,永遠等不到
- $display("#60 a.triggered!"); //不會被打印
- end
-
- endmodule
在多线程通信中,可以使用event实现线程的同步,即一个线程等待/触发另一个线程。
使用上述方法,Thread2就会blocking在 @event / wait(event.triggered); 处,只有Thread1执行完 -> event; 后,Thread2才会向下执行。按上述方法使用是没问题的,那么有下面几个问题:
- module event_test();
- event a; //使用关键字event来声明一个事件a
-
- initial begin
- #1;
- ->a;
- $display("Event a is being triggered!");
- end
-
- initial begin
- #1;
- @a; //第一个进程在1ns后触发了事件a,那么第二个进程在1ns的时候等待a,有可能等的到,有可能等不到,产生竞争
- $display("wait event a");
- end
-
- initial begin
- #1;
- wait(a.triggered); //第一个进程在1ns后触发了事件a,那么第二个进程在1ns的时候等待a,一定能等到
- $display("wait a.triggered");
- end
-
- endmodule
- forever begin
- wait(handshake.triggered); //注意不要寫成wait(handshake.triggered()),會有編譯錯誤,因為triggered不是一個function
- $display("get nexr event ...");
- process_in_zero_time();
- end
如果是在循环中使用wait(event.triggered),并且在下次等待之前没有延时,那么该事件一旦被触发就会反复执行,对上面的例子,如果某一时刻触发了handshake事件,则该Thread就会一直display(導致仿真Hang死),这种结果不是我们想要的,解法有两种:
1、wait(handshake.triggered)之后增加让时间推进的操作,如@(clk)。
- forever begin
- wait(handshake.triggered);
- $display("get nexr event ...");
- process_in_zero_time();
- @clk;
- end
2、将wait(handshake.triggered)换成 @handshake, 可以避免零延时循环。
- forever begin
- @handshake;
- $display("get nexr event ...");
- process_in_zero_time();
- end
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。