首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FPGA系统中的同步与异步重设

FPGA系统中的同步与异步重设
EN

Stack Overflow用户
提问于 2015-12-03 13:27:15
回答 3查看 2.5K关注 0票数 0

我刚开始创建一个FPGA系统来驱动I2C总线(尽管我认为这个问题适用于任何FPGA系统),使用各种不同的模块,这些模块都使用同步复位。

该模块使用时钟分频器模块进行时钟锁定,该分频器模块获取系统时钟,并将较低的频率输出到系统的其余部分。

我遇到的问题是,当复位信号变低时,分频器会重置,因此其他模块依赖于停止的时钟-因此其他模块不会注册重置。

一个明显的解决方案是异步重置,然而,在Xilinx中,它似乎不喜欢它们,并发出警告说这与Spartan-6FPGA不兼容(特别是当异步代码后的代码是同步的,这是因为I2C总线使用总线时钟将位放入总线上)。

另一种解决方案是,时钟分配器根本无法复位,因此时钟永远不会停止,所有模块都会正确地重置。然而,这意味着时钟分配器寄存器不能初始化/重新初始化到一个已知的状态--我被告知这将是一个大问题,尽管我知道您可以在模拟中使用:= '0'/'1';操作符,但是这在实际的FPGA(?)上编程后就不能工作了。

同步重置的约定是什么?时钟发生器一般不会重置吗?或者它们只在复位信号的瞬时边缘重置?或者我的建议都不是真正的解决方案!

我提供了一个时序图以及我的代码来说明我的意思,并展示我一直在使用的代码。

非常感谢!

大卫

代码语言:javascript
复制
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library UNISIM;
use UNISIM.VComponents.all;
ENTITY CLK_DIVIDER IS
    GENERIC(INPUT_FREQ : INTEGER;
            OUT1_FREQ  : INTEGER;
            OUT2_FREQ  : INTEGER
    );
    PORT(SYSCLK  : IN  STD_LOGIC;
         RESET_N : IN  STD_LOGIC;
         OUT1    : OUT STD_LOGIC;
         OUT2    : OUT STD_LOGIC);
END CLK_DIVIDER;
architecture Behavioral of Clk_Divider is
    constant divider1 : integer   := INPUT_FREQ / OUT1_FREQ / 2;
    constant divider2 : integer   := INPUT_FREQ / OUT2_FREQ / 2;
    signal counter1   : integer   := 0;
    signal counter2   : integer   := 0;
    signal output1    : std_logic := '0';
    signal output2    : std_logic := '0';
begin
    output1_proc : process(SYSCLK)
    begin
        if rising_edge(SYSCLK) then
            if RESET_N = '0' then
                counter1 <= 0;
                output1  <= '1';
            else
                if counter1 >= divider1 - 1 then
                    output1  <= not output1;
                    counter1 <= 0;
                else
                    counter1 <= counter1 + 1;
                end if;
            end if;
        end if;
    end process;
    output2_proc : process(SYSCLK)
    begin
        if rising_edge(SYSCLK) then
            if RESET_N = '0' then
                counter2 <= 0;
                output2  <= '1';
            else
                if counter2 >= divider2 - 1 then
                    output2  <= not output2;
                    counter2 <= 0;
                else
                    counter2 <= counter2 + 1;
                end if;
            end if;
        end if;
    end process;
    OUT1 <= output1;
    OUT2 <= output2;
end Behavioral;
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-12-03 14:25:51

不要生成具有用户逻辑的内部时钟,但是如果确实需要多个时钟,则使用特定于设备的PLL/DCM。然后,在导出时钟上运行的所有用户逻辑都应该保持复位状态,直到时钟稳定为止,然后根据设计的要求,可以释放对用户逻辑的重置。可以使用同步复位或异步复位。

但在这种情况下,可能会生成时钟启用信号,并在每次需要更新信号时断言该启用信号为单个周期,以便生成所需的任何协议,例如具有适当定时的I2C协议。

使用较少的时钟,再加上同步时钟启用信号,可以简化静态时序分析(STA)的设置,同时也避免了重置同步和时钟域交叉(CDC)的问题。

票数 4
EN

Stack Overflow用户

发布于 2015-12-04 14:59:46

在这样的系统中,一种处理重置的健壮方法如下:

使用Xilinx FPGA中的DCM/PLL/MMCM处理输入系统时钟并生成所需的所有输出时钟频率,同时考虑到真正的低频,您应该在时钟管理器的规范范围内使用一个时钟,并生成一个与之结合使用的时钟启用信号。这可以在启动时从主机系统重置,或者如果在任何时候输入时钟被移除,然后重新应用。

反转来自时钟管理器的锁定信号,以便在复位时或在锁定到输入端的过程中产生活动的高复位。这应该通过SRL16或SRL32来延迟。这个SRL应该与PLL的输出一起时钟,当它被放在一个BUFG的全局时钟路由上之后。在SRL之后使用额外的触发器来改进计时。然后,该信号可用作对所需设备中的逻辑的其余部分的主动高同步复位。

如果在时钟上出现计时错误,因为它是高扇形网络,那么也可以通过BUFG来访问快速的全球时钟网络来提高定时。

票数 3
EN

Stack Overflow用户

发布于 2015-12-06 23:50:39

@斯图尔特·维维安

(这应该作为评论发布,但我没有足够的声誉点来这么做,对此我很抱歉)

考虑使用计数器而不是移位寄存器来延迟重置,因为如果在加载比特流之后没有清除LUT内容(一些FPGA家族具有这种行为),重置信号可能会反弹,导致不可预测的结果。

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

https://stackoverflow.com/questions/34067276

复制
相关文章

相似问题

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