首先:从代码功能角度出发,如果是因为少些了else等语句造成功能性错误,那么代码本身就有问题。
其次:从目标器件来看,是FPGA开发还是ASIC开发。如果For ASIC,那么在保证功能正确的前提下,代码风格是推荐不写else等语句的,目的就是为了综合后生成锁存器,减少芯片面积。如果是For FPGA,那么推荐if,case语句要完整。这是为了避免产生一些不必要的时序问题
先分析四段代码:
//组合逻辑生成latch实例
always @(*)
begin
if (en)
dataout = datain;
end
上述代码描述的电路为组合逻辑,会生成一个锁存器。因为组合逻辑电路中没有存储元件,只能通过锁存器来保持数据。
//组合逻辑避免生成latch实例
always @(*)
begin
if (en)
dataout = datain;
else
dataout = 1'b0;
end
// 时序逻辑即使条件语句没有说明全部,也不会产生锁存器?
always @(posedge clk)
begin
if (en)
dataout <= datain;
end
可以看出来会生成一个锁存器:由触发器和连线构成
always @(posedge clk)
begin
if (en)
dataout <= datain;
else
dataout <= 1'b0;
end
较上图,少了一条反馈连线,不生成锁存器。
为什么要避免产生锁存器?
一般地,我们认为锁存器对毛刺敏感。但是,我们再考虑下,在组合电路中,即便语句完整没有生成锁存器,也会有竞争和冒险的存在,其它逻辑元件也会对毛刺敏感,有时也会产生我们不希望看到的结果。
如果加一个时钟变为时序电路,即便语句不完整,产生了锁存器(其实在时序电路中,即便语句不完整,也不会产生锁存器,只是具备锁存功能),那么也不会对毛刺敏感。
其实,考虑到FPGA的构成,FPGA内部是基于LUT和寄存器的,根本没有锁存器这种东西,也就是说,如果你产生了锁存器的话,将耗费更多的资源来构成它。另外,还有一个原因就是不利于时序路径的分析,以及后端设计的实现。
最最重要的一点,如果不是要真的需要锁存的功能,仅是因为代码风格问题(不写else)而导致电路中出现锁存器或者类似功能的逻辑,那么其本身就是一个功能错误!
为什么说时序电路中,即使语句不完整,也不会产生锁存器?
时序逻辑中,要锁存数据,优先用触发器来完成。触发器由FPGA内部的可编程寄存器组成,具有使能端。使能无效时,数据保持不变,有锁存数据的功能。
个人理解:
综合后的逻辑电路图,其中时序电路确实没有生成狭义上的锁存器(LDCE),而是用FDRE和逻辑连线实现了锁存器的功能。