在FPGA的设计过程中,有时候会遇到双向信号(既能作为输出,也能作为输入的信号叫双向信号)。比如,IIC总线中的SDA信号就是一个双向信号,QSPI Flash的四线操作的时候四根信号线均为双向信号。在Verilog中用关键字inout定义双向信号,这里总结一下双向信号的处理方法。

  实际上,双向信号的本质是由一个三态门组成的,三态门可以输出高电平,低电平和高阻态三种状态,在FPGA中,一个三态门的结构如下图所示:

    

  描述这个逻辑的Verilog代码如下:

module inout_top
(
input I_data_in ,
inout IO_data ,
output O_data_out ,
input Control
); assign IO_data = Control ? I_data_in : 'bz ;
assign O_data_out = IO_data ; endmodule

  当Control为1时,IO_data为输出,输出I_data_in的值

  当Control为0时,IO_data为输入,把输入的信号赋值给O_data_out

  这段代码在Vivado2015.4.2编译环境下的RTL图如下图所示

  在ISE14.7的编译环境下的RTL图如下图所示

  

  可以发现在Vivado2015.4.2环境的Control信号的IBUF后面居然还综合出了一个LUT,在ISE14.7环境下Control信号后面综合出了一个反向器,出现这个LUT和反向器的原因是Control为1才把IO_data设置成输出,而在Xilinx中一个IOBUF资源默认T端为0时IO端才为输出,T端为1时,IO端为输入,所以把

  assign IO_data = Control ? I_data_in : 1'bz ;

  改为

  assign IO_data = (Control == 1’b0) ? I_data_in : 1'bz ;

  在Vivado2015.4.2环境下综合出的RTL图为下图

  

  在ISE14.7的环境下综合出的RTL图如下图所示

  

  显然,Vivado环境中LUT和ISE环境中的反相器不见了,节省了1个Cell资源。

  以上是处理inout的第一种方法,第二种处理inout信号的方法是调用Xilinx的IOBUF原语,IOBUF的原语可以在Vivado2015.4.2的Language Templates中找到

  

  调用这个原语的Verilog代码如下:

module inout_top
(
input I_data_in,
inout IO_data ,
output O_data_out ,
input Control
); IOBUF #(
.DRIVE(), // Specify the output drive strength
.IBUF_LOW_PWR("TRUE"), // Low Power - "TRUE", High Performance = "FALSE"
.IOSTANDARD("DEFAULT"), // Specify the I/O standard
.SLEW("SLOW") // Specify the output slew rate
) IOBUF_inst (
.O(O_data_out), // Buffer output
.IO(IO_data), // Buffer inout port (connect directly to top-level port)
.I(I_data_in), // Buffer input
.T(Control) // 3-state enable input, high=input, low=output
); endmodule

  在Vivado2015.4.2环境下综合出的RTL图如下图所示

  

  在ISE14.7环境下综合出的RTL图如下图所示

  

  显然和  assign IO_data = (Control == 1’b0) ? I_data_in : 1'bz ;这种情况下综合出的RTL完全一样。

总结,利用Verilog处理双向信号有两种方式:

  1、写代码

    assign IO_data = (Control == 1’b0)? I_data_in : 1'bz ;

    assign O_data_out = IO_data ;

  2、例化IOBUF原语

    IOBUF #(

     .DRIVE(12), // Specify the output drive strength

    .IBUF_LOW_PWR("TRUE"),  // Low Power - "TRUE", High Performance = "FALSE"

    .IOSTANDARD("DEFAULT"), // Specify the I/O standard

    .SLEW("SLOW") // Specify the output slew rate

    ) IOBUF_inst (

    .O(O_data_out),     // Buffer output

    .IO(IO_data),   // Buffer inout port (connect directly to top-level port)

     .I(I_data_in),     // Buffer input

    .T(Control)      // 3-state enable input, high=input, low=output

    );

题外话:

  最近调一套代码,代码是前辈写的,之前都是用ISE开发,那套代码用ISE编译出的bit文件可以正常运行,但是最新的项目由于要添加更多的功能,所以选用了K7系列的FPGA,在Vivado下开发,结果发现原来正常运行的代码在Vivado下就不能运行了,通过反复检查与定位,发现原来的那套代码对inout信号的处理十分不规范,而且没有加Control这个控制信号来控制inout的方向,直接想当然的作为输入或者输出来使用。最后我们把inout信号全部采用上面两种规范的处理方法处理以后,代码正常运行。所以平时在设计的过程中一定要多注意细节,力求规范。

欢迎关注我的公众号:FPGA之禅

