先放上連接規則的簡圖,再詳細解釋
1. 構建模型——污水處理之流水模型
我們先將上述結構構件一個簡單模型,以幫助我們理解。
- 污水:輸入數據
- 凈水:輸出數據
- 雙向數據暫不討論,取輸入和輸出的交集即可
- 污水處理廠:模塊(設計塊/激勵塊)
2. 結構——放大模型,展現細節
這里只對input和output進行展現,先暫時不管inout。
在展現之前,先來明確對于幾個重要概念的理解
2.0 深入理解規則才能打破規則!
問題1:net類型和reg類型究竟有什么區別?
問題2:為什么這幾個接口的類型要這樣限定?
2.1 net與reg的區別——水管閥門模型
我們將數據比喻為水,數據的處理過程就像水在水管中流動一樣。
-
net類型:無閥門的水管,只能讓水流動,不能儲存。
-
reg類型:雙閥門的水管,即可以讓水流動,也能存儲水。
- reg類型需要接收數據,則打開閥門A,水滿之后關閉閥門A,就實現了存儲數據
- 需要使用數據的時候,則可以打開閥門B
- 需要讓數據流入后直接流出,則可以同時打開A和B,這時候就和net類型的功能一樣
-
需要強調的是:reg和net是一類數據類型的總稱,將這個類型分別類比為兩種水管;這是粗略的模型,具體細分的數據類型再進一步展開即可。
2.2 構建結構——污水處理模型細節化
下面我們來逐一分析一下:
- ①輸入端口的外部:
可以是reg或者net,因為外部的污水可以是從別處直接流過來的,也可以是之前被保存起來,然后再開閘流過來的 - ②輸入端口的外部:
來者不拒!外面流過來污水,就必須接收! - ③輸出端口的內部:
- 凈水可以直接留到外面去
- 凈水也可以被保留起來,它可能會被回環用于污水處理過程,這是由其實際需求而被規定的,如果有需求就用,沒有就不用。
- ④輸出端口的外部:
輸出的凈水不能被封閉起來,一定要被排出去,否則就堵死了!
接下來,我們繼續優化這個模型,增加結構的細節!
好的我想你是能夠理解這個圖形的,對于輸出端口,內部可能回環再利用,外部可能直接輸出,也可能返回來在進入輸入,這些都可能發生的,具體怎么設定,看實際需求。
另外,對于①和③,也可以是無閥門的管道,這點我再強調一遍。
2.3 三種模式——端口與外部信號的連接模式
- 進去之后全部出去(與門)
- 進去后部分出去,部分回來(T觸發器)
- 多門路互相影響(SR鎖存器)
2.4 reg與net 的使用原則
- 對于內部接口的設置
- 不寫就默認wire
- 特殊需求:輸出顯式使用reg
- 對于外部接口的設置
看實際需求和使用習慣!
這一部分簡單看看就可以,不用深入了解,這些原則的使用方法,應該由大量實踐得出。
3. 回歸Verilog——結構的實現
我想,你通過污水處理結構,已經能夠對Verilog端口連接規則有了理解,并且,事實上你非常輕松地理解了它!
下面讓我們上升一個抽象層次,看一看具體在Verilog中是如何使用端口連接規則的。
以下采用
- EDA工具:Vivado 2017.4
- 代碼風格:ANSI C風格
- 端口連接:命名端口連接
3.1 內部模塊的端口設計
module show(input a,input [3:0] b,output c,output reg d);
……<模塊內容>
……
endmodule
注:也可以使用 input a,b 的形式,對于代碼風格,也需要參考EDA工具的支持情況,不同工具的使用規則可能不一樣。
3.2 模塊與外部信號的連接
對于外部信號而言,不是reg就是net類型,怎么著都應該能夠輸入進如其他的模塊實例,因此,也就能夠進一步理解,為什么輸入端口的外部允許reg和net類型的數據了。
這里只講解命名端口連接規則,先給出實例,模塊show為底層模塊,而模塊show_up為其上一級模塊。
module show_up(input aa,input [3:0] bb,output cc,output reg dd;);show s1( //調用模塊實例并且進行端口連接.a(aa),.b(bb),.c(cc),// .d(dd) 非法連接!reg類型的外部信號,不能連到輸出端口上// 可以選擇不連接,或者修改為net類型);
……
<模塊內容>
……
endmodule
需要注意的幾個問題:
- 警惕輸出端口非法連接
外部信號與模塊端口連接的時候,reg類型的輸出信號不能與輸出信號連接,可以有以下修改方式(由需求決定):- 將reg類型變為net類型
- 增加一個wire類型的輸出與之相連,reg類型的輸出不進行端口連接
- 模塊實例的端口可以不連接
- 模塊內外兩部分的位寬要匹配,否則可能出現問題
4. 實戰經驗
對于一整個設計模型而言,如果子模塊的輸出端口均與它的上級模塊連接,那么,整個設計系統中,只有葉單元的(內部)輸出端口可以是reg類型,其余是上層單元只能是net類型!
這個不做過多解釋,我相信你能夠想明白,只需要你在設計模塊端口的時候注意這個問題!
一般情況下,輸出端口默認wire即可,除非特殊情況采用reg!