当前位置:   article > 正文

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

verilog inout
芯片设计验证社区·芯片爱好者聚集地·硬件相关讨论社区·数字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;
  • 1

方法二:虽然本专栏在探讨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
  • 1
  • 2
  • 3
  • 4
  • 5

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

六、更多资料

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/420655
推荐阅读
相关标签
  

闽ICP备14008679号