在 UVM 监视器中循环时无法退出

Unable to exit while loop in UVM monitor

这可能是我忽略的一个愚蠢的错误,但我对 UVM 还很陌生,在此之前我曾尝试修改我的代码一段时间。我正在尝试使用 Data valid stall 协议从我的 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 语句 "before printing input packet from monitor"。

HIGH 定义为二进制 1,LOW 定义为二进制 0。

显示语句方面的代码输出如下。

数据收集前
在检查失速之前
检查失速后
2
在输入监视器中打印检查 @ time = 105
在检查失速之前
检查失速后
1
在输入监视器中打印检查 @ time = 115
在检查失速之前
检查失速后
3
在输入监视器中打印检查 @ time = 125

您环境中的其他地方可能会放弃主要阶段异议。 UVM 将自动终止在阶段结束时生成的任何线程。

要解决此问题,请不要反对您显示器中的主要阶段。反对那个阶段是创建刺激的线程的责任。相反,您应该在 run_phase 期间启动此监视器,这将确保您的循环在模拟结束之前不会被终止。

此外,在关闭阶段,您会希望您的监视器在当前看到数据包时进行反对。这将确保模拟不会在发送刺激后立即结束,让您的其他监视器有时间收集来自 DUT 的响应。