寄存器组与latch的问题?
时间:10-02
整理:3721RD
点击:
大家帮忙看一下,我这个程序在综合时老是说产生了latch,请问如何修改?感激不尽~
其中frame_20为一个宽度为8,深度为20的寄存器组。
always @ (*)
begin
next_state <= idle;
if(!rst_n)
begin
b_full_reg <= 1'b0;
led_flag <= 1'b0;
des <= 8'd0;
res <= 8'd0;
datatype <= 8'd0;
send_en <= 1'b0;
addr<=8'b00000000;
end
else
begin
b_full_reg <= 1'b0;
led_flag <= 1'b0;
res <= frame_20[0];
des <= frame_20[1];
datatype <= frame_20[2];
send_en <= 1'b0;
case(state)
idle:
begin
if(ri_cnt==5'd20)
begin
b_full_reg <= 1'b1;
next_state <= select_do;
end
else if(ri_posedge)
begin
frame_20[ri_cnt]<=datain;
next_state <= idle;
end
else
begin
send_en <= 1'b0;
b_full_reg <= 1'b0;
led_flag <= 1'b0;
next_state <= idle;
end
end
select_do:
begin
if(des == 8'h01)
begin
case (res)
TWO:
begin
addr<=8'b00101100; //44
next_state <= pro_frame;
end
THREE:
begin
case(datatype)
d_one:
begin
addr<=8'b01000010; //66
next_state <= pro_frame;
end
d_two:
begin
led_flag<=1'b1;
next_state <= pro_led_w;
end
default
begin
addr<=8'b00000000;
led_flag<=1'b0;
next_state <= pro_frame;
end
endcase
end
FOUR:
begin
addr<=8'b01011000; //88
next_state <= pro_frame;
end
default
begin
addr<=8'b00000000; //0
next_state <= pro_frame;
end
endcase
end
else
begin
next_state <= idle;
led_flag <= 1'b0;
addr<=8'b00000000;
end
end
pro_led_w:
if(led_on_neg)
begin
next_state <= idle;
b_full_reg <= 1'b0;
led_flag <= 1'b0;
addr <= addr+8'b0;
end
else
begin
b_full_reg <= 1'b1;
led_flag <= 1'b1;
next_state <= pro_led_w;
addr <= addr+8'b0;
end
pro_frame:
begin
send_en <= 1'b1;
next_state <= pro_frame_w;
addr <= addr+8'b0;
end
pro_frame_w:
begin
addr <= addr+8'b0;
if(ti_22_pos)
begin
next_state <= idle;
b_full_reg <= 1'b0;
addr <= addr+8'b0;
end
else
begin
next_state <= pro_frame_w;
b_full_reg <= 1'b1;
if(ti_posedge & send_en)
addr <= addr+8'b1;
else addr <= addr+8'b0;
end
end
default
begin
next_state <= idle;
addr <=8'b00000000;
b_full_reg <= 1'b0;
led_flag <= 1'b0;
des <= 8'd0;
res <= 8'd0;
datatype <= 8'd0;
send_en <= 1'b0;
end
endcase
end
end
出错的警告信息为:
frame_20[0],frame_20[1],frame_20[2]和addr四个地方均产生了latch,怎么修改啊 ?
其中frame_20为一个宽度为8,深度为20的寄存器组。
always @ (*)
begin
next_state <= idle;
if(!rst_n)
begin
b_full_reg <= 1'b0;
led_flag <= 1'b0;
des <= 8'd0;
res <= 8'd0;
datatype <= 8'd0;
send_en <= 1'b0;
addr<=8'b00000000;
end
else
begin
b_full_reg <= 1'b0;
led_flag <= 1'b0;
res <= frame_20[0];
des <= frame_20[1];
datatype <= frame_20[2];
send_en <= 1'b0;
case(state)
idle:
begin
if(ri_cnt==5'd20)
begin
b_full_reg <= 1'b1;
next_state <= select_do;
end
else if(ri_posedge)
begin
frame_20[ri_cnt]<=datain;
next_state <= idle;
end
else
begin
send_en <= 1'b0;
b_full_reg <= 1'b0;
led_flag <= 1'b0;
next_state <= idle;
end
end
select_do:
begin
if(des == 8'h01)
begin
case (res)
TWO:
begin
addr<=8'b00101100; //44
next_state <= pro_frame;
end
THREE:
begin
case(datatype)
d_one:
begin
addr<=8'b01000010; //66
next_state <= pro_frame;
end
d_two:
begin
led_flag<=1'b1;
next_state <= pro_led_w;
end
default
begin
addr<=8'b00000000;
led_flag<=1'b0;
next_state <= pro_frame;
end
endcase
end
FOUR:
begin
addr<=8'b01011000; //88
next_state <= pro_frame;
end
default
begin
addr<=8'b00000000; //0
next_state <= pro_frame;
end
endcase
end
else
begin
next_state <= idle;
led_flag <= 1'b0;
addr<=8'b00000000;
end
end
pro_led_w:
if(led_on_neg)
begin
next_state <= idle;
b_full_reg <= 1'b0;
led_flag <= 1'b0;
addr <= addr+8'b0;
end
else
begin
b_full_reg <= 1'b1;
led_flag <= 1'b1;
next_state <= pro_led_w;
addr <= addr+8'b0;
end
pro_frame:
begin
send_en <= 1'b1;
next_state <= pro_frame_w;
addr <= addr+8'b0;
end
pro_frame_w:
begin
addr <= addr+8'b0;
if(ti_22_pos)
begin
next_state <= idle;
b_full_reg <= 1'b0;
addr <= addr+8'b0;
end
else
begin
next_state <= pro_frame_w;
b_full_reg <= 1'b1;
if(ti_posedge & send_en)
addr <= addr+8'b1;
else addr <= addr+8'b0;
end
end
default
begin
next_state <= idle;
addr <=8'b00000000;
b_full_reg <= 1'b0;
led_flag <= 1'b0;
des <= 8'd0;
res <= 8'd0;
datatype <= 8'd0;
send_en <= 1'b0;
end
endcase
end
end
出错的警告信息为:
frame_20[0],frame_20[1],frame_20[2]和addr四个地方均产生了latch,怎么修改啊 ?
这个状态机 我看看
小编好
always @ (*) 变化一次就会对代码判断一次 当(!rst_n)==1时会做清0操作,如果(!rst_n)==0 状态idle中是不是要给addr赋值下吧 (如果跳入idle状态中,由于这个状态里没有对addr赋值,那会生成个latch对addr数据保存下的)
frame_20[0],frame_20[1],frame_20[2]这3个信号 是输入信号吗? 这3个信号产生latch的原因也类似。
楼上说的对
没怎么看懂。
frame_20 在除了idle状态外没有被赋值
综合工具就认为是保持原值,由于你写的是组合逻辑,这就产生latch了
在default 里面赋值就可以了
1# verilog20090412
补充一下 你写的是组合逻辑建议使用 阻塞赋值“=”
1. 搞清楚时序与组合没有?
2. 搞清阻塞与非阻塞没有?
3. 看看 “极品非车10” 的回复
4. 写状态机不建议这样写,只关心状态就可以了,不要把其他逻辑引入
5. 最好不要把rst引入到组合逻辑中
不要用always @ (*)。
用 always @(posedge clk or negedge rst_n) 就好了。
程序太长
没有仔细看
在程序最前面(begin后)给出现Latch的信号附初值就好了
要搞清楚出现latch的原因:
一般是在组合逻辑中没有完整的赋值
比如If后没有else(只在If中赋值,没有在else中赋值)
或case中没有Default或others
好复杂~
第一句就有问题,太长不想细看,
always @ (*),你到底是要生产组合逻辑还是时序逻辑?
