Xilinx原语详解——IBUFDS OBUFDS

news2024/11/17 8:33:44

  在使用FPGA时,往往会用到一些差分信号,比如HDMI接口,LVDS接口的ADC、显示器等等设备,而FPGA内部往往只会使用单端信号,就需要完成单端信号和差分信号的相互转换,xilinx提供了两个原语对所有IO信号实现差分和单端的转换,IBUFDS将FPGA输入的差分信号转换为单端信号,而OBUFDS负责把FPGA内部的单端信号转换为差分信号输出。

1、IBUFDS

  IBUFDS是一个支持低电压差分信号的输入缓冲器,图1是IBUFDS的框图。在IBUFDS中,有两个输入接口,一个是差分输入的正极端口I,另一个是差分输入的负极端口IB,两个端口的信号极性必须相反才能正常工作,输出端O将输入的差分信号转换为单端信号输出。

在这里插入图片描述

图1 IBUFDS框图

  IBUFDS的真值表如图2所示(直接从UG768中截图),注意只有当I和IB极性相反的时候才能表示两个信号互为差分对,此时才能正常工作,输出I端口的电平。一般是不会出现均为高电平或低电平状态的,除非差分走线没有做等长处理,此时是硬件设计的问题。

在这里插入图片描述

图2 IBUFDS真值表

  IBUFDS的Verilog HDL原语模板如下所示:

   IBUFDS #(
      .DIFF_TERM("FALSE"),       // Differential Termination
      .IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 
      .IOSTANDARD("DEFAULT")     // Specify the input I/O standard
   ) IBUFDS_inst (
      .O(O),  // Buffer output
      .I(I),  // Diff_p buffer input (connect directly to top-level port)
      .IB(IB) // Diff_n buffer input (connect directly to top-level port)
   );

2、OBUFDS

  IBUFDS是在FPGA的输入管脚使用,将外部的差分信号转为单端信号供内部使用。 OBUFDS刚好相反,其在输出管脚使用,将内部的单端信号转换为差分信号输出FPGA。图3是OBUFDS的框图,I为单端输入信号,O为差分输出正极,OB是差分输出负极。

在这里插入图片描述

图3 OBUFDS框图

  OBUFDS功能比较简单,对应真值表(可以从UG768手册直接获取)如图4所示。

在这里插入图片描述

图4 OBUFDS真值表

  OBUFDS对应的Verilog HDL原语模板如下所示:

   OBUFDS #(
      .IOSTANDARD("DEFAULT"), // Specify the output I/O standard
      .SLEW("SLOW")           // Specify the output slew rate
   ) OBUFDS_inst (
      .O(O),     // Diff_p output (connect directly to top-level port)
      .OB(OB),   // Diff_n output (connect directly to top-level port)
      .I(I)      // Buffer input
   );

3、IOBUFDS

  除了上述单向的差分信号外,可以利用三态差分转换器件IOBUFDS实现双向差分转换,对应的框图如图5所示,T是三态的使能信号,低电平有效(图中少画了圈),T为低电平时,I作为FPGA输出的单端信号,IO和IOB作为转换后的差分输出引脚。当T为高电平时,三态门关闭,此时IO作为差分输入的正极,IOB作为差分输入的负极,O作为差分输入转换后的单端输入信号。

在这里插入图片描述

图5 IOBUFDS框图

  对应的真值表如图6所示,

在这里插入图片描述

图6 IOBUFDS真值表

  IOBUFDS对应的Verilog HDL原语模板如下所示:

   IOBUFDS #(
      .DIFF_TERM("FALSE"),     // Differential Termination ("TRUE"/"FALSE")
      .IBUF_LOW_PWR("TRUE"),   // Low Power - "TRUE", High Performance = "FALSE" 
      .IOSTANDARD("BLVDS_25"), // Specify the I/O standard
      .SLEW("SLOW")            // Specify the output slew rate
   ) IOBUFDS_inst (
      .O(O),     // Buffer output
      .IO(IO),   // Diff_p inout (connect directly to top-level port)
      .IOB(IOB), // Diff_n inout (connect directly to top-level port)
      .I(I),     // Buffer input
      .T(T)      // 3-state enable input, high=input, low=output
   );

