【Xilinx FPGA】异步 FIFO 的复位

FIFO(First-In-First-Out,先入先出)是一种的存储器类型,在 FPGA 开发中通常用于数据缓存、位宽转换或者跨时钟域(多 bit 数据流)。在使用异步 FIFO 时,应注意复位信号是否遵循相关要求和规范,避免数据丢失或损坏。本文主要介绍 Xilinx FPGA 对异步 FIFO 复位的时序要求,并参考 IP 核示例工程设计异步 FIFO 的复位逻辑。

目录

1 复位类型

2 异步 FIFO 的复位


1 复位类型

        Xilinx FIFO Generator 提供了复位端口,用于复位计数器与输出寄存器。有两种复位的类型:同步复位(Synchronous Reset)和异步复位(Asynchronous Reset)。

        对于同步复位方式,由于复位信号已经是同步的,因此无需设计额外的同步逻辑。

The asynchronous reset (rst) input asynchronously resets all counters, output registers, and memories when asserted. When reset is implemented, it is synchronized internally to the core with each respective clock domain for setting the internal logic of the FIFO to a known state. This synchronization logic allows for proper timing of the reset logic within the core to avoid glitches and metastable behavior.

        对于异步复位方式,复位信号会分别被同步到读/写时钟域,同步逻辑确保 FIFO 正确复位,避免“毛刺”或者亚稳态。

        

        异步复位应遵循以下 2 个设计规则:

(1)复位必须在所有时钟有效时进行,否则 FIFO 的状态无法预测;

(2)复位信号的脉宽至少为 3 个慢时钟周期。

        在复位期间,应避免对 fifo 进行读写操作,以防止数据丢失或损坏。在复位完成后,需要等待一段时间才能对 fifo 进行读写操作。

        开启 Safety Circuit 的 FIFO,复位释放之后需至少等待 60 个慢时钟周期。

        未开启 Safety Circuit 的 FIFO,复位释放之后需至少等待 30 个慢时钟周期。

2 异步 FIFO 的复位

        打开 IP 核自带的 Example Design,参考激励文件异步 FIFO 的复位逻辑。

        在 reset 释放之后 50 个写周期,释放 reset_ext 信号。reset 连接到 FIFO 的异步复位端口,reset_ext 则用于读/写控制逻辑的复位。

        在 Example Design 的顶层文件中,将 reset_ext 信号分别同步到读/写时钟域。这里不知道是不是参考工程的错误,rst_async_rd1 ~ rst_async_rd3 使用了同步复位,同步释放的方式。

        以下是根据参考工程,自己设计的异步 FIFO 的复位控制逻辑。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity eth_rx_adjust is
   port(
      -- System level
      nRst                : in std_logic;
      sysclk              : in std_logic;

      -- GMII IN data port
      --gmii_rxd_rxctl    : in std_logic_vector(9 downto 0);
      --gmii_rxc          : in std_logic;
      eth_phy_rxd         : in std_logic_vector(7 downto 0);
      eth_phy_rxdv        : in std_logic;
      eth_phy_rxc         : in std_logic;

      -- eth_rx data
      eth_rxd_sys         : out std_logic_vector(7 downto 0);
      eth_rxdv_sys        : out std_logic
   );
end entity;
architecture behav of eth_rx_adjust is
-- internal component and signal declarations
component fifo_8bit_2048 is
   port(
      din                 : in std_logic_vector(7 downto 0);
      wr_en               : in std_logic;
      wr_clk              : in std_logic;
      full                : out std_logic;
      dout                : out std_logic_vector(7 downto 0);
      rd_en               : in std_logic;
      rd_clk              : in std_logic;
      empty               : out std_logic;
      rst                 : in std_logic;
      wr_data_count       : out std_logic_vector(10 downto 0);
      rd_data_count       : out std_logic_vector(10 downto 0)
   );
end component;

signal reset              : std_logic := '1';
signal reset_cnt          : std_logic_vector(5 downto 0) := (others => '0');
signal reset_ext_cnt      : std_logic_vector(5 downto 0) := (others => '0');
signal RESET_EXT          : std_logic := '1';
signal rst_async_wr1      : std_logic := '1';
signal rst_async_wr2      : std_logic := '1';
signal rst_async_wr3      : std_logic := '1';
signal rst_async_rd1      : std_logic := '1';
signal rst_async_rd2      : std_logic := '1';
signal rst_async_rd3      : std_logic := '1';
signal rst_int_wr         : std_logic := '1';
signal rst_int_rd         : std_logic := '1';