【设计经验】1、Verilog中如何规范的处理inout信号的更多相关文章

  1. 硬件描述语言Verilog设计经验总结

    一.硬件描述语言Verilog 粗略地看Verilog与C语言有许多相似之处.分号用于结束每个语句,注释符也是相同的(/* ... */和// 都是熟悉的),运算符"=="也用来测 ...

  2. 【设计经验】5、Verilog对数据进行四舍五入(round)与饱和(saturation)截位

    一.软件平台与硬件平台 软件平台: 操作系统:Windows 8.1 64-bit 开发套件:Vivado2015.4.2  Matlab2016a 仿真工具:Vivado自带仿真器 二.引言 在利用 ...

  3. 【设计经验】2、ISE中ChipScope使用教程

    一.软件与硬件平台 软件平台: 操作系统:Windows 8.1 开发套件:ISE14.7 硬件平台: FPGA型号:XC6SLX45-CSG324 二.ChipScope介绍 ChipScope是X ...

  4. 编写高质量代码改善C#程序的157个建议——建议154:不要过度设计,在敏捷中体会重构的乐趣

    建议154:不要过度设计,在敏捷中体会重构的乐趣 有时候,我们不得不随时更改软件的设计: 如果项目是针对某个大型机构的,不同级别的软件使用者,会提出不同的需求,或者随着关键岗位人员的更替,需求也会随个 ...

  5. 《设计模式之美》 <03>面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?

    面向对象 现在,主流的编程范式或者是编程风格有三种,它们分别是面向过程.面向对象和函数式编程.面向对象这种编程风格又是这其中最主流的.现在比较流行的编程语言大部分都是面向对象编程语言.大部分项目也都是 ...

  6. Web API接口设计经验总结

    在Web API接口的开发过程中,我们可能会碰到各种各样的问题,我在前面两篇随笔<Web API应用架构在Winform混合框架中的应用(1)>.<Web API应用架构在Winfo ...

  7. web设计经验<三>值得你深入了解的交互设计5大支柱

    随着单页式设计和移动端的兴起,网页中的交互设计越来越重要了.为了打造流畅而可靠的用户体验,你需要对交互设计有更加深入的了解. 正如同我们在<交互设计最佳实践(卷1)>中所述,要做好交互设计 ...

  8. web设计经验<一> 提升移动设备响应式设计的8个建议

    今天看到一些关于web设计的一些建议和设计经验,拿出来分享分享. 第一篇: 提升移动设备响应式设计的8个建议 一.直观性和易用性 在使用移动设备时,对于杂乱.复杂或者不直观的设计造成的混乱不佳的用户体 ...

  9. 关于Verilog 中的for语句的探讨

    在C语言中,经常用到for循环语句,但在硬件描述语言中for语句的使用较C语言等软件描述语言有较大的区别. 在Verilog中除了在Testbench(仿真测试激励)中使用for循环语句外,在Test ...

随机推荐

  1. leetcode79

    class Solution { public boolean exist(char[][] board, String word) { for(int i=0; i<board.length; ...

  2. 深入理解Java虚拟机之Java内存区域随笔

    1.java内存区域与内存溢出异常 Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域:1.程序计数器,2.栈(虚拟机栈和本地方法栈 ),3.堆,4.方法区(包含 ...

  3. 一些值得收藏的MySQL知识链接

    https://yq.aliyun.com/articles/5533(死锁分析的很好的一篇文章) http://hedengcheng.com/?spm=5176.100239.blogcont55 ...

  4. 【ESP8266】、ESP8266通讯使用的AT指令

    一.AT指令介绍 AT(Attention), AT指令一般应用于终端设备和PC应用之间建立连接.通过AT指令来控制. 二.常用AT指令 AT指令主要分为: 基础AT指令,WIFI功能AT指令,TCP ...

  5. MFC笔记4

    1.添加图片 1)静态加载图片,直接在resourceView中控件设置就可以以实现 2)动态加载时,按照鸡啄米的教程http://www.jizhuomi.com/software/193.html ...

  6. 为什么要使用mybaits

    通常在项目开发过程中,有很多代码是重复的,固定不变的.为了提升开发效率,可将这些 固定不变的代码提取出来,生成class文件,将class文件打jar包,基于框架开发. mybaits是一个ORM框架 ...

  7. 【Nodejs】Nodejsの環境構築

    参考URL:http://www.runoob.com/nodejs/nodejs-install-setup.html Windowにインストールする方法を紹介します. ▲ダウンロードURL:htt ...

  8. React Context(一):隐式传递数据

    一 Context概述 Context provides a way to pass data through the component tree without having to pass pr ...

  9. Django的rest_framework的分页组件源码分析

    前言: 分页大家应该都很清楚,今天我来给大家做一下Django的rest_framework的分页组件的分析:我的讲解的思路是这样的,分别使用APIview的视图类和基于ModelViewSet的视图 ...

  10. 解决IE浏览器缓存导致AJAX请求数据异常

    IE10浏览器会把AJAX请求的数据都缓存下来,然后每次想去刷新数据时发现数据都是一样的,于是导致数据显示异常. 解决方法: 在页面<head>标签里,加上以下声明: <!-- 解决 ...