有时我会在Xilinx ISE中收到警告:
可以从不完整的case或if语句生成锁存器。我们的确是 不建议尽可能使用FPGA / CPLD设计中的锁存器 导致计时问题。
但是如果我使用rising_edge()函数,那么即使我的案例不完整也没有警告,例如:
process (clk, rst)
begin
if (rst = '1') then
test <= '0';
elsif (rising_edge(clk)) then
test <= '1';
end if;
end process;
那么为什么FPGA中的锁存器被认为是一种丑陋的设计呢?为什么使用rising_edge()函数可以避免这些警告? (事实上,我认为使用rising_edge()函数也会引入一个锁存器)
答案 0 :(得分:3)
在任何一种情况下,(锁存或寄存器;没有或带有rising_edge(clk))不完整的IF或CASE表示需要存储,以保持信号的当前值。
所以rising_edge(clk)函数并没有真正改变电路的逻辑,它只是清理它的时序。具体来说,它允许综合工具在任何地方放置一个需要锁存器的时钟寄存器。
这通常被视为一件好事,因为FPGA和大多数其他技术都支持时钟寄存器(触发器)。它们是具有可预测时序的构建模块,对于快速可靠的设计至关重要。
锁存器(“透明锁存器”)具有较不可靠的时序,使时序分析更加困难,因此FPGA通常不能很好地支持它们,并且不鼓励使用它们(尽管ASIC设计人员可以非常谨慎地成功使用它们)
所以rising_edge()并不完全“避免警告” - 它会设置一个安全寄存器而不是可能不可靠的锁存器,从而避免了潜在的时序问题。
答案 1 :(得分:1)
使用rising_edge(clk)
会导致边缘敏感的顺序设计元素,它是一个触发器,而不是锁存器。如果状态更新的条件是级别敏感的,则会生成锁存,例如en = '1'
。
FPGA针对基于上升沿敏感触发器的同步设计的实现进行了优化,例如来自Xilinx的一些FPGA技术,如果使用锁存器则限制资源利用率。此外,通常更难以确保基于锁存器的设计的正确时序约束。
因此,如果出于某些特定原因需要使用锁存器,并且在大多数设计中,即使是大型设计,也应该没有锁存器。
答案 2 :(得分:1)
由于您的问题已经得到解答,我只想在闩锁设计上添加一些注意事项。
闩锁不是“丑陋的设计”,虽然如果你在基本的网站上阅读,每个人似乎都认为相反。锁存器设计的一个最大问题是它们无法在FPGA上实现,因为FPGA设计用于触发器。 FPGA通常用于测试代码,大多数设计人员不喜欢编写两次代码(一个用于FPGA,一个用于ASIC)。此外,锁存器设计更复杂,因为您至少需要两个时钟相位(主从),但您也可以拥有更多相位。另一方面,良好的锁存设计可以比FF设计更好,特别是对于低功耗设计:不需要固定保持时间,转换时间有较少的约束等等。
无论如何,有一件事情应该是明确的:如果你不是一个对低功耗技术感兴趣的ASIC设计师,你就可以只用触发器来生活。