【FPGA开发】FPGA点亮LED灯(增加按键暂停恢复/复位操作)

发布于:2025-03-23 ⋅ 阅读:(39) ⋅ 点赞:(0)

目录

一、VScode下载安装

1.1 官网下载

1.2 安装插件

二、LED流水灯点亮

2.1 任务说明

2.2 新建项目

2.3 创建Verilog文件添加至顶层实体

2.4 引脚分配 

2.5 选择烧录器

2.6 添加烧录文件&下载

2.7 烧录结果

三、增加按键操作

3.1 按键暂停和恢复功能:

3.2 引脚分配:

3.3 完整代码: 

3.4 烧录结果 


一、VScode下载安装

1.1 官网下载

在官网点击进行下载:Visual Studio Code - Code Editing. Redefined

官网速度比较慢,要使用国内镜像,本人之前已经下载安装完成了,所以可以参考博客:

VScode下载安装及使用教程_vscode qq浏览器下载-CSDN博客https://blog.csdn.net/qq_35697978/article/details/120541378?ops_request_misc=%257B%2522request%255Fid%2522%253A%25227296b49de1d5aaed030289223ac2ff33%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=7296b49de1d5aaed030289223ac2ff33&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~top_positive~default-1-120541378-null-null.nonecase&utm_term=VScode%E4%B8%8B%E8%BD%BD%E5%AE%89%E8%A3%85&spm=1018.2226.3001.4450

1.2 安装插件

在扩展处搜索下载安装 Verilog-HDL/SystemVerilog 插件,实现Verilog代码的语法高亮/自动补全

二、LED流水灯点亮

2.1 任务说明

在DE2-115开发板上,用Verilog设计一个LED流水灯实验:用6个LED完成周期为1秒的跑马灯效果

2.2 新建项目

建立项目工程名

然后一直点击NEXT进入开发板选型界面

最后点击finish

这是创建好的界面

2.3 创建Verilog文件添加至顶层实体

编译代码如下:

module LED_Flow #(parameter CLK_FREQ = 50_000_000, parameter LED_NUM = 6)(
    input               sys_clk,      // 系统时钟 (50 MHz)
    input               sys_rst_n,    // 复位信号,低电平有效
    output reg [5:0]    led           // 6 个 LED 输出
);

    // 定义计数器
    reg [25:0] cnt;                   // 26 位计数器,用于计时 1/6 秒
    wire add_cnt;                     // 计数器使能信号
    wire end_cnt;                     // 计数器结束信号

    // 定义 LED 状态计数器
    reg [2:0] led_state;              // 3 位计数器,用于控制 LED 状态
    wire add_led_state;               // LED 状态计数器使能信号
    wire end_led_state;               // LED 状态计数器结束信号

    // 计算 1/6 秒的计数值
    localparam CNT_MAX = CLK_FREQ / LED_NUM - 1; // 1/6 秒的计数值

    // 主计数器逻辑
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if (!sys_rst_n) begin
            cnt <= 26'b0;            // 复位时清零计数器
        end
        else if (add_cnt) begin
            if (end_cnt) begin
                cnt <= 26'b0;        // 计数达到最大值时清零
            end
            else begin
                cnt <= cnt + 1'b1;   // 计数器加 1
            end
        end
    end

    // LED 状态计数器逻辑
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if (!sys_rst_n) begin
            led_state <= 3'b0;       // 复位时清零 LED 状态计数器
        end
        else if (add_led_state) begin
            if (end_led_state) begin
                led_state <= 3'b0;   // 计数达到最大值时清零
            end
            else begin
                led_state <= led_state + 1'b1; // LED 状态计数器加 1
            end
        end
    end

    // LED 输出逻辑
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if (!sys_rst_n) begin
            led <= 6'b000001;        // 复位时点亮第一个 LED
        end
        else begin
            case (led_state)
                3'b000: led <= 6'b000001; // 第 1 个 LED 点亮
                3'b001: led <= 6'b000010; // 第 2 个 LED 点亮
                3'b010: led <= 6'b000100; // 第 3 个 LED 点亮
                3'b011: led <= 6'b001000; // 第 4 个 LED 点亮
                3'b100: led <= 6'b010000; // 第 5 个 LED 点亮
                3'b101: led <= 6'b100000; // 第 6 个 LED 点亮
                default: led <= 6'b000001; // 默认点亮第 1 个 LED
            endcase
        end
    end

    // 计数器使能信号
    assign add_cnt = 1'b1;            // 计数器始终使能
    assign end_cnt = (cnt == CNT_MAX); // 计数达到 1/6 秒时结束

    // LED 状态计数器使能信号
    assign add_led_state = end_cnt;  // 主计数器结束时,LED 状态计数器加 1
    assign end_led_state = (led_state == LED_NUM - 1); // LED 状态计数器达到最大值时结束

endmodule

另存为.v文件(名称与工程名一致)

选择Files,显示LED.v文件

右键点击文件,将其设置为顶层实体 

进行编译

2.4 引脚分配 

分配引脚如下: 

2.5 选择烧录器

点击选择烧录器

选择USB-Blaster [USB-0]

PS:如果遇到无法识别USB接口的情况,即只显示No-Hardware,可参考一下博客进行解决:

使用Altera综合工具Quartus II下载到FPGA时无法识别USB-Blaster问题_fpga usb blaster 禁止-CSDN博客https://blog.csdn.net/l2563898960/article/details/80309089

2.6 添加烧录文件&下载

点击LED.sof文件,点击open 

 

点击第一项编程与配置,然后开始下载 

 下载成功

2.7 烧录结果

三、增加按键操作

3.1 按键暂停和恢复功能:

按下按键时流水灯停止工作,松开按键流水灯继续工作

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        running <= 1'b1;  // 初始状态为运行
    end else if (pause) begin
        running <= ~running;  // 按键按下时切换运行状态
    end
end

3.2 引脚分配:

3.3 完整代码: 

module led_flow (
    input wire clk,          // 时钟信号
    input wire rst_n,        // 复位信号,低电平有效
    input wire pause,        // 暂停按键,高电平有效
    output reg [5:0] leds    // 6个LED输出
);

    reg [25:0] counter;      // 计数器,用于生成1秒的时钟周期
    reg [2:0] state;         // 状态寄存器,用于控制LED流水灯的状态
    reg running;            // 运行状态标志,1表示运行,0表示暂停

    // 时钟分频,生成1秒周期
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            counter <= 26'd0;
        end else if (running) begin
            if (counter == 26'd49_999_999) begin
                counter <= 26'd0;
            end else begin
                counter <= counter + 1;
            end
        end
    end

    // 状态机控制LED流水灯
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            state <= 3'd0;
            leds <= 6'b000001;  // 初始状态,第一个LED亮
        end else if (running && counter == 26'd49_999_999) begin
            case (state)
                3'd0: begin leds <= 6'b000010; state <= 3'd1; end
                3'd1: begin leds <= 6'b000100; state <= 3'd2; end
                3'd2: begin leds <= 6'b001000; state <= 3'd3; end
                3'd3: begin leds <= 6'b010000; state <= 3'd4; end
                3'd4: begin leds <= 6'b100000; state <= 3'd5; end
                3'd5: begin leds <= 6'b000001; state <= 3'd0; end
                default: begin leds <= 6'b000001; state <= 3'd0; end
            endcase
        end
    end

    // 按键暂停和恢复功能
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            running <= 1'b1;  // 初始状态为运行
        end else if (pause) begin
            running <= ~running;  // 按键按下时切换运行状态
        end
    end

endmodule

3.4 烧录结果 


网站公告

今日签到

点亮在社区的每一天
去签到