always_comb 构造并不推断纯粹的组合逻辑

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

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

错误 (10166):GameFSM.sv(40) 处的 SystemVerilog RTL 编码错误:always_comb 构造不能推断纯粹的组合逻辑。

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

//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
状态时,我就知道应该返回到哪里。

compilation verilog system-verilog quartus
1个回答
1
投票

问题是您读取并分配给

counter
块旁边的
always_comb
信号:

                counter = counter - 1;

这可以创建组合反馈循环。

同样适用于:

                counter = DELAY_TIME;

也许你应该对

counter
使用顺序逻辑:
always @(posedge clk ...)

另一个问题信号可能是

return_state
。我不知道为什么我的模拟器不抱怨这个。我认为
return_state
也应该分配在它自己的顺序逻辑块中。

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