我想锁存一个信号,但是当我尝试这样做时,我得到了一个周期的延迟,我如何避免这种情况?
myLatch: process(wclk, we) -- Can I ommit the we in the sensitivity list?
begin
if wclk'event and wclk = '1' then
lwe <= we;
end if;
end process;但是,如果我尝试这样做,并在模拟过程中查看波,lwe会延迟一个wclk周期。我想要实现的就是在wclk的上升沿采样we,并使其保持稳定,直到下一个上升沿。然后,我将锁存的信号分配给架构中定义的另一个实体端口映射。
==============================================
好吧,我想我必须省略wclk'event来获得一个锁存器而不是触发器。这在我看来是相当不直观的。通过简单地缩短我对要锁存的信号进行采样的时间,我从一个锁存器转到另一个触发器。有没有人能解释为什么会这样,以及我的看法哪里错了。(我是vhdl初学者)
发布于 2012-09-29 23:00:59
首先,对您在上面粘贴的过程有一些观察:
myLatch: process(wclk, we)
begin
if wclk'event and wclk = '1' then
lwe <= we;
end if;
end process;if wclk'event and wclk = '1' then而不是if rising_edge(wclk) then或if falling_edge(wclk) then,有一篇很好的博客文章介绍了为什么使用like通过省略wclk'event,您可以将进程从时钟进程更改为组合进程,如下所示:
myLatch: process(wclk, we)
begin
if wclk = '1' then
lwe <= we;
end if;
end process;在组合过程中,所有输入都应该出现在敏感度列表中,因此在列表中同时包含wclk和we将是正确的,因为它们对输出有影响。通常,您将确保在if语句的所有情况下都分配lwe,以避免推断闩锁,但在这种情况下,这似乎是您的意图。
一般情况下应该避免闩锁,所以如果您发现自己需要一个闩锁,您可能应该停下来考虑一下您的方法。Doulos有几篇关于闩锁、here和here的文章,您可能会发现它们很有用。
您说过,您要实现的所有目标是在wclk的上升沿对we进行采样,并使其保持稳定,直到下一个上升沿。下面的过程将实现这一点:
store : process(wclk)
begin
if rising_edge(wclk) then
lwe <= we;
end if;
end process;通过此过程,lwe将在wclk的每个上升沿使用we的值进行更新,并且它将在单个时钟周期内保持有效。
如果这能帮你理清头绪,请告诉我。
发布于 2012-09-29 23:01:31
VHDL通常用于同步硬件设计--也就是说,使用在上升沿采样并在下降沿设置输出的触发器,以便在读取和写入之间没有竞争条件。但在VHDL中,这种主/从逻辑实际上并不是使用相反的时钟边沿来模拟的。
考虑一个过程
process (clock) begin
if rising_edge(clock) then
a <= b;
end if;
end process;在模拟时间步长开始时,如果clock刚刚上升,则将执行if。然后将执行分配a <= b,这不会立即导致分配发生,但会在时间步结束时安排分配。
在所有进程都运行之后,所有计划的分配都会发生。这意味着在下一个时间步之前,没有进程会“看到”a的新值。
Time a b Actions
Start of ts 1 '0' '1' a <= '1' is scheduled
End of ts 1 '1' '0' a <= '1' is executed
Start of ts 2 '1' '0' a <= '0' is scheduled
End of ts 2 '0' '1' a <= '0' is executed因此,当您查看波形查看器时,您将看到a显然被设置在时钟的上升沿,并且在b之后延迟了一个时钟周期;您看不到导致这种情况发生的中间赋值调度。
当然,在现实生活中,没有“时间步长的结束”,而信号a的实际变化发生在触发器的从属部分触发时,即在负边沿上。(对于VHDL来说,仅仅使用负边缘可能不会那么令人困惑;但是,哦,好吧,这就是它的工作方式)。
这里有两个用于您的锁存代码的测试台:
在第一个例子中,如果你看一下波形查看器,你会看到你所描述的-- lwe看起来延迟了一个时钟周期--但实际上,延迟发生在设置counter的非阻塞赋值中--所以当上升沿发生时,we实际上还没有它的新值。在第二个示例中,您看不到这样的延迟;lwe恰好设置在当时we的值的上升沿。
发布于 2012-10-01 19:05:13
根据您的描述,您拥有的流程就是您想要的流程,尽管应该从敏感度列表中删除'we‘。如果这不能像你认为的那样工作,那几乎可以肯定是你的测试平台/模拟出了问题。(参见Owen的回答。)具体地说,您可能更改'we‘的值太晚了,以便触发器锁存以前的值,而不是新值。
我很想知道这个信号的来源是什么,如果它是一个可以随时改变的异步信号,你必须添加一些逻辑来防止亚稳态。
为了回答你关于闩锁的第二个问题,省略wclk‘’event将导致闩锁是正确的。然而,这个过程不会做你想做的事情,因为它会在整个时钟的正半周期内将更改传播到'we‘到'lwe’。对您的问题的简短回答是,实现这种类型的行为需要锁存器,而原始进程描述的行为需要触发器。
https://stackoverflow.com/questions/12652255
复制相似问题