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

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

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4450|回复: 11

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

[复制链接]
发表于 2013-8-1 13:06:36 | 显示全部楼层 |阅读模式

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

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

x
各位:
      正在写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

我该怎么办呢?
发表于 2013-8-1 14:47:29 | 显示全部楼层
for(i=0;i<cnt;i++) begin: loop1

loop的名字似乎是写在后面的吧
 楼主| 发表于 2013-8-1 15:00:13 | 显示全部楼层
回复 2# liangxiaowu
呃,我这样写也没报错,另外,我查了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



复制代码


唉,我现在好闲啊,都有时间再去翻一遍书了。。。。
这个问题不解决没办法往下做了呀,谁来救救我呀~~~~~~~~~~~
发表于 2013-8-2 00:18:40 | 显示全部楼层
感觉loop1定义的就是一个begin...end包着部分代码的名字,所以它只能终止一次,也是因为你等待的上升沿只有一个吧?也许要把loop1放在for前面,本来这只是一个别名,所以编译应该不会报错的。
发表于 2013-8-5 10:07:42 | 显示全部楼层
将for循环放在begin...end之中,然后disable这个begin...end
发表于 2013-8-5 11:42:28 | 显示全部楼层
回复 1# oscillator_cn1


    可以试试continue代替disable那段语句
发表于 2013-8-5 11:47:59 | 显示全部楼层
回复 6# zhuyi1234567899


    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
发表于 2013-8-5 11:48:54 | 显示全部楼层




  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


复制代码
回复 7# zhuyi1234567899
 楼主| 发表于 2013-8-6 13:35:32 | 显示全部楼层
不行。因为task “drive_one_beat”就是一个简单的valid与ready配合的操作,如果ready一直为0,那么就卡死在等待ready为“1”的时候了。整个dive_transfer就卡在22行了。而continue则是在第10行,都卡住了,回不到开始的地方去continue呀。
发表于 2013-8-7 21:41:44 | 显示全部楼层
把loop1 外面再套一层fork---join_any  起个名 然后disable 这个 就行了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

×

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

GMT+8, 2024-12-20 00:59 , Processed in 0.022736 second(s), 8 queries , Gzip On, Redis On.

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