为什么我会收到推断闩锁错误?
Why am I getting an inferring latch error?
我正在尝试使用 FSM 在 System Verilog 中创建一个自动售货机,在综合过程中,软件警告我这个错误:
[Synth 8-327] inferring latch for variable
'FSM_sequential_statoProssimo_reg' ["MacchinettaMerendine.sv":87]
密码是:
...
module FSM_50_Cent (
input logic Clk100_MHz, Reset,
input logic Cent20, Cent50, Euro1, Confirm,
input logic [7:0] Switch50,
output logic Er, r10, r20, r40, r50
);
enum logic [4:0] {S0, S1, S2, S3, S4, S5, S6, S7, S8, S9,
S10, S11, S12, S13, S14, S15, S16, S17} Stati; //STATES
logic [4:0] Stato, statoProssimo; //STATE AND NEXTSTATE
always_ff @(posedge Clk100_MHz, posedge Reset) //FLIP FLOP
begin
if(Reset) Stato <= S0;
else Stato <= statoProssimo;
end
always_comb //NEXT STATE LOGIC
begin
if((|Switch50) == 1)
begin
case(Stato)
S0: if (Cent20) statoProssimo = S1;
else if (Cent50) statoProssimo = S3;
else if (Euro1) statoProssimo = S8;
else if (Confirm) statoProssimo = S0;
S1: if (Cent20) statoProssimo = S2;
else if (Cent50) statoProssimo = S5;
else if (Euro1) statoProssimo = S9;
else if (Confirm) statoProssimo = S1;
S2: if (Cent20) statoProssimo = S4;
else if (Cent50) statoProssimo = S7;
else if (Euro1) statoProssimo = S10;
else if (Confirm) statoProssimo = S2;
S3: if (Confirm) statoProssimo = S0;
S4: if (Confirm) statoProssimo = S0;
S5: if (Confirm) statoProssimo = S0;
S6: if (Confirm) statoProssimo = S0;
S7: if (Confirm) statoProssimo = S0;
S8: if (Confirm) statoProssimo = S0;
S9: if (Confirm) statoProssimo = S0;
S10: if (Confirm) statoProssimo = S0;
default statoProssimo = S0;
endcase
end
end
...
endmodule
...
错误在这一行:S0: if (Cent20) statoProssimo = S1;
为什么?
为避免闩锁,always_comb
块必须在所有条件下为 statoProssimo
赋值。
但是,例如,当 Switch50
为 0 时,块不会为 statoProssimo
赋值。因此Verilog仿真会保留statoProssimo
的值。这推断出一个存储元素(一个锁存器)。
您可以添加一个 else
子句并分配一个值。例如:
always_comb //NEXT STATE LOGIC
begin
if((|Switch50) == 1)
begin
case(Stato)
...
endcase
end
else statoProssimo = S0;
end
这同样适用于每个 case
项目。您应该使用 else
子句来赋值。
S0: if (Cent20) statoProssimo = S1;
else if (Cent50) statoProssimo = S3;
else if (Euro1) statoProssimo = S8;
else statoProssimo = S0;
您需要决定在每种情况下分配什么值。
浏览答案的工具解释并查看此代码的 always_comb
部分。
module FSM_50_Cent (
input logic Clk100_MHz, Reset,
input logic Cent20, Cent50, Euro1, Confirm,
input logic [7:0] Switch50,
output logic Er, r10, r20, r40, r50
);
typedef enum logic [4:0] {S0, S1, S2, S3, S4, S5, S6, S7, S8, S9,
S10, S11, S12, S13, S14, S15, S16, S17} Stati; //STATES
Stati Stato, statoProssimo; //STATE AND NEXTSTATE
//STATE FLIP FLOPS
always_ff @(posedge Clk100_MHz, posedge Reset)
if(Reset) Stato <= S0;
else Stato <= statoProssimo;
//NEXT STATE LOGIC
always_comb begin
statoProssimo = Stato;
if((|Switch50) == 1)
case(Stato)
S0: if (Cent20) statoProssimo = S1;
else if (Cent50) statoProssimo = S3;
else if (Euro1) statoProssimo = S8;
else if (Confirm) statoProssimo = S0;
S1: if (Cent20) statoProssimo = S2;
else if (Cent50) statoProssimo = S5;
else if (Euro1) statoProssimo = S9;
else if (Confirm) statoProssimo = S1;
S2: if (Cent20) statoProssimo = S4;
else if (Cent50) statoProssimo = S7;
else if (Euro1) statoProssimo = S10;
else if (Confirm) statoProssimo = S2;
S3,S4,
S5,S6,
S7,S8,
S9,S10: if (Confirm) statoProssimo = S0;
default statoProssimo = S0;
endcase
end
我正在尝试使用 FSM 在 System Verilog 中创建一个自动售货机,在综合过程中,软件警告我这个错误:
[Synth 8-327] inferring latch for variable 'FSM_sequential_statoProssimo_reg' ["MacchinettaMerendine.sv":87]
密码是:
...
module FSM_50_Cent (
input logic Clk100_MHz, Reset,
input logic Cent20, Cent50, Euro1, Confirm,
input logic [7:0] Switch50,
output logic Er, r10, r20, r40, r50
);
enum logic [4:0] {S0, S1, S2, S3, S4, S5, S6, S7, S8, S9,
S10, S11, S12, S13, S14, S15, S16, S17} Stati; //STATES
logic [4:0] Stato, statoProssimo; //STATE AND NEXTSTATE
always_ff @(posedge Clk100_MHz, posedge Reset) //FLIP FLOP
begin
if(Reset) Stato <= S0;
else Stato <= statoProssimo;
end
always_comb //NEXT STATE LOGIC
begin
if((|Switch50) == 1)
begin
case(Stato)
S0: if (Cent20) statoProssimo = S1;
else if (Cent50) statoProssimo = S3;
else if (Euro1) statoProssimo = S8;
else if (Confirm) statoProssimo = S0;
S1: if (Cent20) statoProssimo = S2;
else if (Cent50) statoProssimo = S5;
else if (Euro1) statoProssimo = S9;
else if (Confirm) statoProssimo = S1;
S2: if (Cent20) statoProssimo = S4;
else if (Cent50) statoProssimo = S7;
else if (Euro1) statoProssimo = S10;
else if (Confirm) statoProssimo = S2;
S3: if (Confirm) statoProssimo = S0;
S4: if (Confirm) statoProssimo = S0;
S5: if (Confirm) statoProssimo = S0;
S6: if (Confirm) statoProssimo = S0;
S7: if (Confirm) statoProssimo = S0;
S8: if (Confirm) statoProssimo = S0;
S9: if (Confirm) statoProssimo = S0;
S10: if (Confirm) statoProssimo = S0;
default statoProssimo = S0;
endcase
end
end
...
endmodule
...
错误在这一行:S0: if (Cent20) statoProssimo = S1;
为什么?
为避免闩锁,always_comb
块必须在所有条件下为 statoProssimo
赋值。
但是,例如,当 Switch50
为 0 时,块不会为 statoProssimo
赋值。因此Verilog仿真会保留statoProssimo
的值。这推断出一个存储元素(一个锁存器)。
您可以添加一个 else
子句并分配一个值。例如:
always_comb //NEXT STATE LOGIC
begin
if((|Switch50) == 1)
begin
case(Stato)
...
endcase
end
else statoProssimo = S0;
end
这同样适用于每个 case
项目。您应该使用 else
子句来赋值。
S0: if (Cent20) statoProssimo = S1;
else if (Cent50) statoProssimo = S3;
else if (Euro1) statoProssimo = S8;
else statoProssimo = S0;
您需要决定在每种情况下分配什么值。
浏览答案的工具解释并查看此代码的 always_comb
部分。
module FSM_50_Cent (
input logic Clk100_MHz, Reset,
input logic Cent20, Cent50, Euro1, Confirm,
input logic [7:0] Switch50,
output logic Er, r10, r20, r40, r50
);
typedef enum logic [4:0] {S0, S1, S2, S3, S4, S5, S6, S7, S8, S9,
S10, S11, S12, S13, S14, S15, S16, S17} Stati; //STATES
Stati Stato, statoProssimo; //STATE AND NEXTSTATE
//STATE FLIP FLOPS
always_ff @(posedge Clk100_MHz, posedge Reset)
if(Reset) Stato <= S0;
else Stato <= statoProssimo;
//NEXT STATE LOGIC
always_comb begin
statoProssimo = Stato;
if((|Switch50) == 1)
case(Stato)
S0: if (Cent20) statoProssimo = S1;
else if (Cent50) statoProssimo = S3;
else if (Euro1) statoProssimo = S8;
else if (Confirm) statoProssimo = S0;
S1: if (Cent20) statoProssimo = S2;
else if (Cent50) statoProssimo = S5;
else if (Euro1) statoProssimo = S9;
else if (Confirm) statoProssimo = S1;
S2: if (Cent20) statoProssimo = S4;
else if (Cent50) statoProssimo = S7;
else if (Euro1) statoProssimo = S10;
else if (Confirm) statoProssimo = S2;
S3,S4,
S5,S6,
S7,S8,
S9,S10: if (Confirm) statoProssimo = S0;
default statoProssimo = S0;
endcase
end