signal eth_fifo_wdata     : std_logic_vector(7 downto 0);
signal eth_fifo_wrreq     : std_logic;
signal eth_fifo_empty     : std_logic;
signal eth_fifo_rcnt      : std_logic_vector(10 downto 0);
signal eth_fifo_rdreq     : std_logic;
signal eth_fifo_rdata     : std_logic_vector(7 downto 0);
signal eth_fifo_rdvld     : std_logic;

attribute ASYNC_REG: string;
attribute ASYNC_REG of rst_async_wr1: signal is "true";
attribute ASYNC_REG of rst_async_wr2: signal is "true";
attribute ASYNC_REG of rst_async_wr3: signal is "true";

attribute ASYNC_REG of rst_async_rd1: signal is "true";
attribute ASYNC_REG of rst_async_rd2: signal is "true";
attribute ASYNC_REG of rst_async_rd3: signal is "true";

---------------------------------------------------------
begin
---------------------------------------------------------

process(nRst,eth_phy_rxc) 
begin
   if nRst = '0' then
      reset_cnt <= "000000";
   elsif rising_edge(eth_phy_rxc) then
      if reset_cnt < "001000" then
         reset_cnt <= reset_cnt + '1';
      else
         reset_cnt <= reset_cnt;
      end if;
   end if;
end process;

process(nRst,eth_phy_rxc) 
begin
   if nRst = '0' then
      reset <= '1';
   elsif rising_edge(eth_phy_rxc) then
      if reset_cnt < "001000" then
         reset <= '1';
      else
         reset <= '0';
      end if;
   end if;
end process;

process(reset,eth_phy_rxc) 
begin
   if reset = '1' then
      reset_ext_cnt <= "000000";
   elsif rising_edge(eth_phy_rxc) then
      if reset_ext_cnt < "110010" then
         reset_ext_cnt <= reset_ext_cnt + '1';
      else
         reset_ext_cnt <= reset_ext_cnt;
      end if;
   end if;
end process;

process(reset,eth_phy_rxc) 
begin
   if reset = '1' then
      RESET_EXT <= '1';
   elsif rising_edge(eth_phy_rxc) then
      if reset_ext_cnt < "110010" then
         RESET_EXT <= '1';
      else
         RESET_EXT <= '0';
      end if;
   end if;
end process;

-- Asynchronous reset, synchronous release for rst_async_wr1, rst_async_wr2, rst_async_wr3
process(RESET_EXT,eth_phy_rxc) 
begin
   if RESET_EXT = '1' then
      rst_async_wr1 <= '1';
      rst_async_wr2 <= '1';
      rst_async_wr3 <= '1';
   elsif rising_edge(eth_phy_rxc) then
      rst_async_wr1 <= RESET_EXT;
      rst_async_wr2 <= rst_async_wr1;
      rst_async_wr3 <= rst_async_wr2;
   end if;
end process;

-- Asynchronous reset, synchronous release for rst_async_rd1, rst_async_rd2, rst_async_rd3
process(RESET_EXT,sysclk) 
begin
   if RESET_EXT = '1' then
      rst_async_rd1 <= '1';
      rst_async_rd2 <= '1';
      rst_async_rd3 <= '1';
   elsif rising_edge(sysclk) then
      rst_async_rd1 <= RESET_EXT;
      rst_async_rd2 <= rst_async_rd1;
      rst_async_rd3 <= rst_async_rd2;
   end if;
end process;

rst_int_wr <= rst_async_wr3;
rst_int_rd <= rst_async_rd3;

--===============================================================
-- eth_fifo_inst
eth_fifo_instx: component fifo_8bit_2048
port map(
   din             => eth_fifo_wdata     , -- in std_logic_vector(7 downto 0)
   wr_en           => eth_fifo_wrreq     , -- in std_logic
   wr_clk          => eth_phy_rxc        , -- in std_logic
   full            => open               , -- out std_logic
   dout            => eth_fifo_rdata     , -- out std_logic_vector(7 downto 0)
   rd_en           => eth_fifo_rdreq     , -- in std_logic
   rd_clk          => sysclk             , -- in std_logic
   empty           => eth_fifo_empty     , -- out std_logic
   rst             => reset              , -- in std_logic
   wr_data_count   => open               , -- out std_logic_vector(10 downto 0)
   rd_data_count   => eth_fifo_rcnt        -- out std_logic_vector(10 downto 0)
);

