实验要求
编写“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全灭