SystemVerilog:always_comb 构造不推断纯组合逻辑

SystemVerilog: always_comb construct does not infer purely combinational logic

我有这个 FSM 可以控制我正在构建的游戏中的不同事件(在 Quartus Prime Lite Edition 17.0 中)。 当我尝试编译它时,出现此错误:

Error (10166): SystemVerilog RTL Coding error at GameFSM.sv(40): always_comb construct does not infer purely combinational logic.

我已将所有输出分配为默认值,因此我相信不应推断出锁存器(我不完全理解它是如何工作的..)。

    //Game FSM, controls the game events

module GameFSM (
    input logic clk, resetN, NPCCollisions, Dead_NPCs, start_game, pause_game, continue_game, delay_indicator,

    output logic Message_main_menu,
    output logic Message_pause,
    output logic Message_win,
    output logic Message_lose,
    output logic Display_Main_Menu,
    output logic MainMenu_Music,
    output logic BackGround_Music, 
    output logic Paused,
    output logic Win_Music,
    output logic Lose_Music
   );

enum logic [2:0] {main_Menu, three_hearts, two_hearts, one_heart, delay_state, pause, win, lose} prState, nxtState;

logic [1:0] return_state;

always @(posedge clk or negedge resetN)
  begin

    if ( !resetN ) begin // Asynchronic reset
        prState <= main_Menu;
    end

    else    begin   // Synchronic logic FSM
        prState <= nxtState;
    end

end // always

always_comb // Update next state and outputs
    begin
        nxtState = prState; // default values 
        Message_main_menu = 1'b0;
        Message_pause = 1'b0;
        Message_win = 1'b0;
        Message_lose = 1'b0;
        MainMenu_Music = 1'b0;
        BackGround_Music = 1'b0;
        Paused = 1'b0;
        Win_Music = 1'b0;
        Lose_Music = 1'b0;
        Display_Main_Menu = 1'b0;

        case (prState)

            main_Menu: begin
                Message_main_menu = 1'b1;
                MainMenu_Music = 1'b1;
                Display_Main_Menu = 1'b1;
                if(start_game)
                    nxtState = three_hearts; 
            end

            three_hearts: begin
                BackGround_Music = 1'b1;
                return_state = 2'h3;
                if(NPCCollisions) //Corony hits an npc while he has 3 hearts left
                    nxtState = delay_state;
                else if(Dead_NPCs) //all npc's are dead
                    nxtState = win;
                else if(pause_game)
                    nxtState = pause;
            end

            two_hearts: begin
                BackGround_Music = 1'b1;
                return_state = 2'h2;
                if(NPCCollisions) //Corony hits an npc while he has 2 hearts left
                    nxtState = delay_state;
                else if(Dead_NPCs) //all npc's are dead
                    nxtState = win;
                else if(pause_game)
                    nxtState = pause; 
            end

            one_heart: begin
                BackGround_Music = 1'b1;
                return_state = 2'h1;
                if(NPCCollisions) //Corony lost all his hearts
                    nxtState = lose;
                else if(Dead_NPCs) //all npc's are dead
                    nxtState = win;
                else if(pause_game)
                    nxtState = pause;
            end

            delay_state: begin
                if(delay_indicator) begin
                    if(return_state == 2'h3)
                        nxtState = two_hearts;
                    else if(return_state == 2'h2)
                        nxtState = one_heart;
                end
            end

            pause: begin
                Paused = 1'b1;
                Message_pause = 1'b1;
                if(continue_game) begin
                    if(return_state == 2'h3)
                        nxtState = three_hearts;
                    else if(return_state == 2'h2)
                        nxtState = two_hearts;
                    else
                        nxtState = one_heart;
                end
            end

            win: begin
                Win_Music = 1'b1;
                Message_win = 1'b1;
            end

            lose: begin
                Lose_Music = 1'b1;
                Message_lose = 1'b1;
                end 



            endcase
    end // always comb

endmodule

return_state 用于让我知道哪个状态将我传送到 pause 状态,所以当我想离开 pause 状态时,我知道我应该去哪里return到.

问题是您读取并分配给 always_comb 块内的 counter 信号:

                counter = counter - 1;

这可以创建一个组合反馈回路。

同样适用于:

                counter = DELAY_TIME;

也许您应该为 counter 使用顺序逻辑:always @(posedge clk ...)

另一个问题信号可能是 return_state。我不确定为什么我的模拟器不抱怨这个。我认为 return_state 也应该在它自己的顺序逻辑块中分配。