文章目錄
- 一、安裝VScode,在其中下載安裝Verilog-HDL/SystemVerilog插件;
- (1)安裝VScode
- (2)安裝插件
- (3)與Quartus關聯
- 二、不分模塊實現流水燈
- (1)新建工程
- (2)添加流水燈實現代碼
- (3)配置引腳
- (4)燒錄
- (5)實現效果
- 三、分模塊實現流水燈
- (1)新建工程
- (2)添加流水燈實現代碼
- (3)配置引腳
- (4)燒錄
- (5)實現效果
一、安裝VScode,在其中下載安裝Verilog-HDL/SystemVerilog插件;
(1)安裝VScode
網上的相關教程很多我就不過多贅述了。默認安裝好了。
(2)安裝插件
在VScode中安裝相關插件
(3)與Quartus關聯
打開Quartus按照下圖步驟進行關聯,關聯成功后在新建文件后會自動打開VScode編輯器。
二、不分模塊實現流水燈
(1)新建工程
(2)添加流水燈實現代碼
代碼:
module lsd #(parameter TIME_1S = 26'd49_999_999)( input sys_clk,input sys_rst_n,output reg [5:0] led
);reg [25:0] cnt; // 修正為26位寬wire add_cnt;wire end_cnt;reg [2:0] cnt1;wire add_cnt1;wire end_cnt1;// 1秒定時器邏輯always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n) begincnt <= 26'b0;end else if (add_cnt) begincnt <= (end_cnt) ? 26'b0 : cnt + 1'b1;endend// LED狀態計數器邏輯always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n) begincnt1 <= 3'b0;end else if (add_cnt1) begincnt1 <= (end_cnt1) ? 3'b0 : cnt1 + 1'b1;endend// LED顯示邏輯(直接循環左移更簡潔)always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n) beginled <= 6'b000001;end else if (end_cnt) begin // 每秒左移一次led <= {led[4:0], led[5]}; // 循環左移endend// 控制信號定義assign add_cnt = 1'b1;assign end_cnt = (cnt == TIME_1S);assign add_cnt1 = end_cnt;assign end_cnt1 = (cnt1 == 3'd5);endmodule
(3)配置引腳
(4)燒錄
(5)實現效果
三、分模塊實現流水燈
(1)新建工程
(2)添加流水燈實現代碼
新建代碼后跳轉到VScode時會默認起一個名字最好另存為對應文件名否則在后面運行會報錯。
新建保存完代碼后將代碼文件添加到工程中并將LedBlink.v設置為頂層模塊
選中頂層文件右鍵選擇Set as Top…
LedBlink.v
module LedBlink(input clk,input sys_rst_n_raw, // 原始復位信號(KEY0)input pause_key, // 暫停按鍵(KEY1)output [5:0] led
);// 同步復位信號reg [1:0] sync_rst_n;wire sys_rst_n;always @(posedge clk) beginsync_rst_n <= {sync_rst_n[0], sys_rst_n_raw};endassign sys_rst_n = sync_rst_n[1];// 分頻模塊(生成1Hz使能)wire en_1Hz;fenpin u_fenpin(.clk(clk),.rst_n(sys_rst_n),.en(en_1Hz));// 按鍵控制模塊(消抖+脈沖)wire pause_pulse;key_ctrl u_key_ctrl(.clk(clk),.rst_n(sys_rst_n),.key_in(pause_key),.key_pulse(pause_pulse));// 暫停狀態標志reg pause_flag;always @(posedge clk or negedge sys_rst_n) beginif (!sys_rst_n) beginpause_flag <= 1'b0;end else if (pause_pulse) beginpause_flag <= ~pause_flag;endend// 顯示模塊display u_display(.clk(clk),.rst_n(sys_rst_n),.en(en_1Hz),.pause(pause_flag),.led(led));
endmodule
fenpin.v
module fenpin(input clk, // 50MHz時鐘input rst_n, // 復位信號(低有效)output reg en // 1Hz使能信號
);reg [25:0] cnt; // 26位計數器(0~49,999,999)always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt <= 0;en <= 0;end else beginif (cnt == 26'd49_999_999) begin // 50MHz → 1Hzcnt <= 0;en <= 1;end else begincnt <= cnt + 1;en <= 0;endendend
endmodule
display.v
module display(input clk,input rst_n, // 復位信號(低有效)input en, // 1Hz使能input pause, // 暫停狀態(1=暫停)output reg [5:0] led
);always @(posedge clk or negedge rst_n) beginif (!rst_n) beginled <= 6'b000001; // 復位時LED0亮end else if (en && !pause) beginled <= {led[4:0], led[5]}; // 循環左移endend
endmodule
key_ctrl.v
module key_ctrl(input clk, // 50MHz時鐘input rst_n, // 復位信號(低有效)input key_in, // 原始按鍵輸入(KEY1)output key_pulse // 消抖后的按鍵脈沖(按下一次產生一個脈沖)
);reg [19:0] debounce_cnt; // 消抖計數器(20ms)reg key_sync; // 同步后的按鍵狀態reg key_sync_prev; // 前一刻按鍵狀態(用于邊沿檢測)// 消抖邏輯always @(posedge clk or negedge rst_n) beginif (!rst_n) begindebounce_cnt <= 0;key_sync <= 1'b1; // 復位時按鍵狀態為高end else beginif (key_in != key_sync) begindebounce_cnt <= debounce_cnt + 1;if (debounce_cnt == 20'd1_000_000) begin // 20ms消抖key_sync <= key_in;debounce_cnt <= 0;endend else begindebounce_cnt <= 0;endendend// 邊沿檢測(下降沿:1→0)always @(posedge clk or negedge rst_n) beginif (!rst_n) beginkey_sync_prev <= 1'b1;end else beginkey_sync_prev <= key_sync;endend// 生成按鍵脈沖(按下時產生一個時鐘周期高電平)assign key_pulse = (~key_sync) & key_sync_prev;
endmodule
(3)配置引腳
(4)燒錄
(5)實現效果
四、總結
本次實驗學會了更多關于Quartus的使用操作也學習到了更多關于FPGA的內容。