首页 > 其他分享 >systemverilog中for/foreach并行执行

systemverilog中for/foreach并行执行

时间:2024-08-04 23:06:25浏览次数:14  
标签:fork none join 并行执行 线程 foreach automatic systemverilog

目录

for-join_none并行

for循环fork-join_none语句可以组合使用来并行执行多个块,这里必须使用非阻塞的fork-join_none来启动多线程,因为使用fork-join_none时每一次循环都会创建新的fork块,并且不影响之后创建fork块,而fork-join则会阻塞后面的fork块的执行,主要是保证fork块内的线程并行执行。但其实在使用for-join_none并行执行时,很容易出现错误情况,下面先描述一种常见错误情况。

program no_auto;
  initial begin
  for(int j=0;j<3;j++)
    fork
      $write(j);
    join_none
  #0 $display("\n");
  end
endprogram

上面代码本意时每个线程依次打印0,1,2,但在执行线程前需要在#0时延之前计算完成。因此依次执行下面代码

  1. j=0 创建write(j)——线程0,创建不执行
  2. j=1 创建write(j)——线程1,-创建不执行
  3. j=2 创建write(j)——线程2,-创建不执行
  4. #0 执行消耗时间前,多线程同时执行
  5. j=2 执行write(j)——线程0
  6. j=2 执行write(j)——线程1
  7. j=2 执行write(j)——线程2
  8. $display("\n")——主线程执行

而由于多线程之间使用的时同一个变量,则导致线程0、1、2打印的都为j=2.
因此为了避免这种错误,可以使用自动变量来保存变量的拷贝,之后每一个线程都会创建自动变量k并保存一次j的值,#0之后三个线程将打印出其拷贝值k,而不再是共同且唯一的变量j。

program no_auto;
  initial begin
  for(int j=0;j<3;j++)
    //当然也可以放在这里
    //automatic int k=j;
    fork
      automatic int k=j;
      $write(k);
    join_none
  #0 $display("\n");
  end
endprogram

当然如果代码是在automatic类型的代码或者模块里面,那么声明时可以不适用关键词automatic声明变量,而是可以直接在循环中使用变量,即可自动在每个线程中创建变量。

program automatic auto;//通过指定代码块为自动变量存储,此时在for循环中的k
  initial begin					//在每一次循环中都会给定不同的存储空,此时多次调用
    for(int j=0;j<3;j++)//将不会存在问题
    int k=j;
    fork
      $write(k);
    join_none
  #0 $display("\n");
  end
endprogram

但在UVM中是不是需要必须指明automatic代码块呢?
答案是不一定的,因为SV中的class的方法就默认是automatic模式,因此不需要特别的在fork前面的外部自动变量做automatic int k=j的声明,直接按照变量声明即可 int k=j,但为保证含义清晰,最好添加上automatic

foreach并行

