芯路恒电子技术论坛

 找回密码
 立即注册
热搜: 合集
查看: 2182|回复: 0

Verilog中如何规范的处理inout信号

[复制链接]
  • TA的每日心情
    开心
    2021-12-31 09:03
  • 71

    主题

    79

    帖子

    967

    积分

    高级会员

    Rank: 6Rank: 6

    积分
    967
    发表于 2021-8-16 10:13:17 | 显示全部楼层 |阅读模式
    在FPGA的设计过程中,有时候会遇到双向信号(既能作为输出,也能作为输入的信号叫双向信号)。比如,IIC总线中的SDA信号就是一个双向信号,QSPI Flash的四线操作的时候四根信号线均为双向信号。在Verilog中用关键字inout定义双向信号,这里总结一下双向信号的处理方法。
    实际上,双向信号的本质是由一个三态门组成的,三态门可以输出高电平,低电平和高阻态三种状态,在FPGA中,一个三态门的结构如下图所示:

    001.png

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

    1. module inout_top(
    2.         input       I_data_in        ,
    3.         inout       IO_data          ,
    4.         output     O_data_out     ,
    5.         input       Control
    6.         );

    7.         assign IO_data = Control ? I_data_in : 1'bz ;
    8.         assign O_data_out = IO_data ;

    9. endmodule
    复制代码


    1、        当Control为1时,IO_data为输出,输出I_data_in的值。
    2、        当Control为0时,IO_data为输入,把输入的信号赋值给O_data_out。
    这段代码在Vivado2015.4.2编译环境下的RTL图如下图所示:
    002.png
    在ISE14.7的编译环境下的RTL图如下图所示:

    003.png

    可以发现在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图为下图:

    004.png

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

    005.png

    显然,Vivado环境中LUT和ISE环境中的反相器不见了,节省了1个Cell资源。
    以上是处理inout的第一种方法,第二种处理inout信号的方法是调用Xilinx的IOBUF原语,IOBUF的原语可以在Vivado2015.4.2的Language Templates中找到。

    006.png

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


    1. module inout_top
    2.         (
    3.         input   I_data_in,
    4.         inout   IO_data  ,
    5.         output  O_data_out  ,
    6.         input   Control
    7.         );

    8.         IOBUF #(
    9.                 .DRIVE(12), // Specify the output drive strength
    10.                 .IBUF_LOW_PWR("TRUE"),  // Low Power - "TRUE", High Performance = "FALSE"
    11.                 .IOSTANDARD("DEFAULT"), // Specify the I/O standard
    12.                 .SLEW("SLOW") // Specify the output slew rate
    13.         ) IOBUF_inst (
    14.                 .O(O_data_out),     // Buffer output
    15.                 .IO(IO_data),   // Buffer inout port (connect directly to top-level port)
    16.                 .I(I_data_in),     // Buffer input
    17.                 .T(Control)      // 3-state enable input, high=input, low=output
    18.         );

    19. endmodule
    复制代码


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

    007.png

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

    008.png

    显然和
    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、        在vivado中,可以采用例化原语的方法
    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
    );





    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|小黑屋|Archiver|芯路恒电子技术论坛 |鄂ICP备2021003648号

    GMT+8, 2024-4-28 19:25 , Processed in 0.107811 second(s), 34 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

    快速回复 返回顶部 返回列表