今天在写I2C接口,分析和综合代码时,出现了一个以前没见过或者很少见的警告,这里记录一下:
先看代码:
//设备地址
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
device_addr_a <= {4'b1010,device_addr,1'b0};
end
else if(wr_flag) begin
device_addr_a <= {4'b1010,device_addr,1'b0};
end
else if(rd_flag) begin
device_addr_a <= {4'b1010,device_addr,1'b1};
end
else begin
device_addr_a <= {4'b1010,device_addr,1'b0};
end
end
警告:
Warning (13004): Presettable and clearable registers converted to equivalent circuits with latches. Registers power-up to an undefined state, and DEVCLRn places the registers in an undefined state.
Warning (13310): Register "device_addr_a[2]" is converted into an equivalent circuit using register "device_addr_a[2]~_emulated" and latch "device_addr_a[2]~1"
Warning (13310): Register "device_addr_a[1]" is converted into an equivalent circuit using register "device_addr_a[1]~_emulated" and latch "device_addr_a[1]~5"
Warning (13310): Register "device_addr_a[3]" is converted into an equivalent circuit using register "device_addr_a[3]~_emulated" and latch "device_addr_a[3]~9"
在这个警告中,大体意思是:可预置且可清除的寄存器已转换为带锁存器的等效电路。
意思反正是生成了锁存器,打架都知道,FPGA设计中要尽量避免锁存器,防止占用过多资源,影响电路稳定。
原因:
代码中在复位时将这个信号给了一个特定的寄存数据,电路复位时,应该将信号清零或者预置确定的常数。
解决:
将复位下的信号改成确定值:
//设备地址
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
device_addr_a <= 0;
end
else if(wr_flag) begin
device_addr_a <= {4'b1010,device_addr,1'b0};
end
else if(rd_flag) begin
device_addr_a <= {4'b1010,device_addr,1'b1};
end
else begin
device_addr_a <= {4'b1010,device_addr,1'b0};
end
end
这样,重新编译就不会再出错。