原創聲明:
本原創教程由芯驛電子科技(上海)有限公司(ALINX)創作,版權歸本公司所有,如需轉載,需授權并注明出處(http://www.alinx.com)。
適用于板卡型號:
PGL22G/PGL12G
1. 實驗簡介
通過LED流水燈實驗,介紹使用PDS軟件開發FPGA的基本流程,器件選擇、設置、代碼編寫、編譯、分配管腳、下載、程序FLASH固化、擦除等;同時也檢驗板上LED燈是否正常。
2. 實驗環境
-
Windows 10 64位
-
Pango Design Suite 2020.3
3. 實驗原理
3.1 LED硬件電路
開發板 LED部分原理圖
從上面的LED部分原理圖可以看出,開發板都是將IO經過一個電阻和LED串聯接電源端,FPGA的IO輸出低電平點亮LED。IO輸出高電平LED燈熄滅,其中的串聯電阻都是為了限制電流。
3.2程序設計
FPGA的設計中通常使用計數器來計時,對于50Mhz的系統時鐘,一個時鐘周期是20ns,那么表示一秒需要50000000個時鐘周期,如果一個時鐘周期計數器累加一次,那么計數器從0到49999999正好是50000000個周期,就是1秒的時鐘。
程序中定義了一個32位的計數器:
//Definethetimecounter reg[31:0]timer;
最大可以表示4294967295,十六進制就是FFFFFFFF,如果計數器到最大值,可以表示85.89934592秒。程序設計中是每隔1秒LED變化一次,一共消耗4秒做一個循環。
always@(posedgesys_clkornegedgerst_n)begin if(~rst_n) timer<=32'd0; elseif(timer?==32'd199_999_999) timer?<=32'd0; else timer?<=?timer?+1'b1;end
在第一秒、第二秒、第三秒、第四秒到來的時候分別改變LED的狀態,其他時候都保持原來的值不變。
//LEDcontrolalways@(posedgesys_clkornegedgerst_n)begin if(~rst_n) led<=4'b0000; elseif(timer?==32'd49_999_999) led?<=4'b0001; elseif(timer?==32'd99_999_999) led?<=4'b0010; elseif(timer?==32'd149_999_999) led?<=4'b0100; elseif(timer?==32'd199_999_999) led?<=4'b1000;end
4. PDS工程
4.1 創建工程
1)啟動Pango Design Suite 2020.3開發環境(在開始菜單中選擇pango->Pango Design Suite 2020.3>Pango Design Suite 。Pango Design Suite(簡稱PDS)或者雙擊桌面的Pango Design Suite 2020.3的圖標直接打開軟件。
2)在PDS 開發環境里雙擊Create Project或File->New Project...這兩種方式都可,如下圖:
3) 彈出一個PDS的工程向導,點擊Next按鈕。
4)在彈出的對話框中輸入工程名和工程存放的目錄,這里取一個led_test的工程名,點擊Next;
5) 在下面的對話框中默認選擇RTL Project, 因為我們這里使用verilog行為描述語言來編程,單擊Next
6) 進入Add Design Source Files界面,這里先不添加任何設計文件。點擊Next;
7)這里問是否添加已有的IP,保持默認不添加,單擊Next;
8)提示是否添加已有的約束文件,這里約束文件我們也沒有設計好,也不添加。
9)在接下來的對話框選擇所用的FPGA器件,以及進行一些配置。開發板首先在Family欄里選擇Logos,Device中選擇PGL22G,在Package欄選擇BG324, Speed grade欄選擇-6;綜合工具選擇ADS;單擊NEXT進入下一界面:
10)再次確認一下板子型號有沒有選對, 沒有問題再點擊“Finish”完成工程創建。
11)工程創建后如下圖所示:
4.2 編寫流水燈的verilog代碼
1)雙擊Sources下的Designs圖標;
2) 在Add Design Source Files界面中進行如下設置,點擊OK;
3)可以看到已經新建發led_test.v文件,點擊OK按鈕。
向導會提示您定義I/O的端口,這里我們可以不定義,后面自己在程序中編寫就可以,單擊OK完成。
這時在Navigator界面下的Designs里已經有了一個led_test.v文件, 并且自動成為項目的頂層(Top)模塊了。
4)接下去我們來編寫led_test.v的程序,這里我們定義了一個32位的寄存器timer, 用于循環計數0~199_999_999(4秒鐘), 當計數到49_999_999(1秒)的時候,熄滅第一個LED燈;當計數到99_999_999(2秒)的時候,熄滅第二個LED燈;當計數到149_999_999(3秒)的時候,熄滅第三個LED燈;當計數到199_999_999(4秒)的時候,熄滅第四個LED燈,計數器再重新計數。具體的操作直接看代碼吧。
`timescale1ns/1nsmoduleled_test( sys_clk,//systemclock50Mhzonboardrst_n,//reset,lowactive led//LED,useforcontroltheLEDsignalonboard);inputsys_clk;inputrst_n;output[3:0]led;//definethetimecounterreg[31:0]timer;reg[3:0]led;always@(posedgesys_clkornegedgerst_n)beginif(~rst_n) timer<=32'd0;//?when?the?reset?signal?valid,time?counter?clearingelseif(timer?==32'd199_999_999)//4?seconds?count(50M*4-1=199999999)??????????timer?<=32'd0;//count?done,clearing?the?time?counterelse ????????????timer?<=?timer?+1'b1;//timer?counter?=?timer?counter?+?1endalways@(posedge?sys_clk?ornegedge?rst_n)beginif(~rst_n) ??????????led?<=4'b0000;//when?the?reset?signal?active????????? elseif(timer?==32'd49_999_999)//time?counter?count?to?1st?sec,LED1?lighten ??????????led?<=4'b0001;elseif(timer?==32'd99_999_999)//time?counter?count?to?2nd?sec,LED2?lightenbegin ??????????led?<=4'b0010;endelseif(timer?==32'd149_999_999)//time?counter?count?to?3nd?sec,LED3?lighten??????????led?<=4'b0100;elseif(timer?==32'd199_999_999)//time?counter?count?to?4nd?sec,LED4?lighten??????????led?<=4'b1000;endendmodule
5)編寫好代碼后保存,點擊菜單File -Save All。
添加UCE約束
User Constraint Editor(Timing and Logic)簡稱UCE,主要是完成管腳的約束,時鐘的約束, 以及組的約束。這里我們需要對led_test.v程序中的輸入輸出端口分配到FPGA的真實管腳上。
1)擊菜單欄“Tools”下的"User Constraint Editor";
2)在彈出的界面中單擊Device;
3)在Device中單擊I/O,可看到工程中用到的IO端口;
4)按如下方式分配管腳,LOC就是與硬件中FPGA相對應的管腳,VCCIO是FPGA的IO的電壓標準,與硬件對應,其它在這里保持默認即可;
5)單擊保存后會彈對話框,在這里選擇默認;
4.4 生成位流文件
雙擊Generate Bitstream,然后軟件會按照Synthesize-> Device Map-> Place & Route-> Generate Bitstream來產生位流文件。
如果工程在生成位流文件過程中沒有錯誤,則會出現下圖中每一步都正確的“√”,否則就會在Messages欄中顯示errors的錯誤。
位流文件生成完成后,我們可以在Report Summary頁面的到了FPGA資源的使用情況。
此外還可以通過下圖操作查看RTL視圖;
4.5 下載和調試
在上面生成了位流文件(.sbit)后,我們可以把sbit文件下載到FPGA芯片中,看一下LED實際運行的效果。下載和調試之前先連接硬件,把JTAG下載器和開發板連接,然后開發板上電(下圖為開發板的硬件連接圖)。
1)單擊界面中的“Configuration”按鈕,作用一是下載程序到FPGA中運行;二是固化程序到flash中。
2)在彈出的界面中的單擊“Boundary Scan”,然后在右側空白區單擊右鍵選擇“Scan Device”;
3)在掃描到JTAG設備后會彈出如下對話框,并按如下加載.sbit文件即可;
4)然后可以看到左側顯示了要加載的文件,選中右側綠色的方塊,右擊會彈出下拉菜單并選擇"Program...",下載完成后在板上可以在開發板上看到LED流水燈的效果。注意:這種方式程序是在FPGA運行,掉電后會消失。
4.6 FLASH程序固化
可能已經有朋友發現下載.sbit文件到FPGA后,開發板重新上電后配置程序已經丟失,還需要JTAG下載。這豈不麻煩!好吧,這一節我們來介紹如何把配置程序固化到開發板上的FLASH中,這樣不用擔心掉電后程序丟失了。
在我們的開發板上有一個8Pin的128Mbit的FLASH, 用于存儲配置程序。我們不能直接把sbit文件下載到這個FLASH中,只能下載sfc文件到flash中。下面為大家介紹FLASH程序的固化的流程。
1)首先,需要sbit文件轉換成能下載的flash的sfc文件。在完成上節下載和調試后,選擇菜單"Operations"下"Convert File"進行文件轉換。
然后彈出如下界面,這里要根據硬件的flash型號來選擇flash的廠家和設備型號,開發板用到的是WINBOND的W25Q128Q。Flash Read Mode 選擇SPI X4然后選擇要轉換的sbit文件,點擊OK即可轉換;
轉換完成后顯示如下界面,單擊OK;
2)選中右側綠色的方塊,右擊會彈出下拉菜單并選擇"Scan outer Flash"。
選擇已生成的sfc文件,單擊Open;
可以看到界面中有了flash器件,選中“Outer Flash”綠色方塊并右擊選擇菜單中“Program...”
彈出正在編程的進度界面,flash編程完成后進度界面自動消失。
至此,SPI FLASH 燒寫完畢,led_test程序已經固化到SPI FLASH中了。我們來驗證一下,關電重新啟動開發板,等待一會兒你就可以看到開發板上的LED燈已經在做跑馬運動了。
4.7 仿真驗證
接下來我們不妨小試牛刀,讓仿真工具modelsim來輸出波形驗證流水燈程序設計結果和我們的預想是否一致。具體步驟如下:
1)添加激勵測試文件,點擊Project下的Add Source;
2)點擊Add or create simulation sources并"Next";
3)在彈出的對話框中輸入激勵文件的名字,這里我們輸入名為vtf_led_test,其它按下圖設置;
4)點擊OK按鈕返回。
5)這里我們先不添加IO Ports,點擊OK。
6)在Simulation目錄下多了一個剛才添加的vtf_led_test文件。雙擊打開這個文件,可以看到里面只有module名的定義,其它都沒有。
7) 接下去我們需要編寫這個vtf_led_test.v文件的內容。首先定義輸入和輸出信號,然后需要實例化led_test模塊,讓led_test程序作為本測試程序的一部分。再添加復位和時鐘的激勵。完成后的vtf_led_test.v文件如下:
`timescale1ns/1ns////////////////////////////////////////////////////////////////////////////////////ModuleName:vtf_led_test//////////////////////////////////////////////////////////////////////////////////modulevtf_led_test;//Inputsregsys_clk;regrst_n;//Outputswire[3:0]led;//InstantiatetheUnitUnderTest(UUT)led_testuut(.sys_clk(sys_clk),.rst_n(rst_n),.led(led));initialbegin//InitializeInputssys_clk=0; rst_n=0;//Wait100nsforglobalresettofinish#1000; rst_n=1;//Addstimulushere#20000;//$stop;endalways#10sys_clk=~sys_clk;//20ns,endmodule
8) 編寫好后保存,vtf_led_test.v自動成了這個仿真的頂層了,它下面是設計文件led_test.v;
9)接下來設置PDS的仿真配置,在軟件菜單Project->Project Setting,然后在彈出的界面中進行如下設置,注意仿真庫的路徑在《00.Pango Design Suite 2020.3安裝》教程中已介紹。,設置好后單擊OK。
10)右擊仿真文件并在下拉菜單中選擇Run Behavioral Simulation。這里我們做一下行為級的仿真就可以了。
如果沒有錯誤,PDS會調用Modelsim仿真軟件開始工作了。
11)在彈出仿真界面后如下圖,界面是仿真軟件自動運行到仿真設置的50ms的波形。
由于LED[3:0]在程序中設計的狀態變化時間長,而仿真又比較耗時,在這里觀測timer[31:0]計數器變化。把它放到Wave中觀察(點擊界面中的uut, 再右擊右側timer, 在彈出的下拉菜單里選擇Add Wave)。
添加后timer顯示在Wave的波形界面上,如下圖所示。
12)點擊Restart按鈕復位一下,再點擊Run All按鈕。(需要耐心?。。。梢钥吹椒抡娌ㄐ闻c設計相符。
我們可以看到led的信號會逐一變1,說明LED1~LED4燈逐個熄滅。
這里為止,我們的第一個項目就圓滿完成了,相信您也掌握了PDS的FPGA開發的整個流程,再也不是那個FPGA的門外漢了吧! 師傅領進門,修行還需要靠本身!PDS軟件的一些技巧的使用和掌握就需要靠大家在長期實踐和探索中慢慢熟悉了。
5. 附錄
led_test.v(verilog代碼)
`timescale1ns/1psmoduleled_test( inputsys_clk,//systemclock50Mhzonboard inputrst_n,//reset,lowactive outputreg[3:0]led//LED,useforcontroltheLEDsignalonboard);//definethetimecounterreg[31:0]timer;//cyclecounter:from0to4secalways@(posedgesys_clkornegedgerst_n)begin if(~rst_n) timer<=32'd0;//when?the?reset?signal?valid,time?counter?clearing elseif(timer?==32'd199_999_999)//4?seconds?count(50M*4-1=199999999) timer?<=32'd0;//count?done,clearing?the?time?counter else timer?<=?timer?+1'b1;//timer?counter?=?timer?counter?+?1end//?LED?controlalways@(posedge?sys_clk?ornegedge?rst_n)begin if(~rst_n) led?<=4'b0000;//when?the?reset?signal?active elseif(timer?==32'd49_999_999)//time?counter?count?to?1st?sec,LED1?lighten led?<=4'b0001; elseif(timer?==32'd99_999_999)//time?counter?count?to?2nd?sec,LED2?lighten led?<=4'b0010; elseif(timer?==32'd149_999_999)//time?counter?count?to?3rd?sec,LED3?lighten led?<=4'b0100; elseif(timer?==32'd199_999_999)//time?counter?count?to?4th?sec,LED4?lighten led?<=4'b1000;endendmodule
注意:在定義寄存器時,如果寄存器在always塊里使用必須定義為reg類型,如果僅是用于連線或是直接賦值需定義為wire類型,輸入信號的類型不能定義為reg型,不管是reg類型信號還是wire類型的信號,定義的寄存器寬度必須滿足使用時的需要,但必須稍大于或等于需要使用的位寬。若定義寄存器位寬遠遠大于使用需求則會浪費資源,如果定義的位寬小于使用需求,則會造成數據位截斷,導致程序錯誤。還有其他信號的類型及用法請大家參考Verilog語法教程。
-
FPGA
+關注
關注
1630文章
21796瀏覽量
605996 -
led
+關注
關注
242文章
23355瀏覽量
663173 -
流水燈
+關注
關注
21文章
433瀏覽量
59832 -
PDS
+關注
關注
2文章
32瀏覽量
15349 -
紫光同創
+關注
關注
5文章
88瀏覽量
27560
發布評論請先 登錄
相關推薦
評論