FPGA之IO信号类型深入理解

  在FPGA设计开发中,很多场合会遇到同一根信号既可以是输入信号,又可以是输出信号,即IO类型(Verilog定义成inout)。

  对于inout型的信号,我们既可以使用FPGA原语来实现,也可以使用Verilog代码来实现。下面将介绍在Xilinx 7系列FPGA上两种实现方式的差别和注意点。

  不管哪种方式实现IO功能,从编译结果看都会调用IOBUF原语,为此,我们先来看一下IOBUF的结构,如下图所示。

  1.FPGA原语实现

  首先,我们编写的代码如下:

 1`define PRIMITIVE
 2
 3 module io_buf(
 4     input    T    ,
 5     input    I    ,
 6     output    O    ,
 7     inout    IO
 8 );
 9
10 `ifdef PRIMITIVE
11     IOBUF #(
12         .DRIVE            (12            ),    // Specify the output drive strength
13         .IBUF_LOW_PWR    ("TRUE"        ),    // Low Power - "TRUE", High Performance = "FALSE"
14         .IOSTANDARD        ("DEFAULT"    ),    // Specify the I/O standard
15         .SLEW            ("SLOW"        )    // Specify the output slew rate
16     ) IOBUF_INST (
17         .O                (O            ),    // Buffer output
18         .IO                (IO            ),    // Buffer inout port (connect directly to top-level port)
19         .I                (I            ),    // Buffer input
20         .T                (T            )    // 3-state enable input, high=input, low=output
21     );
22 `else
23     assign IO = T? I:1‘bz;
24     assign O  = IO;
25 `endif
26
27 endmodule

  该代码通过原语IOBUF实现IO功能,使用Vivado编译后的原理图如下图所示。可以看到IOBUF内部由OBUFT和IBUF原语构成。

  2.使用Verilog实现

  把`define PRIMITIVE注释掉,则为通过Verilog的实现方式,如下图:

//`define PRIMITIVE 

module io_iobuf(
    input    T    ,
    input    I    ,
    output    O    ,
    inout    IO
);

`ifdef PRIMITIVE
    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            ),    // Buffer output
        .IO                (IO            ),    // Buffer inout port (connect directly to top-level port)
        .I                (I            ),    // Buffer input
        .T                (T            )    // 3-state enable input, high=input, low=output
    );
`else
    assign IO = T? I:1‘bz;
    assign O  = IO;
`endif

endmodule

  该代码使用Vivado编译后的原理图如下图所示。该实现方式也会调用IOBUF原语,但多消耗了一个LUT资源。

 

  通过Verilog实现时,我们在把IO信号当成输入时给赋值高阻态(1‘bz)。假如我们把此时的IO信号赋值1‘b0或者1‘b1,会出现什么情况呢?我们把1‘bz写成1‘b1,如下所示:

 1 //`define PRIMITIVE
 2
 3 module io_iobuf(
 4     input    T    ,
 5     input    I    ,
 6     output    O    ,
 7     inout    IO
 8 );
 9
