1. LED闪烁控制器
任务目标
设计一个可综合的Verilog LED闪烁控制器,支持通过外部输入选择两种闪烁频率(快闪/慢闪),并在FPGA开发板上驱动LED实现视觉验证。本案例聚焦于时钟分频与模式选择的RTL实现,提供完整的仿真测试与板级验证路径。
模块设计与端口定义
控制器采用同步时序逻辑设计,通过计数器对系统时钟分频产生闪烁周期。核心思路:使用一个32位计数器对50MHz系统时钟计数,最高位作为慢闪时钟(周期约1.7s),次高位作为快闪时钟(周期约0.85s),通过外部按键选择输出源。
完整RTL代码
module led_flash_controller (
input wire clk, // 50MHz系统时钟
input wire rst_n, // 异步复位,低有效
input wire mode_sel, // 闪烁模式选择:0=慢闪,1=快闪
output reg led_out // LED驱动输出
);
// 32位计数器,最高位周期 = 2^32 / 50MHz ≈ 85.9s
// 实际使用bit[25]和bit[24]以适配常见开发板观察效果
reg [25:0] counter;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
counter <= 26'd0;
else
counter <= counter + 1'b1;
end
// 慢闪:bit[25]翻转周期 = 2^26/50MHz ≈ 1.34s(LED亮灭各0.67s)
// 快闪:bit[24]翻转周期 = 2^25/50MHz ≈ 0.67s(LED亮灭各0.34s)
wire slow_clk = counter[25];
wire fast_clk = counter[24];
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
led_out <= 1'b0;
else if (mode_sel)
led_out <= fast_clk;
else
led_out <= slow_clk;
end
endmodule
仿真测试平台
`timescale 1ns/1ps
module tb_led_flash_controller;
reg clk = 0;
reg rst_n = 0;
reg mode_sel = 0;
wire led_out;
// 生成50MHz时钟
always #10 clk = ~clk;
led_flash_controller uut (
.clk(clk),
.rst_n(rst_n),
.mode_sel(mode_sel),
.led_out(led_out)
);
// 简化计数器以加速仿真:在测试中直接观察模式切换行为
reg [25:0] expected_counter;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) expected_counter <= 0;
else expected_counter <= expected_counter + 1;
end
initial begin
// 复位
rst_n = 0;
#100;
rst_n = 1;
// 验证慢闪模式:等待计数器bit[25]翻转
mode_sel = 0;
#1000; // 观察led_out初始状态
// 切换到快闪模式
mode_sel = 1;
#1000;
// 再次切回慢闪
mode_sel = 0;
#1000;
$display("仿真完成:验证模式切换功能");
$finish;
end
// 自动检查:确保led_out跟随所选时钟源
always @(posedge clk) begin
if (rst_n) begin
if (mode_sel == 1'b1)
assert (led_out == counter[24]) else $error("快闪模式输出错误");
else
assert (led_out == counter[25]) else $error("慢闪模式输出错误");
end
end
endmodule
运行与验证方法
仿真验证:使用ModelSim或Vivado XSim运行测试平台,观察led_out波形是否与所选计数器位同步翻转。通过断言自动检查输出正确性,若仿真结束无断言错误即通过功能验证。
板级验证:将代码综合后下载至FPGA开发板,连接LED至led_out引脚。操作步骤:
- 将mode_sel连接至板载拨码开关或按键
- 复位后观察LED:mode_sel=0时约0.67秒亮灭一次(慢闪)
- 切换mode_sel=1时约0.34秒亮灭一次(快闪)
- 通过视觉观察两种闪烁频率差异明显,即验证成功
综合约束建议
若使用实际开发板,需在XDC/SDC文件中添加时钟约束:create_clock -period 20.0 [get_ports clk]。本设计为纯时序逻辑,无特殊时序路径要求,满足建立/保持时间即可正常综合。