我正在寻找对系统verilog方法的直觉理解,该方法等待接口上的某些信号以进行以下操作:1)在监视器中捕获事务,或2)响应来自DUT的某些信号来驱动事务。假设DUT声明就绪信号,并且驱动程序必须在声明有效信号的同时背对背驱动两个数据拍(值1和2),以便DUT知道何时捕获数据。
我知道有两种方法等待DUT中的就绪单; 1)一个是iff条件时钟事件,另一个是2)在某些信号不正确(例如,就绪为低电平)时消耗时钟。可以在EDA playground (line 37 of my_driver.sv)中找到测试平台代码。
第一种方法是使用@(posedge dut_vif.clock iff(dut_vif.ready == 1));
第二种方法是使用while( ! dut_vif.ready) @(posedge dut_vif.clock);
,并且两种方法之间只有一个时钟差,如波形所示。我最好的理解是-
@(posedge dut_vif.clock iff(dut_vif.ready == 1));
此方法在“就绪” == 1条件下等待时钟上升事件。因此,数据和有效信号在25ns时被驱动为高电平。
while( ! dut_vif.ready) @(posedge dut_vif.clock);
另一方面,该语句表示在就绪状态为低时,仿真应消耗时钟。但是,这种解释与systemverilog的实际行为非常不同。在15ns时,就绪信号变高,有效数据和数据以同一周期驱动。我的理解是,在15ns时,测试台仍应将准备就绪状态捕获为低电平,而仿真应消耗一个时钟。因此,第二种方法的行为应与第一种方法相同。
我可以对如何理解这种差异进行一些解释吗?
我在这里附加波形。
答案 0 :(得分:1)
该问题是由于get_next_item()
的调用中存在隐藏的增量延迟,即使时间仍为15,counter
以及ready
现在也有了它们的 new 调用返回后的em>值。使用iff
可以使时钟边缘的值更清晰。当!ready
为x
时,还可以避免问题,因为它的计算结果为false。
答案 1 :(得分:0)
@(event iff (expression));
等效于
do @event; while (!expression);
不是
while (!expression); @event;
正如戴夫(Dave)在here所提到的,也许他忘记了。因此,您错过了一个时钟周期。