Always_comb 中的 SystemVerilog“if”语句“不是纯粹的组合逻辑”错误

Geo*_*ler 4 if-statement system-verilog

我很困惑!并且有点沮丧。我花了相当多的时间在 Modelsim 中研究一些 SystemVerilog。我已经达到了可以在我的硬件上测试它的某个阶段,但是在 Quartus 中编译不成功。我确实知道这可能会发生,但在这种情况下我的错误似乎没有意义。

下面的代码位于always_comb 块内。当我编译时,出现以下错误:

Error (10166): SystemVerilog RTL Coding error at fifo_interface.sv(80): always_comb construct does not infer purely combinational logic.
Run Code Online (Sandbox Code Playgroud)

我实在不明白这个。这是代码,它只是一个复用器。

always_comb
    if(fifo_select == 0)
    begin
        fifo0_data_in = data_in;
        fifo0_in_clk = in_clk;
        fifo0_in_dn = in_dn;
        in_rdy = fifo0_in_rdy;

        fifo1_in_clk = 0;   //Prevent 'in_clk' entering fifo1
    end

    else
    begin
        if(fifo_select == 1)
        begin
            fifo1_data_in = data_in;
            fifo1_in_dn = in_dn;
            fifo1_in_clk = in_clk;
            in_rdy = fifo1_in_rdy;

            fifo0_in_clk = 0;   //Prevent 'in_clk' entering fifo0
        end 
    end
end
Run Code Online (Sandbox Code Playgroud)

当我将块更改为“始终”时,Modelsim 会表现得很奇怪。它会破坏代码,或者会与退出代码 211 一起崩溃。将类型更改回“always_comb”并不能解决问题,因此我必须重新启动 modelsim 才能成功模拟 HDL。

我很想知道错误的根源是什么?

谢谢你的帮助。

ngu*_*rie 6

您没有分配多路复用器的所有分支中的所有输出。例如,fifo0_data_in如果 则被分配fifo_select == 0。但如果fifo_select == 1那样的话它就没有价值了。这意味着fifo0_data_in如果发生变化,需要记住它的价值是什么fifo_select。因此,综合将推断出该输出的锁存器。

这就是我认为你想要的:

always_comb
    if(fifo_select == 0)
    begin
        fifo0_data_in = data_in;
        fifo1_data_in = '0;
        fifo0_in_clk = in_clk;
        fifo1_in_clk = '0;
        fifo0_in_dn = in_dn;
        fifo1_in_dn = '0;
        in_rdy = fifo0_in_rdy;
    end

    else
    begin
        fifo1_data_in = data_in;
        fifo0_data_in = '0;
        fifo1_in_clk = in_clk;
        fifo0_in_clk = '0;
        fifo1_in_dn = in_dn;
        fifo0_in_dn = '0;
        in_rdy = fifo1_in_rdy;
    end
end
Run Code Online (Sandbox Code Playgroud)

而且,由于您似乎将时钟门控到未使用的 FIFO,因此您可以进一步简化,如下所示:

assign fifo0_data_in = data_in;
assign fifo1_data_in = data_in;
assign fifo0_in_dn = in_dn;
assign fifo1_in_dn = in_dn;

always_comb
    if(fifo_select == 0)
    begin
        fifo0_in_clk = in_clk;
        fifo1_in_clk = '0;
        in_rdy = fifo0_in_rdy;
    end

    else
    begin
        fifo0_in_clk = '0;
        fifo1_in_clk = in_clk;
        in_rdy = fifo1_in_rdy;
    end
end
Run Code Online (Sandbox Code Playgroud)