FPGA實現LED流水燈
1.vscode的安裝和使用
vscode下載
Visual Studio Code - Code Editing. Redefined
vscode插件(Verilog-HDL/SystemVerilog)下載
quartus綁定vscode
2.用6個LED完成周期為1秒的跑馬燈效果
流水燈模塊設計
時鐘輸入
DE2-115開發板配備了一個固定的時鐘源。該開發板內置了一個50MHz的晶振,這意味著開發板上有一個能夠產生每秒50百萬個周期信號的振蕩器或時鐘發生器,用于驅動FPGA(現場可編程門陣列)芯片
時鐘周期
時鐘周期是時鐘信號的一個完整波形(從上升沿到下一個上升沿或下降沿到下一個下降沿)所需的時間,可以通過下面的公式計算:
對于50MHz的時鐘頻率,時鐘周期為20納秒。
1s內點亮6個led,即等待前一個燈熄滅后1/6s=0.167s點亮下一個燈,所以代碼編寫如下
代碼編寫(計數器版本)
module led_test(input wire clk, ? ? // 50MHz時鐘輸入input wire rst_n, ? // 復位信號,低電平有效output reg [5:0] led // 6個LED燈的狀態 ); ? // 計數器,計數1s需要50_000_000個時鐘周期 reg [25:0] cnt; ? // 計數器模塊 always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt <= 26'd0; // 復位時計數器歸零end else if (cnt == 50_000_000 - 1) begin // 計滿1秒后復位cnt <= 26'd0;end else begincnt <= cnt + 1'd1; // 使用非阻塞賦值end end ? // LED狀態更新邏輯:每次觸發時先清零所有LED always @(posedge clk or negedge rst_n) beginif (!rst_n) beginled <= 6'b000000; // 復位時關閉所有LEDend else begin// 默認保持當前狀態(非阻塞賦值)led <= led;if (cnt == 8_333_333 - 1) beginled <= 6'b000001; // 點亮第一個LEDendelse if (cnt == 16_666_666 - 1) beginled <= 6'b000010; // 點亮第二個LEDendelse if (cnt == 25_000_000 - 1) beginled <= 6'b000100; // 點亮第三個LEDendelse if (cnt == 33_333_333 - 1) beginled <= 6'b001000; // 點亮第四個LEDendelse if (cnt == 41_666_666 - 1) beginled <= 6'b010000; // 點亮第五個LEDendelse if (cnt == 50_000_000 - 1) beginled <= 6'b100000; // 點亮第六個LEDendend end ? endmodule
我需要將現有的代碼拆分為至少兩個模塊:一個計數器模塊和一個LED控制模塊,然后創建一個頂層模塊來連接這兩個模塊
頂層模塊
module led_test(input wire clk,input wire rst_n,output wire [5:0] led ); // 連接計數器與LED控制器 wire [25:0] cnt_net; ? counter counter_inst (.clk(clk),.rst_n(rst_n),.cnt(cnt_net) ); ? led_controller led_ctrl_inst (.clk(clk),.rst_n(rst_n),.cnt_value(cnt_net),.led(led) ); ? endmodule
LED控制模塊 (led_controller.v)
module led_controller(input wire clk,input wire rst_n,input wire [25:0] cnt_value,output reg [5:0] led ); // LED狀態更新邏輯 always @(posedge clk or negedge rst_n) beginif (!rst_n) beginled <= 6'b000000;end else beginled <= led; // 默認保持當前狀態// 順序點亮LED(每個LED間隔約1/6秒)case (1'b1)(cnt_value == 26'd8_333_332): led <= 6'b000001;(cnt_value == 26'd16_666_665): led <= 6'b000010;(cnt_value == 26'd24_999_998): led <= 6'b000100;(cnt_value == 26'd33_333_331): led <= 6'b001000;(cnt_value == 26'd41_666_664): led <= 6'b010000;(cnt_value == 26'd49_999_997): led <= 6'b100000;default: ;endcaseend end endmodule
計數器模塊
module counter(input wire clk,input wire rst_n,output reg [25:0] cnt ); // 計數1秒(50MHz時鐘) always @(posedge clk or negedge rst_n) beginif (!rst_n)cnt <= 26'd0;else if (cnt == 26'd49_999_999) // 50M-1cnt <= 26'd0;elsecnt <= cnt + 1'b1; end endmodule
管腳綁定
使用的LEDR[0]~[5]這六個led燈來進行實驗,LED引腳配置說明如下:
管腳綁定如下:
效果展示
2.(選做)增加流水燈的按鍵暫停、按鍵恢復功能
使用按鈕開關
DE2-115 提供了四個按鈕開關,每個按鈕開關都通過一個施 密特觸發器進行了去抖動處理。四個施密特觸發器的輸出信 號,分別為KEY0、KEY1、KEY2、KEY3,直接連接到了Cyclone IV E FPGA。當按鈕沒有 被按下的時候,它的輸出是高電平,按下去則給出一個低電平
我選擇KEY0做為復位按鈕,KEY1作為控制led流水燈暫停的按鈕
代碼編寫
module flow_led_pause(input ? ? ? ? clk, ? ? ? // 50MHz時鐘input ? ? ? ? rst_n, ? ? // 異步復位(低有效)input ? ? ? ? key_pause, // 暫停/繼續按鍵(低有效)output reg [5:0] led ? ? // 6位LED輸出 ); ? // 參數定義 parameter CLK_FREQ = 50_000_000; // 50MHz時鐘 parameter LED_INTERVAL = CLK_FREQ / 6; // 每個LED亮0.1667秒 ? // 主計數器(1秒周期) reg [25:0] cnt; wire cnt_max = (cnt == LED_INTERVAL - 1); ? // 按鍵消抖(兩級寄存器同步) reg [1:0] key_sync; always @(posedge clk or negedge rst_n) beginif (!rst_n) key_sync <= 2'b11;else key_sync <= {key_sync[0], key_pause}; end wire pause_trig = (key_sync == 2'b10); // 下降沿檢測 ? // 暫停標志 reg pause_flag; always @(posedge clk or negedge rst_n) beginif (!rst_n) pause_flag <= 1'b0;else if (pause_trig) pause_flag <= ~pause_flag; // 按鍵切換狀態 end ? // LED狀態計數器(0~5循環) reg [2:0] led_state; always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt <= 0;led_state <= 0;endelse if (!pause_flag) beginif (cnt_max) begincnt <= 0;led_state <= (led_state == 3'd5) ? 0 : led_state + 1;endelse cnt <= cnt + 1;end end ? // LED輸出邏輯 always @(posedge clk or negedge rst_n) beginif (!rst_n) led <= 6'b000001; // 復位后LED0亮else if (!pause_flag) begincase (led_state)3'd0: led <= 6'b000001; // LED03'd1: led <= 6'b000010; // LED13'd2: led <= 6'b000100; // LED23'd3: led <= 6'b001000; // LED33'd4: led <= 6'b010000; // LED43'd5: led <= 6'b100000; // LED5default: led <= led;endcaseend end ? endmodule
管腳綁定
按鈕開關配置說明如下:
管腳綁定如下:
效果展示
flow
參考鏈接:
vscode安裝+配置+使用+調試【保姆級教程】
VSCode配置Verilog/SystemVerilog環境(二)插件安裝
FPGA點亮led
led流水燈
FPGA學習——按鍵控制LED流水燈(附源碼 無按鍵消抖版本)