首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无延迟的锁存信号

无延迟的锁存信号
EN

Stack Overflow用户
提问于 2012-09-29 19:21:34
回答 3查看 2.7K关注 0票数 1

我想锁存一个信号,但是当我尝试这样做时,我得到了一个周期的延迟,我如何避免这种情况?

代码语言:javascript
复制
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初学者)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-09-29 23:00:59

首先,对您在上面粘贴的过程有一些观察:

代码语言:javascript
复制
myLatch: process(wclk, we)
begin
  if wclk'event and wclk = '1' then
    lwe    <= we;
  end if;
end process;

  1. 信号,我们可以从灵敏度列表中省略,因为您已经描述了一个时钟过程。在这样一个进程的灵敏度列表中,唯一需要的信号就是时钟和异步重置(同步重置不需要添加到灵敏度列表中)。
  2. 您应该使用if wclk'event and wclk = '1' then而不是if rising_edge(wclk) thenif falling_edge(wclk) then,有一篇很好的博客文章介绍了为什么使用like

通过省略wclk'event,您可以将进程从时钟进程更改为组合进程,如下所示:

代码语言:javascript
复制
myLatch: process(wclk, we)
begin
  if wclk = '1' then
    lwe    <= we;
  end if;
end process;

在组合过程中,所有输入都应该出现在敏感度列表中,因此在列表中同时包含wclkwe将是正确的,因为它们对输出有影响。通常,您将确保在if语句的所有情况下都分配lwe,以避免推断闩锁,但在这种情况下,这似乎是您的意图。

一般情况下应该避免闩锁,所以如果您发现自己需要一个闩锁,您可能应该停下来考虑一下您的方法。Doulos有几篇关于闩锁、herehere的文章,您可能会发现它们很有用。

您说过,您要实现的所有目标是在wclk的上升沿对we进行采样,并使其保持稳定,直到下一个上升沿。下面的过程将实现这一点:

代码语言:javascript
复制
  store : process(wclk)
  begin
    if rising_edge(wclk) then
      lwe <= we;
    end if;
  end process;

通过此过程,lwe将在wclk的每个上升沿使用we的值进行更新,并且它将在单个时钟周期内保持有效。

如果这能帮你理清头绪,请告诉我。

票数 2
EN

Stack Overflow用户

发布于 2012-09-29 23:01:31

VHDL通常用于同步硬件设计--也就是说,使用在上升沿采样并在下降沿设置输出的触发器,以便在读取和写入之间没有竞争条件。但在VHDL中,这种主/从逻辑实际上并不是使用相反的时钟边沿来模拟的。

考虑一个过程

代码语言:javascript
复制
process (clock) begin
    if rising_edge(clock) then
        a <= b;
    end if;
end process;

在模拟时间步长开始时,如果clock刚刚上升,则将执行if。然后将执行分配a <= b,这不会立即导致分配发生,但会在时间步结束时安排分配。

在所有进程都运行之后,所有计划的分配都会发生。这意味着在下一个时间步之前,没有进程会“看到”a的新值。

代码语言:javascript
复制
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的值的上升沿。

票数 2
EN

Stack Overflow用户

发布于 2012-10-01 19:05:13

根据您的描述,您拥有的流程就是您想要的流程,尽管应该从敏感度列表中删除'we‘。如果这不能像你认为的那样工作,那几乎可以肯定是你的测试平台/模拟出了问题。(参见Owen的回答。)具体地说,您可能更改'we‘的值太晚了,以便触发器锁存以前的值,而不是新值。

我很想知道这个信号的来源是什么,如果它是一个可以随时改变的异步信号,你必须添加一些逻辑来防止亚稳态。

为了回答你关于闩锁的第二个问题,省略wclk‘’event将导致闩锁是正确的。然而,这个过程不会做你想做的事情,因为它会在整个时钟的正半周期内将更改传播到'we‘到'lwe’。对您的问题的简短回答是,实现这种类型的行为需要锁存器,而原始进程描述的行为需要触发器。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12652255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档