這一章我們來實現第一個FPGA工程—LED流水燈。我們將通過流水燈例程向大家介紹一次完整的FPGA開發流程,從新建工程,代碼設計,綜合實現,管腳約束,下載FPGA程序。掌握本章內容,大家就算正式的開始入門FPGA開發了。
1.1.1.電路說明
1.1.2.新建工程
第一步:從開始菜單啟動Quartus II 13.1(64 bit) ,如下圖。
第二步:菜單欄選擇File—>New Project Wizard,新建工程。
第三步:彈出新建工程對話框,點擊Next,下一步。
第三步:如下圖,依次設置工程的存放路徑,工程名稱,頂層文件名稱,如圖依次設置好,這里我們將所有工程相關的文件放在prj文件夾內,便於工程文件與源碼文件的管理,同時要保持工程名稱與頂層實體名稱一致,繼續Next。
第四步:添加設計文件,這一步我們不需要添加,后續我們會新建相應的代碼文件。這里繼續Next。
第五步:選擇FPGA器件,如圖所示,這里我們選擇器件家族是CycloneIV系列的,封裝是FBGA,管腳數為256,速度等級為8。這里速度等級越小,速度越快。這里我們FPGA的具體型號為EP4CE6F17C8。大家通過這個對話框了解這個器件的基本資源。這里我簡單介紹一下這些資源的名稱,在后面的章節里我們還會詳細講解FPGA內部資源與結構。
1、CoreVoltage是內核電壓,Cyclone IV的內核電壓是1.2V。
2、LE是Altera最基本的邏輯單元,LEs表示FPGA的所有的邏輯資源, 我們這款芯片的邏輯資源數為6272。
3、User I/Os表示用戶IO數,這里共有180個IO可以供用戶使用。
4、Memory Bits與embedded multiplier 9-bit elements實際是一回事,后者簡稱M9K,M9K就是指位寬為9bit,深度為1K的RAM。這里一共有30個M9K,大家計算一下9*1024*30=276480就是Memory Bits。
5、PLL鎖相環,內部一共有兩個鎖相環。
6、Global clocks全局時鍾網絡數,這里一共有10個。設計中的時鍾信號會優先全局時鍾資源。
第六步:設置EDA工具,這里我們就設置一下仿真工具,使用默認Modelsim
-Altera,語言選擇Verilog。實際后面我們不建議大家使用Modelsim-Altera。我們會推薦大家在直接使用Modelsim-SE,后者的通用性更強。繼續Next。
第七步:總結新建工程的基本信息。到這里就完成工程的建立。
1.1.3.代碼設計
大家閱讀本節前,首先應該對Verilog語法有一定了解,其次閱讀我們提供的編碼規范文件,了解基本的命名規則和工程架構,從一開始就培養良好的編碼習慣。
第一步:新建verilog源文件,如下圖,點擊新建文件圖標,或者通過菜單欄File—>New打開新建文件向導。
第二步:在新建文件向導中,選擇Verilog HDL File,點擊OK。
第三步:因為我們已經配置過UltraEdit為默認編輯器,此時會打開UltraEdit(注意:UltraEdit編輯Verilog代碼前,要添加語法高亮文件,詳見3.3.3節內容),彈出新建源文件,將源文件另存至src文件夾下,命名為led_test.v與頂層實體名稱一致。我們將源碼文件和工程文件放在不同文件夾下,方便日后的工程維護。
第四步:編寫代碼邏輯,這里我們實現了一個流水燈。這里我們用了一個27位的計數器,時鍾頻率為50MHz,周期為20ns,當計數到第25位置位時,計數器值為25’d16777216,此時時間為16777216*20ns=335ms。這樣每大約經過335ms,計數器的[26:24]位就會加1。我們第一個always實現計數器,第二個always實現控制不同時間時LED的輸出,即每隔335ms改變一次LED的輸出狀態。
1. module led_test
2. (
3. input i_clk, //input clk ,50mhz
4. input i_rst_n, //reset, active low
5. output reg [3:0]o_led //led out
6. );
7. reg [26:0] led_count;
8. //-------------------------------------------------------------------
9. // 流水燈計數器
10. //-------------------------------------------------------------------
11. always @ (posedge i_clk or negedge i_rst_n)
12. begin
13. if(!i_rst_n)
14. led_count <=27'd0;
15. else
16. led_count <=led_count + 27'd1;
17. end
18. //-------------------------------------------------------------------
19. // 計數器bit24置1,表示已大約計數335ms,每隔335ms,led_count[26:24]自動加1
20. //-------------------------------------------------------------------
21. always @ (posedge clk or negedge i_rst_n)
22. begin
23. if(!i_rst_n)
24. o_led <=4'b1111;
25. else begin
26. case(led_count[26:24]) //when 25th bit set= 335ms
27. 3'b000: o_led<= 4'b1110;
28. 3'b001: o_led<= 4'b1101;
29. 3'b010: o_led<= 4'b1011;
30. 3'b011: o_led<= 4'b0111;
31. 3'b100: o_led<= 4'b1100;
32. 3'b101: o_led<= 4'b1001;
33. 3'b110:o_led <= 4'b0011;
34. 3'b111: o_led<= 4'b0000;
35. default: o_led<= o_led;
36. endcase
37. end
38. end
39. endmodule
1.1.4.綜合實現
對於剛接觸FPGA的同學可能不太了解綜合實現的意思,其實簡單里說,綜合實現就相當於單片機的編譯過程。而FPGA的編譯過程不像其他高級語言的編譯過程,FPGA編譯過程實際是相應硬件電路的實現過程。
第三小節,我們完成了代碼設計,我們就可以綜合實現了。步驟就是雙擊task窗口下的“Compile Design”,就會開始綜合實現了。
Altera的FPGA編譯過程大致分為以下幾個過程:分析綜合,布局布線,生成燒寫文件,時序分析,EDA網表生成。如下圖所示。
分析綜合:這個過程首先是完成對源碼文件的語法編譯,其次是將我們設計的語言綜合成相應的網表文件,而這個網表文件實際是與FPGA上資源是相互映射的。首先什么是網表文件?網表文件描述了相應工程的FPGA設計中包含了FPGA資源,同樣描述了這些資源又是如何連接的。其次,FPGA有哪些資源?我們會在后續章節詳細介紹,這里就說一個最簡單的資源——觸發器,這個是我們數電里面學習過的,在FPGA里一般叫做寄存器。例如我們這個工程中,最終led_count和o_led都會映射到相應的寄存器。
布局布線:這個過程是根據分析綜合中得到的網表文件進行的,如果大家有PCB設計經驗可能會更好理解。所謂布局,就像PCB布局,將設計中用到的資源布局到FPGA器件內部不同的位置。所謂布線,同樣類似PCB布線,將FPGA內部用到的資源根據網表文件中描述的鏈接關系連在一起。
生成燒寫文件:這個過程比較好理解,基於上述過程產生的文件,再生成用燒寫FPGA的文件。
EDA網表生成:這個過程則是用來生成仿真所需網表文件。仿真時會用到。
1.1.5.管腳分配
這一節我們將介紹管腳分配,管腳分配過程中我們會同時講解關於Altera FPGA管腳主要特點及分類。
第一步:管腳分配前應該先將源碼文件進行綜合,讓Quartus獲取相應的IO信息。這一步第四小節已經講了,我就不做詳細介紹了。
第二步:打開管腳分配工具Pin Planner,如下圖。或者可以通過菜單欄Assignments—>Pin Planner打開,也可以下圖所示快捷圖標打開。
第三步:分配管腳之前,我們先介紹一下FPGA的IO分布情況、管腳的特點及種類,以及Pin Planner工具的使用。如下圖為Pin Planner界面。
Pin Planner工具界面大致可分為以下幾個部分:
總體管腳布局區域:如圖所示,中間器件圖描述了每個管腳的位置。
Report區域:通過這個區域,將相應信息打上√,就可以高亮我們所關心的IO信息。這里我們高亮IO的bank信息。FPGA的管腳是分bank的,而且每個bank的IO的電平都可以獨立配置的。
Tasks區域:這個區域包含了很多IO信息,我們可以雙擊需要的IO信息,相應的信息就會添加到Repoat區域中。
Pin Legend區域:這里具體說明IO的所有種類,並用不同的顏色和形狀表示出來。而FPGA的IO管腳大致分為 用戶IO,配置管腳,電源管腳這幾類。
管腳分配區域:我們在這個區域內對我們設計中的IO進行分配。
第四步:分配管腳。在Location欄中輸入相應管腳的位置,完成管腳分配。