Verilog写状态机报错
[Synth 8-327] inferring latch for variable ‘FSM_sequential_NS_reg’ [“E:/LPC_draft/8_20_FSM_test/LPC_FSM_new/lpc_fsm/lpc_fsm.srcs/sources_1/new/lpc_wr.v”:248]
解决方法:
- if-else 和case-default必须配套
- 若组合逻辑中含有状态输出,该状态中需要的信号都要赋一次初值。前辈的做法是状态机中要赋值的信号在每个状态都要赋值,简单粗暴,我的做法是该状态用了什么信号赋初值就可以,也解决了问题,如data_cnt_flag、data_wr_en。如果某个信号你想在两三个状态中都用到,那每个状态都要给一次初值,满足条件后再改变值。
- 如果还是报错,检查next_state、current_state 是否赋初值了(一般为IDLE状态或FORCE_RESET)。
Verilog Code Example:
DATA:begin//DMA16bit、32bit跳转较复杂//5
data_cnt_flag = 1'b1;
lpc_rd_st = 1'b0;
data_wr_en = 1'b0;
if ( lframe_n )begin
data_cnt_flag = 1'b1;
data_wr_en = 1'b0;
data_rd_en = 1'b0 ;
size_cnt_pro = 1'b0;
if ((!cycle_type[2]) && cycle_type[0])begin//IO写
data_wr_en = 1'b1 ;
data_cnt_flag= 1'b1;
if (data_cnt_done) begin
NS = TAR1_1;
data_cnt_flag = 1'b0;
end
else NS = DATA;
end
else if ((!cycle_type[2]) && (!cycle_type[0]))begin//IO读
data_cnt_flag = 1'b1;
data_rd_en = 1'b1 ;
lpc_rd_st = 1'b1;
if (data_cnt_done) begin
NS = TAR2_1;
data_cnt_flag = 1'b0;
end
else NS = DATA;
end
else if(cycle_type[2] && (!cycle_type[0]))begin //DMA读(CPU写)
data_wr_en = 1'b1 ;
data_cnt_flag= 1'b1;
if (data_cnt_done) begin
NS = TAR1_1;
data_cnt_flag = 1'b0;
end
else NS = DATA;
end
else if (cycle_type[2] && cycle_type[0]) begin //DMA写(CPU读)
data_cnt_flag = 1'b1;
data_rd_en = 1'b1 ;
lpc_rd_st = 1'b1;
if (data_cnt_done) begin
if (size_cnt != 3'd0) begin
NS = SYNC;
data_cnt_flag = 1'b0;
size_cnt_pro = 1'b1;
end
else begin
NS = TAR2_1;
data_cnt_flag = 1'b0;
end
end
else NS = DATA;
end
end
else NS = IDLE;
end