我有两个进程A和B,每个进程都有自己的时钟输入。
时钟频率略有不同,因此不同步。
处理A从IC采样数据,这些数据需要传递给进程B,进程B需要将此数据写入另一个IC。
我目前的解决方案是在流程A和流程B之间使用一些简单的握手信号。 内存已在进程A(非块内存)中声明为分布式RAM(128Bytes作为std_logic_vector数组(7 downto 0))。
我正在使用Xilinx的Spartan 3AN和ISE Webpack。
但这是正确的方法吗?
我在某处看到Spartan 3有双端口块存储器支持两个时钟,所以这会更正确吗?
我问的原因是因为我的设计行为不可预测,在这种情况下我只是讨厌魔术。 : - )
答案 0 :(得分:5)
除了非常特殊的例外情况,在两个独立时钟域之间移动数据的唯一正确方法是使用异步FIFO(也称为多速率FIFO)。
在几乎所有的FPGA(包括您正在使用的Xilinx器件)中,您都可以使用供应商创建的FIFO - 在Xilinx的情况下,您可以使用CoreGen工具生成自己的FIFO。
你也可以使用双端口RAM和适当的握手逻辑自己构建这样的FIFO,但是像大多数事情一样,除非你有充分的理由这样做,否则你不应该自己重新发明。
您还可以考虑您的设计是否真的需要多个时钟域。有时这绝对是必要的,但是,与大多数刚开始相信的人相比,这种情况要少得多,很多。例如,即使您需要以多种速率运行的逻辑,您也可以通过使用单个时钟和适当生成的同步时钟来实现此目的。
答案 1 :(得分:1)
您遇到的魔力很可能是因为您没有在合成中正确约束您的设计,或者您没有正确地完成握手。您有两种选择:
使用wjl所述的多速率FIFO,这是一种非常常见的解决方案,始终有效(正确完成时)并且在资源方面是巨大的。此解决方案的一大优点是您不必关心实际的时钟域交叉问题,并且您将获得两个域之间的最大带宽。永远不要尝试在VHDL中建立异步FIFO,因为这不起作用;甚至在VHDL中也有一些你根本做不到的事情;使用Xilinx的相应生成器,我认为是CoreGen
在两个域中至少有两个数据寄存器,并构建一个完整的请求/确认握手逻辑,如果不包含这些寄存器,它将无法正常工作。通过在接收域中为握手信号添加至少两个寄存器,确保握手逻辑正确同步,否则由于亚稳态问题,您很可能会有不可预测的行为。
答案 2 :(得分:1)
要获得跨时钟域的“有效/确认”标记集,您可能希望查看the Flancter和here's an application of it
但在一般情况下,使用双时钟FIFO是一天的顺序。编写自己的将是一个有趣的练习,但验证所有潜在的时钟计时案例是一场噩梦。这是我将实例化Coregen块的少数几个地方之一。