文章目录
一、安装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) begin
if (!sys_rst_n) begin
cnt <= 26'b0;
end else if (add_cnt) begin
cnt <= (end_cnt) ? 26'b0 : cnt + 1'b1;
end
end
// LED状态计数器逻辑
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
cnt1 <= 3'b0;
end else if (add_cnt1) begin
cnt1 <= (end_cnt1) ? 3'b0 : cnt1 + 1'b1;
end
end
// LED显示逻辑(直接循环左移更简洁)
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
led <= 6'b000001;
end else if (end_cnt) begin // 每秒左移一次
led <= {led[4:0], led[5]}; // 循环左移
end
end
// 控制信号定义
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) begin
sync_rst_n <= {sync_rst_n[0], sys_rst_n_raw};
end
assign 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) begin
if (!sys_rst_n) begin
pause_flag <= 1'b0;
end else if (pause_pulse) begin
pause_flag <= ~pause_flag;
end
end
// 显示模块
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) begin
if (!rst_n) begin
cnt <= 0;
en <= 0;
end else begin
if (cnt == 26'd49_999_999) begin // 50MHz → 1Hz
cnt <= 0;
en <= 1;
end else begin
cnt <= cnt + 1;
en <= 0;
end
end
end
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) begin
if (!rst_n) begin
led <= 6'b000001; // 复位时LED0亮
end else if (en && !pause) begin
led <= {led[4:0], led[5]}; // 循环左移
end
end
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) begin
if (!rst_n) begin
debounce_cnt <= 0;
key_sync <= 1'b1; // 复位时按键状态为高
end else begin
if (key_in != key_sync) begin
debounce_cnt <= debounce_cnt + 1;
if (debounce_cnt == 20'd1_000_000) begin // 20ms消抖
key_sync <= key_in;
debounce_cnt <= 0;
end
end else begin
debounce_cnt <= 0;
end
end
end
// 边沿检测(下降沿:1→0)
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
key_sync_prev <= 1'b1;
end else begin
key_sync_prev <= key_sync;
end
end
// 生成按键脉冲(按下时产生一个时钟周期高电平)
assign key_pulse = (~key_sync) & key_sync_prev;
endmodule
(3)配置引脚
(4)烧录
(5)实现效果
四、总结
本次实验学会了更多关于Quartus的使用操作也学习到了更多关于FPGA的内容。