10 `ifdef PRIMITIVE
11     IOBUF #(
12         .DRIVE            (12            ),    // Specify the output drive strength
13         .IBUF_LOW_PWR    ("TRUE"        ),    // Low Power - "TRUE", High Performance = "FALSE"
14         .IOSTANDARD        ("DEFAULT"    ),    // Specify the I/O standard
15         .SLEW            ("SLOW"        )    // Specify the output slew rate
16     ) IOBUF_INST (
17         .O                (O            ),    // Buffer output
18         .IO                (IO            ),    // Buffer inout port (connect directly to top-level port)
19         .I                (I            ),    // Buffer input
20         .T                (T            )    // 3-state enable input, high=input, low=output
21     );
22 `else
23     assign IO = T? I:1‘b1;
24     assign O  = IO;
25 `endif
26
27 endmodule

  编译后的原理图如下,可以看到并不会调用IOBUF原语,IO的不能实现输入功能,这就是解释了为什么在使用Verilog实现一根信号的IO功能时需要赋值1‘bz。

原文地址:https://www.cnblogs.com/lai-jian-tao/p/12143866.html

时间: 2024-08-02 00:23:57

FPGA之IO信号类型深入理解的相关文章

“System.IO.FileNotFoundException”类型的未经处理的异常在 mscorlib.dll 中发生

这个错误是我在打包的时候,发现的,因为我移动了我的工程的位置(从C盘移动到了D盘),看一下出错的代码: Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DBUser") '这里修改配置文件就可以确定是查询那个表了. '/// <summary> '/// depiction:<实例化一个DAL中的User表的类> '/// </summary>

java基础之IO流及递归理解

一.IO流(简单理解是input/output流,数据流内存到磁盘或者从磁盘到内存等) 二.File类(就是操作文件和文件夹的) 1.FIleFile类构造方法 注意:通过构造方法创建的file对象是在内存里面,而不是在磁盘里面. File(String pathname)  根据指定的路径名创建file对象 File(String parent, String child)  根据 parent 路径名字和 child 路径名创建一个File对象 File(File parent, Strin

Javascript对于类型的理解

1.instanceof和typeof区别 两者都是用来判断类型用的,instanceof顾名思义,是否是某一类型的实例,这个返回值是bool值,例如(new String("so") instanceof String) typeof返回值则是类型名,如(typeof 'so') Javascript对于类型的理解

golang把io.ReadCloser类型转化为[]byte

//比如要解析resp.Body(io.ReadCloser),我们可以这样处理 body, err := ioutil.ReadAll(resp.Body) 接着,我们继续分析分析函数 func ReadAll(r io.Reader) ([]byte, error) { return readAll(r, bytes.MinRead) //const MinRead = 512 } // func readAll(r io.Reader, capacity int64) (b []byte,

2、第八周 - 网络编程进阶 - 数据库类型的理解

前言 1.关系型数据库与非关系型数据库 A.什么是数据库? 数据库是数据的仓库.数据库与普通的文件系统的主要区别:数据库能快速查找对应的数据. B.什么是关系型数据库? 关系型数据库是依据关系模型来创建的数据库.所谓关系模型就是"一对一.一对多.多对多"等关系模型,关系模型就是指二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的一个数据组织.关系模型包括数据结构(数据存储的问题,二维表).操作指令集合(SQL语句).完整性约束(表内数据约束.表与表之间的约束). 常见的

我对于java基本类型的理解

问:为什么基本类型数组不能和Object数组对传呢?答:那是因为基本类型数组虽然被看作成一个引用类型,但是基本类型数组里的每个元素还是基本类型,但是java并没有提供对基本类型的操作的方法所以不能转为Object数组类型,同理把对应的基本类型数组转为对应包装类数组即可在方法中使用Object数组传递参数 问:为什么基本类型传递给Object参数却可以呢?答:java有种名为自动包装的机制,在传递给Object行参时,会把该基本类型通过包装机制成为一个新的类.在java中每一个基本类型都对应着相应

java String类型 深入理解

本文摘自:http://www.cnblogs.com/ITtangtang/p/3976820.html 这作者写的非常好,少许地方有笔误,值得收藏 在讲解String之前,我们先了解一下Java的内存结构. 一.Java内存模型 按照官方的说法:Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配. JVM主要管理两种类型内存:堆和非堆,堆内存(Heap Memory)是在 Java 虚拟机启动时创建,非堆内存(Non-heap Memory)是在JVM堆之外的

java之IO其它类型的流

一.操作基本数据类型的流 DataInputStream DataOutputStream 数据输出流允许应用程序以适当方式将基本java数据类型写入输出流中.然后,应用程序可以使用数据输入流将数据读入. package a; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import

io调度策略noop的理解

io电梯算法,网上一堆,在此不再赘述. 手上有几块厂商提供的sas的ssd,做如下实验. 考虑到没有磁头移动,ssd一般采用noop的io调度策略,结果看到如下的iostat测试数据: Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %utildm-0 84.00 0.00 600.00 0.00 342.00 0.00 1167.36 1.15 1.92 1.92 0