ZYNQ GPIO 缓冲实现方法

在Vivado中,EMIO IP(system和AXI扩展部分)引出实际上有3个管脚,分别是gpio_i,gpio_o,gpio_t,

要把它们转化为标准的GPIO,要外加缓冲器,步骤如下

在顶层模块中,会生成如下代码
IOBUF gpio_0_tri_iobuf_0
(.I(gpio_0_tri_o_0),
.IO(gpio_0_tri_io[0]),
.O(gpio_0_tri_i_0),
.T(gpio_0_tri_t_0));
IOBUF gpio_0_tri_iobuf_1
(.I(gpio_0_tri_o_1),
.IO(gpio_0_tri_io[1]),
.O(gpio_0_tri_i_1),
.T(gpio_0_tri_t_1));
IOBUF gpio_0_tri_iobuf_10
(.I(gpio_0_tri_o_10),
.IO(gpio_0_tri_io[10]),
.O(gpio_0_tri_i_10),
.T(gpio_0_tri_t_10));
IOBUF gpio_0_tri_iobuf_11
(.I(gpio_0_tri_o_11),
.IO(gpio_0_tri_io[11]),
.O(gpio_0_tri_i_11),
.T(gpio_0_tri_t_11));

有多少IO,就会有多少个缓冲器。

缓冲器内部结构如图所示

这个缓冲器其实也可以自己写得更加简洁一些,比如adi官方的例子
module ad_iobuf (

dio_t,
dio_i,
dio_o,
dio_p);

parameter DATA_WIDTH = 1;

input [(DATA_WIDTH-1):0] dio_t;
input [(DATA_WIDTH-1):0] dio_i;
output [(DATA_WIDTH-1):0] dio_o;
inout [(DATA_WIDTH-1):0] dio_p;

genvar n;
generate                         #循环例化   
for (n = 0; n < DATA_WIDTH; n = n + 1) begin: g_iobuf
assign dio_o[n] = dio_p[n];
assign dio_p[n] = (dio_t[n] == 1'b1) ? 1'bz : dio_i[n];
end
endgenerate

endmodule

调用
ad_iobuf #(
.DATA_WIDTH(32)                    #参数输入,例化32个
) i_iobuf (
.dio_t(gpio_t[31:0]),
.dio_i(gpio_o[31:0]),
.dio_o(gpio_i[31:0]),
.dio_p(gpio_bd));

当然,这样一来更新稍有不便,而且需要手工增加3个线,有点复杂。

如没有特殊要求推荐第一种方法。

原文链接: http://www.cnblogs.com/qiantuo1234/p/6693429.html