【问题标题】:How to act on both signal (communication clock) edges in VHDL?如何作用于 VHDL 中的两个信号(通信时钟)边沿?
【发布时间】:2020-04-23 11:01:08
【问题描述】:

我想知道什么是“最好的”或至少是“好”的方式来实现一个同时作用于总线或通信时钟上的进程。

假设您想提供一个可以发送和接收数据的 FiFo。通常,接收到的数据在其总线“com_clk”的“下降”沿分配,其中发送的数据需要在“com_clk”的上升沿更新,以便在对方分配数据时最稳定下降沿。

对于这种情况,我可以想到多种实现方式,但我无法评估它们在硬件使用、鲁棒性或综合性方面的“好”程度,而且我通常也不知道看起来像这样的好资源.

我的方法看起来像这样,当然是通常的框架:

方法一:

wait until rising_edge(com_clk);
  if reading='1' then 
    wait until com_clk='0';
    internal_mem <= bus_data;  --read the data from the bus
  else
    bus_data <= internal_mem ; --write the data to the bus
  end if;

方法二:

wait until rising_edge(sys_clk);   --should be much faster than "clk" i guess about 10x(?)
  if reading='1' then 
    wait until com_clk='0';        --wait for the com_clk to become '0'
    internal_mem <= bus_data;      --read the data from the bus
  else
    wait until com_clk='1';        --wait for the com_clk to become '1'
    bus_data <= internal_mem ;     --write the data to the bus
  end if;

解决方案 2 的派生是为“com_clk”构建一个边缘检测器,并将该信号用于“等待”或“if 子句”。 那么,什么是对 com_clk 信号的两个边缘起作用的“好”或“最佳”方法,我如何自己评估呢?

【问题讨论】:

  • "通常接收到的数据在其总线 "com_clk" 的 "下降" 沿被分配,而发送出去的数据需要在 "com_clk" 的上升沿被更新 " 不,那是不寻常的。通常情况下,一切都从一个时钟沿开始。两个边沿上的时钟不会为您带来任何好处,因为您不妨将一个边沿与两倍快的时钟一起使用。优点是您的时钟不必精确到 50/50。
  • 我很确定我现在已经在几个应用笔记中读到了这一点,它在信噪比方面很有意义。在数据变化的同时记录数据并不是一个好主意。
  • 这不是一个 VHDL 问题,而是一个设计问题。您可以在 VHDL 中很好地在两个边缘上计时。它只是不可能将它映射到 FPGA(甚至它是一个 asic,而不是你编码的方式)。以 2 倍速率进行时钟是非常正常的 - 然后您在时序规范中设置时钟数据时序,以确保您保持正确的建立/保持时间要求。
  • 假设您正在尝试实现类似 UART 的功能?在通常的 FPGA 实现中,此类功能不是由时钟直接触发,而是由用作使能的派生信号触发。 FPGA 通常没有能够在两个时钟边沿触发的硬件。
  • @Tricky 我只关心 VHDL 中的实现,所以我想说这个问题只是关于 VDHL,我不想在两个边缘都计时,问题的核心真的是如何让我的解决方法。当我正确地将 sys_clk 频率提高到至少两倍于 com_clk 时,为 com_clk 构建两个边缘检测器,然后根据边缘检测器状态选择一个动作将是一种选择。我如何确保建立/保持时间,这些是我的架构还是可配置参数的结果?

标签: vhdl


【解决方案1】:

您实际上想在 FPGA 上实现双倍数据速率。

可怕的方式:你可以做两个过程,一个在上升沿工作,一个在下降沿工作。这可能会或可能不会合成,具体取决于您的技术,它可能会或可能不会合成以使用硬件触发器。

坏方法:你不能同时使用时钟和上升沿。您基本上在这里使用两个时钟域。如果你的时机不对,你可能会得到亚稳态。您将需要在这里执行通常的亚稳态处理电路。

更好的方法:生成较慢的时钟。从时钟创建上升沿和下降沿脉冲。这些脉冲将被馈送到触发器的启用端口。

【讨论】:

  • 谢谢。所以你的前两种方式,坏的对我来说也很糟糕。如果只是因为我对 VHDL / FPGA 的了解有限,我不敢做一些异步或冒着亚稳态风险的事情。我的代码很快就会出现故障:(你更好的方法本质上是一个边缘检测器,一个说两位移位寄存器查看 com_clk 并在它看到“01”或“10”时设置“falling_bit”和“rising_bit”。进程时钟有那么至少比 com_clk 快两倍,我做对了吗?
  • 边缘检测有几种方法。我喜欢注册信号时钟->clockR。然后对于 fEdgePulse,如果时钟 = 0 和时钟 R = 1。根据奈奎斯特速率,是至少两次。
  • 谢谢,您的回答对我很有帮助。您能向我推荐一些涵盖该主题的文献吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多