在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 1795|回复: 6

[求助] 为什么小面这段代码的trans随机化有问题?

[复制链接]
发表于 2020-1-3 22:58:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
小弟第一次接触sv,写了个generator遇到个问题很困惑,求大佬解答。
如下代码,在generator中声明了transaction成员trans,然后在start方法中使用repeat循环进行例化后随机化并发送给driver,随机化没问题:




  1. class generator;
  2.         transaction trans;
  3.         mailbox gen2drv;
  4.         int repeat_times;
  5.         event ended;
  6.        
  7.         function new(mailbox gen2drv);
  8.                 this.gen2drv=gen2drv;
  9.         endfunction
  10.        
  11.         task start();
  12.                 $display("generator starts");
  13.                 repeat(repeat_times) begin
  14.                         trans = new();
  15.                         if(trans.randomize())
  16.                                 $display("generator's randomize <span style="background-color: rgb(255, 255, 255); color: rgb(51, 51, 51); font-family: arial;">success</span>");


复制代码
Snipaste_2020-01-03_22-53-12.png
但后面修改了一下代码,发现如果把trans的例化改到generator的构造函数new中,然后调用start方法中使用repeat循环进行随机化并发送给driver,发现并没有随机化,只能产生一种激励,请问这是怎么回事?




  1. class generator;
  2. transaction trans;
  3. mailbox gen2drv;
  4. int repeat_times;
  5. event ended;

  6. function new(mailbox gen2drv);
  7. this.gen2drv=gen2drv;
  8. trans = new();
  9. endfunction

  10. task start();
  11. $display("generator starts");
  12. repeat(repeat_times) begin
  13. if(trans.randomize())
  14. $display("generator's randomize <span style="color: rgb(51, 51, 51); font-family: arial; background-color: rgb(255, 255, 255);">success</span>");
  15. gen2drv.put(trans);
  16. end
  17. ->ended;
  18. $display("generator ends");
  19. endtask

  20. endclass


复制代码
Snipaste_2020-01-03_22-55-37.png
关键是打印的信息也显示随机化正常这是怎么回事。。。

发表于 2020-1-4 17:44:18 | 显示全部楼层
我觉得问题不是randomize

前一种写法 generator 每次loop, 都新gen了一个trans,然后随机化trans中的field;
后一种写法 整个过程 trans 只有一个,每次loop 只是random去改写 trans中的field;

我觉得两种写法应该都是work 的;
至于 waveform上看到,后一种写法不OK,
猜测是不是 generator -> driver 的过程出了问题?

如果说得不对,请指正!
发表于 2020-1-4 18:22:45 | 显示全部楼层
应该是gen->dri之间,没有重新创建trans,driver通过接口只获取到一次trans。他们之间通信传输的trans,在一次传输完以后一定要重新分配一个指针,才会继续交互,否则trans只会用一次。
 楼主| 发表于 2020-1-4 20:32:28 | 显示全部楼层


gaurson 发表于 2020-1-4 18:22
应该是gen->dri之间,没有重新创建trans,driver通过接口只获取到一次trans。他们之间通信传输的trans,在 ...


下面是driver的相对应driver的代码,在driver的start方法内是每接收一个创建了一个trans的句柄,请问这样是正确的吗



  1. class driver;
  2.         virtual INTF intf;
  3.         mailbox gen2drv;
  4.         int num_of_trans;
  5.        
  6.         function new(virtual INTF intf,mailbox gen2drv);
  7.                 this.intf=intf;
  8.                 this.gen2drv=gen2drv;
  9.         endfunction
  10.        
  11.         task start();
  12.                 $display("dirver starts");
  13.                 forever begin
  14.                         transaction trans;
  15.                         gen2drv.get(trans);
  16.                         @(posedge intf.clk);
  17.                         intf.valid <= 1;
  18.                         intf.a <= trans.a;
  19.                         intf.b <= trans.b;
  20.                         @(posedge intf.clk);
  21.                         intf.valid <= 0;
  22.                         trans.c = intf.c;
  23.                         @(posedge intf.clk);
  24.                         trans.display("[driver]");
  25.                         num_of_trans++;
  26.                 end
  27.                 $display("dirver ends");
  28.         endtask
  29.        
  30. endclass



复制代码




 楼主| 发表于 2020-1-4 20:33:35 | 显示全部楼层


守护小熊猫 发表于 2020-1-4 17:44
我觉得问题不是randomize

前一种写法 generator 每次loop, 都新gen了一个trans,然后随机化trans中的fiel ...


我把driver的代码也贴了出来,大佬您看看有无问题
 楼主| 发表于 2020-1-4 20:34:37 | 显示全部楼层
本帖最后由 leine 于 2020-1-4 22:25 编辑

重新检查了下代码,这里就不贴了,1楼的两个代码在put前都打印一遍trans,发现trans放不放在trans构造函数中,确实都随机化成功了,但是检查了下driver感觉应该没有问题,不过我从控制台的信息大概推测是什么原因了,下面是原因:首先是env的start方法,可以看到我预期的是gen,dev,mon,scb4个组件都是并行的。但是控制台的信息里可以看到,gen率先把所有的trans都生成了然后put进了邮箱,而剩下其他几个组件都是并行的:
env.png concil.png
这个执行顺序导致我后面从gen—>drv的事务出了问题。
然后,楼上两位大佬说的都是对的,讲trans放在gen的构造函数确实不会影响到随机化过程,这两种写法关键在于gen中trans的指针的变化,如果例化放在了构造函数new里那么trans的指针始终只有一个,放在repeat循环里就会产生多个trans的指针:
1.png 2.png
最后,mailbox是put一个trans的指针再将它交给另一个get它的trans变量。
那么上面三者是怎么造成看起来像是随机化失败的问题的呢?下面是控制台的信息,分别对应放在new中与放在repeat中:
new.png ###### repeat.png
mailbox是按照先进先出的队列来取信息的,所以放在repeat中(左图)的drv与gen的顺序能对应的上。而放在new中(右图)的drv是取得最后一个put进maibox得trans,这显然不合理,前面已经提到过放在new中得话,trans的指针就没有改变只不过是其内容再不断随机化,所以相当于mailbox不断put同一个指针的trans,所以drv中的maibox虽然是按照先进先出的顺序来取的,但是get到的trans的指针就没有改变过,只不过是trans的内容随机化了,所以看起来造成了drv取了最后一个trans。
但是这两种随机化与发送的方法我觉得都没啥问题,我想问的是为啥我这里env的start方法中使用的fork语句中gen不是和其他三个组件并行的?其实如果gen要是和drv与mon并行的话,即便是将trans的例化放在new中也不影响,即便指针没变,但是可以生成器put一个trans,驱动器再get一个trans。但诡异的是我这里fork的结果是gen优先执行完毕,然后drv、mon和scb再开始工作。
代码里gen的start方法是一个不带任何时间延迟的task,mon、drv和scb的start方法都带了时间延迟语句的,难道sv使用fork执行并发进程时优先执行不带时间延迟的吗?求大佬们指教











发表于 2020-1-11 08:43:01 | 显示全部楼层
所谓的并行, 是simulator给你的错觉, thread level parallel 实际是每个thread 都执行单独执行到blocking为止切换(具体thread 切换的granularity 每个simulator/OS/CPU都不一样).  你的generator start 函数里并没有blocking的语句,所以直接执行完再切换到其他thread执行是没有问题的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

×

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-3-28 19:12 , Processed in 0.035902 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表