SystemVerilog之event
在verilog中,实现线程同步通过阻塞的方式,单个线程是使用@操作符在信号边缘操作,多个线程之间则通过使用->操作符进行同步。
然而->操作符是瞬时的,也就是说,过了操作的时间点,如果没有捕捉到,那么就会被阻塞在那里,直到下一次到来。如果没有下一次,那么就一直阻塞。
在SV中,引入了triggered()函数,该函数可用于判断事件是否已经被触发,而不是只检测当前时刻,线程只等待该结果,而不是在@处阻塞。
上述例子中,因为clk一直没有变,因此@操作符无效,但是wait只需要clk为高即可触发,仿真结果如下:
因为过了5个时间单位后,clk为低,此时wait无效,因此只会出现第二种情况。
example4:
当然是Error啦,因为clk不是event,不能使用trigger函数...
下面开始进入真正的event,感觉亦可赛艇~~
example5:
仿真结果如下:
#笔记##读书笔记#
然而->操作符是瞬时的,也就是说,过了操作的时间点,如果没有捕捉到,那么就会被阻塞在那里,直到下一次到来。如果没有下一次,那么就一直阻塞。
在SV中,引入了triggered()函数,该函数可用于判断事件是否已经被触发,而不是只检测当前时刻,线程只等待该结果,而不是在@处阻塞。
下面看下这些语句的区别,比较直观的了解SV的强大之处。
example1:
program automatic test_event( ); logic clk,a,b,c; initial begin clk =1'b1; end initial begin wait(clk) $display("i have reach clk"); end initial begin @(clk) $display("reached posedge of clk"); end endprogram
example2:
program automatic test_event( ); logic clk,a,b,c; initial begin clk =1'b1; #3 clk = '0; end initial fork begin #5 ; wait(clk) $display("i have reached clk"); end begin @(clk) $display("reached posedge of clk"); end join endprogram仿真结果如下:
因为过了5个时间单位后,clk为低,此时wait无效,因此只会出现第二种情况。
example3:
program automatic test_event( ); logic clk,a,b,c; initial begin clk =1'b0; #3 clk = '1; end initial fork begin #5 ; wait(clk) $display("i have reached clk"); end begin @(clk) $display("reached posedge of clk"); end join endprogram仿真结果如下:
此时两种状态都有效,但是3个时间单位时上升沿触发,因此第二种情况先出现,第一种情况晚出现。
example4:
program automatic test_event( ); logic clk,a,b,c; initial begin clk =1'b1; #3 clk = '0; end initial begin wait(clk.triggered()) $display("i have reached clk"); end initial begin @(clk) $display("reached posedge of clk"); end endprogram那么这种情况呢?
当然是Error啦,因为clk不是event,不能使用trigger函数...
下面开始进入真正的event,感觉亦可赛艇~~
example5:
program automatic test(); event e1,e2; initial begin $display("@%0d:1:before trigger",$time); -> e1; @e2; $display("@%0d:1:after trigger",$time); end initial begin $display("@%0d:2:before trigger",$time); -> e2; @e1; $display("@%0d:2:after trigger",$time); end endprogram你问我sv支持不支持这种写法,那sv肯定是资瓷的啦~~~~
仿真结果如下:
结果是只有三种情况,因为触发是瞬态的,因此按先后顺序,只有@e2是可以触发的,另一种就没了...
example6:
program automatic test(); event e1,e2; initial begin $display("@%0d:1:before trigger",$time); -> e1; wait (e2); $display("@%0d:1:after trigger",$time); end initial begin $display("@%0d:2:before trigger",$time); -> e2; wait (e1); $display("@%0d:2:after trigger",$time); end endprogram结果就是因为触发相当于脉冲信号,只有一瞬间是高电平,因此结果如下:
example7:
program automatic test(); event e1,e2; initial begin $display("@%0d:1:before trigger",$time); -> e1; wait (e2.triggered); $display("@%0d:1:after trigger",$time); end initial begin $display("@%0d:2:before trigger",$time); -> e2; wait (e1.triggered); $display("@%0d:2:after trigger",$time); end endprogram仿真结果如下:
因为e1先触发,因此wait (e1.triggered)先实现,先打印2再打印1。这个就是只需要曾经拥有就可以啦,昙花一现也会捕捉到,美滋滋~