這兩天在做verilog的ds1302,ds1302中有一個端口是輸入/輸出管教。即這個管教即是輸出,同時也可以當輸入。在verilog中有一個特殊的端口與之對應,就是inout。

Inout這個端口,之前用得不多,所以用法也不怎麼記得。但是這個地方要用,所以就要學習下。

在端口申明中,可以申明一個端口為inout,申明後,這個端口就是輸入/輸出端口。那麼怎麼用這個端口了,什麼時候讓他輸出,什麼時候讓他輸入。這個時候,就有一個固定的用法。就是assign

如:申明一個 inout端口 a, inout a,

那麼在用的時候,就要這樣用: assign a = read == 1 ? 1'bz : data;

可以看出,這裏多了一個read信號,這個read信號就説明此端口a,在什麼時候作為輸入,什麼時候作為輸出。當read為1的時候,a為輸入,否則作為輸出。

以下是一個inout使用的一個實例代碼:

 

module inout_1(
input clk,
input rst_n,
input read,
input data,
inout a,
output reg b
);
assign a = read == 1 ? 1'bz : data;
always@( posedge clk ) begin
if( !rst_n )
b <= 0;
else
begin
if(read)
b <= a;
end
end
    endmodule

 

 

以上代碼,功能是,當a端口作為輸入的時候,把輸入a的值給輸出b。當a端口作為輸出的時候,將輸入data的值輸出給a。

Inout使用時很簡單的,其實就是控制使能信號。使能信號有效的話,就將端口當做輸入用。使能信號無效的時候,就把端口當做輸出,此時改變輸出的值,就改變assing語句中的輸出信號值(上例中就是data信號)。、

接下來就是仿真了,對於inout的端口,仿真和其他兩種端口是不一樣的,input端口在仿真中,就是定義為reg型,然後直接在測試文件中改變值。而輸出就是定義為wire型,直接在仿真結果中查看信號結果即可。

那對於inout又該怎麼定義信號了。其實inout信號,在測試文件中,要定義為wire型。另外還要加一個assign語句。

如上例中,a為inout信號,那麼在測試文件中,要有這樣一個語句

assign a = read== 1 ? in_a : 1'bz;

信號in_a是a的輸入值,可以看出,測試的assign和功能代碼中的assign順序是反着的。在功能代碼中,是使能信號有效的時候,inout信號的值為z,即表示為輸入。但是在測試中,信號有效的時候,inout的值是定義的一個輸入的值,而信號無效的時候,值為z,表示輸出。

上面的順序不能反,之前做的時候,在testbench中對assign的賦值順利反了,結果仿真中,a的值輸出的時候有值,而輸入的值為高阻。

以下是上面功能代碼的測試代碼:

module inout_1_tb;
// Inputs
reg clk;
reg rst_n;
reg read;
reg data;
// Outputs
wire b;
// Bidirs
wire a;
// Instantiate the Unit Under Test (UUT)
inout_1 uut (
.clk(clk),
.rst_n(rst_n),
.read(read),
.data(data),
.a(a),
.b(b)
);
reg in_a;
assign a = read == 1 ? in_a : 1'bz;
always #1 clk = ~clk;
initial begin
// Initialize Inputs
clk = 0;
rst_n = 0;
read = 0;
data = 0;
in_a = 0;
#10 rst_n = 1;
repeat(10) begin //a作為輸出 此時a的值等於data
#2 data = {$random}%2;
end
read = 1;
repeat(10) begin //a作為輸入,此時a的值為in_a
#2 in_a = {$random}%2;
end
// Add stimulus here
end
endmodule


用isim仿真,其仿真圖如下:


 

從圖中,可以看出,當read信號為低的時候,a作為輸出,此時a的值等於data的值。當read信號為高的時候,a作為輸入,此時a的值等於in_a的值。仿真正確。

對於inout信號的時候,要注意使能信號的正確運用,以及對應的assign賦值寫好。其次要注意,inout信號最好是使用在設計的端口中,不要在設計的內部模塊中使用inout。

Read=0時,a<=data;a作為輸出端口,向外部模塊輸出數據。

Read=1時,b<=a;a作為輸入端口,從外部模塊輸入數據。