課程資源
視頻:https://www.bilibili.com/video/BV14K4y1u7kH/
資料:https://www.aliyundrive.com/s/E9H7Mc5hqhu
第1章 FPGA簡(jiǎn)介
第1節(jié) 什么是FPGA
FPGA是什么東西?
-
FPGA全稱Field-Programmable Gate Array,即現(xiàn)場(chǎng)可編程門陣列
-
簡(jiǎn)而言之FPGA是一個(gè)可以通過(guò)編程來(lái)改變內(nèi)部結(jié)構(gòu)的芯片。
-
如果要實(shí)現(xiàn)相應(yīng)的功能,需要通過(guò)編程即使用硬件描述語(yǔ)言進(jìn)行程序設(shè)計(jì),經(jīng)過(guò)EDA工具編譯、綜合、布局布線成后轉(zhuǎn)換為可燒錄的文件,最終加載到FPGA器件中去,改變FPGA內(nèi)部的連線,最終完成所實(shí)現(xiàn)的功能。
FPGA可以做什么?
- FPGA一般應(yīng)用于通信接口設(shè)計(jì)、數(shù)字信號(hào)處理等比較高端的場(chǎng)合。
- ASIC(application specific integrated circuit,專用集成電路)的原型驗(yàn)證。
- FPGA還用于一些非標(biāo)(沒(méi)有定義標(biāo)準(zhǔn)的)場(chǎng)合,F(xiàn)PGA在軍工領(lǐng)域應(yīng)用很廣泛。
- FPGA也是比較適用于新科技新領(lǐng)域。
FPGA相較于其他集成電路的優(yōu)勢(shì)和劣勢(shì)
- FPGA的優(yōu)勢(shì)是:
- 相較于ASIC,F(xiàn)PGA的開(kāi)發(fā)難度,大大縮減了開(kāi)發(fā)周期
- FPGA是可重復(fù)編程的,其研發(fā)成本與風(fēng)險(xiǎn)也要比ASIC小許多
- FPGA比單片機(jī)、CPU等集成電路芯片擁有更高的效率,更低的功耗
- FPGA也有劣勢(shì)。
- FPGA開(kāi)發(fā)難度比單片機(jī)、CPU難
- FPGA相較于ASIC成本較高、性能較差,資源利用率低的問(wèn)題
單片機(jī)、ASIC和FPGA的開(kāi)發(fā)難度和性能排序
- 開(kāi)發(fā)難度:?jiǎn)纹瑱C(jī)<FPGA<ASIC
- 性能:?jiǎn)纹瑱C(jī)<FPGA<ASIC
第2節(jié) FPGA的基本結(jié)構(gòu)
FPGA只能采用一種可以重復(fù)配置的結(jié)構(gòu)來(lái)實(shí)現(xiàn),查找表(LUT)可以很好滿足這一要求,目前主流的FPGA芯片是基于SRAM工藝的查找表。
查找表(LUT,Look-Up-Table),本質(zhì)上是一個(gè)RAM。
以實(shí)現(xiàn)數(shù)字邏輯 Y = A & B & C Y=A\& B\& C Y=A&B&C的功能為例,對(duì)比ASIC和FPGA的實(shí)現(xiàn)結(jié)構(gòu)
-
ASIC為了實(shí)現(xiàn)該邏輯,邏輯門都已經(jīng)事先確定好,Y的輸出值為兩個(gè)邏輯與運(yùn)算后的結(jié)果,其基本實(shí)現(xiàn)結(jié)構(gòu)如下圖所示:
-
FPGA如果要實(shí)現(xiàn)同樣的邏輯功能,用戶首先在 EDA工具中用硬件描述語(yǔ)言寫出" Y = A & B & C Y=A\& B\& C Y=A&B&C"邏輯代碼;EDA工具分析這一行代碼,得出該邏輯代碼的真值表;然后軟件工具將真值表寫到查找表上,從而實(shí)現(xiàn)該代碼的功能。
FPGA芯片最重要的參考指標(biāo)
- 可編程邏輯模塊的數(shù)量
- 固定功能邏輯模塊的數(shù)目,如乘法器的數(shù)目
- 存儲(chǔ)器資源的大小,如嵌入式RAM的大小
在最底層的可編程邏輯模塊上,存在著基本的兩種部件:觸發(fā)器和查找表。觸發(fā)器和查找表的組合方式不同,是各個(gè)FPGA家族之間區(qū)別的重要依據(jù),并且查找表本身的結(jié)構(gòu)也可能各不相同(有4輸入或6輸入或其他)
第3節(jié) 更為復(fù)雜的FPGA架構(gòu)
1985年Xilinx公司推出了第一塊FPGA芯片-XC2064,最初的FPGA包含8×8=64的邏輯塊陣列和85000個(gè)晶體管,其門電路不超過(guò)1000個(gè),且每個(gè)邏輯塊由一個(gè)4輸入的查找表和其他簡(jiǎn)單功能模塊構(gòu)成。
22年后,F(xiàn)PGA行業(yè)兩大巨頭Xilinx和Altera公司紛紛推出了采用最近65nm工藝的FPGA產(chǎn)品,其門數(shù)量已經(jīng)達(dá)到千萬(wàn)級(jí),晶體管個(gè)數(shù)更是超過(guò)10億個(gè)。
在這22年間,F(xiàn)PGA在緊跟半導(dǎo)體工藝進(jìn)步的同時(shí)也推動(dòng)了半導(dǎo)體的發(fā)展進(jìn)程——2001年采用150nm工藝、2002年采用130nm工藝,2003年采用90nm工藝,2006年采用65nm工藝。隨著技術(shù)的發(fā)展和工藝節(jié)點(diǎn)的進(jìn)步,F(xiàn)PGA的容量和性能在不斷提高的同時(shí),其功耗卻不斷的優(yōu)化減少。
在FPGA內(nèi)部,有“軟內(nèi)核”和“硬內(nèi)核”之分。
-
比如,如果要利用FPGA的可編程性在芯片內(nèi)部構(gòu)造實(shí)現(xiàn)一個(gè)計(jì)數(shù)器邏輯,那么在構(gòu)造計(jì)數(shù)器邏輯過(guò)程中使用到的功能便可以稱為“軟功能”,又稱為軟內(nèi)核。
-
而如果某個(gè)功能是直接利用芯片實(shí)現(xiàn)的,則利用了芯片內(nèi)部的“硬功能”,又叫硬內(nèi)核。比如時(shí)間單元等。可以理解為:硬內(nèi)核是實(shí)現(xiàn)固定功能的芯片。
第4節(jié) 帶嵌入式處理器的FPGA
利用FPGA的可編程構(gòu)造實(shí)現(xiàn)的事情之一即為使用其中的一部分?jǐn)?shù)字邏輯資源制作一個(gè)或多個(gè)軟處理器內(nèi)核。如果FPGA供應(yīng)商希望提供一個(gè)占用較少硅片面積、消耗較低功率但性能更高的處理器,解決方案是將其實(shí)現(xiàn)為硬內(nèi)核。如果需要高速、高性能的處理器,并且需要實(shí)現(xiàn)邏輯編程時(shí),傳統(tǒng)的方法是在電路板上放置處理器**(如ARM、DSP等)和FPGA**。
在2010年4月硅谷舉行的嵌入式系統(tǒng)大會(huì)上,賽靈思發(fā)布了可擴(kuò)展處理平臺(tái)的架構(gòu)詳情,這款基于ARM處理器的SoC可滿足復(fù)雜嵌入式系統(tǒng)的高性能、低功耗和多核處理能力要求。該處理器將通用基礎(chǔ)雙ARM Cortex-A9 MP Core處理器系統(tǒng)作為“主系統(tǒng)”,結(jié)合低功耗28nm工藝技術(shù),以實(shí)現(xiàn)高度的靈活性、強(qiáng)大的配置功能和高性能。
帶有嵌入式處理器的FPGA意味著ARM+FPGA;進(jìn)一步意味著這種芯片既需要軟件工程師編寫軟件,也需要FPGA工程師搭建周邊電路(如ARM的接口、時(shí)鐘配置和可編程邏輯部分的開(kāi)發(fā))。
第5節(jié) 數(shù)據(jù)存儲(chǔ)以及配置方式
FPGA實(shí)現(xiàn)一個(gè)邏輯表達(dá)式時(shí),會(huì)把邏輯表達(dá)式的真值表寫到LUT上去,斷電之后LUT中的內(nèi)容就清除了。即FPGA中的程序的特點(diǎn)是:斷電之后程序就清除了,如果需要運(yùn)行程序,需要上電之后,重新加載。
通過(guò)不同的配置模式,F(xiàn)PGA便會(huì)有不同的編程方式。以下為常用的幾種配置模式:
- 并行模式:通過(guò)并行PROM、Flash配置FPGA;
- 主從模式:使用一片PROM配置多片F(xiàn)PGA;
- 串行模式:串行PROM配置FPGA;
- 外設(shè)模式:將FPGA作為微處理器的外設(shè),由微處理器對(duì)其編程。
目前,主流的FPGA都是基于SRAM工藝的,在大部分的FPGA開(kāi)發(fā)板上,使用的都是串行配置模式。由于SRAM掉電就會(huì)丟失內(nèi)部數(shù)據(jù),因此往往都會(huì)外接一個(gè)能夠掉電保存數(shù)據(jù)的片外存儲(chǔ)器以保存程序。上電時(shí)FPGA便將外部存儲(chǔ)器(PROM)中的數(shù)據(jù)讀入片內(nèi)RAM以完成配置,對(duì)FPGA編程完成后便進(jìn)入工作狀態(tài);掉電后FPGA內(nèi)部SRAM中存儲(chǔ)的數(shù)據(jù)丟失,邏輯清零。這種方式配置FPGA不僅能反復(fù)使用,還無(wú)需重復(fù)的手動(dòng)配置。完成一次主動(dòng)配置之后每次上電便會(huì)自動(dòng)的實(shí)現(xiàn)FPGA的內(nèi)部編程。
第2章 FPGA開(kāi)發(fā)流程
FPGA的設(shè)計(jì)流程就是利用EDA開(kāi)發(fā)軟件和編程工具對(duì)FPGA芯片進(jìn)行開(kāi)發(fā)的過(guò)程。
原理圖和HDL(Hardware description language,硬件描述語(yǔ)言)是兩種最常用的數(shù)字硬件電路描述方法。其中運(yùn)用HDL設(shè)計(jì)方法具有更好的移植性、通用性以及利于模塊劃分的特點(diǎn)。
典型的FPGA的開(kāi)發(fā)流程有9步,如下圖所示
- 功能定義/器件選型
- 設(shè)計(jì)輸入
- 功能仿真
- 綜合優(yōu)化
- 綜合后仿真
- 時(shí)序仿真
- 布線后仿真
- 板級(jí)仿真與驗(yàn)證
- 芯片燒錄與調(diào)試
FPGA需要做的工作是:功能定義/器件選型、設(shè)計(jì)輸入、功能仿真、芯片燒制與調(diào)試、靜態(tài)時(shí)序分析(選擇做)??偨Y(jié)而言,主要工作就是:需求分析、寫代碼和調(diào)試代碼。其他非工作都由工具輔助完成。功能仿真、調(diào)試是工作中最花時(shí)間的部分
第1節(jié) 功能定義/器件選型
FPGA設(shè)計(jì)項(xiàng)目開(kāi)始之前,需要進(jìn)行方案論證、系統(tǒng)設(shè)計(jì)和FPGA芯片的選型等準(zhǔn)備性工作。
在確定并評(píng)估好方案后,需要進(jìn)行系統(tǒng)功能的定義和模塊的劃分。
FPGA器件選型
- 根據(jù)方案中任務(wù)要求,如方案中所確定的系統(tǒng)功能以及復(fù)雜度,對(duì)硬件的工作速度和器件自身的資源、成本以及性能指標(biāo)等各方面進(jìn)行綜合考慮,選擇合適的器件類型。
第2節(jié) 設(shè)計(jì)輸入
FPGA系統(tǒng)設(shè)計(jì)方法
-
設(shè)計(jì)方法一般采用自頂向下的設(shè)計(jì)方法。
-
首先將整個(gè)系統(tǒng)劃分成若干基本模塊;然后在將每個(gè)基本模塊劃分成下一層次的基本單元;依次劃分后,確定好各個(gè)模塊的功能以及各個(gè)模塊需要設(shè)計(jì)的輸入和輸出信號(hào);在通過(guò)EDA工具進(jìn)行各個(gè)模塊的設(shè)計(jì)。
-
最終要實(shí)現(xiàn)的目標(biāo):針對(duì)每個(gè)輸入信號(hào),利用EDA工具以及FPGA資源設(shè)計(jì)出需要的輸出信號(hào)邏輯。
設(shè)計(jì)輸入是指在EDA工具中代碼設(shè)計(jì)出所希望的系統(tǒng)的過(guò)程。通常情況下是使用HDL的方式描繪設(shè)計(jì)出最終的數(shù)字電路。
設(shè)計(jì)師接觸比較多的HDL語(yǔ)言是行為HDL,其主流語(yǔ)言是Verilog HDL和VHDL,這兩種語(yǔ)言都是IEEE標(biāo)準(zhǔn)。雖然兩者在語(yǔ)法結(jié)構(gòu)以及設(shè)計(jì)標(biāo)準(zhǔn)上存在差別,但是都有一個(gè)共同的特點(diǎn):語(yǔ)言和芯片工藝無(wú)關(guān)。在任何一款FPGA上,使用任何一種語(yǔ)言都可以設(shè)計(jì)出所希望的數(shù)字電路。
早期也會(huì)用原理圖的方法進(jìn)行輸入設(shè)計(jì)?,F(xiàn)在用的很少。
除了兩種IEEE標(biāo)準(zhǔn)語(yǔ)言外還有廠商自己的語(yǔ)言。在實(shí)際的設(shè)計(jì)中也可用HDL為主,原理圖為輔的混合設(shè)計(jì)方式,以發(fā)揮兩者的各自特色與優(yōu)勢(shì)。
第3節(jié) 功能仿真
功能仿真也稱為綜合前仿真,用戶設(shè)計(jì)好數(shù)字邏輯后需要檢查自己的設(shè)計(jì)是否符合預(yù)期,在不需要綜合之前通過(guò)仿真軟件對(duì)電路進(jìn)行邏輯驗(yàn)證。在功能仿真器件電路可以不用考慮延遲等因素,僅對(duì)初步的功能進(jìn)行檢驗(yàn)。通過(guò)建立測(cè)試平臺(tái)即Testbench,利用波形編譯器(仿真軟件)和硬件描述語(yǔ)言建立好波形文件和激勵(lì)信號(hào),在仿真軟件上會(huì)模擬實(shí)際電路的波形顯示出輸出波形信號(hào),并生成報(bào)告文件。用戶通過(guò)觀察各個(gè)時(shí)間點(diǎn)信號(hào)的變化情況來(lái)驗(yàn)證自己所設(shè)計(jì)邏輯的正確性。綜合前仿真在FPGA開(kāi)發(fā)過(guò)程中不是一定要進(jìn)行的步驟,但卻是極為關(guān)鍵的一步。在實(shí)際的工作學(xué)習(xí)中,充分利用好仿真工具,能夠提高設(shè)計(jì)的效率并及時(shí)發(fā)現(xiàn)設(shè)計(jì)缺陷,從而為后續(xù)的開(kāi)發(fā)過(guò)程提供保障。常用的硬件描述語(yǔ)言的仿真工具有ModelTech公司的ModelSim、VCS、Ncsim以及NC-VHDL等軟件。
第4節(jié) 綜合優(yōu)化
所謂綜合即針對(duì)給定的電路實(shí)現(xiàn)功能和實(shí)現(xiàn)該電路的約束條件,如速度、功耗、成本及電路類型等,通過(guò)計(jì)算機(jī)進(jìn)行優(yōu)化處理獲得一個(gè)能滿足上述要求的電路設(shè)計(jì)方案。也就是說(shuō),被綜合的文件是HDL文件(或其他相應(yīng)文件),綜合的依據(jù)是邏輯設(shè)計(jì)的描述和各種約束條件,綜合的結(jié)果則是一個(gè)硬件電路的實(shí)現(xiàn)方案,該方案必須同時(shí)滿足預(yù)期的功能和約束條件。對(duì)于綜合來(lái)說(shuō),滿足要求的方案可能有多個(gè),綜合器將產(chǎn)生一個(gè)最優(yōu)的或接近最優(yōu)的結(jié)果。因此,綜合的過(guò)程也就是設(shè)計(jì)目標(biāo)的優(yōu)化過(guò)程,最后獲得的結(jié)構(gòu)與綜合器的工作性能有關(guān)。常用的綜合工具有Synplicity公司的Synplify/SynplifyPro軟件以及各個(gè)FPGA廠家自己推出的綜合開(kāi)發(fā)工具。
獲得的是電路模型,不是真正的電路。
第5節(jié) 綜合后仿真
綜合后仿真是用來(lái)檢查綜合結(jié)果是否和原設(shè)計(jì)一致。后仿真與前仿真的區(qū)別在于:前仿真是指綜合前的仿真,如在Modelsim對(duì)撰寫的代碼直接進(jìn)行仿真,而后仿真是綜合后的仿真,也就是功能仿真。假設(shè)設(shè)計(jì)師在Modelsim中用HDL編寫了一個(gè)計(jì)數(shù)器代碼,其通過(guò)了行為級(jí)的仿真后被加載到quartus或者其他的綜合工具中進(jìn)行綜合,完成綜合后會(huì)生成功能網(wǎng)表,將行為語(yǔ)言轉(zhuǎn)換成寄存器傳送級(jí)語(yǔ)言,此時(shí)設(shè)計(jì)師再將其加載到Modelsim中進(jìn)行的仿真被叫做后仿真。后仿真成功后還需要在quartus中進(jìn)行映射和布局布線,并進(jìn)行時(shí)序分析生成時(shí)序網(wǎng)表,描述器件里門或者布線的延時(shí)。最后將延時(shí)網(wǎng)表和功能網(wǎng)表一起加載到Modelsim中仿真,這一仿真為門級(jí)仿真,而在實(shí)際的設(shè)計(jì)過(guò)程中,一般來(lái)說(shuō)不做綜合后仿真也不會(huì)帶來(lái)太大的影響。
第6節(jié) 布線后仿真
布局布線可理解為利用實(shí)現(xiàn)工具把邏輯映射到目標(biāo)器件結(jié)構(gòu)的資源中從而決定邏輯的最佳布局,選擇邏輯與輸入輸出功能鏈接的布線通道進(jìn)行連線,并產(chǎn)生相應(yīng)文件(如配置文件與相關(guān)報(bào)告)。實(shí)現(xiàn)是將綜合生成的邏輯網(wǎng)表配置到具體的FPGA芯片上,布局布線是其中最重要的過(guò)程。在完成綜合之后,就是相當(dāng)于有了各種元件,但如何建立元件之間的連接,就像在PCB上把元件放在哪里,元件之間的連接以及相連關(guān)系又是怎么樣的,這個(gè)都是布局布線完成的工作,綜合的結(jié)果可能每次都一樣,但是布局布線的結(jié)構(gòu)基本每次都不會(huì)一樣。布局將邏輯網(wǎng)表中的硬件原語(yǔ)和底層單元合理地配置到芯片內(nèi)部的固有硬件結(jié)構(gòu)上,并且往往需要在速度最優(yōu)和面積最優(yōu)之間作出選擇。布線根據(jù)布局的拓?fù)浣Y(jié)構(gòu),利用芯片內(nèi)部的各種連線資源,合理正確地連接各個(gè)元件。目前,F(xiàn)PGA的結(jié)構(gòu)非常復(fù)雜,特別是在有時(shí)序約束條件時(shí),需要利用時(shí)序驅(qū)動(dòng)的引擎進(jìn)行布局布線。布線結(jié)束后,軟件工具會(huì)自動(dòng)生成報(bào)告,提供有關(guān)設(shè)計(jì)中各部分資源的使用情況。由于只有FPGA芯片生產(chǎn)商對(duì)芯片結(jié)構(gòu)最為了解,所以布局布線必須選擇芯片開(kāi)發(fā)商提供的工具。
第7節(jié) 時(shí)序仿真
時(shí)序仿真,也稱為后仿真,是指將布局布線的延時(shí)信息反標(biāo)注到設(shè)計(jì)網(wǎng)表中來(lái)檢測(cè)有無(wú)時(shí)序違規(guī)(即不滿足時(shí)序約束條件或器件固有的時(shí)序規(guī)則,如建立時(shí)間、保持時(shí)間等)現(xiàn)象。時(shí)序仿真使用布局布線后器件給出的模塊和連線的延時(shí)信息,在最壞的情況下對(duì)電路的行為作出實(shí)際地估計(jì)。時(shí)序仿真使用的仿真器和功能仿真使用的仿真器是相同的,所需的流程和激勵(lì)也是相同的,唯一的差別是:時(shí)序仿真加載到仿真器的設(shè)計(jì)包括基于實(shí)際布局布線設(shè)計(jì)的最壞情況的布局布線延時(shí),并且在仿真結(jié)果波形圖中時(shí)序仿真后的信號(hào)加載了時(shí)延,而功能仿真沒(méi)有。由于不同芯片的內(nèi)部延時(shí)不一樣,不同的布局布線方案也給延時(shí)帶來(lái)不同的影響。因此在布局布線后,通過(guò)對(duì)系統(tǒng)和各個(gè)模塊進(jìn)行時(shí)序仿真,分析其時(shí)序關(guān)系,估計(jì)系統(tǒng)性能,以及檢查和消除競(jìng)爭(zhēng)冒險(xiǎn)是非常有必要的。在功能仿真中介紹的軟件工具一般都支持綜合后仿真。
第8節(jié) 板級(jí)仿真與驗(yàn)證
板級(jí)仿真主要應(yīng)用于高速電路設(shè)計(jì)中,對(duì)高速系統(tǒng)的信號(hào)完整性、電磁干擾等特征進(jìn)行分析,一般都以第三方工具進(jìn)行仿真和驗(yàn)證,在實(shí)際的工作中一般接觸較少。
第9節(jié) 芯片燒錄與調(diào)試
設(shè)計(jì)的最后一步就是芯片的編程與調(diào)試。編程是指將FPGA開(kāi)發(fā)工具最后產(chǎn)生使用的數(shù)據(jù)文件(位數(shù)據(jù)流文件,BitstreamGeneration)加載到FPGA芯片中。其中,芯片編程需要滿足一定的條件,如編程電壓、編程時(shí)序和編程算法等,而這些條件一般廠家都會(huì)事先完成設(shè)計(jì),設(shè)計(jì)師直接按照規(guī)范操作即可。數(shù)據(jù)文件下載到FPGA芯片中以后還需要進(jìn)行調(diào)試驗(yàn)證,邏輯分析儀(LogicAnalyzer,LA)便是FPGA設(shè)計(jì)的主要調(diào)試工具。使用LA需要引出大量的測(cè)試管腳,且LA價(jià)格昂貴,但是當(dāng)工程較大、所需要調(diào)試觀察的信號(hào)過(guò)多時(shí),仍舊需要LA來(lái)對(duì)芯片內(nèi)部的信號(hào)進(jìn)行觀察驗(yàn)證。目前,主流的FPGA芯片生產(chǎn)商都提供了內(nèi)嵌的在線邏輯分析儀(如XilinxISE中的ChipScope、AlteraQuartusII中的SignalTapII以及SignalProb),它們只需要占用芯片少量的邏輯資源便可達(dá)到同樣的效果,在實(shí)際的工程調(diào)試中發(fā)揮了極大的作用。
第3章 硬件描述語(yǔ)言Verilog
第1節(jié) Verilog的歷史
傳統(tǒng)硬件電路設(shè)計(jì)方法:原理圖設(shè)計(jì)法。不適用于大規(guī)模電路設(shè)計(jì)。
傳統(tǒng)的設(shè)計(jì)方法無(wú)法滿足高級(jí)設(shè)計(jì)的需求,最終出現(xiàn)了借助先進(jìn)EDA工具的使用硬件描述語(yǔ)言(HDL)的設(shè)計(jì)方法。設(shè)計(jì)工程師可以使用HDL來(lái)表述自己的設(shè)計(jì)思想,通過(guò)利用EDA工具進(jìn)行仿真,自動(dòng)綜合到門級(jí)電路,最終在ASIC或FPGA實(shí)現(xiàn)其功能。
HDL發(fā)展至今已有二十多年歷史,當(dāng)今業(yè)界標(biāo)準(zhǔn)(IEEE標(biāo)準(zhǔn))中主要有VHDL和Verilog HDL這兩種硬件描述語(yǔ)言。本書(shū)采用的是Verilog HDL。
Verilog HDL最初在1983年由Gateway Design Automation公司為其模擬器產(chǎn)品開(kāi)發(fā)的硬件描述語(yǔ)言,當(dāng)時(shí)這只是公司產(chǎn)品的專用語(yǔ)言。隨著公司模擬、仿真器產(chǎn)品的廣泛使用,Verilog HDL作為一種實(shí)用語(yǔ)言逐漸為眾多設(shè)計(jì)者所接受。1990年一次致力于增加語(yǔ)言普及性的活動(dòng)中,Verilog HDL被推向公眾領(lǐng)域從而被更多人熟知。
Open Verilog International(OVI)是促進(jìn)Verilog發(fā)展的國(guó)際性組織。1992年OVI決定致力于推廣Verilog OVI標(biāo)準(zhǔn)為IEEE標(biāo)準(zhǔn),這一推廣最后獲得成功,Verilog語(yǔ)言與1995年成為IEEE標(biāo)準(zhǔn),稱為IEEE Std1364—1995。
第2節(jié) 綜合和仿真
2.1 綜合
在Verilog描述出硬件功能后需要使用綜合器對(duì)Verilog代碼進(jìn)行解釋并將代碼轉(zhuǎn)化成實(shí)際的電路來(lái)表示,最終產(chǎn)生實(shí)際的電路,也被稱為網(wǎng)表。這種將Verilog代碼轉(zhuǎn)成網(wǎng)表的工具就是綜合器,Verilog代碼轉(zhuǎn)化成網(wǎng)表的過(guò)程被稱為綜合。
QUARTUS、ISE和VIVADO等FPGA開(kāi)發(fā)工具都是綜合器,而在集成電路設(shè)計(jì)領(lǐng)域常用的綜合器是DC。
2.2 仿真
如果在編寫好代碼、綜合成電路、燒寫到FPGA后才發(fā)現(xiàn)問(wèn)題,此時(shí)再去定位問(wèn)題就會(huì)非常地困難。而在綜合前,設(shè)計(jì)師可以在電腦里通過(guò)仿真軟件對(duì)代碼進(jìn)行仿真測(cè)試,檢測(cè)出BUG并將其解決,最后再將程序燒寫進(jìn)FPGA。
需要注意的是:在仿真過(guò)程中沒(méi)有將代碼轉(zhuǎn)成電路,仿真器只是對(duì)代碼進(jìn)行仿真驗(yàn)證。至于該代碼是否可轉(zhuǎn)成電路,仿真器并不關(guān)心。
由此可見(jiàn),Verilog的代碼不僅可以描述電路,還可以用于測(cè)試。事實(shí)上,Verilog定義的語(yǔ)法非常之多,但絕大部分都是為了仿真測(cè)試來(lái)使用的,只有少部分才是用于電路設(shè)計(jì)。
Verilog中用于設(shè)計(jì)的語(yǔ)法是學(xué)習(xí)的重點(diǎn),掌握好設(shè)計(jì)的語(yǔ)法并熟練應(yīng)用于各種復(fù)雜的項(xiàng)目是技能的核心。而其他測(cè)試用的語(yǔ)法,在需要時(shí)查找和參考就已經(jīng)足夠了。
2.3 可綜合設(shè)計(jì)
Verilog是描述硬件電路的,其建立在硬件電路的基礎(chǔ)之上。而有些語(yǔ)法結(jié)構(gòu)只是以仿真測(cè)試為目的,是不能與實(shí)際硬件電路對(duì)應(yīng)起來(lái)的。也就是說(shuō)在使用這些語(yǔ)法時(shí),將一個(gè)語(yǔ)言描述的程序映射成實(shí)際硬件電路中的結(jié)構(gòu)是不能實(shí)現(xiàn)的,也稱為不可綜合語(yǔ)法。
“綜合”要做的事情有:編譯rtl代碼,從庫(kù)里選擇用到的門器件,把這些器件按照“邏輯”搭建成“門”電路。
不可綜合,是指找不到對(duì)應(yīng)的“門”器件來(lái)實(shí)現(xiàn)相應(yīng)的代碼。比如“#100”之類的延時(shí)功能,簡(jiǎn)單的門器件是無(wú)法實(shí)現(xiàn)延時(shí)100個(gè)單元的,還有打印語(yǔ)句等,也是門器件無(wú)法實(shí)現(xiàn)的。
下面是不可綜合或不推薦使用的代碼:
下面是推薦使用的設(shè)計(jì)代碼:
第3節(jié) 模塊結(jié)構(gòu)
模塊(module)是Verilog的基本描述單元,是用于描述某個(gè)設(shè)計(jì)的功能或結(jié)構(gòu)及與其他模塊通信的外部端口。
模塊在概念上可等同一個(gè)器件。
基于模塊,Verilog采用模塊化的設(shè)計(jì)方法使得系統(tǒng)更有條理也便于仿真和測(cè)試。
對(duì)大型的數(shù)字電路進(jìn)行設(shè)計(jì)時(shí),可以將其分割成大小不一的小模塊,每個(gè)小模塊實(shí)現(xiàn)特定的功能,最后通過(guò)由頂層模塊調(diào)用子模塊的方式來(lái)實(shí)現(xiàn)整體功能,這就是自頂向下(Top-Down)的設(shè)計(jì)思想。
模塊有5個(gè)主要部分:端口定義、參數(shù)定義(可選)、I/O說(shuō)明、內(nèi)部信號(hào)聲明和功能定義。它的一般語(yǔ)法結(jié)構(gòu)如下所示:
3.1模塊名和端口定義
其中模塊是以module開(kāi)始,以endmodule結(jié)束。模塊名是模塊唯一的標(biāo)識(shí)符,一般建議模塊名盡量用能夠描述其功能的名字來(lái)命名,并且模塊名和文件名相同。
模塊的端口表示的是模塊的輸入和輸出口名,也是其與其他模塊聯(lián)系端口的標(biāo)識(shí)。
模塊名和端口定義語(yǔ)法格式
module module_name(
端口1,
端口2,
端口3,
);
endmodule
3.2 參數(shù)定義
參數(shù)定義是將常量用符號(hào)代替以增加代碼可讀性和可修改性。
參數(shù)定義的語(yǔ)法格式:
parameter DATA_W = x; // x是一個(gè)常數(shù)
3.3 接口定義
模塊的端口可以是輸入端口、輸出端口或雙向端口。
輸入端口語(yǔ)法格式:
input [信號(hào)位寬-1: 0] 端口名;
輸出端口語(yǔ)法格式:
output [信號(hào)位寬-1: 0] 端口名;
雙向端口語(yǔ)法格式:
inout [信號(hào)位寬-1: 0] 端口名;
3.4 信號(hào)類型
信號(hào)類型有兩種:reg(寄存器型)和wire(線網(wǎng)型)
語(yǔ)法格式如下
reg [信號(hào)位寬-1: 0] R變量1;
wire [信號(hào)位寬-1: 0] W變量1;
3.5 功能描述
模塊中最重要的部分是邏輯功能定義部分,有三種方法可以在模塊中產(chǎn)生邏輯
- 使用
assign
聲明語(yǔ)句,如描述一個(gè)兩輸入的與門assign a = b & c
- 使用
always
塊 - 模塊例化,模塊例化指:在此模塊中調(diào)用其他模塊。
- 模塊例化可以采用位置關(guān)聯(lián)和名字關(guān)聯(lián),建議按照名字來(lái)關(guān)聯(lián),可能有些關(guān)鍵沒(méi)有用到,可以在映射中采用空白處理。
3.6 模塊例化
信號(hào)端口可以通過(guò)位置關(guān)聯(lián),也可以通過(guò)名稱關(guān)聯(lián),但是不能混合使用。建議使用名稱關(guān)聯(lián)。
舉例說(shuō)明模塊的例化
module and (C, A, B);
input A, B;
output C;
// 功能邏輯
endmodule
// 模塊and_2就是對(duì)模塊and的例化
module and_2(XXX);
// 端口定義
// 方式1:例化時(shí),采用位置關(guān)聯(lián)
and A1(T3, A, B);
// 方式2:例化時(shí),采用名稱關(guān)聯(lián)
and A2(
.C(T3),
.A(A),
.B(B)
);
endmodule
在實(shí)例化中,有些管腳沒(méi)用到,可在映射中采用空白處理,如:
DFF d1(
.Q(QS),
.Qbar(), // 該管腳懸空
.Data(D),
.Preset(), // 該管腳懸空
.Clock(CK)
);
第4節(jié) 信號(hào)類型
4.1 信號(hào)位寬
定義信號(hào)類型的同時(shí),必須定義好信號(hào)的位寬。默認(rèn)信號(hào)的位寬是1位,如位寬為1的wire型信號(hào)a可直接用wire a
來(lái)表示。信號(hào)的位寬大于1位時(shí)就一定要表示出來(lái),如用wire [7: 0]
來(lái)表示該wire信號(hào)的位寬為8位。
信號(hào)的位寬取決于該信號(hào)要表示的最大值。該信號(hào)能表示的無(wú)符號(hào)數(shù)最大值是:2n-1,其中n表示該信號(hào)的位寬。
4.2 線網(wǎng)類型wire
線網(wǎng)類型代表的就是物理連接線,因此其不存儲(chǔ)邏輯值,必須由器件驅(qū)動(dòng)。通常用assign進(jìn)行賦值。
定義wire型變量如下所示:
wire [3: 0] Sat; // 4位線型信號(hào)
wire Cnt; // 1位線型信號(hào)
wire [31: 0] Kisp, pisp, Lisp; // 32位線型信號(hào)
4.3 寄存器類型reg
reg是最常用的寄存器類型,寄存器類型通常用于對(duì)存儲(chǔ)單元的描述,如D型觸發(fā)器、ROM等。
寄存器類型信號(hào)的特點(diǎn)是:在某種觸發(fā)機(jī)制下分配了一個(gè)值,在下一個(gè)觸發(fā)機(jī)制到來(lái)之前保留原值。
值得注意的是:reg類型的變量不一定是存儲(chǔ)單元,如在always語(yǔ)句中進(jìn)行描述的必須使用reg類型的變量。
定義reg類型變量如下所示:
reg [3: 0] Sat; // 4位寄存器型信號(hào)
reg Cnt; // 1位寄存器
reg [31: 0] Kisp; // 32位寄存器
4.4 wire和reg的區(qū)別
reg型信號(hào)并不一定生成寄存器。
針對(duì)何時(shí)使用reg何時(shí)使用wire,此處總結(jié)一套方法:在本模塊中使用always設(shè)計(jì)的信號(hào)都定義為reg型,其他信號(hào)都定義為wire型。
第5節(jié) 功能描述-組合邏輯
5.1 assign語(yǔ)句
assign語(yǔ)句是連續(xù)賦值語(yǔ)句,一般是將一個(gè)變量的值不間斷地賦值到另一個(gè)變量,兩個(gè)變量之間就類似于被導(dǎo)線連在了一起,習(xí)慣上當(dāng)做連線用。
assign語(yǔ)句的基本格式
assign a = b (邏輯運(yùn)算符) c;
assign語(yǔ)句的功能屬于組合邏輯的范疇,應(yīng)用范圍可以概括為以下幾點(diǎn):
- 持續(xù)賦值
- 連線
- 對(duì)wire型變量賦值
需要說(shuō)明的是:多條assign語(yǔ)句之間相互獨(dú)立、并行執(zhí)行。
5.2 組合邏輯always語(yǔ)句
always語(yǔ)句是條件循環(huán)語(yǔ)句,執(zhí)行機(jī)制是通過(guò)一個(gè)稱為敏感變量表的事件驅(qū)動(dòng)來(lái)實(shí)現(xiàn)的。always語(yǔ)句的基本格式是:
always @(敏感事件)begin
程序語(yǔ)句
end
always
是@
后面跟著事件。整個(gè)always
的意思是:當(dāng)敏感事件的條件滿足時(shí),就執(zhí)行一次“程序語(yǔ)句”。敏感事件每滿足一次,就執(zhí)行“程序語(yǔ)句”一次。
示例代碼
always @(a or b or c or sel)begin
if(sel == 0)
c = a + b
else
c = a + d
end
示例代碼的意思是當(dāng)信號(hào)a或信號(hào)b或信號(hào)d或信號(hào)sel發(fā)生變化時(shí),就執(zhí)行2-5行。sel值為0時(shí),c的結(jié)果為a+b;sel值不為0時(shí),c的結(jié)果為a+d。
當(dāng)敏感信號(hào)非常多時(shí),很容易把敏感信號(hào)遺漏,為了避免這種情況可以用*
來(lái)代替。這個(gè)*
指的是“程序語(yǔ)句”中所有的條件信號(hào),即a、b、d、sel(不包括c),推薦這種寫法。具體代碼如下所示:
always @(*)begin
if (sel==0)
c = a + b
else
c = a + d
end
這種條件信號(hào)變化則結(jié)果立即變化的always語(yǔ)句被稱為“組合邏輯”。
注意點(diǎn)
- 組合邏輯always語(yǔ)句中敏感變量必須寫全,或者用
*
代替 - 組合邏輯器件的賦值采用阻塞賦值“=”,時(shí)序邏輯器件的賦值語(yǔ)句采用非阻塞賦值
<=
。
5.3 數(shù)字進(jìn)制
數(shù)字表示方式
在Verilog中數(shù)字表示方式最常用的格式是:<位寬>'<基數(shù)><數(shù)值>
,如4'b1011
。
位寬,通俗理解就是位寬是幾就有幾根線??蛇x項(xiàng),如果沒(méi)有這一項(xiàng)就可以通過(guò)常量的值進(jìn)行推斷。如b10010
可以推斷出位寬為5。
基數(shù),表示數(shù)值的進(jìn)制??梢允嵌M(jìn)制(b或B)、十進(jìn)制(d或D)、八進(jìn)制(o或O)、十六進(jìn)制(h或H)??蛇x項(xiàng),默認(rèn)為十進(jìn)制。
數(shù)值,是由基數(shù)所決定的表示常量真實(shí)值的一串ASCII碼。如果基數(shù)定義為b或B,數(shù)值可以是0、1、x或X(不定態(tài))、z或Z(高阻態(tài))。其他進(jìn)制不可以有x或z。位寬比數(shù)值的位數(shù)大,數(shù)值高位補(bǔ)零,位寬比數(shù)值的位數(shù)小,數(shù)值取低位。
二進(jìn)制
二進(jìn)制是FPGA中最重要的進(jìn)制。
二進(jìn)制表示數(shù)
二進(jìn)制表示有符號(hào)數(shù),加一根線表示符號(hào)。
二進(jìn)制表示小數(shù)
不管表示小數(shù)還是整數(shù),可以自定義二進(jìn)制數(shù)值表(自己對(duì)數(shù)值進(jìn)行編碼)。
不定態(tài)
數(shù)字電路中只有高電平和低電平,分別用1和0表示。但是代碼中常常能見(jiàn)到如1'bx
和1'bz
這樣的代碼。數(shù)字電路中沒(méi)有實(shí)際的電平來(lái)對(duì)應(yīng)x和z。x和z更多地是用來(lái)表示設(shè)計(jì)者的意圖或用于仿真目的,旨在告訴綜合器和仿真器如何解釋這段代碼。
x態(tài),稱為不定態(tài),常用于判斷條件,旨在告訴綜合工具,無(wú)論電平是0或1都可以。
判斷條件din==4'b10x0
等價(jià)于din==4'b1000||din==4'b1010
,其中||
是“或”符號(hào)。
注意點(diǎn):
- 電路中沒(méi)有不定態(tài),只有高電平和低電平
- 不定態(tài)只能用于表示不關(guān)注電路是高電平還是低電平
- 建議所有信號(hào)寫成明確的0或1,不要寫成不定態(tài)
高阻態(tài)
z態(tài),稱為高阻態(tài),表示設(shè)計(jì)者不驅(qū)動(dòng)這個(gè)信號(hào)(既不給0又不給1),通常用于三態(tài)門接口當(dāng)中。
硬件上使用三態(tài)門是為了減少管腳,而fpga內(nèi)部沒(méi)有必要減少連線,所以在fpga內(nèi)部使用高阻態(tài)‘z’是沒(méi)有意義的,建議不要使用高阻態(tài)z。
這樣的電路是由下面兩行代碼實(shí)現(xiàn)的
assign data = (wr_en==1)?wr_data:1'bz;
assign rd_data = data;
總的來(lái)說(shuō)高阻態(tài)“z”是表示“不驅(qū)動(dòng)總線”這個(gè)行為。
5.4 算數(shù)運(yùn)算符
盡量避免除法和求余,如果一定要用到除法,盡量讓除數(shù)為2的n次方。
加減是最簡(jiǎn)單的運(yùn)算,而乘法可以拆解為多個(gè)加法運(yùn)算。加減乘對(duì)應(yīng)的電路都比較小。
位寬問(wèn)題
FPGA開(kāi)發(fā)中,需要注意信號(hào)的位寬,運(yùn)算的最終結(jié)果取決于“=”左邊信號(hào)的位寬,保留低位,丟棄高位。以減法為例
補(bǔ)碼問(wèn)題
- 使用加法的時(shí)候,為了保證結(jié)果的正確性,必須要保留進(jìn)位,也就是結(jié)果要擴(kuò)展位寬。
- 正數(shù)的補(bǔ)碼不變,負(fù)數(shù)的補(bǔ)碼是數(shù)值位取反后加1。
- FPGA及其他計(jì)算機(jī)系統(tǒng)中,所有數(shù)據(jù)的保存方式都是以補(bǔ)碼的方式保存。
5.5 邏輯運(yùn)算符
邏輯與(符號(hào):&&
)
-
1位邏輯與
電路圖如圖
說(shuō)明:A和 B 都為 1 , C 為 1; 否則 C 為 0。
verilog代碼示例
reg A, B; always@(*)begin C = A && B; end
-
多位邏輯與
電路圖如圖
說(shuō)明:A或 B 都不 為 0 時(shí),C 為 1, 否則 為 0。
verilog代碼示例
reg[2: 0] A, B, C; always@(*)begin C = A && B; end
邏輯或(符號(hào):||
)
-
1位邏輯或
電路圖如圖
說(shuō)明:A和 B 其中 1 個(gè) 為 1, C 為 1;否 則 C 為 0。
verilog代碼示例
reg A, B; always@(*)begin C = A || B; end
-
多位邏輯或
電路圖如圖
說(shuō)明:A和 B 其中 1 個(gè) 非 0, C 為 1;否 則 C 為 0。
verilog代碼示例
reg[2: 0] A, B, C; always@(*)begin C = A || B; end
邏輯非
verilog代碼示例
if(!a)begin{
}
end
總結(jié)
- 進(jìn)行邏輯運(yùn)算的時(shí)候,如果操作數(shù)是多位的,則可以將操作數(shù)看做整體,若操作數(shù)中每一位都是0值則為邏輯0值;若操作數(shù)中至少存在一個(gè)1則為邏輯1值。非零為真
- 雙目邏輯運(yùn)算符
&&
和||
的優(yōu)先級(jí)高于算術(shù)運(yùn)算符,!
的優(yōu)先級(jí)高于雙目邏輯運(yùn)算符。 - 為了提高程序的可讀性,多用括號(hào)區(qū)分運(yùn)算符的優(yōu)先級(jí)
- 多用
邏輯與
和邏輯或
,少用邏輯非
5.6 按位邏輯運(yùn)算符
Verilog語(yǔ)言中有4種按位運(yùn)算符
-
~
:一元非,相當(dāng)于非門運(yùn)算 -
&
:二元與,相當(dāng)于與門運(yùn)算 -
|
:二元或,相當(dāng)于或門運(yùn)算 -
^
:二元異或,相當(dāng)于異或門運(yùn)算
這4個(gè)按位運(yùn)算符有如下幾種用法
-
單目按位與
表示對(duì)一個(gè)信號(hào)進(jìn)行每位之間相與的操作,例子如下
-
單目按位或
表示對(duì)一個(gè)信號(hào)每位進(jìn)行相或的操作,例子如下
-
單目按位非
表示對(duì)一個(gè)信號(hào)進(jìn)行每位取反的操作
-
雙目按位與
表示對(duì)兩個(gè)信號(hào)進(jìn)行對(duì)應(yīng)位相與的操作
如果操作數(shù)長(zhǎng)度不相等,長(zhǎng)度較小的操作數(shù)在最左側(cè)添0補(bǔ)位
-
雙目按位或
表示對(duì)兩個(gè)信號(hào)進(jìn)行對(duì)應(yīng)位相或的操作
如果操作數(shù)長(zhǎng)度不相等,長(zhǎng)度較小的操作數(shù)在最左側(cè)添0補(bǔ)位
-
雙目按位異或
表示對(duì)兩個(gè)信號(hào)進(jìn)行對(duì)應(yīng)位相異或的操作
如果操作數(shù)長(zhǎng)度不相等,長(zhǎng)度較小的操作數(shù)在最左側(cè)添0補(bǔ)位
5.7 關(guān)系運(yùn)算符
關(guān)系運(yùn)算符有:>(大于)、<(小于)、>=(不小于)、<=(不大于)、==(邏輯相等)和!=(邏輯不等)。
關(guān)系操作符的結(jié)果為真(1)或假(0)。如果操作數(shù)中有一位為x或z,那么結(jié)果為x。
如果操作數(shù)長(zhǎng)度不同,長(zhǎng)度較短的操作數(shù)在最重要的位方向(左方)添0補(bǔ)齊。
5.8 移位運(yùn)算符
在VerilogHDL中有兩種移位運(yùn)算符,分別為“<<”(左移位運(yùn)算符)和“>>”(右移位運(yùn)算符)。下面分別介紹兩者的用法
移位操作實(shí)際上是選哪根線相連
左移
-
左移操作屬于邏輯移位,需要用0來(lái)填補(bǔ)移出的空位,即在低位補(bǔ)0。
-
左移操作需根據(jù)位寬儲(chǔ)存結(jié)果,例子如下
-
左移操作的操作數(shù)可以是常數(shù),也可以是信號(hào)。同樣,左移操作的移位數(shù)可以是常數(shù),也可以是信號(hào)。
右移
- 右移操作屬于邏輯移位,需要用0來(lái)填補(bǔ)移出的空位,即在高位補(bǔ)0,補(bǔ)多少個(gè)0,取決于保存結(jié)果的信號(hào)的位寬。
- 與左移操作相似,右移操作是不消耗邏輯資源的,其只是線的連接。
- 移操作的移位數(shù)可以是常數(shù),也可以是信號(hào)。
注意
- 通過(guò)左移實(shí)現(xiàn)乘法
- 通過(guò)右移實(shí)現(xiàn)除法
- 利用左移產(chǎn)生獨(dú)熱碼(one-hot code)
5.9 條件運(yùn)算符
條件語(yǔ)句的三種常見(jiàn)形式,如下所示:
Verilog中條件語(yǔ)句共有4種形式
- 三目運(yùn)算符
- if語(yǔ)句
- case語(yǔ)句
- 選擇語(yǔ)句
三目運(yùn)算符
-
語(yǔ)法格式
條件表達(dá)式? 真表達(dá)式: 假表達(dá)式; condition_expr? true_expr: false_expr;
其含義為:當(dāng)
條件表達(dá)式
為真時(shí),執(zhí)行真表達(dá)式
;當(dāng)條件表達(dá)式
為假時(shí),執(zhí)行假表達(dá)式。 -
示例
always@(*) begin r=s? t: u; end
其對(duì)應(yīng)的電路圖如下:
-
條件表達(dá)式的作用實(shí)際上類似于多路選擇器,其可以用if-else語(yǔ)句代替
-
條件運(yùn)算符可用在數(shù)據(jù)流建模中的條件賦值,這種情況下條件表達(dá)式的作用相當(dāng)于控制開(kāi)關(guān)。
-
條件三目表達(dá)式可以嵌套使用
if語(yǔ)句
-
條件表達(dá)式需要使用括號(hào)括起來(lái)
-
如果存在if-if語(yǔ)句,可能會(huì)有二義性,需要使用語(yǔ)句
begin--end
-
簡(jiǎn)單示例
if(Sum < 60)begin Grade = C; Total_C = Total_C + 1; end else if(Sum < 75)begin Grade = B; Total_B = Total_B + 1; end else begin Grade = A; Total_A = Total_A + 1; end
case語(yǔ)句
-
語(yǔ)法
case (<expression>) case_item1 : <single statement> case_item2, case_item3 : <single statement> case_item4 : begin <multiple statements> end default : <statement> endcase
-
建議:case語(yǔ)句的缺省項(xiàng)必須寫,防止產(chǎn)生鎖存器。
選擇語(yǔ)句
-
語(yǔ)法
vect[a +: b] 或 vect[a -: b] 1. vect為變量名 2. a為起始位置,可以是常數(shù)也可以是信號(hào) 3. 加號(hào)或者減號(hào)代表升序或者降序 4. b表示位寬,只能是常數(shù)
-
vect[a +: b]
等價(jià)于vect[a : a+b-1]
,示例如下:vect[7 +: 3]==vect[7 : 9]
vect[9 -: 4]==vect[9 : 6]
-
選擇語(yǔ)句的實(shí)際用法如下
需求:當(dāng)cnt==0時(shí),將
din[7: 0]
賦值給data[15: 8]
;當(dāng)cnt==1
時(shí),將din[7: 0]
賦值給data[7: 0]
實(shí)現(xiàn):
data[15-8*cnt -: 8] <= din[7: 0]
-
選擇語(yǔ)句其本質(zhì)上時(shí)一個(gè)選擇器
總結(jié)
- 初學(xué)者喜歡使用if-else,但case語(yǔ)句電路時(shí)延更低
- if-else有優(yōu)先級(jí),綜合會(huì)得到類似級(jí)聯(lián)的結(jié)構(gòu);case無(wú)優(yōu)先級(jí),電路是并行的會(huì)得到多路選擇器
- 雖然在RTL視圖中,兩種語(yǔ)句綜合出的電路存在著較大的差別,但是在布局布線時(shí)會(huì)自動(dòng)對(duì)電路進(jìn)行優(yōu)化,最終映射到FPGA上電路基本毫無(wú)差別。
5.10 拼接運(yùn)算符
拼接運(yùn)算符不消耗硬件資源,只是把線換一種組合方式,參照實(shí)例如下:
wire [7: 0] Dbus;
// 以反轉(zhuǎn)的順序?qū)⒌投?位賦給高端4位
assign Dbus[7: 4] = {Dbus[0], Dbus[1], Dbus[2], Dbus[3]};
// 高4位與低4位交換
assign Dbus = {Dbus[3: 0], Dbus[7: 4]};
第6節(jié) 功能描述- 時(shí)序邏輯
6.1 always語(yǔ)句
時(shí)序邏輯的代碼一般有兩種
- 同步復(fù)位的時(shí)序邏輯
- 異步復(fù)位的時(shí)序邏輯
同步復(fù)位的時(shí)序邏輯中,復(fù)位不是立即有效,而是沿著時(shí)鐘上升沿時(shí)復(fù)位才有效,代碼結(jié)構(gòu)如下
always @(posedge clk)begin
if (rst_n == 1'b0)
// 代碼語(yǔ)句
else begin
// 代碼語(yǔ)句
end
end
異步復(fù)位的時(shí)序邏輯中,復(fù)位立即有效,與時(shí)鐘無(wú)關(guān),其代碼結(jié)構(gòu)如下:
always @(posedge clk or negedge rst_n)begin
if (rst_n==1'b0)
// 代碼語(yǔ)句
else begin
// 代碼語(yǔ)句
end
end
為了教學(xué)方便,本課程采用異步時(shí)鐘邏輯
6.2 D觸發(fā)器
數(shù)字電路中介紹了多種觸發(fā)器,如JK觸發(fā)器、D觸發(fā)器、RS觸發(fā)器、T觸發(fā)器等
在FPGA中使用的是最簡(jiǎn)單的D觸發(fā)器
D觸發(fā)器結(jié)構(gòu)和功能
上圖為D觸發(fā)器的結(jié)構(gòu)圖,可以將其視為一個(gè)芯片,該芯片擁有4個(gè)管腳,其中3個(gè)是輸入管腳,1個(gè)輸出管腳
- 輸入管腳
- 時(shí)鐘:clk
- 復(fù)位:rst_n
- 信號(hào):d
- 輸出管腳
- 輸出:q
D觸發(fā)器的功能
- 當(dāng)復(fù)位rst_n管腳為0時(shí),輸出q立刻為0
- 當(dāng)復(fù)位rst_n管腳為1時(shí)
- 在時(shí)鐘clk的上升沿時(shí),將信號(hào)d的值傳給q
- 時(shí)鐘clk不是上升沿時(shí),d變化,q不會(huì)發(fā)生變化
D觸發(fā)器的波形圖示例
D觸發(fā)器的Verilog代碼
always @(posedge clk or negedge rst_n)begin
if (rst_n==1'b0)begin
q<=0;
end
else begin
q<=d;
end
end
理想波形圖和實(shí)際波形圖
先有時(shí)鐘上升沿,此為因,然后再將d的值賦給q,這才是結(jié)果。這個(gè)因果是有先后關(guān)系的,對(duì)于硬件來(lái)說(shuō)這個(gè)“先后”無(wú)論是多么地迅速,也一定會(huì)占用一定時(shí)間,所以q的變化會(huì)稍后于clk的上升沿。例如下圖就是硬件的實(shí)際變化情況。
上升沿時(shí)刻輸出信號(hào)的值與上升沿前一瞬間輸出信號(hào)的值相同
6.3 時(shí)鐘
時(shí)鐘信號(hào)就是每隔固定時(shí)間上下變化的信號(hào)
- 時(shí)鐘周期:本次上升沿和上一次上升沿之間占用的時(shí)間
- 時(shí)鐘頻率:時(shí)鐘周期的倒數(shù)
- 占空比:高電平占整個(gè)時(shí)鐘周期的時(shí)間
FPGA時(shí)鐘的占空比一般是50%。占空比對(duì)與FPGA而言沒(méi)有太大的意義,因?yàn)镕PGA使用的是時(shí)鐘上升沿來(lái)觸發(fā),設(shè)計(jì)師們更加關(guān)心的是時(shí)鐘頻率。
普通FPGA所支持的時(shí)鐘頻率不超過(guò)150M,高端器件一般不超過(guò)700M。FPGA所對(duì)應(yīng)的時(shí)鐘周期一般在納秒級(jí)。
時(shí)鐘是FPGA中最重要的信號(hào),其他所有信號(hào)在時(shí)鐘的上升沿統(tǒng)一變化,這就像軍隊(duì)的令旗。所有士兵看到令旗到來(lái)的時(shí)刻,執(zhí)行已經(jīng)設(shè)定好的命令。
FPGA系統(tǒng)的時(shí)鐘越少越好,最好只存在一個(gè)時(shí)鐘。不要用自制的分頻時(shí)鐘;不要敏感列表檢測(cè)信號(hào)的上升沿。
6.4 時(shí)序邏輯代碼和硬件
always @(posedge clk or negedge rst_n)begin
if (rst_n==1'b0)begin
q<=0;
end
else begin
q<=a+d;
end
end
上面代碼的電路圖表示如下所示:
上面代碼也可以如下表示,兩份代碼表示的電路圖完全一樣,兩種寫法視情況而定。下面的寫法即為組合邏輯+D觸發(fā)器。
assign c=a+d;
always @(posedge clk or negedge rst_n)begin
if (rst_n==1'b0)begin
q<=0;
end
else begin
q<=a+d;
end
end
6.5 阻塞賦值和非阻塞賦值
Verilog語(yǔ)言支持兩種類型的賦值:
- 阻塞賦值:使用
=
語(yǔ)句。在一個(gè)begin...end
中,阻塞賦值是按照賦值順序一行一行執(zhí)行的。 - 非阻塞賦值:使用
<=
語(yǔ)句。在一個(gè)begin...end
中,在同一時(shí)間內(nèi)同時(shí)賦值
例如下面的代碼
begin
c=a;
d=c+a;
end
begin
c<=a;
d<=c+a;
end
語(yǔ)法層面分析上述代碼如下所示:
規(guī)范要求:組合邏輯都使用阻塞賦值,時(shí)序邏輯都使用非阻塞賦值。制定這個(gè)規(guī)范的原因并不是考慮語(yǔ)法需要,而是為了正確的進(jìn)行硬件描述。
第4章 FPGA開(kāi)發(fā)平臺(tái)介紹
第1節(jié) 開(kāi)發(fā)環(huán)境
目前兩大FPGA制造商分別是Xilinx(目前被AMD收購(gòu))和Altera(目前被Intel收購(gòu))。Xilinx芯片的開(kāi)發(fā)工具包括vivado和ISE,Altera芯片的開(kāi)發(fā)工具是Quartus。
本課程使用的開(kāi)發(fā)板是XILINX-K7芯片
第2節(jié) 軟件界面
Vivado
第3節(jié) 第一個(gè)上板例程
本節(jié)關(guān)鍵點(diǎn)
- 新建工程
- 使用Verilog代碼錄入設(shè)計(jì)
- 將綜合的電路布局到Xilinx FPGA
- 分配電路的輸入輸出到FPGA上的指定引腳
- 編程配置教學(xué)板上的FPGA芯片
3.1 新建工程
-
填寫工程名和工程位置
-
project type一般為
RTL Project
-
新的空白工程一般不用
Add Source
和Add Constraints
-
選擇默認(rèn)的Xilinx器件
3.2 代碼設(shè)計(jì)
-
新建.v文件:File-> Text Editor->New File
-
在工程目錄下新建src目錄
-
在src目錄下新建
light.v
文件
-
-
Add Sources:點(diǎn)擊Add Sources按鈕,選中第二個(gè)單選按鈕
Add or create design sources
,將light.v
添加進(jìn)去
3.3 編譯設(shè)計(jì)電路
完成代碼設(shè)計(jì)之后,需要經(jīng)過(guò)Vivado軟件中的幾個(gè)工具的處理,分別是:
- 分析代碼
- 綜合電路
- 生成目標(biāo)芯片的實(shí)現(xiàn)內(nèi)容
這些應(yīng)用工具被聚集在一起,統(tǒng)稱為編譯器。
選擇Vivado左側(cè)下方的PROGRAM AND DEBUG->Generate Bitstream
運(yùn)行編譯器。
編譯一遍一般會(huì)報(bào)錯(cuò),提示沒(méi)有配置引腳
3.4 引腳分配
-
點(diǎn)擊Vivado左側(cè)下方的
IMPlEMENTATION->Open Implemented Design
-
切換到
I/O Planning
視圖 -
配置好引腳
-
Ctrl+S
,保存約束 -
重新編譯
3.5 下載和調(diào)試
-
點(diǎn)擊
PROGRAM AND DEBUG->Open Hardware Manager->Open Target->Auto Connect
-
點(diǎn)擊
PROGRAM AND DEBUG->Open Hardware Manager->Program Device
,把編譯生成的Bit流文件下載到開(kāi)發(fā)板上文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-481280.html -
在開(kāi)發(fā)板上撥動(dòng)開(kāi)關(guān)進(jìn)行調(diào)試文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-481280.html
- 調(diào)試的時(shí)候發(fā)現(xiàn)與預(yù)期不符合,就需要定位問(wèn)題,此時(shí)將使用到ILA在線調(diào)試工具,具體使用方法見(jiàn)下一章。
- 完成調(diào)試之后,工程最終確定之后,需要把工程固化到開(kāi)發(fā)板里面,讓開(kāi)發(fā)板只要上電就可以運(yùn)行工程,而不需要重新下載。具體方法如下:
Settings->Project Settings->Bitstream->勾選-bin_file
- 重新編譯一次生成bin文件,生成的文件會(huì)放在
工程目錄->工程名.runs->impl_1
目錄下 - 在保證連接開(kāi)發(fā)板的情況下,點(diǎn)擊
PROGRAM AND DEBUG->Open Hardware Manager->Add Configuration Memory Device
- 選擇Flash芯片的型號(hào)
- 選擇生成的bin文件,將工程固化到fpga中
到了這里,關(guān)于《FPGA至簡(jiǎn)設(shè)計(jì)原理與應(yīng)用》學(xué)習(xí)筆記1 —— FPGA基礎(chǔ)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!