【问题标题】:Verilog always block triggers misbehavingVerilog 总是阻止行为异常的触发器
【发布时间】:2013-11-03 15:27:20
【问题描述】:

我有一个包含开关和键的 always 块。当我在敏感度列表中只有键时,它的行为很好(只执行一次代码然后退出块)。当我将开关添加到灵敏度列表时,它变得疯狂并且似乎在我按住键时无限循环,即使我只是在按键按下时触发它。

我正在尝试实现一个仅在每次按键时递增一次的计数器。

这里是工作代码,只有敏感列表中的key(sw[1]是表示是向上还是向下计数):

always @ (negedge key[2]) begin
  if (~key[2]) 
      begin
        if (sw[1] == 0) begin
          if (p3ctr == 15) p3ctr = 0;
          else p3ctr = p3ctr + 1;
        end
        else if (sw[1] == 1) begin
          if (p3ctr == 0) p3ctr = 15;
          else p3ctr = p3ctr - 1;
        end
    end
end

这是损坏的代码(我正在使用 sw[7] 来重置计数器,当它启动时。此代码无限循环,而 key[2] 被按住)

always @ (negedge key[2] or posedge sw[7]) begin
  if (~key[2]) 
      begin
        if (sw[1] == 0) begin
          if (p3ctr == 15) p3ctr = 0;
          else p3ctr = p3ctr + 1;
        end
        else if (sw[1] == 1) begin
          if (p3ctr == 0) p3ctr = 15;
          else p3ctr = p3ctr - 1;
        end
    end
  else begin
    p3ctr = 0;
  end
end

我认为 always 块中的代码只会在敏感度列表中的信号发生变化时执行一次,但显然情况并非如此。

知道如何让这段代码在每次按键时只执行一次,以便计数器正常运行吗?

谢谢!

【问题讨论】:

  • “发疯”到底是什么意思?仿真中也会发生这种情况吗?你在进行模拟,不是吗?

标签: verilog


【解决方案1】:

我假设在 FPGA 上运行时会出现问题;纯粹的模拟会很好。综合工具假设第一个if 是异步逻辑,else 条件被视为同步逻辑,因为这是正确的编码风格。在提供的代码中,第一个条件是if (~key[2]),这意味着综合工具会将negedge key[2] 视为低电平有效异步逻辑。从重置条件if (sw[7])开始,你应该会得到想要的结果。

always @ (negedge key[2] or posedge sw[7]) begin
  if (sw[7]) begin
    p3ctr <= 0;
  end
  else begin
    if (sw[1] == 0) begin
      if (p3ctr == 15) p3ctr <= 0;
      else p3ctr <= p3ctr + 1;
    end
    else if (sw[1] == 1) begin
      if (p3ctr == 0) p3ctr <= 15;
      else p3ctr <= p3ctr - 1;
    end
  end
end

注意:最佳实践是使用非阻塞赋值 (&lt;=) 和 flops。阻塞赋值(=)用于组合逻辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多