Systemverilog中关于@和wait的区别

news/2024/5/19 19:50:29 标签: 学习, systemverilog

本文转载自Systemverilog中@和wait區別及應用案例分析

               Systemverilog中@和wait區別及應用案例分析

 

       前言:在SystemVerilog中,用来触发事件时,使用->;用来等待事件使用@或者wait。那么@和wait有什么区别呢?在Verilog中当一个线程在一个事件上发生阻塞的同时,正好另一个线程触发了这个事件,则竞争就出现了。如果触发线程先于阻塞线程,则触发无效(触发是一个零宽度的脉冲)。


一、解决方法:

       Systemverilog 引入了triggered()函数,用于检测某个事件是否已被触发过,包括正在触发。线程可以等待这个结果,而不用在@操作符上阻塞。

 1.1、使用@等待某個Event產生競爭

`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

 1.2、使用wait(event_a.triggered)等待Event

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: @/trigger​ed()

       在多线程通信中,可以使用event实现线程的同步,即一个线程等待/触发另一个线程。

 2.1、使用方法​

  • Thread 1(触发线程): ​​ -> event;
  • Thread 2(等待线程):@event / wait(event.triggered);​

       使用上述方法,Thread2就会blocking在 ​@event / wait(event.triggered); ​处,只有Thread1执行完 ​​-> event; 后,Thread2才会向下执行。按上述方法使用是没问题的,那么有下面几个问题:

 

 2.2、典型问题

  • Q1: ​ 如里Thread2等待的语句在Thread1触发后执行,会是什么样的结果呢?
  • A: 如果Thread1触发操作只有一次,那么Thread2将永远blocking在等待语句@event / wait(event.triggered())处​。
  • 結論:等待线程的等待语句必须发生在触发线程之前執行。

 

  • Q2​: @event与wait(event.triggered)​的区别
  • A: ​若触发线程和等待线程在同一时刻发生,则使用wait(event.triggered)的线程会被触发,结束blocking,而使用@event的线程则会永远blocking在这,无法结束。看下面的两个例子:
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
  • Q3: 从上面的例子可以看出,在该类应用中,使用wait(event.triggered)要优于使用@event的方法,但wait(event.triggered)的方法在任何时候都会优于@event吗?
  • A: 答案是否定的。看下面这个例子:
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

http://www.niftyadmin.cn/n/1787978.html

相关文章

C语言手撕代码

本文总结了一些在笔试中常见的一些C语言代码题。 文章目录冒泡排序字符翻转字母计数找质数/素数冒泡排序 冒泡排序是比较基础的排序算法之一,其思想是相邻的元素两两比较,较大的数下沉,较小的数冒起来,这样一趟比较下来&#xff…

好程序员web前端分享如何构建单页Web应用

好程序员web前端分享如何构建单页Web应用,首先我们来看一看单页应用是什么?所谓单页应用,指的是在一个页面上集成多种功能,甚至整个系统就只有一个页面,所有的业务功能都是它的子模块,通过特定的方式挂接到主界面上。…

笔试真题-LFK

本文整理了一些LFK最近笔试的代码题。 set a {12} set b {345} set c {6789} lappend a $b lappend a $c #如何从a中得到6?这道题考了TCL脚本的使用 解决方法如下: set str [lindex $a 2] string range $str 0 0

个人作业--Alpha

这个作业属于哪个课程 <课程的链接> 这个作业要求在哪里 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/homework/3338 团队名称 <西柚皇家编程团队> 这个作业的目标 <对非自己所在的团队的三个项目进行测试&#xff0c;并提出建议或问…

UVM产生异常激励的方法

在UVM中&#xff0c;产生异常激励的方法&#xff08;以白皮书中源码为例&#xff09; 在my_transaction中添加一个crc_err的标志位这样&#xff0c;在post_randomize中计算CRC前先检查一下crc_err字段&#xff0c;如果为1&#xff0c;那么直接使用随机值&#xff0c;否则使用真…

goroutine

一些例子 等待 goroutine 完成 在线示例 - 等待 goroutine 完成 // main.go package mainimport ("fmt""net/http""sync" )func main() {fmt.Println("start...")var urls []string{"https://www.baidu.com/","https:…

notepad++实现verilog代码的编译

介绍 在verilog学习中&#xff0c;我们想要检查代码的语法是否有误&#xff0c;一般需要在questasim或者其他的工程软件中进行编译仿真&#xff0c;大大降低了开发速度。对此&#xff0c;notepad编辑器中可以通过安装插件的方式&#xff0c;直接在notepad中实现编译&#xff0…

【sv中的继承与多态】

文章目录继承多态虚方法实现多态步骤继承 在验证的过程中&#xff0c;经常会有新的测试用例被添加进来&#xff0c;而且需要对原有的验证平台进行改进&#xff0c;特殊的测试用例经常会要求验证平台添加特定的功能。在过程化编程语言中&#xff0c;这要求修改原来的代码并且有…