赞
踩
数字电路基础知识——锁存器与触发器在Verilog中使用问题
锁存器与触发器
一般数字电路中说D触发器指的是边沿D触发器,钟控D触发器其实就是D锁存器,边沿D触发器才是真正的D触发器,钟控D触发器在使能情况下输出随输入变化,边沿触发器只有在边沿跳变的情况下输出才变化。
这里一般用的最多的触发器的结构是以用CMOS传输门构成的D触发器:
常见的锁存器包括三个端口:数据输入口、数据输出口、使能端。当使能端为高电平时,输入口的数据直接送到输出口,此时输入输出口可以看成是直接连通的;当使能端为低电平时,输出口的数据保持之前的数据不变,无论输入口的数据怎么变化,输出都保持不变,就是把原来的状态锁存下来了(所以才叫锁存器)。锁存器与触发器的区别在于:锁存器是电平触发,而触发器是边沿触发。锁存器在不锁存数据时,输出随输入变化;但一旦数据锁存时,输入对输出不产生任何影响。
锁存器与其所有的输入信号相关,当输入信号变化时锁存器就变化,没有时钟端;触发器受时钟控制,只有在时钟触发时才采样当前的输入,产生输出。
锁存器由电平触发,非同步控制。在使能信号有效时锁存器相当于通路,在使能信号无效时锁存器保持输出状态。触发器由时钟沿触发,同步控制。
锁存器对输入电平敏感,受布线延迟影响较大,很难保证输出没有毛刺产生;触发器则不易产生毛刺。
两个锁存器可以构成一个触发器,归根到底还是dff是边沿触发的,而latch是电平触发的。
总结下锁存器的主要缺点:
(1)对毛刺敏感,不能异步复位,因此在上电后处于不确定的状态。
(2)锁存器会使静态时序分析变得非常复杂,不具备可重用性。 (首先, 锁存器没有时钟参与信号传递,无法做 STA;其次,综合工具会将 latch 优化掉,造成前后仿真结果不一致)
(3)在 PLD 芯片中,基本的单元是由查找表和触发器组成的,若生成锁存器反而需要更多的资源。根据锁存器的特点可以看出,在电路设计中,要对锁存器特别谨慎,如果设计经过综合后产生出和设计意图不一致的锁存器,则将导致设计错误,包括仿真和综合。因此,在设计中需要避免产生意想不到的锁存器。
由于always块可以表示时序逻辑或者组合逻辑,也可以用always块既表示电平敏感的透明锁存器又同时表示组合逻辑。但不推荐使用这种描述方法,因为这容易产生错误和多余的电平敏感的透明锁存器。这在电路中是尽量避免发生的。
因此在使用Verilog中极易产生锁存器的情况有如下几种:
module combination(a,b,c);
input a,b,c;
reg e,d;
always @(a or b or c) begin //d信号没有在敏感信号列表中,综合时会产生一个透明的锁存器 会锁存d
e =d & a & b;
end
endmodule
解决办法:
上面的代码片段,极容易出现透明的电平敏感锁存器,可以使用always(*)或者assign语句赋值。
module combination(a,b,c);
input a,b,c;
reg e,d;
always @(*) begin
e =d & a & b;
end
// assign e = d & a & b;
endmodule
对于上面生成锁存器的组合逻辑电路可以
修改如下:
module dff(q,enable,data);
input data,enable;
output q;
reg q;
always@(enable or data) begin
if (enable)
q <= data;
else
q<= 0;
end
endmodule
其RTL电路:(2MUX)
2)时序逻辑中,即使case语句不完整,在综合时,会生成一个触发器,并不会生成锁存器。
4. 即使if-else 语句完整并且是组合逻辑电路一定不会生成锁存器吗?
答案是否定的
例如:锁存器的Verilog描述:
module dff(q,sel,data);
input data;
input sel;
output q;
reg q;
always@(*) begin // 锁存器的定义描述
if(sel)
q = data;
else
q = q;
end
endmodule
综合出的RTL电路:
仍然会得到一个锁存器
if/else文件是完整,但是依然产生了锁存器,因为我们这个电路所描述的功能就是一个锁存器。其实语句不完整和else data_out=data_out;是一样的。这里,所希望的就是保持数值,但这种情况可以通过增加一个寄存器来保持,也不应该生成一个锁存器。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。