從現(xiàn)代FPGA設(shè)計(jì)相關(guān)的數(shù)字電路基礎(chǔ)和Verilog硬件描述語言開始,結(jié)合筆者多年的教學(xué)和實(shí)踐經(jīng)驗(yàn),本書詳細(xì)講述了VerilogHDL及其仿真,業(yè)內(nèi)常用IO規(guī)范和各種總線,數(shù)字邏輯在數(shù)字信號處理、數(shù)字通信和控制方向的典型功能單元,F(xiàn)PGA的常規(guī)結(jié)構(gòu),靜態(tài)時序分析等。
前 言筆者2004年開始學(xué)習(xí)FPGA,并被其強(qiáng)大的靈活性所吸引,從此一切成本不敏感的項(xiàng)目能用FPGA的,則不會考慮其他方案。從簡單的邏輯控制、MCU替代到高速的信號處理、網(wǎng)絡(luò)與通信應(yīng)用,沒有什么是一片F(xiàn)PGA(或含有處理器核)不能駕馭的,“一片不行,那就兩片!”在成本不敏感的領(lǐng)域,如科研、產(chǎn)品或芯片原型研發(fā)和驗(yàn)證中,F(xiàn)PGA扮演了極其重要的角色,因?yàn)樵谶@些領(lǐng)域往往包含大量特殊的、創(chuàng)新的定制邏輯和功能,或者具備極高的數(shù)據(jù)傳輸帶寬,并非MCU、MPU(DSP是MPU的一種)或應(yīng)用處理器所能勝任。
即使是MCU或MPU能夠勝任的工作,若使用FPGA來完成,你可以肆意揮灑自己的創(chuàng)意,構(gòu)建符合自己習(xí)慣的邏輯接口和功能,創(chuàng)造符合特殊要求的功能模塊和處理器外設(shè),而不必像使用通用MCU或MPU那樣,需要學(xué)習(xí)為了功能通用而設(shè)置的紛繁復(fù)雜的接口、控制寄存器或API函數(shù)。當(dāng)然,一切的前提是項(xiàng)目成本不敏感,并且你具備深厚的FPGA開發(fā)功力——這比MCU或MPU開發(fā)要難很多。
但終端產(chǎn)品領(lǐng)域是FPGA尚無法觸及的,主要限制是成本、功耗和開發(fā)難度。在成本和功耗上,F(xiàn)PGA靈活的本質(zhì)決定了它無法與MCU或MPU抗衡,同時終端產(chǎn)品往往出貨量也很大,因而在高帶寬或特殊定制邏輯方面,也可以由ASIC勝任——ASIC在量大時成本極低。
而開發(fā)難度大則源于多個方面。在理論方面,想要學(xué)好FPGA,甚至說想要入門FPGA,都必須掌握扎實(shí)的數(shù)字邏輯基礎(chǔ)知識。在語言方面,用于FPGA開發(fā)的硬件描述語言(HDL)描述的數(shù)字邏輯電路是并行的,與人類思維的串行性(即一步一步的思考)不符,而MCU等開發(fā)使用的程序語言則符合人類思維的串行性,相對易于入門和掌握。依筆者淺見,“程序”一詞含有“依序執(zhí)行的過程”之意,與可綜合的硬件描述語言的并行性不符,因而本書盡量避免使用“程序”一詞指代可綜合的硬件描述語言代碼。
開發(fā)困難還源于FPGA技術(shù)近年來的快速發(fā)展和FPGA相關(guān)教育的滯后。
筆者自六年前開始面向華中科技大學(xué)啟明學(xué)院電工電子科技創(chuàng)新中心(以下簡稱“創(chuàng)新中心”)的學(xué)生開設(shè)與FPGA應(yīng)用相關(guān)的選修課,并為他們設(shè)計(jì)開發(fā)板,無論課程內(nèi)容還是開發(fā)板,每年都可能會變動以跟進(jìn)新的技術(shù)發(fā)展。
創(chuàng)新中心的學(xué)生主要來自全校各電類相關(guān)院系,并經(jīng)過嚴(yán)格的考核選入,都是理論成績和實(shí)踐能力兼優(yōu)并對電子技術(shù)有著濃厚興趣的學(xué)生。即便如此,筆者依然感受到FPGA應(yīng)用教學(xué)的困難,特別是在引導(dǎo)和幫助他們使用FPGA實(shí)現(xiàn)具備一定難度和深度的功能的時候,或者在實(shí)現(xiàn)一個完備的電子電路系統(tǒng),比如將FPGA用作大學(xué)生電子設(shè)計(jì)競賽作品主控或者各類研究、雙創(chuàng)項(xiàng)目的主要實(shí)現(xiàn)平臺的時候。
筆者以為,F(xiàn)PGA應(yīng)用教學(xué)的困難直接反映了數(shù)字電路應(yīng)用教學(xué)的困難,這與傳統(tǒng)數(shù)字電路課程設(shè)置不無關(guān)系。在電子技術(shù)子領(lǐng)域日趨細(xì)分、國內(nèi)大學(xué)電類專業(yè)日趨細(xì)分的當(dāng)代,側(cè)重數(shù)字電路應(yīng)用的專業(yè)(如通信、電氣、自動化等)仍然在深入學(xué)習(xí)SR鎖存器的電路構(gòu)成,深入學(xué)習(xí)如何用74系列IC設(shè)計(jì)異步時序邏輯電路。筆者并不認(rèn)為這些不重要,但以為這些應(yīng)該是側(cè)重數(shù)字電路理論的專業(yè)(如電子、電信等)才需要深入學(xué)習(xí)的內(nèi)容,畢竟側(cè)重數(shù)字電路應(yīng)用的專業(yè)的學(xué)生以后一般不需要設(shè)計(jì)IC;不需要在數(shù)字邏輯電路中做晶體管級的優(yōu)化;也不需要為少數(shù)關(guān)鍵路徑而動用異步邏輯、鎖存器邏輯。相應(yīng)地,在側(cè)重數(shù)字電路應(yīng)用的專業(yè)中,現(xiàn)代數(shù)字電路應(yīng)用中的同步時序邏輯內(nèi)容并沒有提升到應(yīng)有的地位,與之相關(guān)的時鐘概念和知識、常用的時序邏輯功能單元、基礎(chǔ)的時序分析概念和知識也是比較缺失的。
在本書中,筆者提煉和擴(kuò)展了傳統(tǒng)數(shù)字電路課程中與FPGA應(yīng)用相關(guān)的部分,形成了本書的第1章,便于讀者快速強(qiáng)化FPGA應(yīng)用設(shè)計(jì)所需的數(shù)字電路基礎(chǔ)知識,尚未學(xué)習(xí)數(shù)字電路課程的低年級讀者也可以通過學(xué)習(xí)第1章來入門數(shù)字電路基礎(chǔ)。
第2章則是SystemVerilog(IEEE 1800—2012)簡明語法講解,主要側(cè)重可綜合(即可以在FPGA中實(shí)現(xiàn))的語法,最新的IEEE 1800—2012標(biāo)準(zhǔn)較早期版本引入了不少“漂亮”的語法元素,讓筆者急切地想與讀者分享,后果是少數(shù)理應(yīng)可綜合的語法在目前主流開發(fā)工具中尚不支持,或許它們還需要一點(diǎn)時間來跟進(jìn),遇到這些特例,書中均會給出解決方法。
第3章是使用ModelSim進(jìn)行Verilog功能仿真的簡單教程。
第4章是Verilog的基本應(yīng)用,這一章主要介紹各種數(shù)字邏輯基本功能單元的描述,并著重介紹了時鐘、使能的概念和跨時鐘域處理。從這一章起,我們正式開始了FPGA應(yīng)用設(shè)計(jì)之旅。
第5章介紹IO規(guī)范,首先通識性地介紹了IO連接的常識和常見電平規(guī)范,而后以四種常見外部邏輯接口規(guī)范為例,介紹了通用接口邏輯的設(shè)計(jì)和實(shí)現(xiàn)。希望讀者能在學(xué)習(xí)過程中領(lǐng)會到此類設(shè)計(jì)的一般思路和處理方法。
第6章介紹片上系統(tǒng)的內(nèi)部互連。片上系統(tǒng)(SoC)結(jié)合了通用處理器和FPGA邏輯的優(yōu)勢,實(shí)現(xiàn)了軟硬件協(xié)同設(shè)計(jì),是當(dāng)下FPGA應(yīng)用技術(shù)的熱門。而要充分利用SoC的優(yōu)勢,發(fā)揮軟硬件協(xié)同的潛力,處理器系統(tǒng)與FPGA邏輯的高速互連至關(guān)重要。此章從一種簡單的互連接口入手,逐步過渡到目前應(yīng)用最為廣泛的AXI互連協(xié)議。
第7章介紹Verilog在數(shù)字
目 錄Contents
前言
第1章 數(shù)字電路基礎(chǔ)1
1.1 模擬電路與數(shù)字電路1
1.2 二進(jìn)制相關(guān)知識3
1.2.1 二進(jìn)制和其他進(jìn)制3
1.2.2 進(jìn)制間的相互轉(zhuǎn)換4
1.2.3 二進(jìn)制的四則運(yùn)算5
1.3 二進(jìn)制在電路中的表達(dá)6
1.3.1 有限字長和補(bǔ)碼6
1.3.2 負(fù)數(shù)、有符號數(shù)和無符號數(shù)6
1.4 門電路和基本邏輯運(yùn)算10
1.4.1 非門、與門和或門11
1.4.2 與非門和或非門12
1.4.3 異或門和同或門12
1.4.4 三種表達(dá)形式的轉(zhuǎn)換13
1.4.5 基本門的電路實(shí)現(xiàn)14
1.4.6 三態(tài)輸出和漏極開路輸出15
1.4.7 波形圖17
1.4.8 門電路的一些非典型應(yīng)用18
1.5 邏輯代數(shù)22
1.5.1 基本定律22
1.5.2 表達(dá)式的代數(shù)化簡法23
1.5.3 卡諾圖化簡法23
1.6 基本組合邏輯24
1.6.1 編碼器和譯碼器24
1.6.2 未定義的輸入狀態(tài)26
1.6.3 數(shù)據(jù)選擇器27
1.6.4 延遲和競爭冒險27
1.6.5 加法器28
1.6.6 乘法器31
1.6.7 數(shù)值比較器32
1.7 鎖存器32
1.7.1 SR鎖存器32
1.7.2 D鎖存器33
1.8 觸發(fā)器34
1.8.1 D觸發(fā)器、時鐘和使能34
1.8.2 D觸發(fā)器的異步和同步復(fù)位36
1.8.3 D觸發(fā)器的建立時間、保持時間和傳輸延遲37
1.8.4 其他觸發(fā)器38
1.9 時序邏輯40
1.9.1 移位寄存器和串-并互換40
1.9.2 延遲鏈42
1.9.3 分頻器43
1.9.4 計(jì)數(shù)器44
1.9.5 同步時序邏輯46
1.9.6 累加器48
1.10 存儲器49
1.10.1 存儲器容量和類型49
1.10.2 SRAM50
1.10.3 雙端口SRAM54
1.10.4 同步SRAM54
1.11 小數(shù)55
1.11.1 定點(diǎn)小數(shù)及其范圍和誤差55
1.11.2 定點(diǎn)小數(shù)的運(yùn)算56
1.11.3 浮點(diǎn)小數(shù)58
第2章 Verilog HDL和SystemVerilog60
2.1 硬件描述語言簡介60
2.2 設(shè)計(jì)方法和流程62
2.3 標(biāo)識符和關(guān)鍵字63
2.4 值、數(shù)和字面量63
2.4.1 整型常數(shù)64
2.4.2 浮點(diǎn)常數(shù)65
2.4.3 時間常數(shù)和字符串常數(shù)65
2.5 線網(wǎng)66
2.6 變量67
2.7 參數(shù)和常量68
2.8 類型和位寬轉(zhuǎn)換70
2.9 操作符和表達(dá)式71
2.9.1 位選取操作符74
2.9.2 位拼接和流運(yùn)算符74
2.9.3 按位邏輯運(yùn)算符76
2.9.4 縮減運(yùn)算符76
2.9.5 移位77
2.9.6 自增賦值和自減賦值77
2.9.7 條件判斷相關(guān)運(yùn)算符78
2.9.8 條件運(yùn)算符79
2.9.9 let語句79
2.10 結(jié)構(gòu)和聯(lián)合80
2.11 數(shù)組82
2.12 賦值、過程和塊83
2.12.1 賦值的延遲84
2.12.2 賦值的強(qiáng)度85
2.12.3 流程控制語句86
2.12.4 always過程88
2.12.5 阻塞和非阻塞賦值91
2.13 模塊93
2.14 接口97
2.15 生成塊100
2.16 任務(wù)和函數(shù)101
2.17 包102
2.18 系統(tǒng)任務(wù)和函數(shù)103
2.18.1 顯示相關(guān)104
2.18.2 文件相關(guān)105
2.18.3 存儲器相關(guān)106
2.18.4 仿真相關(guān)107
2.18.5 錯誤和信息107
2.18.6 類型轉(zhuǎn)換和數(shù)學(xué)函數(shù)107
2.19 編譯指令108
第3章 ModelSim和仿真111
3.1 仿真和測試的相關(guān)概念111
3.2 測試代碼編寫112
3.2.1 時鐘的產(chǎn)生112
3.2.2 復(fù)位的產(chǎn)生114
3.2.3 一般輸入的產(chǎn)生115
3.3 ModelSim軟件仿真流程118
3.3.1 主界面簡介118
3.3.2 創(chuàng)建工程119
3.3.3 向工程中添加文件121
3.3.4 開始仿真122
3.3.5 帶有信號和波形的例子124
3.4 波形和格式127
第4章 Verilog基本應(yīng)用130
4.1 代碼風(fēng)格130
4.2 常用組合邏輯單元的描述132
4.2.1 編碼器和譯碼器132
4.2.2 數(shù)據(jù)選擇器133
4.3 常用時序邏輯單元的描述133
4.3.1 移位寄存器133
4.3.2 延遲鏈134
4.3.3 計(jì)數(shù)器134
4.3.4 累加器136
4.4 時鐘域和使能137
4.5 跨時鐘域問題138
4.5.1 域外慢速跳沿138
4.5.2 域間狀態(tài)傳遞140
4.5.3 域間事件傳遞142
4.5.4 域間數(shù)據(jù)傳遞144
4.6 存儲器及其初始化144
4.6.1 各種模式的存儲器描述145
4.6.2 存儲器的初始化148
4.7 用存儲器實(shí)現(xiàn)延遲鏈151
4.8 單時鐘FIFO152
4.9 雙時鐘FIFO156
4.10 用戶按鍵和數(shù)碼LED157
4.10.1 用戶按鍵處理157
4.10.2 數(shù)碼LED159
4.11 PWM和死區(qū)161
4.11.1 單端PWM161
4.11.2 差分PWM162
4.11.3 死區(qū)165
4.12 正交增量編碼器接口166
4.13 有限狀態(tài)機(jī)170
4.13.1 秒表例子171
4.13.2 數(shù)字示波器觸發(fā)采樣例子175
第5章 IO規(guī)范與外部總線182
5.1 單端信號和地182
5.2 傳輸線與端接184
5.3 差分信號185
5.4 高速串行接口188
5.5 UART189
5.5.1 UART規(guī)范介紹189
5.5.2 發(fā)送器的設(shè)計(jì)190
5.5.3 接收器的設(shè)計(jì)193
5.5.4 UART收發(fā)仿真195
5.6 SPI197
5.6.1 SPI規(guī)范介紹197
5