作者:WenGalois123
本文转载自:https://www.cnblogs.com/WenGalois123/p/16300448.html
IOBUF这个原语在Xilinx的原语手册有说明,主要作为三态端口使用,作用是把FPGA内部三态信号与外部的双向信号连接。对于UltraScale系列芯片说明文档为:ug974-vivado-ultrascale-libraries.pdf,对于Z7系列芯片说明文档为:ug953-vivado-7series-libraries.pdf。可自行到xilinx官网下载。笔者粗略对比两文档中的IOBUF原语,发现差别不大,Z7多了些参数设置,大多情况默认即可。下面为UltraScale文档IOBUF部分说明:
根据上述大段的英文介绍笔者大概了解关键信息:当信号T为1时,IOBUF作为输入;T为0时IOBUF作为输出。
实际使用时,方向引脚对应T,代码模块输出对应IOBUF的I,代码块输入对应IOBUF的O。需要注意代码块的引脚方向信号必须是1为输入,0为输出,IOBUF的IO脚直接连FPGA引脚。
UltraScale官方代码如下:
// IOBUF: Input/Output Buffer // UltraScale // Xilinx HDL Language Template, version 2020.1 IOBUF IOBUF_inst ( .O(O), // 1-bit output: Buffer output .I(I), // 1-bit input: Buffer input .IO(IO), // 1-bit inout: Buffer inout (connect directly to top-level port) .T(T) // 1-bit input: 3-state enable input ); // End of IOBUF_inst instantiation
Z7官方代码如下:
// IOBUF: Single-ended Bi-directional Buffer // All devices // Xilinx HDL Language Template, version 2020.1 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 ); // End of IOBUF_inst instantiation
根据三态门的原理可以通过代码把3态门表示出来,为了不与IOBUF的名称相冲突,该模块改为PIN脚的PIOBUF:
module PIOBUF ( inout IO , input T , input I , output O ); assign O = IO; assign IO = ~T ? I : 1'bz; endmodule
module PIOBUF ( inout IO , input T , input I , output O ); assign O = T ? IO : I; assign IO = ~T ? I : 1'bz; endmodule
以上便是最常见的两种三态门写法,很多双向口都是使用该方法。实际上这两种方式是一样的,assign语句是线型,所以当T为0时,直接把I的值赋给O与先把值赋给IO,IO再赋给O,结果是一样的。
根据Xilinx的IOBUF原语T=0时,I与O信号是连接的特性,可以实现一些接口的小妙用。比如对于音频接口I2S,如果RX与TX作为两个模块,在FPGA作为时钟WCLK,BCLK输出,同时使用数据输出输入时,那么WCLK,BCLK分别使用IOBUF连接可以简单的解决既能发送数据,也能采样接收的数据。也可以在GPIO使用,三态口接IOBUF,输出高低电平时可以通过读取输入得到实际输出状态。