testbench——双向端口的仿真

双向端口(inout)可以通过引脚复用来节省引脚。

在控制信号控制下,inout既可作为输入input也可作为输出output,因此对其仿真描述不当可能会引起仿真错误。当然,不只在testbench中,在程序中对inout口一般也是要做特殊处理的。

testbench:

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:
//
// Create Date:   12:01:57 07/11/2017
// Design Name:   work
// Module Name:   C:/Users/gao/Desktop/isetest/work/testbench.v
// Project Name:  work
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: work
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////

module testbench;

	// Inputs
	reg clk;
	reg rst;

	// Outputs
	wire inout_vld;

	// Bidirs
	wire [3:0] inout_data;
	
	reg [3:0] data_in;


	initial begin
		clk = 0;
		forever #5 clk = ~clk;
	end

	initial begin
		rst = 0;
		#7 rst = 1;
		#16 rst = 0; 
	end

	always @(posedge clk or posedge rst) begin
		if (rst) begin
			// reset
			data_in <= 0;
		end
		else begin
			data_in <= data_in + 1;
		end
	end

	assign inout_data = inout_vld ? 4'bzzzz : data_in;

	// Instantiate the Unit Under Test (UUT)
	work uut (
		.clk(clk), 
		.rst(rst), 
		.inout_data(inout_data), 
		.inout_vld(inout_vld)
	);

   
endmodule
其中wire [3:0]inout_data用来连接inout口,inout_vld为模块输出,用以标志当前模块数据为输入(inout_vld == 0)还是输出(inout == 1)。

当为输出时(inout == 1),inout_data强制为16'bzzzz,此时与模块输出线与得到值为模块的输出值;当为输入时(inout == 0),inout_data连接寄存器,驱动模块端口。


在模块中的inout口做相似处理。

work:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    11:42:10 07/11/2017 
// Design Name: 
// Module Name:    work 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module work(
	clk
	,rst
	,inout_data
	,inout_vld
    );
input  clk, rst;
inout  [3:0]inout_data;
output inout_vld;

reg [3:0]counter;
always @(posedge clk or posedge rst) begin
	if (rst) begin
		// reset
		counter <= 0;
	end
	else begin
		counter <= counter + 1;
	end
end

reg inout_vld; //0->in 1->out
always @(posedge clk or posedge rst) begin
	if (rst) begin
		// reset
		inout_vld <= 0;
	end
	else if (counter == 4'b1111) begin
		inout_vld <= !inout_vld;
	end
	else begin
		inout_vld <= inout_vld;
	end
end

reg [3:0]data_out;
always @(posedge clk or posedge rst) begin
	if (rst) begin
		// reset
		data_out <= 4;
	end
	else begin
		data_out <= data_out - 1;
	end
end

assign inout_data = inout_vld ? data_out : 4'bzzzz;

endmodule

最后得到波形如下:


绿色为testbench中信号,橘黄色为模块信号。

可以看到在inout_vld == 0即输入时,模块的inout_data被外部接线驱动;在inout_vld == 1即输出时,模块的inout_data被内部寄存器data_out驱动,模块接线得到此时的值。



原文地址:https://www.cnblogs.com/mingmingruyue99/p/7202001.html