这可能是我身边的一个愚蠢的错误,我忽略了但是我对UVM很新,我在此之前尝试修补我的代码一段时间。我正在尝试使用从我的UVM驱动程序到DUT的数据有效停止协议在数据包中发送8位数据流。我遇到一个问题,我的输入监视器无法获取这些被驱动的事务。
我有一个while循环,其条件是有效位必须为高且停止位应为低。只要这个条件保持良好,监视器就需要获取数据字节并推入队列。我知道有一个事实是数据被拾取并推送到队列,因为我沿途使用了$display
语句。一旦接收到所有数据字节并且有效位变低,就会出现问题。理想情况下,这应该导致从while循环退出但不会这样做。任何帮助在这里将不胜感激。我附上了以下代码的片段。提前谢谢。
virtual task main_phase (uvm_phase phase);
$display("Run phase of input monitor");
collect_transfer();
endtask: main_phase
virtual task collect_transfer();
fork
forever begin
wait_for_valid_transaction_cycle();
create_and_populate_pkt();
broadcast_pkt();
@(iP0_vif.cb_iP0_MON);
end
join_none
endtask: collect_transfer
virtual task wait_for_valid_transaction_cycle();
wait(iP0_vif.cb_iP0_MON.ip_valid && ~iP0_vif.cb_iP0_MON.ip_stall);
endtask: wait_for_valid_transaction_cycle
virtual task create_and_populate_pkt();
pkt = Router_seq_item :: type_id :: create("pkt");
pkt.valid = iP0_vif.cb_iP0_MON.ip_valid;
pkt.sop = iP0_vif.cb_iP0_MON.ip_sop;
$display("before data collection");
while(iP0_vif.cb_iP0_MON.ip_valid === `HIGH && iP0_vif.cb_iP0_MON.ip_stall === `LOW) begin
$display("After checking for stall");
pkt.data = iP0_vif.cb_iP0_MON.ip_data;
$display(pkt.data);
pkt.data_q.push_front(pkt.data);
pkt.eop = iP0_vif.cb_iP0_MON.ip_eop;
$display("print check in input monitor @ time = %0t", $time);
@(iP0_vif.cb_iP0_MON);
end
$display("before printing input packet from monitor");
Check_for_port_route_and_populate_packet_field(pkt);
print_packet(pkt);
endtask: create_and_populate_pkt
在显示来自监视器的输入数据包之前的$display
语句“未显示。
HIGH定义为二进制1,LOW定义为二进制0.
根据显示语句输出的代码如下所示。
数据收集前的
在检查摊位之前
检查摊位后
2
打印输入监视器@ time = 105
在检查摊位之前
检查摊位后
1
打印输入监视器@ time = 115
在检查摊位之前
检查摊位后
3
打印输入监视器@ time = 125
答案 0 :(得分:1)
主要阶段异议可能会被丢弃到您环境中的其他位置。 UVM将自动终止在结束阶段生成的任何线程。
要解决此问题,请将不对象添加到监视器中的主阶段。反对该阶段是创建刺激的线程的责任。相反,您应该在run_phase期间启动此监视器,这将确保在模拟结束之前不会终止循环。
此外,在关机阶段,您需要监视器在当前看到数据包时进行对象。这将确保仿真不会在刺激发送后立即结束,让您的其他监视器有时间收集来自DUT的响应。