如何在verilog中的“always”块中使用两个事件

时间:2015-09-23 01:40:36

标签: verilog

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

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

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

  

逻辑for与已知的FF或Latch模板不匹配。

然而,当我只使用一个事件(posedge pb1)尝试它时,它起作用了。

那为什么会这样呢?

1 个答案:

答案 0 :(得分:0)

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

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

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

解决方案取决于您想要做什么 - 如果您要求计数器在pb1pb2上升沿递增,与其他无关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;

所有选项都有自己的限制,限制和缺点,因此很大程度上取决于您想要做什么。角落案件很重要。

请注意,我将这些示例代码放在一起而未对其进行测试 - 如果您遇到任何问题,请在评论中告诉我,我会调查一下。