【问题标题】:System verilog: if loop inside always block not executing系统verilog:如果循环内部总是阻止不执行
【发布时间】:2017-10-26 18:50:54
【问题描述】:

当另一个 64 位信号 (val) 的值更改超过阈值时,我编写了一段代码来同步断言信号 (val_changed)。稍后需要根据第三个信号的 (adj_in_prog) 否定来取消断言此信号。

这里 clk 和 val 是块的输入。

logic [63:0] val_reg;

 always @(posedge clk) begin
    val_reg <= val;
 end

 always @(posedge clk) begin
    if ((val - val_reg) > 64'hFFFFF) //Threshold = 64'hFFFFF
          val_changed <= 1'b1;
    @(negedge adj_in_prog);
    val_changed <= 1'b0;
 end

我知道上面的方法不是最干净的方法,但是由于这是测试台代码,所以我不需要综合它,想尝试一下。但是这段代码不起作用,因为 val_changed 不会 1。我想知道为什么 if 循环不会执行。根据我的说法, val_changed 应该在标记位于附加波形中的时钟边沿变高。有人可以帮忙吗? (波形值为十六进制)

【问题讨论】:

  • @(negedge adj_in_prog) 在 if 语句之外。不知道为什么你有这个语句,因为它不可合成并阻止检测未来posedge clk
  • 可以添加adj_in_prog的踪迹吗?现在请记住,在您得到 adj_in_prog 的否定之前,第二个 always 块不会第二次执行。它会留在那里,不会重新进入。
  • @Greg adj_in_prog 是一个我知道肯定会在 val_changed 变为 1 后至少上升和下降一次的信号,因此它在 if 循环之外。我想要实现的是: Diff 超过阈值-> val_changed 得到 1-> 等到 adj_in_prog 的 negedge -> val_changed 得到 0。一旦 val_changed 为 1,我不介意错过未来 posedge clk。事实上,我不介意当 val_changed 为 1 时想要 posedge clk 检测。
  • @Serge adj_in_prog 在我上面粘贴的波形窗口中保持低电平。一旦 val 信号的突然变化在几个周期后到达设计内部的模块,该信号在模拟的稍后时间变高。感谢您指出控制不重新进入总是阻塞直到 adj_in_prog 的否定,但这正是我的意图。
  • @thorondor1990 因此,在 clk 的第一个姿势中,它开始等待 adk_in_prog 在非零之后变为 0。但这不会在您的窗口期间发生。所以,val_changed 永远不会变成“1”。实际上,“if”语句在第一次时只会执行一次。它将在所有时钟周期内被忽略,直到您获得信号的 negedge。

标签: verilog system-verilog


【解决方案1】:

在您的情况下,在 clk 的第一个 posedge 时,第二个 always 块开始执行并处理“if”语句。然后它坚持@(negedge adj_in_prog) 语句,等待事件。在下一个时钟沿,它将继续等待,并且不会重新输入和评估“if”语句,依此类推。所以,这就解释了为什么它没有进展。

所以,假设adj_in_progval_changed 更改为1 时打开,以下应该适合您。

always @(posedge clk) begin
    if ((val - val_reg) > 64'hFFFFF) //Threshold = 64'hFFFFF
      val_changed <= 1'b1;
    else if (!adj_in_prog);
      val_changed <= 1'b0;
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    相关资源
    最近更新 更多