verilog - 如何在 verilog 中的 "always" block 中使用两个事件

标签 verilog

我有两个按钮(使用 Basys2 rev C 板),我想在按下其中一个时增加一个寄存器(计数器)。我用过这个:

always @( posedge pb1 or posedge pb2 )
 begin
 if(count2==9) count2=0;
 else count2= count2+1;
 end

但是当我实现它时(使用ISE 9.2),出现了一个错误:

The logic for does not match a known FF or Latch template.

然而,当我尝试仅使用一个事件 (posedge pb1) 时,它成功了。

那为什么会这样呢?

最佳答案

错误消息意味着目标技术(我猜您的情况是 FPGA 或 CPLD)没有实现您使用此行为代码描述的功能所需的物理电路。

编写可综合 RTL(verilog 或 VHDL)时要考虑的重要事项之一是您正在描述电子电路。在开始编码之前,您应该了解您正在尝试实现的真实世界逻辑(组合逻辑、寄存器)。在这种情况下,您描述的是一个具有两个独立时钟的寄存器——这在我见过的任何 FPGA 或 ASIC 库中都不存在。如果您无法弄清楚您要实现的是什么,合成器很可能也无法弄清楚。

换句话说,并非您在 Verilog 中描述的所有内容都可以转化为实际电路。

解决方案取决于您想要做什么 - 如果您要求计数器在 pb1pb2 上升沿递增,< em>不考虑其他 pb 的状态,我会研究使用另一个(独立)时钟(下面代码中的 clk)的解决方案 - 类似于这个:

reg old_pb1, old_pb2;
always @ (posedge clk) begin
  if (old_pb1 == 0 && pb1 == 1)
    if(count2==9) count2 = 0;
    else count2 <= count2 + 1;
  if (old_pb2 == 0 && pb2 == 1)
    if(count2==9) count2 = 0;
    else count2 <= count2 + 1;
  old_pb1 <= pb1;
  old_pb2 <= pb2;
end

如果您没有其他时钟,您也可以像本例中那样组合两个输入信号:

wire pbs = pb1 | pb2;
always @ (pbs) begin
 if(count2==9) count2 <= 0;
 else count2 <= count2 + 1;
end

另一种选择是对输入使用独立的计数器:

always @ (posedge pb1)
 begin
   if(count_pb1==9) count_pb1 <= 0;
   else count_pb1 <= count_pb1 + 1;
 end
always @ (posedge pb2)
 begin
   if(count_pb2==9) count_pb2 <= 0;
   else count_pb2 <= count_pb2 + 1;
 end

wire [4:0] count2 = count_pb1 + count_pb2;

所有选项都有自己的限制、限制和缺点,因此这在很大程度上取决于您想要做什么。极端情况很重要。

请注意,我将这些示例代码放在一起并没有对它们进行测试 - 如果您在使用它们时遇到问题,请在评论中告诉我,我会进行调查。

关于verilog - 如何在 verilog 中的 "always" block 中使用两个事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32729676/

相关文章:

verilog - 这段代码在综合时会产生多少次翻转?

regex - Vim - 扩展 verilog 总线的宏

verilog - 如何在 verilog 中使用环境变量或命令行设置宏的值?

verilog - 使用always@* |意义和缺点

floating-point - $在控制台中显示 float

verilog - 在综合中应该避免哪些 SystemVerilog 特性?

perl - Emacs 中双模式模式下更好的缩进

verilog - 为什么我在 verilog 中收到 "Incompatible types at assignment"错误?

verilog - iverilog 不编译在一行中写入多个位的多个端口声明

verilog - 部分选择导致非法左值