玩轉Zynq連載20——基于FPGA的模塊化設計 更多資料共享 騰訊微云鏈接:https://share.weiyun.com/5s6bA0s 百度網盤鏈接:https://pan.baidu.com/s/1XTQtP5LZAedkCwQtllAEyw 提取碼:ld9c ![]() 騰訊微云鏈接:https://share.weiyun.com/5s6bA0s 百度網盤鏈接:https://pan.baidu.com/s/1XTQtP5LZAedkCwQtllAEyw 提取碼:ld9c 模塊化設計是FPGA設計中一個很重要的技巧,它能夠使一個大型設計的分工協作、仿真測試更加容易,代碼維護或升級更加便利。 如圖所示,一般整個設計工程的頂層文件里只做例化,不做邏輯處理。然后一個頂層下面會有模塊A、模塊B、模塊C等等,模塊A/B/C下又可以分多個子模塊實現。
![]() 圖模塊設計示意圖 如此一來,就可以將大規模復雜系統按照一定規則劃分成若干模塊,然后對每個模塊進行設計輸入、綜合與實現,并將實現結果約束在預先設置好的區域內,最后將所有模塊的實現結果進行整合集成,就能完成整個系統的設計。 模塊化設計的實現步驟是整個模塊化設計流程中最重要、最特殊的,它包含: ●初始預算,本階段是實現步驟的第一步,對整個模塊化設計起著指導性的作用。在初始預算階段,項目管理者需要為設計的整體進行位置布局,只有布局合理,才能夠在最大程度上體現模塊化設計的優勢;反之,如果因布局不合理而在較后的階段需要再次進行初始預算,則需要對整個實現步驟全面返工。 ●子模塊的設計實現,在該階段,每個項目成員并行完成各自子模塊的實現。 ●模塊的最終集成,在該階段項目管理者將頂層的實現結果和所有子模塊的實現結果進行整合集成,完成整個設計的實現。 模塊劃分的基本原則是,子模塊功能相對獨立,模塊內部聯系盡量緊密,而模塊間的連接盡量簡單。對于那些難以滿足模塊劃分準則的具有強內部關聯的復雜設計,并不適合采用模塊化設計方法。 下面以zstar_ex03工程的頂層源碼zstar.v為例,講解在Verilog代碼中如何實現模塊化設計。在zstar.v模塊下面有4個模塊,包括1個PLL時鐘產生模塊,以及3個控制LED閃爍的模塊。 module zstar( input ext_clk_25m, //外部輸入25MHz時鐘信號 output[2:0] led //LED指示燈接口 ); //------------------------------------- wire clk_25m; //PLL輸出25MHz時鐘 wire clk_50m; //PLL輸出50MHz時鐘 wire clk_100m; //PLL輸出100MHz時鐘 wire sys_rst_n; //PLL輸出的locked信號,作為FPGA內部的復位信號,低電平復位,高電平正常工作 clk_wiz_0 uut_clk_wiz_0 ( // Clock in ports .clk_in1(ext_clk_25m), // input clk_in1 // Clock out ports .clk_out1(clk_25m), // output clk_out1 .clk_out2(clk_50m), // output clk_out2 .clk_out3(clk_100m), // output clk_out3 // Status and control signals .reset(1'b0), // input reset .locked(sys_rst_n)); // output locked //------------------------------------- //25MHz時鐘進行分頻閃爍,計數器為24位 led_controller #(24) uut_led_controller_clk25m( .clk(clk_25m), //時鐘信號 .rst_n(sys_rst_n), //復位信號,低電平有效 .sled(led[2]) //LED指示燈接口 ); //------------------------------------- //25MHz時鐘進行分頻閃爍,計數器為25位 led_controller #(25) uut_led_controller_clk50m( .clk(clk_50m), //時鐘信號 .rst_n(sys_rst_n), //復位信號,低電平有效 .sled(led[1]) //LED指示燈接口 ); //------------------------------------- //25MHz時鐘進行分頻閃爍,計數器為26位 led_controller #(26) uut_led_controller_clk100m( .clk(clk_100m), //時鐘信號 .rst_n(sys_rst_n), //復位信號,低電平有效 .sled(led[0]) //LED指示燈接口 ); endmodule ★ 語法要點 注意zstar.v模塊的代碼中例化了4個子模塊,這是一個不折不扣的模塊化設計工程。下面是對led_controller.v模塊的一個例化代碼。 led_controller #(24) uut_led_controller_clk25m( .clk(clk_25m), //時鐘信號 .rst_n(sys_rst_n), //復位信號,低電平有效 .sled(led[2]) //LED指示燈接口 ); 以上面這段代碼為例,模塊例化大體有下面幾個要點: ● led_controller是原始工程源碼本身的模塊名稱。 ● uut_led_controller_clk25m的名稱是可以隨意起的,只要不和已有的名稱重名即可,它表示我們對當前例化工程led_controller.v的唯一識別名。在這個工程中,我們看到led_controller.v模塊被例化了多次,但它和uut_led_controller_clk25m對應位置的命名是不一樣的,而且必須是不一樣的,表示工程中有多個完全一樣的功能模塊。這和軟件程序里面的調用不一樣,軟件程序由于運行起來總是串行的,所以多次調用同一個函數時,這個函數可以只占一個函數所需的物理存儲空間即可;但是FPGA是并行處理的,它的模塊例化,哪怕是完全一樣的模塊,往往也是需要多個完全一樣的物理資源與余對應的。 ● “.clk(clk_25m),”是接口的映射,“.(),”是固定格式。clk是led_controller.v模塊內部的接口,clk_25m是zstar.v模塊的接口。 如圖所示,當工程編譯后,我們便可以在工程管理窗口中看到整個工程的模塊結構。在zstar.v模塊下面對應了4個子模塊。
![]() 圖 at7_ex03模塊結構 led_controller.v模塊代碼如下。 module led_controller( input clk, //時鐘信號 input rst_n, //復位信號,低電平有效 output sled //LED指示燈接口 ); parameter CNT_HIGH = 24; //計數器最高位 //------------------------------------- reg[(CNT_HIGH-1):0] cnt; //24位計數器 //cnt計數器進行循環計數 always @ (posedgeclk or negedgerst_n) if(!rst_n) cnt<= 0; else cnt<= cnt+1'b1; assign sled = cnt[CNT_HIGH-1]; endmodule |