【FPGA实验】LED定时翻转实验

实验要求

编写“led.v”,定义一个 32 位的寄存器 timer, 用于循环计数 0~49999999(1 秒钟), 计数49999999(1 秒)的时候, 寄存器 timer 变为 0,并翻转四个 LED。

led.v编写思路

通过控制一个32位的计数器cnt来周期性地翻转四个LED灯的状态:

时钟信号:sys_clk是系统的时钟信号,用于驱动计数器的计数操作。

复位信号:rst_n是低电平有效的复位信号。当rst_n为低电平时,计数器cnt和LED状态led会被重置为初始值。

计数器:cnt是一个32位的寄存器,用于计数时钟周期。当cnt达到49999999时,表示已经过了1秒钟(假设系统时钟频率为50MHz),此时cnt会被重置为0,并且LED灯的状态会发生翻转。

LED控制:led是一个4位的寄存器,用于控制四个LED灯的状态。当cnt达到49999999时,led的值会被取反,从而实现LED灯的翻转。

led.v的verilog代码如下:

// 定义时间单位和时间精度(1ns单位,1ps精度)
`timescale 1ns / 1ps

// 定义LED控制模块
module led(
    input sys_clk,       // 系统时钟输入
    input rst_n,         // 低电平有效的复位信号
    output [3:0] led     // 4位LED输出
);

// 定义内部寄存器
reg [3:0] led;          // 4位LED输出寄存器
reg [31:0] cnt;         // 32位计数器,用于计时

// 时钟上升沿或复位下降沿触发的always块
always @(posedge sys_clk or negedge rst_n)
    // 复位信号有效时(低电平)
    if (!rst_n)         
    begin 
        cnt <= 32'd0;   // 计数器清零
        led <= 4'b1111;  // LED全亮(假设低电平点亮LED)
    end
    // 复位信号无效时
    else
    begin
        // 当计数器达到49,999,999时(相当于1秒,假设时钟频率为50MHz)
        if (cnt == 32'd49_999_999)
        begin
            cnt <= 32'd0;  // 计数器归零
            led <= ~led;   // LED状态取反(实现闪烁效果)
        end
        else
            cnt <= cnt + 1; // 计数器加1
    end

endmodule
添加约束文件

led.xdc

create_clock -period 20.000 -name sys_clk -waveform {0.000 10.000} [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
set_property PACKAGE_PIN U18 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property PACKAGE_PIN M15 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property PACKAGE_PIN J14 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property PACKAGE_PIN K14 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property PACKAGE_PIN J18 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
set_property PACKAGE_PIN H18 [get_ports {led[3]}]
仿真验证

Verilog 测试模块代码:

// 定义时间单位和时间精度(1ns 单位,1ps 精度)
`timescale 1ns / 1ps

// 定义 LED 模块的测试模块
module Tb_led1();

    // 定义测试信号
    reg sys_clk = 0;    // 系统时钟信号,初始化为 0
    reg rst_n = 1;      // 复位信号(低电平有效),初始化为 1(无效状态)
    wire [3:0] led;     // 4 位 LED 输出信号(连接到待测试模块的输出)

    // 实例化待测试的 LED 模块
    led led_1(
        .sys_clk(sys_clk),  // 将测试模块的时钟连接到待测试模块
        .rst_n(rst_n),      // 将测试模块的复位信号连接到待测试模块
        .led(led)           // 将待测试模块的 LED 输出连接到测试模块的 wire 信号
    );

    // 生成时钟信号:每 10ns 翻转一次,产生 50MHz 时钟频率(周期=20ns)
    always #10 sys_clk <= ~sys_clk;

    // 初始化测试过程
    initial begin
        sys_clk = 0;    // 确保时钟初始化为 0(虽然前面已经初始化过)
        rst_n = 1;       // 初始时复位信号无效(高电平)
        
        #1000;          // 等待 1000ns(模拟初始稳定状态)
        
        rst_n = 0;      // 产生复位脉冲(有效低电平)
        #20;            // 保持复位 20ns
        
        rst_n = 1;      // 结束复位,恢复正常工作
    end

endmodule

仿真结果:

每过1秒,四个LED灯同时明灭交替。符合实验要求。

实验结果

四个LED全亮

1秒钟后,四个LED全灭

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值