verilog always block仿真和综合的区别

Diffrence between simulation and synthesises of verilog always block

我设计了一个简单的计数器。 下面的代码。

input sig;
reg [3:0] cnt;
always @(sig) begin
    if(sig) 
        cnt = cnt + 1;
end

Modelsim 模拟工作正常。当 sig 高时,我在 fpga(Spartan 6 by ise 14.7)上实现了代码,计数器连续计数!!!? 抱歉我的英语不好。

你说的是在 Modelsim 上的模拟 "works correctly",但没有具体说明你是如何定义的 "correctly"。我模拟了它,但没有发生任何有趣的事情:cnt 保持在 4'bx,因为你没有初始化它的机制。我想你打算 cntsig 的每个上升沿递增。如果您初始化 cnt(请参阅注释掉的代码),则会发生这种情况:

https://www.edaplayground.com/x/4zXf

但是,虽然可以综合此代码,但这不是 同步 设计,因此它综合起来毫无意义(一个加法器和四个锁存器)。假设您确实需要 cntsig 的每个上升沿递增,您需要同步递增此设计 :

always @(posedge sig)
    cnt <= cnt + 1;

这将合成一个加法器和四个 D 型触发器。

重置计数器是正常的,否则在真实硬件中计数器将具有未知值(因此模拟中的 4'bx)。您可以在 FPGA 中初始化 cnt

reg [3:0] cnt = 4'b0;

但您可能需要考虑使用重置信号:

always @(posedge sig, posedge reset)
  if(reset) 
    cnt <= 4'b0;  // or some other reset value
  else
      cnt <= cnt + 1;

我为你的命名感到困扰sig;大多数人会称之为 clkclock 或类似的东西。这个名字表明您可能不熟悉 同步设计。如果是这样,您应该了解这一点并且还应该阅读此答案 here.