4、仿真

  这几个原语功能比较简单,使用一个工程完成三个原语的仿真,设计文件如下所示,外部输入的差分信号ibufds_p和ibufds_n,经过IBUFDS转为单端信号ibufds_o,该信号经过触发器延迟一个时钟得到ibufds_o_r,通过OBUFDS转换为差分信号obufds_p和obufds_n输出。外部输入一个三态控制信号t,用于控制IOBUFDS的三态使能端口,使能有效时,将IBUFDS寄存后的信号ibufds_o_r输出。

module buf_ctrl(
   input       clk      ,//系统时钟信号;
   input       rst      ,//系统复位信号,高电平有效;

   input       iobufds_t,//iobufds使能控制端;
   input       ibufds_p ,//ibufds正极输入;
   input       ibufds_n ,//ibufds负极输入;
   output      obufds_p ,//obufds正极输出;
   output      obufds_n ,//obufds负极输出;
   inout       iobufds_p,//iobufds正极输出;
   inout       iobufds_n,//iobufds负极输出;
   output      iobufds_i //将IOBUFDS输入的数据输出,防止倍优化掉;
); 
   reg         ibufds_o_r;

   wire        ibufds_o ;

   //例化IBUFDS原语
   IBUFDS #(
      .DIFF_TERM     ( "FALSE"   ),// Differential Termination
      .IBUF_LOW_PWR  ( "TRUE"    ),// Low power="TRUE", Highest performance="FALSE" 
      .IOSTANDARD    ( "DEFAULT" ) // Specify the input I/O standard
   )
   u_IBUFDS (
      .O    (ibufds_o   ),// Buffer output
      .I    (ibufds_p   ),// Diff_p buffer input (connect directly to top-level port)
      .IB   (ibufds_n   ) // Diff_n buffer input (connect directly to top-level port)
   );

   always@(posedge clk)begin
      ibufds_o_r <= ibufds_o;
   end

   //例化OBUFDS原语
   OBUFDS #(
      .IOSTANDARD ( "DEFAULT" ),// Specify the output I/O standard
      .SLEW       ( "SLOW"    ) // Specify the output slew rate
   )
   u_OBUFDS (
      .O    (obufds_p   ),// Diff_p output (connect directly to top-level port)
      .OB   (obufds_n   ),// Diff_n output (connect directly to top-level port)
      .I    (ibufds_o_r ) // Buffer input
   );

   //例化IOBUFDS原语
   IOBUFDS #(
      .DIFF_TERM     ("FALSE"    ),// Differential Termination ("TRUE"/"FALSE")
      .IBUF_LOW_PWR  ("TRUE"     ),// Low Power - "TRUE", High Performance = "FALSE" 
      .IOSTANDARD    ("BLVDS_25" ),// Specify the I/O standard
      .SLEW          ("SLOW"     ) // Specify the output slew rate
   )
   u_IOBUFDS (
      .O    (iobufds_i     ),// Buffer output
      .IO   (iobufds_p     ),// Diff_p inout (connect directly to top-level port)
      .IOB  (iobufds_n     ),// Diff_n inout (connect directly to top-level port)
      .I    (ibufds_o_r    ),// Buffer input
      .T    (iobufds_t     ) // 3-state enable input, high=input, low=output
   );

endmodule

  对应的TestBench文件如下所示:

