這兩天在做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使用的一個實例代碼:
|
以上代碼,功能是,當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的值輸出的時候有值,而輸入的值為高阻。
以下是上面功能代碼的測試代碼:
|
用isim仿真,其仿真圖如下:
從圖中,可以看出,當read信號為低的時候,a作為輸出,此時a的值等於data的值。當read信號為高的時候,a作為輸入,此時a的值等於in_a的值。仿真正確。
對於inout信號的時候,要注意使能信號的正確運用,以及對應的assign賦值寫好。其次要注意,inout信號最好是使用在設計的端口中,不要在設計的內部模塊中使用inout。
Read=0時,a<=data;a作為輸出端口,向外部模塊輸出數據。
Read=1時,b<=a;a作為輸入端口,從外部模塊輸入數據。