process(rst_int_wr,eth_phy_rxc) 
begin
   if rst_int_wr = '1' then
      eth_fifo_wdata <= (others => '0');
      eth_fifo_wrreq <= '0';
   elsif rising_edge(eth_phy_rxc) then
      eth_fifo_wdata <= eth_phy_rxd;
      eth_fifo_wrreq <= eth_phy_rxdv;
   end if;
end process;

process(rst_int_rd,sysclk) 
begin
   if rst_int_rd = '1' then
      eth_fifo_rdreq <= '0';
      eth_fifo_rdvld <= '0';
   elsif rising_edge(sysclk) then
      if eth_fifo_rcnt > 6 then
         eth_fifo_rdreq <= '1';
      elsif eth_fifo_rcnt = 1 then
         eth_fifo_rdreq <= '0';
      end if;
      eth_fifo_rdvld <= eth_fifo_rdreq;
   end if;
end process;

process(rst_int_rd,sysclk) 
begin
   if rst_int_rd = '1' then
      eth_rxd_sys <= (others => '0');
      eth_rxdv_sys <= '0';
   elsif rising_edge(sysclk) then
      eth_rxd_sys <= eth_fifo_rdata;
      eth_rxdv_sys <= eth_fifo_rdvld;
   end if;
end process;
end architecture;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/311290.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RediSearch vs. Elasticsearch vs. solr

1. RediSearch vs. Elasticsearch RediSearch是一个分布式全文搜索和聚合引擎&#xff0c;作为Redis之上的一个模块构建。它使用户能够以极快的方式在Redis数据集上执行复杂的搜索查询。RediSearch的独特架构是用C编写的&#xff0c;从头开始构建在优化的数据结构上&#xff0…

行为型模式 | 观察者模式

一、观察者模式 1、原理 观察者模式又叫做发布-订阅&#xff08;Publish/Subscribe&#xff09;模式&#xff0c;定义了一种一对多的依赖关系。让多个观察者对象同时监听某一个主题对象&#xff0c;这个主题对象在状态上发生变化时&#xff0c;会通知所有观察者对象&#xff0…

计算机网络 - 路由器查表过程模拟 C++(2024)

1.题目描述 参考计算机网络教材 140 页 4.3 节内容&#xff0c;编程模拟路由器查找路由表的过程&#xff0c;用&#xff08;目的地址 掩码 下一跳&#xff09; 的 IP 路由表以及目的地址作为输入&#xff0c;为目的地址查找路由表&#xff0c;找出正确的下一跳并输出结果。 1.…

MFC为对话框资源添加类

VC6新建一个对话框类型的工程; 建立之后资源中默认有2个对话框,一个是主对话框,About这个是默认建立的关于版权信息的; 然后主对话框有对应的.h和.cpp文件;可以在其中进行编程; 默认建立的有一个 关于 对话框; 在资源中新插入一个对话框,IDD_DIALOG1是对话框ID; 新加…

软件测试理论----测试设计方法论

1、测试用例格式 &#xff08;1&#xff09;用例编号&#xff1a;用例的唯一标识&#xff0c;要求具有易识别性和易维护性&#xff0c;能能够根据用例编号识别用例的目的和作用&#xff0c;一般格式为&#xff1a;A-B-C-D 其中 A&#xff1a;一般表示产品或者项目名称B&#…

android 9 reboot流程

机器出现开机 自动进入fastboot模式。可能是init 那个进程挂了 然后调用了 RebootSystem(ANDROID_RB_RESTART2, “bootloader”); 函数进入重启流程&#xff0c;然后重启后进入fastboot 浅读一下reboot流程和怎么进入的fastboot 比如说是那个进程挂了调用了这个函数&#xff0c…

SpringBoot默认配置文件

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringBoot ✨特色专栏: MySQL学习 🥭本文内容:SpringBoot默认配置文件 📚个人知识库: Leo知识库,欢迎大家访问 1.前言☕…

CSS3中transform2D变形详解

