求助:该怎么终止这个循环?
正在写driver,遇到一个问题,就是我必须在一个信号的上升沿将当前的transfer的传输终止(不管传没传完,然后去取下一个item,开始下个transfer的传输)。我是用一个for循环来发送数据的,因此,我想用disable来将它终止,但是好像disable只是将这一次的操作终止掉,下次循环又重新开始了,请问,我该如何才能直接终止掉整个loop呀?
- 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
- 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
结果跑出来的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》的例子是:
- module ...
- always always1: begin
- ...
- t1: task1();
- ...
- end
- ...
- endmodule
- always begin
- ...
- disable u1.always1.t1; // 突出在always1(静态)中调用的任务
- 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
- 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
不行。因为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
终止 相关文章: