原創(chuàng)聲明:
本原創(chuàng)教程由芯驛電子科技(上海)有限公司(ALINX)創(chuàng)作,版權(quán)歸本公司所有,如需轉(zhuǎn)載,需授權(quán)并注明出處(http://www.alinx.com)。
適用于板卡型號(hào):
PGL22G/PGL12G
1. 實(shí)驗(yàn)簡(jiǎn)介
通過LED流水燈實(shí)驗(yàn),介紹使用PDS軟件開發(fā)FPGA的基本流程,器件選擇、設(shè)置、代碼編寫、編譯、分配管腳、下載、程序FLASH固化、擦除等;同時(shí)也檢驗(yàn)板上LED燈是否正常。
2. 實(shí)驗(yàn)環(huán)境
-
Windows 10 64位
-
Pango Design Suite 2020.3
3. 實(shí)驗(yàn)原理
3.1 LED硬件電路
開發(fā)板 LED部分原理圖
從上面的LED部分原理圖可以看出,開發(fā)板都是將IO經(jīng)過一個(gè)電阻和LED串聯(lián)接電源端,F(xiàn)PGA的IO輸出低電平點(diǎn)亮LED。IO輸出高電平LED燈熄滅,其中的串聯(lián)電阻都是為了限制電流。
3.2程序設(shè)計(jì)
FPGA的設(shè)計(jì)中通常使用計(jì)數(shù)器來計(jì)時(shí),對(duì)于50Mhz的系統(tǒng)時(shí)鐘,一個(gè)時(shí)鐘周期是20ns,那么表示一秒需要50000000個(gè)時(shí)鐘周期,如果一個(gè)時(shí)鐘周期計(jì)數(shù)器累加一次,那么計(jì)數(shù)器從0到49999999正好是50000000個(gè)周期,就是1秒的時(shí)鐘。
程序中定義了一個(gè)32位的計(jì)數(shù)器:
//Definethetimecounter reg[31:0]timer;
最大可以表示4294967295,十六進(jìn)制就是FFFFFFFF,如果計(jì)數(shù)器到最大值,可以表示85.89934592秒。程序設(shè)計(jì)中是每隔1秒LED變化一次,一共消耗4秒做一個(gè)循環(huán)。
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
在第一秒、第二秒、第三秒、第四秒到來的時(shí)候分別改變LED的狀態(tài),其他時(shí)候都保持原來的值不變。
//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 創(chuàng)建工程
1)啟動(dòng)Pango Design Suite 2020.3開發(fā)環(huán)境(在開始菜單中選擇pango->Pango Design Suite 2020.3>Pango Design Suite 。Pango Design Suite(簡(jiǎn)稱PDS)或者雙擊桌面的Pango Design Suite 2020.3的圖標(biāo)直接打開軟件。
2)在PDS 開發(fā)環(huán)境里雙擊Create Project或File->New Project...這兩種方式都可,如下圖:
3) 彈出一個(gè)PDS的工程向?qū)Вc(diǎn)擊Next按鈕。
4)在彈出的對(duì)話框中輸入工程名和工程存放的目錄,這里取一個(gè)led_test的工程名,點(diǎn)擊Next;
5) 在下面的對(duì)話框中默認(rèn)選擇RTL Project, 因?yàn)槲覀冞@里使用verilog行為描述語言來編程,單擊Next
6) 進(jìn)入Add Design Source Files界面,這里先不添加任何設(shè)計(jì)文件。點(diǎn)擊Next;
7)這里問是否添加已有的IP,保持默認(rèn)不添加,單擊Next;
8)提示是否添加已有的約束文件,這里約束文件我們也沒有設(shè)計(jì)好,也不添加。
9)在接下來的對(duì)話框選擇所用的FPGA器件,以及進(jìn)行一些配置。開發(fā)板首先在Family欄里選擇Logos,Device中選擇PGL22G,在Package欄選擇BG324, Speed grade欄選擇-6;綜合工具選擇ADS;單擊NEXT進(jìn)入下一界面:
10)再次確認(rèn)一下板子型號(hào)有沒有選對(duì), 沒有問題再點(diǎn)擊“Finish”完成工程創(chuàng)建。
11)工程創(chuàng)建后如下圖所示:
4.2 編寫流水燈的verilog代碼
1)雙擊Sources下的Designs圖標(biāo);
2) 在Add Design Source Files界面中進(jìn)行如下設(shè)置,點(diǎn)擊OK;
3)可以看到已經(jīng)新建發(fā)led_test.v文件,點(diǎn)擊OK按鈕。
向?qū)?huì)提示您定義I/O的端口,這里我們可以不定義,后面自己在程序中編寫就可以,單擊OK完成。
這時(shí)在Navigator界面下的Designs里已經(jīng)有了一個(gè)led_test.v文件, 并且自動(dòng)成為項(xiàng)目的頂層(Top)模塊了。
4)接下去我們來編寫led_test.v的程序,這里我們定義了一個(gè)32位的寄存器timer, 用于循環(huán)計(jì)數(shù)0~199_999_999(4秒鐘), 當(dāng)計(jì)數(shù)到49_999_999(1秒)的時(shí)候,熄滅第一個(gè)LED燈;當(dāng)計(jì)數(shù)到99_999_999(2秒)的時(shí)候,熄滅第二個(gè)LED燈;當(dāng)計(jì)數(shù)到149_999_999(3秒)的時(shí)候,熄滅第三個(gè)LED燈;當(dāng)計(jì)數(shù)到199_999_999(4秒)的時(shí)候,熄滅第四個(gè)LED燈,計(jì)數(shù)器再重新計(jì)數(shù)。具體的操作直接看代碼吧。
`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)編寫好代碼后保存,點(diǎn)擊菜單File -Save All。
添加UCE約束
User Constraint Editor(Timing and Logic)簡(jiǎn)稱UCE,主要是完成管腳的約束,時(shí)鐘的約束, 以及組的約束。這里我們需要對(duì)led_test.v程序中的輸入輸出端口分配到FPGA的真實(shí)管腳上。
1)擊菜單欄“Tools”下的"User Constraint Editor";
2)在彈出的界面中單擊Device;
3)在Device中單擊I/O,可看到工程中用到的IO端口;
4)按如下方式分配管腳,LOC就是與硬件中FPGA相對(duì)應(yīng)的管腳,VCCIO是FPGA的IO的電壓標(biāo)準(zhǔn),與硬件對(duì)應(yīng),其它在這里保持默認(rèn)即可;
5)單擊保存后會(huì)彈對(duì)話框,在這里選擇默認(rèn);
4.4 生成位流文件
雙擊Generate Bitstream,然后軟件會(huì)按照Synthesize-> Device Map-> Place & Route-> Generate Bitstream來產(chǎn)生位流文件。
如果工程在生成位流文件過程中沒有錯(cuò)誤,則會(huì)出現(xiàn)下圖中每一步都正確的“√”,否則就會(huì)在Messages欄中顯示errors的錯(cuò)誤。
位流文件生成完成后,我們可以在Report Summary頁面的到了FPGA資源的使用情況。
此外還可以通過下圖操作查看RTL視圖;
4.5 下載和調(diào)試
在上面生成了位流文件(.sbit)后,我們可以把sbit文件下載到FPGA芯片中,看一下LED實(shí)際運(yùn)行的效果。下載和調(diào)試之前先連接硬件,把JTAG下載器和開發(fā)板連接,然后開發(fā)板上電(下圖為開發(fā)板的硬件連接圖)。
1)單擊界面中的“Configuration”按鈕,作用一是下載程序到FPGA中運(yùn)行;二是固化程序到flash中。
2)在彈出的界面中的單擊“Boundary Scan”,然后在右側(cè)空白區(qū)單擊右鍵選擇“Scan Device”;
3)在掃描到JTAG設(shè)備后會(huì)彈出如下對(duì)話框,并按如下加載.sbit文件即可;
4)然后可以看到左側(cè)顯示了要加載的文件,選中右側(cè)綠色的方塊,右擊會(huì)彈出下拉菜單并選擇"Program...",下載完成后在板上可以在開發(fā)板上看到LED流水燈的效果。注意:這種方式程序是在FPGA運(yùn)行,掉電后會(huì)消失。
4.6 FLASH程序固化
可能已經(jīng)有朋友發(fā)現(xiàn)下載.sbit文件到FPGA后,開發(fā)板重新上電后配置程序已經(jīng)丟失,還需要JTAG下載。這豈不麻煩!好吧,這一節(jié)我們來介紹如何把配置程序固化到開發(fā)板上的FLASH中,這樣不用擔(dān)心掉電后程序丟失了。
在我們的開發(fā)板上有一個(gè)8Pin的128Mbit的FLASH, 用于存儲(chǔ)配置程序。我們不能直接把sbit文件下載到這個(gè)FLASH中,只能下載sfc文件到flash中。下面為大家介紹FLASH程序的固化的流程。
1)首先,需要sbit文件轉(zhuǎn)換成能下載的flash的sfc文件。在完成上節(jié)下載和調(diào)試后,選擇菜單"Operations"下"Convert File"進(jìn)行文件轉(zhuǎn)換。
然后彈出如下界面,這里要根據(jù)硬件的flash型號(hào)來選擇flash的廠家和設(shè)備型號(hào),開發(fā)板用到的是WINBOND的W25Q128Q。Flash Read Mode 選擇SPI X4然后選擇要轉(zhuǎn)換的sbit文件,點(diǎn)擊OK即可轉(zhuǎn)換;
轉(zhuǎn)換完成后顯示如下界面,單擊OK;
2)選中右側(cè)綠色的方塊,右擊會(huì)彈出下拉菜單并選擇"Scan outer Flash"。
選擇已生成的sfc文件,單擊Open;
可以看到界面中有了flash器件,選中“Outer Flash”綠色方塊并右擊選擇菜單中“Program...”
彈出正在編程的進(jìn)度界面,flash編程完成后進(jìn)度界面自動(dòng)消失。
至此,SPI FLASH 燒寫完畢,led_test程序已經(jīng)固化到SPI FLASH中了。我們來驗(yàn)證一下,關(guān)電重新啟動(dòng)開發(fā)板,等待一會(huì)兒你就可以看到開發(fā)板上的LED燈已經(jīng)在做跑馬運(yùn)動(dòng)了。
4.7 仿真驗(yàn)證
接下來我們不妨小試牛刀,讓仿真工具modelsim來輸出波形驗(yàn)證流水燈程序設(shè)計(jì)結(jié)果和我們的預(yù)想是否一致。具體步驟如下:
1)添加激勵(lì)測(cè)試文件,點(diǎn)擊Project下的Add Source;
2)點(diǎn)擊Add or create simulation sources并"Next";
3)在彈出的對(duì)話框中輸入激勵(lì)文件的名字,這里我們輸入名為vtf_led_test,其它按下圖設(shè)置;
4)點(diǎn)擊OK按鈕返回。
5)這里我們先不添加IO Ports,點(diǎn)擊OK。
6)在Simulation目錄下多了一個(gè)剛才添加的vtf_led_test文件。雙擊打開這個(gè)文件,可以看到里面只有module名的定義,其它都沒有。
7) 接下去我們需要編寫這個(gè)vtf_led_test.v文件的內(nèi)容。首先定義輸入和輸出信號(hào),然后需要實(shí)例化led_test模塊,讓led_test程序作為本測(cè)試程序的一部分。再添加復(fù)位和時(shí)鐘的激勵(lì)。完成后的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自動(dòng)成了這個(gè)仿真的頂層了,它下面是設(shè)計(jì)文件led_test.v;
9)接下來設(shè)置PDS的仿真配置,在軟件菜單Project->Project Setting,然后在彈出的界面中進(jìn)行如下設(shè)置,注意仿真庫的路徑在《00.Pango Design Suite 2020.3安裝》教程中已介紹。,設(shè)置好后單擊OK。
10)右擊仿真文件并在下拉菜單中選擇Run Behavioral Simulation。這里我們做一下行為級(jí)的仿真就可以了。
如果沒有錯(cuò)誤,PDS會(huì)調(diào)用Modelsim仿真軟件開始工作了。
11)在彈出仿真界面后如下圖,界面是仿真軟件自動(dòng)運(yùn)行到仿真設(shè)置的50ms的波形。
由于LED[3:0]在程序中設(shè)計(jì)的狀態(tài)變化時(shí)間長(zhǎng),而仿真又比較耗時(shí),在這里觀測(cè)timer[31:0]計(jì)數(shù)器變化。把它放到Wave中觀察(點(diǎn)擊界面中的uut, 再右擊右側(cè)timer, 在彈出的下拉菜單里選擇Add Wave)。
添加后timer顯示在Wave的波形界面上,如下圖所示。
12)點(diǎn)擊Restart按鈕復(fù)位一下,再點(diǎn)擊Run All按鈕。(需要耐心?。。。梢钥吹椒抡娌ㄐ闻c設(shè)計(jì)相符。
我們可以看到led的信號(hào)會(huì)逐一變1,說明LED1~LED4燈逐個(gè)熄滅。
這里為止,我們的第一個(gè)項(xiàng)目就圓滿完成了,相信您也掌握了PDS的FPGA開發(fā)的整個(gè)流程,再也不是那個(gè)FPGA的門外漢了吧! 師傅領(lǐng)進(jìn)門,修行還需要靠本身!PDS軟件的一些技巧的使用和掌握就需要靠大家在長(zhǎng)期實(shí)踐和探索中慢慢熟悉了。
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
注意:在定義寄存器時(shí),如果寄存器在always塊里使用必須定義為reg類型,如果僅是用于連線或是直接賦值需定義為wire類型,輸入信號(hào)的類型不能定義為reg型,不管是reg類型信號(hào)還是wire類型的信號(hào),定義的寄存器寬度必須滿足使用時(shí)的需要,但必須稍大于或等于需要使用的位寬。若定義寄存器位寬遠(yuǎn)遠(yuǎn)大于使用需求則會(huì)浪費(fèi)資源,如果定義的位寬小于使用需求,則會(huì)造成數(shù)據(jù)位截?cái)?,?dǎo)致程序錯(cuò)誤。還有其他信號(hào)的類型及用法請(qǐng)大家參考Verilog語法教程。
-
FPGA
+關(guān)注
關(guān)注
1625文章
21637瀏覽量
601327 -
led
+關(guān)注
關(guān)注
240文章
23085瀏覽量
657249 -
流水燈
+關(guān)注
關(guān)注
21文章
432瀏覽量
59612 -
PDS
+關(guān)注
關(guān)注
2文章
28瀏覽量
15260 -
紫光同創(chuàng)
+關(guān)注
關(guān)注
5文章
80瀏覽量
27477
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論