始终阻止不按预期运行

时间:2013-11-21 02:21:40

标签: verilog

我在verilog中创建一个状态机,根据用户输入实现某些算术功能。然而,我遇到了障碍;我的第一个总是阻塞,一个处理我的重置并保持正确状态,阻止不按预期行事;它没有正确更新状态。代码如下:

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

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

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

http://imgur.com/0DUka21

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

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

2 个答案:

答案 0 :(得分:2)

啊,我明白你现在做了什么。您要在两个始终块中分配STATE({case}块的默认值为STATE <= STATE。这很糟糕,因为它是两个块之间的竞争条件,实际分配了哪个。在您的情况下,第二个块覆盖第一个块,以便每个时钟执行STATE <= STATE。您不应在多个always块中分配相同的变量。

此外,您应该注意这些警告,但它们指的是always @(ENABLE)块。这是抱怨,因为你推断了奇怪的锁存行为,因为输出取决于STATE和SW,但它们不在敏感列表中。您可能应该将其设为组合块,并使用自动敏感列表always @*

答案 1 :(得分:1)

每个始终阻塞,以及始终阻止之外的每个语句,都有效地并行运行。

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

在模拟中,如果驱动该单线的多根线具有相同的逻辑值,则可以获得所需的输出;但如果它们具有不同的值,您将得到无效或不可预测的输出。

在综合中,这只会因“多个驱动程序”错误而失败。

此外,始终阻止的敏感性列表应包含三个内容之一:

  1. 时钟
  2. 时钟和异步复位
  3. 用作输入的每个wire / reg始终阻止(*)
  4. 任何其他东西都可能导致无意识的锁存,这会导致问题。

    在第3种情况下,您需要确保always块中驱动的每根导线都有一个默认值。任何其他东西都可能导致无意识的锁定。

    最后,您不能进行循环分配,也不会冒逻辑循环的风险。你可以通过为自己分配next_state来获得一个。任何“循环”都需要一个触发器,也就是上面概述的类型1或2的总是块。