FPGA/CPLD實驗教程二(閃爍燈)

admin @ 2014-03-26 , reply:0

1. 實驗要求及目的:
接著上次的實驗,但是這次需要使8個LED周期性的閃爍。這次我就不詳細的貼圖說明每個步驟了,如果和上一個實驗有不同的,需要特別說明的,我才貼圖。
使用軟體:Quartus II 5.0。

2. 硬體原理圖:

    這個是我自己製作的開發板上的LED的原理圖,一共有8個,IO和別的共用的,使用八個LED的時候板上的JP1和JP5全部戴上短接帽,JP2則空出。如果要點亮這些LED,只需要把與其相連接的FPGA管腳輸出低電平“0”就可以實現這個功能了。(我焊板子的時候把LED1弄壞了,不能用。)
    LED管腳對應的情況如下:
    D1------PIN_97
    D2------PIN_94
    D3------PIN_91
    D4------PIN_84
    D5------PIN_82
    D6------PIN_78
    D7------PIN_76
    D8------PIN_74
    另外,本實驗需要用到時鐘計數,時鐘對應的引腳為PIN_16。
    本文均採用輸出“0”點亮的模式,以下就不再另外再說明了。
    ——這幾句話我直接抄襲上一個實驗的了,因為是一樣的。

3. 程序設計
(1)設計分析:我們要求這次8個燈周期性的閃爍,什麼意思呢?簡單點說,就是那八個燈一會兒亮一會兒滅,如何實現呢?
    我們通過上一個實驗知道了,按照我給出的原理圖,只要把與LED相連的FPGA管腳置低,也就是輸出低電平“0”,就可以實現點亮LED的功能。反之,通過輸出高電平“1”,我們就可以實現熄滅LED了。
    周期性的閃爍,就是要使FPGA的IO周期性的輸出“0”和“1”。講的夠明白了吧:)
    這個周期是怎麼來的呢?比如說我們需要讓LED亮0.5s滅0.5s,那麼這個周期就是1Hz。我板子上使用的晶振是50MHz,也就是1Hz的50000000倍。(有點羅嗦了,汗!)那麼我們就利用計數器計數。等計到50000000/2的時候,把輸出狀態求反,那麼亮著的燈就變滅了,滅的燈也就變亮了。
    廢話少說,來看看源程序吧。
(2)源程序  exp2.v
   程序代碼:
// Light 8 LED periodically
// Designed By Smokingfish @ www.51FPGA.com zhiyuh@163.com
module exp2(LED,CLK);
    output[7:0] LED;
    input CLK;
    reg [7:0] LED;
    reg [24:0] counter;
   
    always@(posedge CLK)                //在時鐘負延跳變,也就是計數什麼的
        begin
            counter<=counter+1;            //計數器加1
            if(counter==25'b1_0111_1101_0111_1000_0100_0000)    //這個數就是25000000
                begin
                    LED<=~LED;        //求反,閃爍
                    counter<=0;        //重新計數
                end
        end
endmodule

4. 實驗步驟
(1)打開Quartus II軟體,進入集成開發環境,點擊File->New project wizard..新建工程項目exp2,直接點擊Finish。
(2)點擊File->New..在該項目下新建Verilog HDL源程序文件exp2.v,輸入上面的源程序代碼並保存。
(3)選擇所用的FPGA器件----EP1C3T144C8,以及進行一些配置。
選擇配置器件,如果要下載程序到EPCS1的話。
選擇不需要使用的IO功能。選擇As inputs,tri-stated。
    點擊兩次ok,回到主界面。
(4)為工程項目鎖定引腳:
    點擊Assignments->Pins,配置LED[0]---LED[7]以及CLK的引腳。
(5)編譯工程項目:點擊Processing->Start Compilation。
(6)模擬:這個實驗我簡單的講一下利用QuartusII的VWF文件進行模擬的流程。(我自己懶的很,所以就抄了點書,呵呵)
1)打開波形編輯器。選擇File->New,在New窗口的Other Files中選擇Vector Waveform File(如下圖):

 

2)設置模擬時間區域。點擊Edit->End Time..,出現下面的對話框,設置正割模擬域的時間:50us。為什麼選這麼小呢?當然有原因的,太長了機器要跑好長時間,自己會很難受的,呵呵。但是計數器要計數那麼多次才行,50us估計還沒有到一次求反就結束了,怎麼辦呢?那麼我們把計數減小一點,把25000000這個數變成25,也就是把源程序中的12行的那個數改成1_1001。(記得保存哦,還有就是要重新編譯一下工程)

 

