System Verilog:为什么信号的非阻塞初始化会发生模拟/综合不匹配?

问题描述 投票:0回答:2

在 VHDL 世界中,在时钟进程中,将信号初始化为默认值,然后根据需要覆盖它(通过 IF 或 CASE 语句)是很常见的。我想在 Verilog 中使用相同的技术,但被告知这可能会出现问题。

考虑这个示例代码:

  always_ff @(posedge sys_ref_clk or negedge rst_n)
    if (~rst_n) begin
      mstate <= STATE1;
      mysig <= '0;
    end else begin
      mysig <= '0;
      case (mstate)
        STATE1 : begin
          if (go) begin
            mstate <= STATE2;
          end
        end
        STATE2 : begin
          mysig <= '1;
          mstate <= STATE3;
        end
        STATE3 : begin
          mstate <= STATE1;
        end
      endcase
    end

在这里,我希望 STATE2 导致

mysig
变为 1,所有其他状态导致 mysig 变为 0。我不想在 STATE1 和 STATE3 中键入
mysig <= '0;
,所以我只设置一个默认值并且只覆盖它处于STATE2。

在VHDL中,以上是我多年来成功使用的技术。但有人告诉我,在 Verilog 中,这可能很危险——特别是因为非阻塞分配可能导致低效或不正确的硬件结构,特别是在用于初始化时。我还被告知,综合工具和模拟工具之间的非阻塞分配可能会有不同的解释。

那么上面的

mysig
初始化真的是危险的Verilog吗?它模拟得很好。除了(明显的,IMO)它的预期方式之外,综合工具还可以用什么其他方式来解释它?

verilog system-verilog
2个回答
0
投票

我不认为上述内容有问题。当提到进程中的行为时,“最后的分配获胜”对于 VHDL 和 Verilog 来说很常见。只要您对同步进程使用 nb 分配,并对组合进程使用阻塞,就应该没问题。我在 case 语句之前对驱动程序使用了状态机样式,这样您就不需要在所有状态下指定一个值。在 Vivado 中工作时没有错误或警告。

Verilog 有一个

initial
处理块,它可能会也可能不会用于设置初始值,具体取决于综合工具以及您想要执行的操作。请参阅您所针对的特定部件系列的综合指南,了解它将如何处理
initial
块。

对于 Verilog

initial
块中的赋值等前卫结构(指综合),问题可能成为供应商可移植性之一。一个供应商可能支持该构造,而另一个供应商可能不支持。因此,使用这种风格进行编码存在风险。


0
投票

使用这种 Verilog 编码风格可以保证按照您的预期进行仿真(对于遵守当前 IEEE Std 1800 的仿真软件)。最后一个非阻塞分配获胜。

我见过综合工具和 RTL linting 工具会生成类似于“多个非阻塞分配”的警告消息。我不记得具体原因了,但指导是更改代码以避免这种情况。

我建议您在 Verilog 代码中避免这种做法。

这不是一种常见的做法,因此,它可能会使其他人更难理解设计。如果我在

case
之前看到第一个作业,我不会期望在
case
中看到另一个作业。

© www.soinside.com 2019 - 2024. All rights reserved.