FPGA随记---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的赋值需要使用一对信号来完成。
方法一:声明一个受control信号控制的inout型的databus,推荐这个方法。
inout odatabus;
assign databus=(control[0]==1)?dataout:32'bz;//位宽由实际情况决定
reg dataIn ;
always @(Ccontrol[1])
begin
if(control[1])
dataIn<=databus;
end
如前所述,inout 端口不能独立存在。为了进一步考虑,当一个模块的inout端口作为输出时,那么另一个模块的inout端口必须作为输入;反之,当一个模块的inout口用作输入时,那么另一个模块的inout口一定是输出口。因此,两个inout端口的控制信号实际上是由一对信号控制的。