新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > FPGA學習:PLL分頻計數的LED閃爍實例

        FPGA學習:PLL分頻計數的LED閃爍實例

        作者: 時間:2018-04-27 來源:網絡 收藏

          如圖8.17所示,本實例將用到內部的資源,輸入引腳上的25MHz時鐘,配置使其輸出4路分別為12.5MHz、25MHz、50MHz和100MHz的時鐘信號,這4路時鐘信號又分別驅動4個不同位寬的計數器不停的計數工作,這些計數器的最高位最終輸出用于控制4個不同的LED亮滅。由于這4個時鐘頻率都有一定的倍數關系,所以我們也很容易通過調整合理的計數器位寬,達到4個LED閃爍一致的控制。

        本文引用地址:http://www.104case.com/article/201804/379162.htm

            

        1.jpg

         

          cy4.v模塊代碼解析

          先來看cy4.v模塊的代碼,它是工程的頂層模塊,主要做接口定義和模塊例化,一般不會在這個模塊中做任何的具體邏輯設計。

          首先是接口部分,只有時鐘、復位和8個LED信號。

          module cy4(

          input ext_clk_25m, //外部輸入25MHz時鐘信號

          input ext_rst_n, //外部輸入復位信號,低電平有效

          output[7:0] led //8個LED指示燈接口

          );

          接著這里申明5個wire類型的信號,所有在不同模塊間接口的信號,在它們的上級模塊中都必須定義為wire類型,這里有4個不同頻率的時鐘以及由的lock信號引出的復位信號sys_rst_n。

          wire clk_12m5; //PLL輸出12.5MHz時鐘

          wire clk_25m; //PLL輸出25MHz時鐘

          wire clk_50m; //PLL輸出50MHz時鐘

          wire clk_100m; //PLL輸出100MHz時鐘

          wire sys_rst_n; //PLL輸出的locked信號,作為內部的復位信號,低電平復位,高電平正常工作

          PLL是我們配置的IP核模塊,它需要在我們的代碼中例化,如下所示。

          //-------------------------------------

          //PLL例化

          pll_controller pll_controller_inst (

          .areset ( !ext_rst_n ),

          .inclk0 ( ext_clk_25m ),

          .c0 ( clk_12m5 ),

          .c1 ( clk_25m ),

          .c2 ( clk_50m ),

          .c3 ( clk_100m ),

          .locked ( sys_rst_n )

          );

          最后4個LED閃爍控制模塊的例化,它們的源碼都是led_controller.v模塊,但它們的名稱不一樣,分別為uut_led_controller_clk12m5、uut_led_controller_clk25m、uut_led_controller_clk50m、uut_led_controller_clk100m。這樣的定義方式最終實現效果不同于軟件的函數調用,軟件的函數調用只有一個函數,分時復用;而FPGA的這種代碼例化卻會實現4個完全一樣的硬件邏輯。當然了,這4個模塊還略有不同,就是兩個名稱中間的“#(n)”,n有23、24、25和26,這個是輸入到led_controller.v模塊的一個參數,大家別急,后面我們馬上就會提到它。

          //-------------------------------------

          //12.5MHz時鐘進行分頻閃爍,計數器為23位

          led_controller #(23) uut_led_controller_clk12m5(

          .clk(clk_12m5), //時鐘信號

          .rst_n(sys_rst_n), //復位信號,低電平有效

          .sled(led[0]) //LED指示燈接口

          );

          //-------------------------------------

          //25MHz時鐘進行分頻閃爍,計數器為24位

          led_controller #(24) uut_led_controller_clk25m(

          .clk(clk_25m), //時鐘信號

          .rst_n(sys_rst_n), //復位信號,低電平有效

          .sled(led[1]) //LED指示燈接口

          );

          //-------------------------------------

          //25MHz時鐘進行分頻閃爍,計數器為25位

          led_controller #(25) uut_led_controller_clk50m(

          .clk(clk_50m), //時鐘信號

          .rst_n(sys_rst_n), //復位信號,低電平有效

          .sled(led[2]) //LED指示燈接口

          );

          //-------------------------------------

          //25MHz時鐘進行分頻閃爍,計數器為26位

          led_controller #(26) uut_led_controller_clk100m(

          .clk(clk_100m), //時鐘信號

          .rst_n(sys_rst_n), //復位信號,低電平有效

          .sled(led[3]) //LED指示燈接口

          );

          //-------------------------------------

          //高4位LED指示燈關閉

          assign led[7:4] = 4'b1111;

          endmodule

          led_controller.v模塊代碼解析

          led_controller.v模塊代碼如下,這里重點注意我們上面剛剛提到的輸入參數。在代碼中,有“parameter CNT_HIGH = 24;”這樣的定義,若是例化這個模塊的上層接口中不定義“#(n)”,則表示“parameter CNT_HIGH = 24;”語句生效,若是定義的“#(n)”中的n值與代碼中定義的24不同,那么以n為最終值。

          module led_controller(

          input clk, //時鐘信號

          input rst_n, //復位信號,低電平有效

          output sled //LED指示燈接口

          );

          parameter CNT_HIGH = 24; //計數器最高位

          //-------------------------------------

          reg[(CNT_HIGH-1):0] cnt; //24位計數器

          //cnt計數器進行循環計數

          always @ (posedge clk or negedge rst_n)

          if(!rst_n) cnt <= 0;

          else cnt <= cnt+1'b1;

          assign sled = cnt[CNT_HIGH-1];

          endmodule

         



        關鍵詞: FPGA PLL

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 沙河市| 土默特左旗| 奈曼旗| 浙江省| 加查县| 阜南县| 泾川县| 侯马市| 南城县| 梅州市| 和田市| 威宁| 嘉义市| 包头市| 温州市| 公安县| 东兴市| 洪湖市| 徐闻县| 高邮市| 开原市| 巴林左旗| 柳林县| 镇雄县| 西畴县| 社旗县| 博湖县| 南部县| 万荣县| 安化县| 大同市| 丽江市| 阳泉市| 汶上县| 南华县| 舞钢市| 远安县| 达孜县| 彭水| 乐亭县| 阿城市|