双向端口应用实例

  三态缓冲器也称三态门,其典型应用是双向端口,常用于双向数据总线的构建。
  在Verilog HDL中,inout型双向端口信号不能被定义成reg型变量,因此在always块内不能被直接赋值使用。
  由于现在FPGA设计和外部存储器或CPU数据交换的频繁运用,以及引脚资源有限,使用双向端口设计可以成倍地节省数据引脚线,所以利用Verilog HDL实现双向端口至关重要。在设计双向端口时应注意亮点:其一,要用三态门的控制来处理实现双向端口;其二,要分别指定双向端口作为输出口和输入口时,对外部对象的数据操作。


下面是一个双向端口的Verilog HDL实例:
module InOut(din, clk, z, dout, dinout);
    input [7:0] din;
    input clk;
    input z;
    output [7:0] dout;
    inout [7:0] dinout;
	 
	 reg [7:0] dout, din_reg;
	 
	 assign dinout = din_reg;
	 
	 always @(posedge clk) begin
		if(!z)
			din_reg <= din;          // inout型双向端口信号不能被定义成reg型变量,因此在always块内不能被直接赋值使用
		else
			dout <= dinout;
	 end


endmodule

注意:z为三态门选通信号,当z=1时,把三态门置为高阻态,这时dinout作为输入口;当z=0时,开通三态门,dinout作为输出端口。

双向端口的仿真:
  编写测试模块时,对于inout类型的端口,需要定义成wire类型变量,而其他输入端口都定义成reg类型,这两者是有区别的。此外,对于双向端口本身,仿真其输出端口和输入端口的语法是不同的。


(1)输出端口特性仿真:当双向端口作为输出口时,不需要对其进行初始化,只要开通三态门即可。
`timescale 1ns/1ps

module tb_InOut;
	reg [7:0] din;
	reg 	  z;
	reg       clk;

	wire [7:0] dout;
	wire [7:0] dinout;

	integer i;

	InOut 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

endmodule

仿真图为:

双向端口应用实例_第1张图片

(2)输入端口特性仿真:当双向端口dinout作为输入口时,需要对它进行初始化赋值并关闭三态门。而如果把它跟一般的输入口一样直接进行初始化赋值,则会出错,这是因为在定义它的时候是wire型的数据变量,而不是reg型数据变量。因此,这里需要用到force命令,以强制给dinout赋值。
`timescale 1ns/1ps

module tb_InOut_in;
	reg [7:0] din;
	reg       z;
	reg       clk;

	wire [7:0] dout;
	wire [7:0] dinout;

	integer i;

	InOut 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;
		for(i=0; i<10; i=i+1)
			#10 force dinout = dinout - 1;
	end


endmodule

不知道为何生不成仿真图,哥就是个杯具。。。
今晚P大又要搞镜湖之夜,哥看着喧闹的人群,却突然觉得好孤单啊~~

你可能感兴趣的:(实例)