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个线,有点复杂。

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

转载于:https://www.cnblogs.com/qiantuo1234/p/6693429.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值