我最近被告知,在VHDL合成期间解决所有(大多数)非预期锁存器的问题是将任何有问题的信号放在记录中。
这似乎有点太好了,但是我不是那么有经验的VHDL,所以可能还有其他一些我不考虑的事情。
我应该将所有信号记录在记录中吗?
答案 0 :(得分:4)
不,你不应该将所有信号都记录在案。这将很快变得非常混乱,你不会通过使用记录获得任何东西。
记录可以帮助您避免锁存的一种方法是,如果您在时钟进程中注册整个记录,那么您实际上是在注册记录的所有组件。这需要一行代码,而不是几十行。如果您有许多需要同等对待的元素,记录可以为您节省“愚蠢的错误”,并可能使您无法创建锁定。
正如其他人所说,记录没有任何具体的综合解释。它只是一组信号,您为了方便编码而将它们组合在一起。
答案 1 :(得分:2)
我不知道这会有什么帮助 - 记录(甚至只是记录的一部分)可以像信号一样容易地成为锁存器。如果信号通过某个组合过程保持其状态(即,在整个过程的所有路径上没有分配值),则产生锁存器。对于记录的成员也是如此。
记录可用于将相关信号分组以便于阅读,但综合记录几乎等同于一堆单独的信号。
我个人建议避免锁存:避免组合过程。使所有进程都计时,并在架构级别进行组合逻辑。
答案 2 :(得分:1)
记录只是对其他类型进行分组的另一种方式,类似于使用数组
用于将std_logic
分组为std_logic_vector
,因此没有任何内容
关于记录的神奇之处,使它们更好地避免设计中的锁存器。
如果你的设计中出现意外的锁扣,我想你会想到的 “锁存问题”,这是因为你的编码风格指定了锁存器,而你 应该改变编码风格,正如@zennehoy所暗示的那样。
一种方法可以是为不同的结构定义一些代码模板 你使用,然后坚持这些已知和工作模板。
具有异步复位的触发器(FF)的模板可以是:
process (clk_i, rst_i) is
begin
-- Clock
if rising_edge(clk_i) then
... Control structures with Qs assign by function for Ds
... Synchronous reset is just another branch
end if;
-- Reset (asynchronous) if required
if rst_i = '1' then
... Qs assign with constant reset value for so or all Qs
end if;
end process;
尽可能使用并发信号分配,更复杂的表达式可以 通过使用并发函数调用来完成,其中使用函数 在以下过程之外:
z_o <= fun(a_i, b_i);
如果一个过程用于创建组合逻辑,那么常见的陷阱和
VHDL中锁存器的原因是忘记灵敏度列表中的信号。
但是,VHDL-2008有一个解决方案,因为您可以使用(all)
灵敏度列表,其中过程中使用的所有信号都是隐含的
包含在敏感性列表中。因此,如果您使用VHDL-2008,那么您的模板
对于组合过程可以是:
process (all) is
begin
z_o <= a_i and b_i;
end process;
这些模板应该是典型的可合成设计所需要的,而且 这些将保持你的设计锁定。