event(qevent *event) 没有被触发_SystemVerilog之event

在verilog中,实现线程同步通过阻塞的方式,单个线程是使用@操作符在信号边缘操作,多个线程之间则通过使用->操作符进行同步。

然而->操作符是瞬时的,也就是说,过了操作的时间点,如果没有捕捉到,那么就会被阻塞在那里,直到下一次到来。如果没有下一次,那么就一直阻塞。

在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

上述例子中,因为clk一直没有变,因此@操作符无效,但是wait只需要clk为高即可触发,仿真结果如下:

dd700590a88e08027dc8389ac261c01d.png

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

仿真结果如下:

83a20eb4ac4d74ab52915a26fe4d8ae6.png

因为过了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

仿真结果如下:

ab64640b62da7840f6ba78b1cb1ee160.png

此时两种状态都有效,但是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肯定是资瓷的啦~~~~

仿真结果如下:

69bb5708311e451b23764d0d15c731b3.png

结果是只有三种情况,因为触发是瞬态的,因此按先后顺序,只有@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

结果就是因为触发相当于脉冲信号,只有一瞬间是高电平,因此结果如下:

7a50f7fca3b71478243c77cb64e839a6.png

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

仿真结果如下:

95bb2078e9d639ff777c6d1260b46d28.png

因为e1先触发,因此wait (e1.triggered)先实现,先打印2再打印1。这个就是只需要曾经拥有就可以啦,昙花一现也会捕捉到,美滋滋~

更多内容,欢迎关注我的公众号~~名字还是一样--数字IC小记

SystemVerilog之event​mp.weixin.qq.com
0e78f8a462c47ac81f8da0236d3d188b.png

8ec88effe87302201e6ddd35b111a38b.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值