FPGA研發之道 14 寫在coding之前的鐵律

2021-07-07 01:55:17 字數 2751 閱讀 8934

寫在coding之前的那些鐵律

(1)注釋: 好的**首先必須要有注釋,注釋至少包括檔案注釋,埠注釋,功能語句注釋。

檔案注釋:檔案注釋就是乙個說明文:這通常在檔案的頭部注釋,用於描述**為那個工程中,由誰寫的,日期是多少,功能描述,有哪些子功能,及版本修改的標示。這樣不論是誰,一目了然。即使不寫文件,也能知道大概。

介面描述:module的介面訊號中,介面注釋描述模組外部介面,例如ahb介面,和sram介面等等。這樣讀**的人即可能夠判斷即模組將ahb介面訊號線轉換成sram介面訊號。

功能語句注釋: 內部關鍵邏輯,狀態機某狀態,讀過程、寫過程。

注釋的重要性,毋庸置疑,好的注釋,能夠提高**的可讀性,可維護性等等。總之,養成注釋的好習慣,代價不大,但是收益很大。

(2)語句:

開始寫**是,在fpga設計中,特別是在可綜合的模組實現中,verilog的語句是很固定的。

在fpga

的設計中,不外乎時序邏輯和組合邏輯,除此之外,別無他法。對於開始功能編碼來說,只需知道組合邏輯訊號即可生效,時序邏輯在時鐘的下一拍起效就夠了。

下面是編碼的例項。

組合邏輯:兩種組合邏輯的描述,其功能是一致的。

assigna = b ? 1 : d ? 2 :3;

always@(*)

if(b)

a = 1

elseif(d)

a = 2;

else

a = 3;

組合邏輯 如果是非同步復位的話,描述如下

always@(posedge sys_clk or negedge rst_n)

if(!rst_n)

a <= 0;

else

a <= b;

