如何解决为什么我会收到推断闩锁错误?
我正在尝试使用 FSM 在 System Verilog 中创建自动售货机,在合成期间,软件警告我此错误:
[Synth 8-327] 为变量推断锁存器 '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
赋值。
但是,例如,当 statoProssimo
为 0 时,块不会为 Switch50
赋值。因此,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,S10: if (Confirm) statoProssimo = S0;
default statoProssimo = S0;
endcase
end
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。