微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 微电子和IC设计 > IC验证交流 > 求助:该怎么终止这个循环?

求助:该怎么终止这个循环?

时间:10-02 整理:3721RD 点击:
各位:
正在写driver,遇到一个问题,就是我必须在一个信号的上升沿将当前的transfer的传输终止(不管传没传完,然后去取下一个item,开始下个transfer的传输)。我是用一个for循环来发送数据的,因此,我想用disable来将它终止,但是好像disable只是将这一次的操作终止掉,下次循环又重新开始了,请问,我该如何才能直接终止掉整个loop呀?

  1. task rate_handw_driver::drive_transfer(vdo_transfer trans);
  2. longint r,g,b;
  3. int cnt;
  4. int i;
  5. `uvm_info("START_FRAME",$psprintf("Start send a new frame data"),UVM_MEDIUM)
  6. cnt=cfg.master_config.hvalid*cfg.master_config.vvalid/rate;
  7. two_vif.lr_mask <= #1 trans.lr_mask;
  8. fork
  9. for(i=0;i<cnt;i++) loop1:begin
  10. r=0;
  11. g=0;
  12. b=0;
  13. for(int j=0;j<rate;j++) begin
  14. r |= trans.r[i*rate+j]<<(j*width);
  15. g |= trans.g[i*rate+j]<<(j*width);
  16. b |= trans.b[i*rate+j]<<(j*width);
  17. end
  18. pix_cnt=i%(cfg.master_config.hvalid/rate);
  19. line_cnt=i/(cfg.master_config.hvalid/rate);
  20. $display("befor call drive_one_beat @%t,i=%d",$time,i);
  21. drive_one_beat(r,g,b,pix_cnt,line_cnt);
  22. end
  23. @(posedge two_vif.vs)
  24. disable loop1;
  25. join_any
  26. $display("break for @%t",$time);
  27. @(posedge two_vif.vdo_clk)
  28. two_vif.valid <= #1 'b0;
  29. two_vif.vlast <= #1 'b0;
  30. two_vif.hlast <= #1 'b0;
  31. endtask : drive_transfer

复制代码


结果跑出来的log如下:
break for @308026000
pix_cnt=5,line_cnt=0,@308030000
befor call drive_one_beat @308030000,i=6
pix_cnt=6,line_cnt=0,@308034000
befor call drive_one_beat @308034000,i=7
pix_cnt=7,line_cnt=0,@308038000
befor call drive_one_beat @308038000,i=8
pix_cnt=8,line_cnt=0,@308042000
befor call drive_one_beat @308042000,i=9
pix_cnt=9,line_cnt=0,@308046000
befor call drive_one_beat @308046000,i=10
pix_cnt=10,line_cnt=0,@308050000
befor call drive_one_beat @308050000,i=11
我该怎么办呢?

for(i=0;i<cnt;i++) begin: loop1
loop的名字似乎是写在后面的吧

呃,我这样写也没报错,另外,我查了systemverilog 3.1a语言参考手册,《8.9节disable》的例子是:

  1. module ...
  2. always always1: begin
  3. ...
  4. t1: task1();
  5. ...
  6. end
  7. ...
  8. endmodule

  9. always begin
  10. ...
  11. disable u1.always1.t1; // 突出在always1(静态)中调用的任务
  12. end

复制代码


唉,我现在好闲啊,都有时间再去翻一遍书了。
这个问题不解决没办法往下做了呀,谁来救救我呀~

感觉loop1定义的就是一个begin...end包着部分代码的名字,所以它只能终止一次,也是因为你等待的上升沿只有一个吧?也许要把loop1放在for前面,本来这只是一个别名,所以编译应该不会报错的。

将for循环放在begin...end之中,然后disable这个begin...end

可以试试continue代替disable那段语句

task rate_handw_driver::drive_transfer(vdo_transfer trans);
longint r,g,b;
int cnt;
int i;
`uvm_info("START_FRAME",$psprintf("Start send a new frame data"),UVM_MEDIUM)
cnt=cfg.master_config.hvalid*cfg.master_config.vvalid/rate;
two_vif.lr_mask <= #1 trans.lr_mask;
fork
for(i=0;i<cnt;i++) loop1:begin
@(posedge two_vif.vs) continue;
r=0;
g=0;
b=0;
for(int j=0;j<rate;j++) begin
r |= trans.r[i*rate+j]<<(j*width);
g |= trans.g[i*rate+j]<<(j*width);
b |= trans.b[i*rate+j]<<(j*width);
end
pix_cnt=i%(cfg.master_config.hvalid/rate);
line_cnt=i/(cfg.master_config.hvalid/rate);
$display("befor call drive_one_beat @%t,i=%d",$time,i);
drive_one_beat(r,g,b,pix_cnt,line_cnt);
end
//@(posedge two_vif.vs)
// disable loop1;
join_any
$display("break for @%t",$time);
@(posedge two_vif.vdo_clk)
two_vif.valid <= #1 'b0;
two_vif.vlast <= #1 'b0;
two_vif.hlast <= #1 'b0;
endtask : drive_transfer

  1. task rate_handw_driver::drive_transfer(vdo_transfer trans);
  2. longint r,g,b;
  3. int cnt;
  4. int i;
  5. `uvm_info("START_FRAME",$psprintf("Start send a new frame data"),UVM_MEDIUM)
  6. cnt=cfg.master_config.hvalid*cfg.master_config.vvalid/rate;
  7. two_vif.lr_mask <= #1 trans.lr_mask;
  8. fork
  9. for(i=0;i<cnt;i++) loop1:begin
  10. @(posedge two_vif.vs) continue;
  11. r=0;
  12. g=0;
  13. b=0;
  14. for(int j=0;j<rate;j++) begin
  15. r |= trans.r[i*rate+j]<<(j*width);
  16. g |= trans.g[i*rate+j]<<(j*width);
  17. b |= trans.b[i*rate+j]<<(j*width);
  18. end
  19. pix_cnt=i%(cfg.master_config.hvalid/rate);
  20. line_cnt=i/(cfg.master_config.hvalid/rate);
  21. $display("befor call drive_one_beat @%t,i=%d",$time,i);
  22. drive_one_beat(r,g,b,pix_cnt,line_cnt);
  23. end
  24. //@(posedge two_vif.vs)
  25. // disable loop1;
  26. join_any
  27. $display("break for @%t",$time);
  28. @(posedge two_vif.vdo_clk)
  29. two_vif.valid <= #1 'b0;
  30. two_vif.vlast <= #1 'b0;
  31. two_vif.hlast <= #1 'b0;
  32. endtask : drive_transfer

复制代码

不行。因为task “drive_one_beat”就是一个简单的valid与ready配合的操作,如果ready一直为0,那么就卡死在等待ready为“1”的时候了。整个dive_transfer就卡在22行了。而continue则是在第10行,都卡住了,回不到开始的地方去continue呀。

把loop1 外面再套一层fork---join_any起个名 然后disable 这个 就行了


那个,不知道是disable loop1呢,还是disable fork呢?

disable fork 加的那一层fork

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top