• systemverilog学习 ---- event


    event

    event 类

    event时systemverilog内建的一个类,我们可以用event声明一个句柄,该句柄称为named event。event是一个静态对象,用于进程之间的同步。event操作一般分为两个阶段的操作组成,一个进程用来触发event,另一个进程用来等待event。
    正是由于句柄的存在,它不同于如时钟上升沿事件,named event需要我们显示指定何时触发和等待。提供如下操作符处理event的触发和等待:

    • -> 触发named event,触发事件之后会解锁所有等待该事件的进程
    • ->> 触发非阻塞事件,使用该操作符语句执行不会阻塞即等待,会创建一个非阻塞赋值更新事件
    • @ 该操作符会阻塞进程,知道给定的event触发。若要实现不阻塞进程的触发,就先需要执行@statement,然后触发进程在执行->
    • wait 如果同时发生事件触发和等待,使用@操作符可能会错过检测事件的触发,而使用wait则可以检测事件的触发。
    • wait_order 这个方法会阻塞进程直到所有指定的事件在给定的顺序(从左到右)触发,如果顺序不对,同样不会解锁进程。
    • 当一个event变量赋值给另一个,两个event就会合并,执行->,任一事件变量都会影响进程执行。

    例子

    module event_ex;
    
        event ev_1;         //declaring event ev_1
    
        initial begin
            fork
                //process-1,triggers the event
                begin
                    #40;
                    $display($time, "\t Triggering The event");
                    ->ev_1;
                end
    
                //process-2,wait for the event to trigger
                begin
                    $display($time, "\t Waiting for the event to trigger");
                    @(ev_1.triggered);
                    $display($time, "\t Event triggered");
                end
            join
        end
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    示例中,fork-join有两个进程,第一个begin-end块经过40个时间单位触发事件ev_1,第二个begin-end块等待ev_1触发,然后打印输出.执行结果,可见,实质上是通过event控制进程的执行进度,提供了一个进程影响另一个的机制
    在这里插入图片描述

    module event_ex;
    
        event ev_1;                 //delaring event ev_1
    
        initial begin
            fork
                //process-1,triggers the event
                begin
                    #40;
                    $display($time, "\t Triggering The event");
                    ->ev_1;
                end
                //process-2,wait for the event to trigger
                begin
                    $display($time, "\t Waiting for the event to trigger");
                    #60;
                    @(ev_1.triggered);
                    $display($time, "\t Event triggered");
                end
            join
        end
    
        initial begin
            #100;
            $display($time, "\t Ending the simulation");
            $finish;
        end
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    由上面例子看出,即使是触发先发生,等待触发后发生。但是由于等待触发更晚一些,因此后面的语句将会呗堵塞,不会被执行。执行结果如下:
    在这里插入图片描述

    module events_ex;
      event ev_1; //declaring event ev_1
    
      initial begin
        fork
          //process-1, triggers the event
          begin
             $display($time,"\tTriggering The Event");
            ->ev_1;
          end
       
          //process-2, wait for the event to trigger
          begin
            $display($time,"\tWaiting for the Event to trigger");
            wait(ev_1.triggered);
            $display($time,"\tEvent triggered");
          end
        join
      end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    执行结果如下,可见当等待在触发前执行,或者同时出现,等待方是可以察觉触发的
    在这里插入图片描述
    对上面的例子进行修改,将进程2的wait换成@
    在这里插入图片描述
    执行结果,可见使用@操作符,等待方检测不到触发
    在这里插入图片描述

    module events_ex;
      event ev_1; //declaring event ev_1
      event ev_2; //declaring event ev_2
      event ev_3; //declaring event ev_3
      
      initial begin
        fork
          //process-1, triggers the event ev_1
          begin
            #6;
            $display($time,"\tTriggering The Event ev_1");
            ->ev_1;
          end
          //process-2, triggers the event ev_2
          begin
            #2;
            $display($time,"\tTriggering The Event ev_2");
            ->ev_2;
          end
          //process-3, triggers the event ev_3
          begin
            #8;
            $display($time,"\tTriggering The Event ev_3");
            ->ev_3;
          end
          //process-4, wait for the events to trigger in order of ev_2,ev_1 and ev_3
          begin
            $display($time,"\tWaiting for the Event's to trigger");
            wait_order(ev_2,ev_1,ev_3)
              $display($time,"\tEvent's triggered Inorder");
            else
              $display($time,"\tEvent's triggered Out-Of-Order");
          end
        join
      end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    由上面例子可以看出,是先触发事件2,再触发事件1,最后触发事件3.再wait_order是按照顺序触发的,因此wait_order后面的语句是可以被执行的。其输出结果如下:
    在这里插入图片描述

    module event_ex;
    
        event ev_1;             //declaring event ev_1
        event ev_2;             //declaring event ev_2
        event ev_3;             //declaring event ev_3
    
        initial begin
            fork
                //process-1,triggers the event ev_1
                begin
                    #6;
                    $display($time, "\t Triggering the event ev_1");
                    ->ev_1;
                end
    
                //process-2,triggers the event ev_2
                begin
                    #2;
                    $display($time, "\t Triggering the event ev_2");
                    ->ev_2;
                end
    
                //process-3,triggers the event ev_3
                begin
                    #1;
                    $display($time, "\t Triggering the event ev_3");
                    ->ev_3;
                end
    
                //process-4.wait for the events to trigger in order of ev_2,ev_2,ev_3
                begin
                    $display($time, "\t Waiting for the event to trigger");
                    wait_order(ev_2,ev_1,ev_3);
                        $display($time, "\t Event's triggered Inorder");
                    else
                        $display($time, "\t Event's triggered out-of-order");
                end
            join
        end
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    上面例子中的触发顺序是先触发ev_3随着是ev_2,ev_1。进程4的等待顺序却是等待ev_2,ev_1,ev_3的顺序,因此是乱序的,其输出结果如下所示:
    在这里插入图片描述

    event regions

    简要谈谈sv元素之间的交互和行为,类似verilog仿真事件队列。IEEE1800-2015标准,将sv的时间戳time slot分成17个有序区域。9个区域用于执行sv的语句,8个区域用于执行PLI(programming language interface,编程语言接口)代码。规定这些,是为了design和testbench在预料中交互
    在这里插入图片描述

  • 相关阅读:
    【Redis在Windows中与Linux中的下载安装,启动服务和设置密码远程连接】
    一篇掌握docker
    【go语言之timer实现】
    终于搞懂了python2和python3的encode(编码)与decode(解码)
    数据库管理-第115期 too many open files(202301107)
    MFC:AfxMessageBox函数随记
    最小生成树——Prim算法与Kruskal算法
    毕昇编译器优化:Lazy Code Motion
    [GWCTF 2019]你的名字 - SSTI注入(waf绕过)
    Docker容器入门笔记,一篇文章告诉你,使用docker的方法和使用Docker的优势
  • 原文地址:https://blog.csdn.net/weixin_45614076/article/details/126378257