赞
踩
1、双向端口简介
实现双向端口的典型方法是三态缓冲器也称三态门,它常用于双向数据总线的构建。在数字电路中,逻辑输出有两个正常态:低电平状态(对应逻辑0)和高电平状态(对应逻辑1);此外,电路还有不属于0和1状态的高阻态(对应逻辑Z )。所谓高阻,即输出端属于浮空状态,只有很小的漏电流流动,其电平随外部电平高低而定,门电平放弃对输出电路的控制。或者可以理解为输出与电路是断开的。最基本的三态缓冲器的逻辑符号如下图:
当OE为高电平时,Dataout与Datain相连;而OE为低时,Dataout为高阻态,相当于与Datain之间的连线断开。
在应用代码中,Verilog HDL程序模块首先要进行I/O端口(input:输入端口;output:输出端口;inout:双向端口,同时具有输入输出功能的端口)的定义,然后是逻辑功能的描述。在Verilog HDL中,output端口可以定义为寄存器型变量,并在always块内可以被赋值使用,而inout型双向端口信号不能被定义为寄存器型变量,因此在always块内不能直接被赋值。
由于现在FPGA设计和外部存储器或CPU数据交换的频繁运用,以及引脚资源有限,使用双向端口设计可以成倍地节省数据引脚线,所以利用Verilog HDL实现双向端口至关重要。在设计双向端口时应注意两点:其一,要用三态门的控制来处理实现双向端口;其二,要分别指定双向端口作为输出口和输入口时,其外部对象的数据操作。
2、双向端口应用实例
实例假设输入输出数据的位宽为8,使用双向端口设计,需要8根数据线。
例:双向端口的Verilog实例。
- module dinout(din,z,clk,dout,dinout)
- input [7:0] din;
- input z;
- input clk;
- output [7:0] dout;
- inout [7:0] dinout;
-
- reg [7:0] dout;
- reg [7:0] din_reg;
-
- assign dinout = (!z)?din_reg:8’bz;
-
- always @(posedge clk)
- begin
- if(!z)
- din_reg=din;
- else
- dout=dinout;
- end
- endmodule
程序在ISE中综合后的RTL级结构图如下图所示。dinout定义为双向端口,即可作为输入端口,又可作为输出端口;当双向端口dinout作为输出口时,从输入端口din输入数据到模块中,让数据从dinout端口输出;当双向端口dinout作为输入口时,数据从dinout口输入,从输出端口dout输出。z为三态门选通信号,当z=1时,三态门置于高阻态,这是dinout作为输入口;当z=0时,开通三态门,dinout作为输出端口。
3、双向端口的仿真
编写测试模块时,对于inout类型的端口,与输出端口一样,需要定义成wire类型的变量,而输入端口定义为reg类型,这两者是有区别的。此外,对于双向端口本身,仿真其输出端口和输入端口的语法是不同的。下面分别给出上例中双向端口的输入、输出特性仿真。
(一)双向端口作为输出端口时仿真
当双向端口作为输出口时,不需要对其进行初始化,只要开通三态门即可。输出端口特性仿真代码如下所示。假设在100ns后,让数据10-20依次从din口输入,然后用10ns的采样时钟从双向端口dinout输出。
- module tb_dout
- reg [7:0] din;
- reg z;
- reg clk;
- wire [7:0] dout;
- wire [7:0] dinout;
- integer i;
-
- dinout uut(
- .din(din),
- .z(z),
- .clk(clk),
- .dout(dout),
- .dinout(dinout)
- );
-
- always #5 clk = ~clk;
-
- initial
- begin
- din=0;
- z=0;
- clk=0;
- #100 din=10;
- for(i=0;i<10;i=i+1)
- #10 din=din+1;
- end
- endmoudle
(二)双向端口作为输入端口时仿真
当双向端口dinout作为输入口时,需要对它进行初始化赋值并关闭三态门。而如果把它跟一般的输入口一样直接初始化赋值,则会出错,这是因为在定义它的时候是wire型的数据变量,而不是reg型数据类型。因此,这里需要用到force命令,用来强制给dinout赋值。同样,下面给出一个Verilog HDL仿真实例,设定在100ns后,让数据20-10从dinout口输入模块,然后用10ns的采样时钟从输出口dout输出。
- module tb_din
- reg [7:0] din;
- reg z;
- reg clk;
- wire [7:0] dout;
- wire [7:0] dinout;
- integer i;
-
- dinout uut(
- .din(din),
- .z(z),
- .clk(clk),
- .dout(dout),
- .dinout(dinout)
- );
-
- always #5 clk = ~clk;
-
- initial
- begin
- z=1;
- clk=0;
- force dinout = 20;
- #100
- #100 din=10;
- for(i=0;i<10;i=i+1)
- #10 dinout=dinout-1;
- end
- endmoudle
参考文件:
《Verilog HDL程序设计与实践(云创工作室)》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。