狀態機實現LED流水燈
????????本次實驗,我們將利用狀態機的思想來進行Verilog編程實現一個LED流水燈,并通過Modelsim來進行模擬仿真,再到DE2-115開發板上進行驗證。 ? 首先進行主要代碼的編寫。
?module led (input ? ? ? ?sys_clk,input ? ? ? ?sys_rst_n,output reg [7:0] led);?// 狀態定義(8個狀態)parameter S0 = 3'd0,S1 = 3'd1,S2 = 3'd2,S3 = 3'd3,S4 = 3'd4,S5 = 3'd5,S6 = 3'd6,S7 = 3'd7;?parameter MAX_COUNT = 25_000_000; // 0.5秒@50MHz?reg [2:0] current_state; // 當前狀態寄存器reg [2:0] next_state; // 下一狀態寄存器reg [25:0] counter; // 26位定時計數器?// 狀態寄存器always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n)current_state <= S0; // 異步復位else ? ? ? ?current_state <= next_state; // 正常狀態轉移end?// 計數器邏輯always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n)counter <= 0; // 復位清零else if (current_state != next_state)counter <= 0; // 狀態切換時清零elsecounter <= counter + 1;end?// 狀態轉移邏輯always @(*) begincase (current_state)S0: next_state = (counter == MAX_COUNT-1) ? S1 : S0;S1: next_state = (counter == MAX_COUNT-1) ? S2 : S1;S2: next_state = (counter == MAX_COUNT-1) ? S3 : S2;S3: next_state = (counter == MAX_COUNT-1) ? S4 : S3;S4: next_state = (counter == MAX_COUNT-1) ? S5 : S4;S5: next_state = (counter == MAX_COUNT-1) ? S6 : S5;S6: next_state = (counter == MAX_COUNT-1) ? S7 : S6;S7: next_state = (counter == MAX_COUNT-1) ? S0 : S7;default: next_state = S0;endcaseend?// 輸出邏輯(循環右移模式)always @(*) begincase (current_state)S0: led = 8'b00000001;S1: led = 8'b00000010;S2: led = 8'b00000100;S3: led = 8'b00001000;S4: led = 8'b00010000;S5: led = 8'b00100000;S6: led = 8'b01000000;S7: led = 8'b10000000;default: led = 8'b00000001;endcaseend?endmodule
????????然后為了能在Modelsim中進行模擬仿真,我們還需要編寫一個測試模塊代碼。
?`timescale 1ns/1ps?module tb_led();?reg sys_clk;reg sys_rst_n;wire [7:0] led;?// 實例化被測試模塊(縮小計數器值便于仿真)led_fsm_8bit #(.MAX_COUNT(3)) uut (.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.led(led));?// 生成50MHz時鐘initial beginsys_clk = 0;forever #10 sys_clk = ~sys_clk; // 20ns周期=50MHzend?// 測試流程控制initial begin// 初始化sys_rst_n = 0;#20; ? ? ? ? ? ? ? ? ? // 等待一個時鐘上升沿sys_rst_n = 1;// 運行2000ns(觀察完整狀態周期)#2000;$finish;end?// 監控輸出initial begin$monitor("Time = %tns | State = %d | LED = %08b",$time, uut.current_state, led);end?endmodule
????????編寫完測試代碼并成功編譯后,就可以準備進行模擬仿真了,首先對仿真文件進行綁定,選擇Setting-->EDA Tool Settings-->Simulation。
????????然后就可以進行模擬仿真了。
????????仿真完成后,進行DE2-115開發板的實物驗證。首先對管腳進行配置。
????????把程序燒錄到開發板,就可以看到效果。
CPLD和FPGA
對比維度 | CPLD | FPGA |
---|---|---|
核心架構 | 基于乘積項(Product-Term)和宏單元(Macrocell),結構簡單,邏輯資源有限 | 基于查找表(LUT)和寄存器,邏輯單元(LE)靈活組合,資源豐富 |
存儲技術 | 采用EEPROM或Flash工藝,非易失性,無需外部配置芯片 | 基于SRAM工藝,掉電丟失配置數據,需外部存儲器 |
資源規模 | 邏輯單元較少(幾十至幾百宏單元),適合小規模邏輯設計 | 邏輯單元可達數百萬級,支持大規模復雜設計 |
時序特性 | 連續式布線,延遲均勻且可預測 | 分段式布線,延遲不可預測 |
功耗 | 靜態功耗較高,適合低復雜度場景 | 動態功耗優化更好,適合高性能計算 |
編程靈活性 | 編程次數有限(約1萬次),邏輯固化后不可重構 | 支持無限次動態重構,靈活適配不同算法 |
啟動時間 | 上電即用,無需配置時間 | 需從外部加載配置數據,存在啟動延遲 |
????????CPLD的典型應用場景:簡單邏輯控制比如狀態機、地址譯碼、總線控制等組合邏輯密集型任務;某些接口的轉換,比如電平轉換(TTL與LVDS)、I/O擴展、協議適配(SPI轉UART);膠合邏輯,這在復雜系統中作為“粘合劑”,可以連接不同功能模塊(DSP與存儲器間的控制邏輯);低功耗需求場景比如工業控制、儀器儀表中的簡單邏輯處理。 ?
????????FPGA的典型應用場景:復雜時序邏輯比如如高速數據處理(通信協議處理、雷達信號處理)、實時控制(自動駕駛傳感器融合);并行計算加速:數字信號處理(DSP)、AI推理、圖像處理(ISP算法加速);動態重構系統,常用于需要硬件功能隨需求變化的場景(軟件定義無線電);高性能計算如數據中心加速、加密解密、科學仿真等對算力要求高的領域。 ?
????????從設計復雜度上看,CPLD適用于門數小于1萬的設計,FPGA更適合大規模設計(>10萬門)。從時序要求上看,CPLD延遲可預測,適合實時性強的控制邏輯;FPGA雖延遲不可預測,但通過時序約束優化可實現高頻運行(如500MHz以上)。從功耗與成本上看,CPLD成本低但功耗較高,FPGA能效比更優但需要額外配置芯片。從技術融合趨勢上看,現代CPLD(如Altera MAX系列)逐漸采用FPGA的LUT架構,界限模糊,但核心差異仍存在。
hdlbitsFPGA組合邏輯練習
D觸發器
D鎖存器
Two gates
計數器1-12
簡單電路A
總結
????????本次實驗通過狀態機設計方法,成功實現了LED流水燈的Verilog編程,并在Modelsim中進行了仿真驗證,最終在DE2-115開發板上進行了實物驗證。此外,通過對CPLD和FPGA的對比分析,進一步加深了對這兩種器件的理解,為今后的設計提供了參考。