因为项目需要,顶层模块的输入输出需要配置成同一个管脚,就需要用到inout类型了,在网上查阅大量资料以及自己实际使用inout类型后做个记录。
verilog中input、output只能做单向的输入或者输出端口,inout类型既能作为输入又能做输出,是一个双向端口,电路层面是通过三态门来实现。三种状态除了高和低还有一个高阻态,当为高阻态时就可以作为输入使用。以下是网上常见的inout类型代码。
module test(
input flag,
input [3:0]in_a,
output [3:0]out_b,
inout [3:0]data
);
assign data = flag?in_a:4'bz;
//flag为高时,data为输出,输出in_a,flag为低时,门电路(data=in_a)为高阻态,data为输入
assign out_b = data;
//data数据连接到out_b
第一点,网上有些资料会对in_a和out_b的类型作出要求,有的说in_a得是reg类型,有的说out_b得是reg类型,实际上没有什么特别的要求,两个引脚都是wire类型都可以,我就是这么用的,程序最后功能完全正常。
第二点,assign out_b = data;这一句在某些情况中会存在问题,网上有人是对out_b再配置了一个三态门,代码是assign out_b = flag?4'bz:data;(意为flag为高时out_b为高阻态断开与外部电路的连接,flag为0时将data赋给 out_b ),这样写在顶层模块是没问题的,因为out_b和in_a都是顶层模块的输入输出引脚。但out_b如果是子模块的引脚,就会报警告,大概意思就是inout类型即三态门只能在顶层模块使用,必须驱动顶层引脚,三态门没有驱动顶层的引脚,这一点需要注意。可以改成assign out_b = flag?4'b1:data;或者assign out_b = flag?4'b0:data;就不会有警告了,看自己程序的需要。