3)保存波形文件:這個不用我說吧?默認的名字是你的工程的名字。
4)將工程中的埠信號選如波形編輯器中。
    首先選擇View->Utility Windows->Node Finder。彈出下面的對話框。

 

    在Filter這個選項框裡面選擇:Pins:all,點擊List按鈕,下面就會出現工程中所有埠的引腳名。然後就可以看到這樣的效果了:

 

    用滑鼠把CLK和LED信號分別拖拽到波形編譯窗口。注意,是拖到紅色那個框裡面,不要拖到右邊白色的框了——那樣是拖不進去的。

 

    關閉這個對話框,進入波形編輯。選擇上圖紅色部分裡面的CLK信號,使其編程藍色條(編輯狀態)。然後單擊左側的時鐘設置鍵(下圖紅色的那個),然後出現藍的部分的對話框(沒有點之前是沒有的,注意哦)。然後設置時鐘周期為10ns,占空比為50%。

 

    設置匯流排數據格式:單擊LED這個信號旁邊的“+”,就可以展開這個匯流排中的所有信號。如果雙擊LED信號,就可以看到下面這個對話框,在Radix裡面有四個選項,可以選擇顯示數據的模式,我這裡選擇的是無符號十進位整數(Unsigned Decimal)。

 

    對模擬器進行一些設置:選擇Assignment->Settings..,出現下面的對話框,選中Category裡面的Simulator,,則出現右邊的設置。在Simulation mode中選中Timing(時序模擬)——藍色部分,Simulation input(模擬激勵文件)選中exp2.vwf——黃色部分,點裡面的藍色部分可以選擇文件;並且選中Simulation coverage reporting以及Glitch detection(毛刺檢測),寬度為1ns。其實這樣的模擬並不是很嚴格,因為我們修改了時鐘頻率,但是這裡我主要是為了簡單的講解一下怎麼模擬,所以就這麼設置了,你可以根據你的具體時鐘周期選擇這些數值(包括模擬域的以及時鐘周期還有就是這裡的毛刺檢測寬度)。完成之後點擊ok。

 

    下面就可以啟動模擬器進行模擬了。點Processing->Start Simulation,直到出現Simulation was successful,模擬結束。
    觀察模擬結果。模擬的波形文件“Simulation Report”自動彈出(注意,Quartus II的模擬波形文件中,波形編輯文件(*.vwf)和波形模擬報告文件(Simulation Report)是分開的,這個和Maxplus II是一個很大的不同點。)用放大縮小按鈕(這個我就不貼圖了,自己在左側的快捷圖標裡面找一下,第二排第二個,就是那個放大鏡的圖標。左鍵放大,右鍵縮小,也可以在報告文件裡面點右鍵選Zoom來放大縮小),使報告的波形能比較清楚的顯示。如下圖:

 

    基本能看到了,八個LED出現了周期性的01變化。但是不能根據我們的計數器來判斷是不是計數到了0.5s的時候跳變的啊,這是為什麼呢?因為我們在編輯模擬波形的時候並沒有把counter這個變數加進去,只是加入了輸入輸出引腳。
    那我們重新回到波形編輯器窗口,這次我們不使用View->Utility Windows->Node Finder這個辦法,我教你另外一個辦法:我們雙擊第六個圖的紅色部分的空白處,會出現這樣的對話框:

 

    現在你可以直接在Name裡面輸入我們需要觀測的計數寄存器信號名:counter。Radix選擇無符號十進位整數。當然如果不想動鍵盤,完全可以用滑鼠全部操作,那就是點Node Finder..,這就出現了前面所用的那個窗口,其實道理是一樣。不過如果你沒有改變設置,這次怎麼你也找不到counter這個信號,為什麼呢?很簡單,因為Filter裡面我們選擇的是Pins:all,也就是FPGA管腳,而counter是我們程序內部的計數寄存器,沒有輸出也沒有輸入。這次我們在Filter裡面選擇Design Entry(all names),然後點List,就可以在左邊的窗口裡面找到counter這個寄存器了。這次就不能用拖拽的辦法把它拖到波形編輯器了,於是我們雙擊counter,它就跑到右邊的窗口了(見下圖),然後點兩次ok,回到波形編輯器主界面。

 

    這下就可以觀察根據counter的計數LED的變化情況了。當然你要首先保存文件,然後重新模擬,結果如下圖:

 

    如果放大縮小還不能比較清楚的看波形,可以點全屏的按鈕(左側工具的第三排那個——第三排只有一個)。我們仔細研究一下這個模擬結果,發現了問題了嗎?
    如果你是細心的人就會發現,我們計數是從0開始的,然後加到25之後的一個始終周期LED才開始跳變,所以其實我們多了一個時鐘周期的計數。如果是25Hz的時鐘,那麼多計數一個周期就是0.04s,50MHz的話就是0.04ns,誤差雖然不大但是我們編程也要嚴謹才行。所以返回源程序修改counter的值為11000,然後重新編譯和模擬,直到結果完全符合我們的要求。
    這裡有一個問題,如果你關閉了模擬報告文件的窗口第二次模擬結束之後有時候就不會自動彈出模擬報告文件的窗口,可以通過點擊Processing->Simulation Report來打開。
    最後把counter的數值改成50MHz晶振的數值,這個不要忘記了,要不然板子上的LED變化的很快,我們肉眼基本看不到有什麼閃爍。值為最初給出的代碼裡面的值-1,也就是1_0111_1101_0111_1000_0011_1111(十進位的24999999),然後編譯工程。

(7)下載目標文件到板子上: 點擊Tools->Programmer,選中Jtag模式,並且選中目標文件,然後點Start。

    終於完成了第二個實驗,這下可以看到板子上的8個LED間隔點亮,間隔0.5s的時候變化一次(亮的變暗,暗的變數)——效果可以看下面的這個Flash文件。是不是覺得比上個實驗更有意思呢?通過這個實驗我們又學到了什麼呢?模擬,還有就是計數器的使用,有沒有一點點收穫呢?希望能有一點,要不我的這個教程不是白寫了么?




[admin via 研發互助社區 ] FPGA/CPLD實驗教程二(閃爍燈)已經有2107次圍觀

http://cocdig.com/docs/show-post-43362.html