foreach相比于for循环,其需要输入数组变量,foreach(变量[迭代器]]),输入变量少,而且可以更方便的迭代。常见用法包括可以在UVM环境中将并行启动多个seqence,将seqence同时发送到多个agent上。


  begin : foreach_fork
    seq_class seq [`CONST];
    foreach(env.agt[i])
      begin
        automatic int j = i;
          seq[j] = seq_class::type_id::create
                  (.name($sformatf("seq_%0d", j)), .contxt(get_full_name()));
        fork
          begin
            seq[j].start(env.agt[j].sqr);
          end
        join_none // non-blocking thread
      end
    wait fork; //等待
  end : foreach_fork  

具体执行过程如下:

  1. foreach循环遍历每一个env.agt集合的每个代理。
  2. automatic int j = i;创建为唯一的索引,对于避免并发问题,这里相当重要,由于这里是类的方法,所以可以不加automatic而单纯是int j=1,并创建对应的sequence.
  3. 使用 fork-join_none 进行并行化启动,此在fork-join_none中新线程来并执行其中的代码块,此关键字指示仿真器继续执行,而无需等待已经启动的线程完成,这允许循环继续迭代并为其他代理启动新线程。
  4. seq.start(env.agt[j].sqr):此行使用sequence在env.agt[j].sqr上启动。
  5. wait fork:所有线程启动完成之后,并在此行之前同时执行。此语句使主线程等待,直到所有先前fork的线程(来自foreach)完成执行,这确保所有线程的sequence发送完成。

参考文献
[1]How can I use foreach and fork together to do something in parallel?
[2] 【system verilog】fork-join_none与循环语句共同使用的行为探究_fork join none-CSDN博客
[3] 绿皮书

标签:fork,none,join,并行执行,线程,foreach,automatic,systemverilog
From: https://www.cnblogs.com/nullbeer/p/18342384

相关文章

  • js-数组内置函数-filter、map、forEach、reduce
    1、过滤数组-filter筛选数组元素,并生成新数组//过滤出分数为60分以上的数据<script>constarr=[{'name':'张三','score':80},{'name':'张六','score':50},{'name':'李四','score&#......
  • [三、渲染控制法]3. ForEach:循环渲染
    ForEach接口基于数组类型数据来进行循环渲染,需要与容器组件配合使用,且接口返回的组件应当是允许包含在ForEach父容器组件中的子组件。例如,ListItem组件要求ForEach的父容器组件必须为List组件。说明从APIversion9开始,该接口支持在ArkTS卡片中使用。接口描述ForEa......
  • js-数组内置函数-filter、map、forEach、reduce
    1、过滤数组-filter筛选数组元素,并生成新数组//过滤出分数为60分以上的数据<script>constarr=[{'name':'张三','score':80},{'name':'张六','score':50},{'name':'李四','scor......
  • mybatis使用foreach批量插入
    创建表createtablepublic."match"(match_datedatenotnull,match_namecharactervarying(20)notnull,match_seasoncharactervarying(10)notnull,match_roundnumeric(2)notnull,home_teamcharactervarying(30)notnull,away_teamcharact......
  • 以块的形式处理大型 Spark DataFrame 的推荐方法是什么:“toPandas()”或“RDD.foreach
    我正在使用PySpark处理大型数据集,并且需要以每个500条记录的块的形式处理数据。我正在考虑使用toPandas()将我的SparkDataFrames转换为PandasDataFrames以方便分块或坚持使用SparkRDD,并使用foreachPartition()手动处理分块。以下是我正在考虑的示例方......
  • 在实际应用中,systemverilog相比vefilog2000有哪些重大的提升
    SystemVerilog相较于Verilog-2000有多项重大提升,这些提升使得SystemVerilog成为更强大的硬件描述和验证语言。以下是一些关键的改进:数据类型扩展:SystemVerilog引入了 logic 数据类型,可以替代Verilog-2000中的 wire 和 reg 类型,提供更灵活的使用方式。支持更广......
  • C# 一个自己写的异步并行执行器
    有的时候咱们需要循环执行业务,如果单以处理过程不是计算密集型,就可以使用多线程并行处理,这样能大幅度提高执行效率最开始我是想着有没有现成的,结果找了半天没发现有现成的,于是就自己封装了一个,简单测试了一下发现没啥问题异步并行执行器///<summary>///异步并行执......
  • 使用forEach循环异步方法,导致使用深拷贝时,得不到最新数据,控制台会打印出最新的数据
    在使用forEach循环遍历一个数组,如果循环时有异步方法,会导致最终深拷贝得不到最新数据,但是控制台会打印最新的数据constarr=[{name:"Jone",age:18},{name:"Tom",age:15},{name:"Liu",age:48}];functionfunTimeout(param){......
  • systemverilog的关联数组
    关联数组定义在SystemVerilog中,关联数组(AssociativeArrays)是一种非常灵活的数据结构,它可以使用任意类型的键(key)来索引数组中的元素。这使得关联数组特别适合于实现类似哈希表(hashtables)或字典(dictionaries)的功能,其中键可以是字符串、数字或其他复杂类型。data_typearray......
  • 关于面向对象的方法并行执行的问题
    LabVIEW的从同一个类实例化的多个对象如何执行各自的方法呢?这几天跟同事讨论到LabVIEW的面向对象编程中,如果我设计的一个类有一个方法比较耗时,那么当我实例化多个对象时,那么这个耗时的方法是怎么执行的呢?是各自并行执行还是,必须等某一个对象的方法调用完,接下来调用第二个对象的该......