也就是說,在verilog的可綜合電路的編碼中,只需要三種語句,分別是assign, always(*) 及時序的always(`clock_edge clk ) 。`clock_edge 可以是上公升沿或者下降沿。

為什麼用always@(*) 而不是always(敏感訊號列表)。「*」包含所有敏感訊號列表,如果在coding過程中,漏掉了某個敏感訊號,則會導致**不正確,例如本例中,敏感變數列表中,需要b or c 但是如果漏掉乙個,**就會在b或c有變化時,輸出沒有變化。導致**和功能不一致,但是對於綜合工具來說,功能還是能夠正常工作的,不會因為敏感變數列表中的值未列全而不綜合某條語句。某些情況下,敏感列表的值可能有十幾個甚至更多,遺漏是可能發生的事情,但是為了避免這種問題,最好採用always(*)而不用敏感變數列表的方式,來避免**結果不一致的情況發生。

(3)賦值:老話重提,阻塞與非阻塞

很多同志喜歡鑽研阻塞賦值和非阻塞賦值,這兩種賦值,分別在always塊裡面用於的阻塞「=」給組合邏輯賦值,非阻塞」<=」給時序邏輯賦值。這應該是鐵律,應該在編碼過程中被嚴格的遵守下來。「為什麼?,不這麼用程式也能跑」。這句話部分是正確的,疑問永遠是工程師最好的老師。

誠然,某些情況下,不嚴格的執行也跑,但是在某些情況下,實現二者就不一樣。

對於下面兩個例子來說明,為什麼?

對於value1的描述方式:其綜合後的如下所示

如果從實際的編譯結果上看b和b1 及c和c1其使用阻塞賦值和非阻塞賦值最終的結果是一致的,因此,也就是說,某些情況下,二者的編譯結果一致。

而對於value2的描述方式:其綜合後的電路圖如下所示。

而對於第二中描述方式,阻塞賦值和非阻塞賦值的區別就顯現出來了,從綜合後的圖中可以看到,c1訊號是b1訊號的寄存,而c訊號和b訊號為同一訊號,都為a訊號的寄存。

作為fpga工程師,一項基本的能力,就是要知道**綜合後的電路和時序,不要讓其表現和你預想的不一致,「不一致」就意味著失敗。即是**的失敗,也是工程的失敗

對於阻塞和非阻塞賦值區別和詳細說明來說,其能夠編寫一本書(如有時間也可專題詳述),但是對fpga工程師,對於verilog的編碼而言,則只需要按照時序邏輯用「<=」非阻塞,組合邏輯用阻塞「=」賦值即可。不要挑戰那些規律,試圖通過語言的特性來生成特殊電路的嘗試是不可取的,開個玩笑的話,是沒有前途的,要把設計的精力放在通過可用的電路來實現需求上,不要捨本逐末。在數位電路設計中,我們需要的是乙個確定的世界,「所見及所得」,不要讓你所想的和綜合編譯工具得認識不一致。這也就是不要亂用和混用這兩個賦值的原因。

(4)乙個變數乙個「家」

不要在兩個always語句中同乙個變數賦值。(這是必須的)

也盡量不要在同乙個always語句中,對兩個變數賦值。(這是可選的)

如果是一組訊號,其有共同的控制條件,則在同一always語句中賦值能夠減少**行數,提高可讀性,除此之外,最好分開來寫。如果幾個不太相關的訊號在同一裡面賦值,其可讀性極差,在組合邏輯中,還容易產生latch。

而前者賦值方式,綜合工具肯定會報錯,這到不用很擔心,因為能夠報的錯誤時是最容易被發現的。俗語說:「咬人的狗不叫」,而對於fpga設計來說「致命的bug,從來不報錯」。

(5)鎖存

fpga中不要有鎖存器的產生。最容易產生的是在always(*)語句中,最後一定是所有分支條件都要描述並賦值,(一定要有最後的else)。狀態機中,同樣如此,不但需要有default的狀態,每個狀態的都要有所有的分支都要賦值。

鎖存器,是fpga設計的大敵,因為會導致非你想要的錯誤功能的產生,並且導致時序分析錯誤,就會產生前述的問題「所見不是所得」,並且綜合工具不會報錯。

時序邏輯會產生鎖存器嗎?當然不會,時序邏輯綜合結果必然是觸發器,因此不用檢查時序邏輯的分支條件。

綜上:這是寫在coding之前的話,編碼的主要功能應該是用可靠的電路來描述fpga功能和需求,不要試圖通過語言的特性來描述功能,設計的主要精力應放在用已知的電路(組合邏輯,時序邏輯)描述未知功能。

FPGA研發之道(25) 管腳

管腳是fpga重要的資源之一,fpga的管腳分別包括,電源管腳,普通i o,配置管腳,時鐘專用輸入管腳gclk 等。1 電源管腳 通常來說 fpga 內部的電壓包括核心電壓和i o電壓。1.核心電壓 即fpga內部邏輯的供電。通常會較i o電壓較低,隨著fpga的工藝的進度,fpga的核心電壓逐漸下...

CODING 告訴你矽谷的研發專案管理之道(4)

譯者注 hubspot 是一家為社交 營銷 內容管理 網路分析和搜尋引擎優化提供工具與服務的科技公司。前幾篇我們翻譯的是男性研發管理者的自述管理者 接下來我們來分享女性研發管理者的工作方式和管理風格。在下文中,除了對技術的持續追求 對高效團隊的不懈努力之外,我們也看到了作為女性管理者特有的細膩 比如...

CODING 告訴你矽谷的研發專案管理之道(5)

coding 已經通過前四期文章,讓大家逐步了解了一些矽谷優秀的專案管理者是如何工作 如何維持團隊高效運作的。在過去的十幾年中,中國的網際網路行業發展過於迅猛,導致很多管理人員都是趕鴨子上架,商場如戰場,不給你任何適應的時間,所以很多人還沒有從技術人員的身份轉變過來就開始帶團隊,在管理方式上難免會有...