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
也应该在它自己的顺序逻辑块中分配。
我有这个 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
也应该在它自己的顺序逻辑块中分配。