CSS3变形 在CSS3中&#xff0c;动画效果包括3个部分&#xff1a; 变形(transform)过渡(transition)动画(animation) 在实际开发中&#xff0c;有时需要实现元素的各种变形效果&#xff0c;如平移&#xff0c;缩放&#xff0c;旋转&#xff0c;倾斜等。 在CSS3中&#xff0c…

APP备案流程

一、 APP备案是指 自2000年起&#xff0c;依据《互联网信息服务管理办法》(国务院令第292号)规定&#xff0c;电信主管部门对从事互联网信息服务的网站开展备案核准工作(即ICP备案)。经过20多年的持续优化完善&#xff0c;已形成“电信主管部门-网络接入服务提供者-互联网信息…

数据结构之排序二叉树

排序二叉树 基本概念 二叉树是一种从上往下的树状结构的数据结构&#xff0c;从根节点开始每个节点最多有两个子节点&#xff0c;左边的为左子节点&#xff0c;右边的为右子节点。 排序二叉树–有顺序&#xff0c;且没有重复元素的二叉树。顺序为&#xff1a; 对每个节点而…

APP流量变现——4项关键指标决定了APP混合变现的收入

APP流量变现的方式有很多种&#xff0c;主要的可以分为IAA&#xff08;广告&#xff09;收入、IAP&#xff08;用户应用内付费&#xff09;收入、订阅收入、单次买断收入。这里主要围绕当前流行的混合变现模式&#xff0c;即广告收入&#xff08;IAA&#xff09;应用内付费&…

探索 hasOwnProperty:处理对象属性的关键(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

spring cloud之集成sentinel

写在前面 源码 。 本文一起看下spring cloud的sentinel组件的使用。 1&#xff1a;准备 1.1&#xff1a;理论 对于一个系统来说&#xff0c;最重要的就是高可用&#xff0c;那么如何实现高可用呢&#xff1f;你可能会说&#xff0c;集群部署不就可以了&#xff0c;但事实并…

window11后台服务优化记录

这里:\WINDOWS\xxx\svchost.exe -k netsvcs -p 信号聚合器服务&#xff0c;用于根据时间、网络、地理位置、蓝牙和 CDF 因素评估信号。支持的功能包括设备解锁、动态锁定和动态 MDM 策略 参考&#xff1a; 优化参考v1

数字化发展助力青少年阅读回归“慢节奏”

近日&#xff0c;《2024年学前及中小学生寒假分年级阅读推荐书目》发布&#xff0c;正尝试引领青少年阅读在短视频时代回归“慢节奏”。该推荐书目针对每个学龄孩子的学习特点、认知特点、心理特点进行推荐&#xff0c;旨在培养孩子的深度思考能力。 在数字化时代&#xff0c;…

Docker的介绍及安装基本操作命令

前言 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是完全使用沙箱…

K8S 存储卷

意义&#xff1a;存储卷----数据卷 容器内的目录和宿主机的目录进行挂载 容器在系统上的生命周期是短暂的&#xff0c;delete,k8s用控制器创建的pod&#xff0c;delete相当于重启&#xff0c;容器的状态也会回复到初始状态 一旦回到初始状态&#xff0c;所有的后天编辑的文件…

区间预测 | Matlab实现CNN-BiLSTM-KDE的卷积双向长短期神经网络结合核密度估计多变量时序区间预测

区间预测 | Matlab实现CNN-BiLSTM-KDE的卷积双向长短期神经网络结合核密度估计多变量时序区间预测 目录 区间预测 | Matlab实现CNN-BiLSTM-KDE的卷积双向长短期神经网络结合核密度估计多变量时序区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CNN-BiLSTM-KDE多…

显示器新赛道Type-C接口

如果把主机比作大脑&#xff0c;那显示器就是眼睛&#xff0c;没有眼睛&#xff0c;大脑再强大也发挥不出效果&#xff0c;所以显示器作为电脑最重要的输出设备&#xff0c;有着举足轻重的地位&#xff0c;可以说在生活中处处都有显示器的影子。其实显示器的历史也是科技发展史…

谈谈Spring Bean

一、IoC 容器 IoC 容器是 Spring 的核心&#xff0c;Spring 通过 IoC 容器来管理对象的实例化和初始化&#xff08;这些对象就是 Spring Bean&#xff09;&#xff0c;以及对象从创建到销毁的整个生命周期。也就是管理对象和依赖&#xff0c;以及依赖的注入等等。 Spring 提供…