通俗易懂的带你解读inout双向端口【Verilog高级教程】

芯片设计验证社区·芯片爱好者聚集地·硬件相关讨论社区·数字verifier星球
四社区联合力荐!近500篇数字IC精品文章收录
【数字IC精品文章收录】学习路线·基础知识·总线·脚本语言·芯片求职·EDA工具·低功耗设计Verilog·STA·设计·验证·FPGA·架构·AMBA·书籍

在这里插入图片描述

一、写在前面

本专栏为作者在 【数字IC手撕代码】 【数字IC笔试面经分享】 【数字IC工具解析】 以外开设的第四个独立专栏,旨在学习并提供有关Verilog硬件描述语言中非基础性的高阶语法特性知识,因本身专栏的独特定位,因此作者并不会涉及基础Verilog语言如阻塞式非阻塞赋值,过程块,数据类型等内容;同时受限于作者知识有限,本专栏也不会涉及System Verilog的相关内容,若按照IEEE的相关标准来看,本专栏将会聚焦Verilog-2005,即“IEEE Std 1364™-2005”以及之前的有关内容,提供相关的IC设计领域语法特性。以下为Verilog的进阶框图,有更多学习需求的读者可以检索相关英文标准进行学习。
在这里插入图片描述

二、什么是inout双向端口

在Verilog中,inout是一个双向接口(区别于input与output),也是一个可综合语句,广泛的应用于比如I2C等协议的设计中,声明inout端口,意味着数据既可以从主设备流向从设备,也可以从从设备流向主设备。

三、inout端口的综合

inout端口会被综合成为如下所示的三态门高阻态的引入,有效的消除了电路中其他部分对于此门的影响,也解决了常规端口可能会出现的多驱动的问题,因此,三态门广泛的应用于总线互联的端口,也是我们今天所讨论的inout端口的综合结果
在这里插入图片描述

四、inout双向端口的要求

  • inout端口默认为wire型,这意味着我们不能在always中对其进行赋值,而需要使用assign进行赋值
  • 每一个inout端口都需要一个reg型的buffer来做缓冲器

考虑这种情况:
当控制信号为真时,三态门开启,此时DataOut的输出通过双向端口传输到数据总线上。
但是DataIn和DataOut是直接相连的,如何保证DataOut的数据不会影响到与DataIn相连的电路呢?
解决这个问题的方法是将DataIn声明为reg类型,将reg类型变量复制到always进程块中,需要添加一个控制信号,由always敏感表监控,保证inout端口的输出不能直接贯通到Datain处。

在Verilog描述的实际过程中,往往容易忽略某个inout端口的reg语句。以 CPU 或 RAM 为例。RAM本身是作为内存用reg声明的,所以不需要这个reg缓冲区;而 CPU 模块的 inout 端口的 reg 语句经常被忽略,因为这东西看起来“多余”。这也是初学者在使用 inout 端口时最容易出错的地方。

  • 我们没有办法同时对inout端口既写又读(即同一时刻,数据只能有一个方向),配合着三态门的综合结果,在接收数据的的时候我们使其保持高高阻态
  • inout 端口不能独立存在

对于一个模块,inout 端口可以用作输入和输出。那么,连接到inout口的另一个模块是什么情况呢?显然,另一个模块也应该是一个inout端口,一个inout端口不能独立存在。但在实际编写 Verilog 代码的过程中,这点往往被忽略。

  • 对inout的赋值需要使用一对信号来完成

如前所述,inout 端口不能独立存在。为了进一步考虑,当一个模块的inout端口作为输出时,那么另一个模块的inout端口必须作为输入;反之,当一个模块的inout口用作输入时,那么另一个模块的inout口一定是输出口。因此,两个inout端口的控制信号实际上是由一对信号控制的。

五、inout端口的赋值

5.1 设计文件的赋值

方法一:声明一个受control信号控制的inout型的myport,当control为1时,赋值为data,control为0时,赋值为高阻态,推荐这个方法

assign myport = control ? data : 'z;

方法二:虽然本专栏在探讨IEEE Verilog-2005的相关设计标准,但是都说到这里了,作者再补充以下System Verilog出现后,inout端口新的赋值方法,以下的赋值看起来会比较奇特,因为正常的寄存器不产生Z值,但是在System Verilog的编译条件下,这种方法也是可行的。

logic myport_reg;
assign myport = myport_reg;] 
// in procedural code
    myport_reg <= data; // myport becomes an output
    myport_reg <= 'z; // myport becomes an input

5.2 仿真文件的赋值

testbench没有端口名称,因此我们没有办法在testbench中将其声明为inout端口,为了在testbench中体现inout,首先,我们需要将inout端口声明为wire型,例化的时候与设计文件连接,其次,我们要分别模拟input和output的行为,读取的时间高阻态,发送的时间有相对应的值,下文的案例为SRAM的testbench,其中Databus在设计文件中声明为了inout端口

module test;

reg [9:0]AddressBus;

reg Read,Write;

wire [31:0]DataBus,TestOut;

reg [31:0]TestIn;

DRAM dram(DataBus,AddressBus,Read,Write);

assign DataBus=(Write==1)?TestIn:32'bz;

assign TestOut=(Read==1)?DataBus:32'bz;

initial

begin

Write=1'b0;Read=1'b0;
AddressBus=1'b0;
TestIn=1'b0;
#100 
Write=1'b1;
AddressBus=10'd4;
TestIn=32'd64;
#10 Write=1'b0;
#10 Read=1'b1;
AddressBus=10'd8;
#30 $stop;
end
endmodule

六、更多资料

有更多学习需求的读者可以直接参考以下连接的文章,虽然是英文的,不过应该可以说将inout讲的非常清晰明了,作者的本篇博客也参考了很多下面的文章内容
How to use the inout port in Verilog

七、往期【Verilog】高级教程文章

  • 14
    点赞
  • 144
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张江打工人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值