`timescale 1 ns/1 ns
module test();
    parameter	CYCLE		=   10          ;//系统时钟周期,单位ns,默认10ns;

    reg			                clk         ;//系统时钟,默认100MHz;
    reg			                rst         ;//系统复位,默认高电平有效;
    reg                         iobufds_t   ;
    reg                         ibufds_p    ;
    reg                         ibufds_n    ;

    wire                        obufds_p    ;
    wire                        obufds_n    ;
    wire                        iobufds_i   ;
    wire                        iobufds_p   ;
    wire                        iobufds_n   ;

    buf_ctrl  u_buf_ctrl (
        .clk            ( clk       ),
        .rst            ( rst       ),
        .iobufds_t      ( iobufds_t ),
        .ibufds_p       ( ibufds_p  ),
        .ibufds_n       ( ibufds_n  ),
        .obufds_p       ( obufds_p  ),
        .obufds_n       ( obufds_n  ),
        .iobufds_i      ( iobufds_i ),
        .iobufds_p      ( iobufds_p ),
        .iobufds_n      ( iobufds_n )
    );

    reg  iobufds_p_i;
    reg  iobufds_n_i;

    assign iobufds_p = (iobufds_t) ? iobufds_p_i : 1'bz;
    assign iobufds_n = (iobufds_t) ? iobufds_n_i : 1'bz;

    //生成周期为CYCLE数值的系统时钟;
    initial begin
        clk = 1;
        forever #(CYCLE/2) clk = ~clk;
    end

    //生成复位信号;
    initial begin
        rst = 0;
        #2;
        rst = 1;//开始时复位10个时钟;
        #(10*CYCLE);
        rst = 0;
        repeat(220) @(posedge clk);
        $stop;//停止仿真;
    end

    initial begin
        #1;
        ibufds_p = 1'b0;
        ibufds_n = 1'b1;
        iobufds_t = 1'b1;
        iobufds_p_i = 1'b0;
        iobufds_n_i = 1'b1;
        #(CYCLE*12);
        ibufds_n = ibufds_p;
        #(CYCLE*2);
        ibufds_p = ~ibufds_p;
        #(CYCLE*2);
        ibufds_n = ibufds_p;
        #(CYCLE*2);
        repeat(200)begin
            ibufds_p = ({$random} % 2);
            ibufds_n = ~ibufds_p;
            #(CYCLE);
            iobufds_t = ({$random} % 2);
            #(CYCLE);
            iobufds_p_i = ({$random} % 2);
            iobufds_n_i = ~iobufds_p_i;
            #(CYCLE);
        end
    end

endmodule

  仿真结果如图7所示,图中对IBUFDS的四种输入取值做了仿真,当IBUFDS的输入同时为高电平或者低电平时,IBUFDS转换的输出信号会保持之前的状态不变。在实际情况下应该避免这种情况出现,其余情况IBUFDS与真值表结果一致,不再赘述。

在这里插入图片描述

图7 IBUFDS输入转换仿真

  下图主要关注OBUFDS相关信号,如图黄色信号为OBUFDS输入单端数据,而红色信号为OBUFDS输出差分信号,由图可知仿真正确。

在这里插入图片描述

图8 OBUFDS转换仿真

  IOBUFDS的仿真如图9所示,红色信号为IOBUFDS的三态使能信号,橙色信号是IOBUFDS的单端输出信号,对应真值表中的I,天蓝色信号表示IOBUFDS的双向差分信号,紫色信号是IOBUFDS的单端输入信号,对应真值表中的O。

在这里插入图片描述

图9 IOBUFDS转换仿真

  当使能信号为高电平时,IOBUFDS的三态门关闭,此时两路天蓝色差分信号为输入信号,紫色信号是两路差分输入转换为单端的结果,紫色信号与差分正极的逻辑保持一致,与橙色信号无关,所以正确。

  当使能信号为低电平时,IOBUFDS的三态门打开,此时IOBUFDS把橙色单端信号转换为两路天蓝色的差分信号输出,紫色信号此时与橙色信号是一致的,与普通三态门逻辑一致,仿真正确。

5、FPGA如何实现差分输入\输出

  通过上文仿真可以知道逻辑实现,但是FPGA是如何实现差分输入和输出的呢?将上述工程分配管脚,然后实现,生产比特流文件,最后查看信号在芯片中的走线及布局。

  如图10所示,是IBUFDS两个差分输入管脚的布局,Xilinx把两个相邻的管脚作为差分信号的两个管脚,通过两个IOB模块实现IOBUFDS的转换功能。

在这里插入图片描述

图10 IOBUFDS管脚分布

  图11是OBUFDS的实现情况,把两个管脚组合成差分信号,通过OBUFDS位于P脚的IOB之中,也就是单端引脚OBUF的位置,该结构可以作为OBUFDS使用,如图12所示。

在这里插入图片描述

图11 差分引脚布局

在这里插入图片描述

图12 OBUFDS位置

  IOBUFDS的情况稍微复杂一点,因为是双向信号,所以会同时使用ILOGIC和OLOGIC,并且因为有三态使能信号,所以OLOGIC需要同时使用上下两条路径,如图13所示,ILOGIC和OLOGIC在IDDR和ODDR文中已经详细分析过,此处不再赘述。

在这里插入图片描述

图13 IOBUFDS布局

  综上,FPGA会将相邻两个管脚配置为差分对,保证两路信号足够近,延时足够小,IBUF和OBUF的位置根据功能不同可能实现IBUFDS、OBUFDS、IOBUFDS等功能,在FPGA中经常可以看见同一器件可以复用多种功能,OLOGCI被作为ODDR,OFB等功能。

  参考资料:UG768 Xilinx 7 Series FPGA and Zynq-7000 All Programmable SoC Libraries Guide for HDL Designs

  本文工程在后台回复“BUF”(不包括引号)即可,UG768直接回复”xilinx手册”即可,包含前文用到xilinx相关所有手册。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【基于ESP32无线蓝牙上传电脑Excel透传数据】

【基于ESP32无线蓝牙上传电脑透传数据】 1. 引言2. 环境搭建2.1 硬件准备:2.2 软件准备:2.3. 配置Excel端口接收功能3. 测试代码4. 连接电脑和 ESP324.1 烧录程序4.2 启动蓝牙服务4.3 测试数据透传5. 总结1. 引言 随着物联网技术的发展,越来越多的设备开始支持无线通信,其…

正在快速兴起的云数据架构

云数据架构的日益流行表明了一个主题&#xff1a;在未来几年&#xff0c;越来越多的企业将把他们的数据中心业务完全迁移到云平台上&#xff0c;因为内部部署数据中心设施具有一些固有的优势。数字时代的企业生存已经成为向云迁移的代名词。 云数据架构的日益流行表明了一个主…

Java:字节流 文件输出与读入方法 并 实现文件拷贝

文章目录 字节 流FileOutputStream换行 与 续写FileInputstream实现 文件拷贝&#xff08;字节数组 读入方法&#xff09;字节流 编码 字节 流 FileOutputStream 创建对象&#xff0c;指定位置&#xff08;产生数据传输通道&#xff09; 参数可以是File对象&#xff0c;也可以…

Python time模块详解

time 模块主要包含各种提供日期、时间功能的类和函数。该模块既提供了把日期、时间格式化为字符串的功能&#xff0c;也提供了从字符串恢复日期、时间的功能。 在 Python 的交互式解释器中先导入 time 模块&#xff0c;然后输入 [e for e in dir(time) if not e.startswith(_)…

最简单的基于 FFmpeg 的音频解码器

最简单的基于 FFmpeg 的音频解码器 最简单的基于 FFmpeg 的音频解码器正文参考工程文件下载 参考雷霄骅博士的文章&#xff0c;链接&#xff1a;最简单的基于FFMPEGSDL的音频播放器&#xff1a;拆分-解码器和播放器 最简单的基于 FFmpeg 的音频解码器 正文 FFmpeg 音频解码器…

c++新经典模板与泛型编程:标准库容器中元素类型的萃取

通过容器(数组)类型萃取元素类型 用GetEleType类模板进行常规实现 #include <iostream>#include <vector> #include <list>// 泛化版本 template<typename T> struct GetEleType;// 特化版本 template<typename T> struct GetEleType<std::v…

Elasticsearch:向量数据库的真相

通过工作示例了解什么是向量数据库、它们如何实现 “相似性” 搜索以及它们可以在明显的 LLM 空间之外的哪些地方使用。除非你一直生活在岩石下&#xff0c;否则你可能听说过诸如生成式人工智能和大型语言模型&#xff08;LLM&#xff09;之类的术语。 除此之外&#xff0c;你很…

Rellax.js,一款超酷的 JavaScript 滚动效果库

嗨&#xff0c;大家好&#xff0c;欢迎来到猿镇&#xff0c;我是镇长&#xff0c;lee。 又到了和大家见面的时间&#xff0c;今天和大家分享一款轻松实现视差滚动效果的 JavaScript 库——Rellax.js。无需大量的配置&#xff0c;即可为你的网站增色不少。 什么是Rellax.js&am…

Flutter自定义下拉选择框dropDownMenu

利用PopupMenuButton和PopupMenuItem写了个下拉选择框&#xff0c;之所以不采用系统的&#xff0c;是因为自定义的更能适配项目需求&#xff0c;话不多说&#xff0c;直接看效果 下面直接贴出代码、代码中注释写的都很清楚&#xff0c;使用起来应该很方便&#xff0c;如果有任何…

【完整项目】双模式答题卡识别软件中YOLO模式的训练部分详解,包括训练填涂区域和手写准考证号,手把手详细教学,可延申拓展训练其他图像数据

目录 前言1. 数据准备2. 数据标注3. 先跑起来Windows下用本地的CPU或GPU训练本地Windows系统连接服务器训练前言 前文:【完整项目】基于Python+Tkinter+OpenCV+Yolo+手写OCR的双模式答题卡识别软件的设计与实现 如果你需要训练自己的答题卡模型,那么请先看上面的文章链接。…

uniapp自定义的日历(纯手写)

效果图&#xff1a; html&#xff1a; <!-- 年月 --><view class"box"><view class"box_time"><view class"time"><image click"lefts" :src"url/uploads/20231206/9d1fb520b12383960dca3c214d84fa0…

uniapp图片预览

用的是Uview组件库里面的 直接在页面写上&#xff1a; <u-album singleSize"100" :urls"[https://lxt.jingyi.icu/item.img]"></u-album> 这图片路径是我自己的 你们可以按照组件库里面的方法去实现

掌握JavaScript继承的精髓:原型继承、构造函数继承以及组合继承的实现技巧

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;JavaScript篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来JavaScript篇专栏内容:JavaScript-Javascript如何实现继承&#xff1f; 目录 一、是什么 二、实现方式 …

智能优化算法应用:基于蜉蝣算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于蜉蝣算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于蜉蝣算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.蜉蝣算法4.实验参数设定5.算法结果6.参考文献7.MA…

侮辱性涨薪!业绩得了S,调薪涨了450

信安这个行业3年前各大媒体&#xff0c;信安自己人都觉得自己在个朝阳行业&#xff0c;红利在咋弄不得再吃5年。 现在拉个干网络安全的再去问问&#xff0c;看看谁不是去年年终奖砍了一半、或者根本就没了&#xff0c;再或者每天岌岌可危生怕去领大礼包。 原本10月份的激励性…

python变量的命名和使用

变量名只能包含字母、数字和下划线 变量名只能包含字母、数字和下划线。变量名可以字母或下划线打头&#xff0c;但不能以数字打头。例如&#xff0c;可将变量命名为message_1&#xff0c;但不能将其命名为1_message。 Python 语言中&#xff0c;以下划线开头的标识符有特殊含…

普冉(PUYA)单片机开发笔记(5): 配置定时器PWM输出

概述 定时器的输出通道作为 PWM 驱动是 MCU 的常用功能。 PY32F003 有一个高级定时器 TIM1 和一个通用定时器 TIM3&#xff0c;这两个定时器都可以驱动4个输出通道。现在我们就利用 TIM1 的某一个通道实现可控占空比的 PWM 输出。 原理简介 看数据手册&#xff0c;简单摘录…

【文件上传系列】No.2 秒传(原生前端 + Node 后端)

上一篇文章 【文件上传系列】No.1 大文件分片、进度图展示&#xff08;原生前端 Node 后端 & Koa&#xff09; 秒传效果展示 秒传思路 整理的思路是&#xff1a;根据文件的二进制内容生成 Hash 值&#xff0c;然后去服务器里找&#xff0c;如果找到了&#xff0c;说明已经…

AI模型平台Hugging Face存在API令牌漏洞;大型语言模型与任务模型

&#x1f989; AI新闻 &#x1f680; AI模型平台Hugging Face存在API令牌漏洞&#xff0c;黑客可窃取、修改模型 摘要&#xff1a;安全公司Lasso Security发现AI模型平台Hugging Face上存在API令牌漏洞&#xff0c;黑客可获取微软、谷歌等公司的令牌&#xff0c;并能够访问模…

若依框架启动过程中遇到的控制台使用npm i下载相关依赖报错的问题以及前端启动遇到的问题

目录 报错截图问题解决其他问题 npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保路径正确&#xff0c;然后再试一次。问题解决更改环境变量新建系统变量 其他问题 错误解决Error: error:0…