【问题标题】:Always block not behaving as expected始终阻止未按预期运行
【发布时间】:2013-11-21 02:21:39
【问题描述】:

我正在用 verilog 制作一个状态机,以根据用户输入实现某些算术函数。但是,我遇到了障碍。我的第一个 always 块,即处理我的重置并保持正确状态的块,没有按预期运行;它没有正确更新状态。代码如下:

always @ (posedge CLOCK_50 or negedge RESET) begin
    if(RESET == 1'b0)
        STATE <= BASE;
    else 
        STATE <= NEXT_STATE; // this always block, and specifically this line, is //not executing correctly.
end

这是文件在复位时的一般输出,然后在 SW = 0000 的情况下按下三个按钮 (KEY[1]):

编辑:添加了实际 CLOCK_50 和 RESET 信号的波形

http://imgur.com/0DUka21

至于我的问题,我只想知道我在这部分代码中做错了什么。我想不出它有这样的行为的理由。感谢您提供的任何帮助。

EDIT2:FFS,我将块更改为否定 CLOCK_50,现在它正在工作。如果你能告诉我,我真的很想知道为什么。

【问题讨论】:

  • 您的波形上的CLOCK_50 在哪里?我只看到一个名为CLOCK 的信号。
  • 抱歉,只是从测试台到模块实例化的名称不同。它们是相同的信号。
  • 如果您显示实际时钟并在波形上正确重置(实际在模块内的那些),我会更有信心。除了没有连接时钟或重置之外,我看不出任何原因为什么STATE 在时钟上升时不采用NEXT_STATE 的值。
  • 好的,我会制作一个新的波形。
  • @Tim 在 OP 中确定新波形。

标签: verilog


【解决方案1】:

啊,我明白你现在做了什么。您在两个 always 块中都分配了 STATE(在 case 块的默认值中为 STATE &lt;= STATE)。这很糟糕,因为它是两个块之间关于实际分配哪个块的竞争条件。在您的情况下,第二个块覆盖第一个块,这样STATE &lt;= STATE 就会每个时钟执行一次。您不应该在多个始终块中分配相同的变量。

您还应该注意这些警告,但它们指的是always @(ENABLE) 块。这是在抱怨,因为您在推断奇怪的锁存行为,因为输出取决于状态和 SW,但它们不在敏感度列表中。你可能应该把它做成一个组合块,并使用自动敏感列表always @*

【讨论】:

    【解决方案2】:

    每个 always 块,以及 always 块之外的每个语句,都有效地并行运行。

    由于您的“状态”由两个 always 块驱动,因此您实际上是将两条线馈入一条线。在数字逻辑设计中,您无法做到这一点。 (不包括上拉电阻之类的,但这是另一个话题。)

    在仿真中,如果驱动单根线的多根线具有相同的逻辑值,则可以得到你想要的输出;但如果它们具有不同的值,您将得到无效或不可预测的输出。

    在综合中,这将简单地因“多个驱动程序”错误而失败。

    此外,always 块的敏感度列表中应包含以下三项之一:

    1. 时钟
    2. 时钟和异步复位
    3. 用作该 always 块 (*) 输入的每条线/寄存器

    其他任何事情都可能导致意外闩锁,从而导致问题。

    在情况 3 中,您需要确保在 always 块中驱动的每条线都具有默认值。其他任何事情都可能导致意外闩锁。

    最后,您不能进行循环分配,否则您将面临逻辑循环的风险。你有一个通过将 next_state 分配给它自己。任何“循环”都需要触发器,也就是上面概述的 1 或 2 类型的 always 块。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-12
      • 1970-01-01
      • 2020-06-28
      • 2012-02-18
      • 2018-01-18
      • 2012-06-14
      • 2019-03-03
      • 2012-09-21
      相关资源
      最近更新 更多