昨天在跑fpga的时候出现了这个错误。今天就来好好的谈一谈这个错误是什么意思。
首先先补充几个概念,在Verilog中,reg型变量会形成一个类似于寄存器的单元。当reg出现在always语句中时,他会根据always的条件来生成对应的寄存器类型
module sample
(
input a1,
input a2,
output b1
);
reg b1;
reg b2;
reg c1;
always @( negedge a1 or posedge a2) begin
b1 <= a1;
end
always @( a1) begin
b2 <= a1;
end
endmodule
上面代码中,
第一个always是沿触发,所以b1会被综合成一个沿触发的寄存器
第二个always是电平触发,所以b2会被综合成一个电平触发的寄存器。
下面谈一下上面那个报错,先放报错代码
module sample
(
input a1,
input a2,
output b1
);
reg b1;
reg b2;
reg c1;
always @( negedge a1 or posedge a2) begin
if(c1) begin
b1 <= a1;
end
end
endmodule
Logic for b1 does not match a standard flip-flop
这句报错的意思是b1没有匹配一个标准的触发器。从上面的代码中我们可以看到,问题在于,在上升沿触发的always里面用到了一个电平信号的if,而且这个电平信号没有在always的敏感列表里面。
通俗的说就是,你if的条件既不是always的触发条件,还不是一个沿信号,这让综合软件很为难。
改正的方法也很简单,可以将c1添加到always的敏感条件里,也可以把c1换成a1或者a2
module sample
(
input a1,
input a2,
output b1
);
reg b1;
reg b2;
reg c1;
always @( negedge a1 or posedge a2 or posedge c1) begin
if(c1) begin
b1 <= a1;
end
end
always @( negedge a1 or posedge a2 or negedge c1) begin
if(c1) begin
b2 <= a1;
end
end
endmodule
上面是两种改代码的思路,第一种加了一个posedge,通过,第二种加了negedge,失败。下面就分析一下第二种改法失败的原因,也就是这个报错的第二个可能性,逻辑冲突。
第二个改法,虽然把c1添加到了always的敏感列表里面,但是,always是c1的下降沿触发,而下面的if是c1等于1的时候执行。从逻辑上来说,c1下降沿的时候,c1不可能是高电平,从程序的角度,它综合了个寂寞。这个问题有时候很直观,就像第二个always,有时候很隐蔽,因为always里面可以很复杂。大家要仔细排查,出现这个报错基本上就是这两个原因了。