2017-09-25 167 views
0

我试图验证两个模块之间的一个非常简单的握手。一个模块处于慢速时钟并提高“请求”,较快的模块应该在下一个快速时钟上提高“确认”并保持它,直到下一个慢速时钟为止。最终的结果是这样的:e HVL(IEEE 1647):期望的表达意外失败

req-ack wave diagram example

这是我写的期待:

expect expect_ack_when_req_go is 
     (@req_rise_e) => @ack_rise_e 
     else dut_error("ERROR: ack expected to be asserted when req rises!"); 

*既@req_rise_e和@ack_rise_e是在慢时钟采样。

运行模拟器会产生错误,因为第一个表达式似乎成功了,但第二个表达式没有成功。尽管事件追踪到wave时,我可以看到两个事件一起发生(如wave:event_req,event_ack中所见)。

+0

我会先尝试添加一个采样时钟给TE,即'expect ...(@req_rise_e => @ack_rise_e)@slow_clk;' – Thorsten

+0

已经尝试过了,它没有做任何好处...此外,我认为这是多余的,因为这两个事件已经被慢速时钟采样: 'event req_rise_e is rise(smp.port_req $)@slow_clk_e;' 'event ack_rise_e is rise(smp.port_ack $)@slow_clk_e;' –

+0

好吧,@ Thorsten看起来你是对的!看起来,在两个**信号上增加一个采样时钟一起改变了模拟器理解检查表达式的方式。我按照你所建议的方式改变了它,但它仍然奏效......尽管我无法解释它......如果你能理解它,也许你应该将它作为解决方案发布? –

回答

3

你试图做重叠的含义,即你的事件发生在同一个周期。 =>操作员所做的是检查结果是否发生在下一个采样事件上,在这种情况下是下一个慢时钟边沿。这被称为SystemVerilog断言术语中的非重叠含义。

您可以通过编写以下得到您想要的行为:

expect expect_ack_when_req_go is 
    (@req_rise_e) => detach({@ack_rise_e; ~[1]}) 
    else dut_error("ERROR: ack expected to be asserted when req rises!"); 

充分说明here

在方法论上,我建议不要以不同的方式编写时态表达式。我假设您正在验证正在驱动的模块ack,并且此模块在两个时钟均可工作。我还假设这个模块用快速时钟取样req。这将是更清晰的制定你的支票:

expect expect_ack_when_req_go is 
    (@req_rise_at_fast_clock_e) => @ack_rise_at_slow_clock_e 
    else dut_error("ERROR: ack expected to be asserted when req rises!"); 

这样你就不必更动detach(...)expect你想要的行为的自然语言描述更匹配。

+0

好,很好的回答!我隐约想起在SVA上有两个蕴涵运算符,但是自从我处理了任何SystemVerilog代码后,这已经有一段时间了。在您的博客上也有很好的技术解释。此外,你在方法论上也是正确的,这就是我要做的修复。谢谢。 –