文章目录
1. 实验简介
流水灯实验是FPGA/数字电路入门最经典的实践项目之一。通过依次点亮多颗LED并使其呈现流动效果,可以帮助初学者理解FPGA中的时序逻辑、计数器、移位寄存器、译码器等数字电路基础知识。
本实验基于Pango FPGA平台,采用50MHz系统时钟,实现8位LED流水灯,分别用移位寄存器法和三八译码器法两种方式实现。
2. 实验硬件基础
- 紫光同创PGL50H开发板
- 8个LED灯
3. 数字电路知识点详解
3.1 时钟(clk)
FPGA中所有时序逻辑的核心。50MHz时钟周期为20ns,所有变化均在时钟上升沿同步发生,保证电路同步。
3.2 复位(rst_n)
低电平有效复位,确保系统上电或异常后恢复初始状态。
3.3 计数器
- 作用:FPGA时钟很快(50MHz),人眼无法分辨LED以这种频率变化。设计一个计数器,每计满50_000_000次后再变化一次LED,实现约1秒的视觉节奏。
- 实现:26位计数器即可满足1秒计满的需求。
3.4 LED输出
8位并行输出,由FPGA的IO管脚驱动外部LED。
4. 移位寄存器法实现
4.1 原理
用一个8位移位寄存器代表LED灯的开关状态,每1秒将其内容循环左移一次,实现LED的流水效果。
4.2 代码实现
module shift_led (
input wire clk, // 50MHz 时钟信号
input wire rst_n, // 复位信号,低电平有效
output reg [7:0] led // 8 个 LED 灯输出
);
// 50MHz 时钟,周期为 20ns,1 秒需要计数 50_000_000 次
localparam COUNT_MAX = 26'd50_000_000;
reg [25:0] counter; // 计数器
// 计数器逻辑,用于产生 1 秒的延时
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
counter <= 26'd0;
led <= 8'b00000001; // 初始状态,第一个 LED 亮
end else if (counter == COUNT_MAX - 1) begin
counter <= 26'd0;
led <= {led[6:0], led[7]}; // 循环左移
end else begin
counter <= counter + 1'b1;
end
end
endmodule
4.3 代码解析
- 移位寄存器:
led <= {led[6:0], led[7]};
Verilog位拼接操作,每次执行时,led
内容左移一位,最高位补上原最低位,实现循环。 - 初始状态:
led <= 8'b00000001;
只有第一个LED亮。 - 每秒变化:计数器每到
COUNT_MAX-1
清零,流水灯状态更新。
4.4 电路原理说明
- 移位寄存器是基础时序逻辑单元,实现数据流的移动,广泛用于信号处理、状态机等。
- 该实现方式本质为一个带循环的移位寄存器,每1秒移位一次。
5. 三八译码器法实现
5.1 原理
用3位二进制计数器做流水灯的“指针”,通过三八译码器将其译码成8位独热码,依次点亮每个LED。
5.2 代码实现
module three_eight_decoder_led (
input wire clk, // 50MHz 时钟信号
input wire rst_n, // 复位信号,低电平有效
output reg [7:0] led // 8 个 LED 灯输出
);
localparam COUNT_MAX = 26'd50_000_000;
reg [25:0] counter; // 计数器
reg [2:0] decoder_in; // 三八译码器的 3 位输入
// 三八译码器逻辑
always @(*) begin
case (decoder_in)
3'b000: led = 8'b00000001;
3'b001: led = 8'b00000010;
3'b010: led = 8'b00000100;
3'b011: led = 8'b00001000;
3'b100: led = 8'b00010000;
3'b101: led = 8'b00100000;
3'b110: led = 8'b01000000;
3'b111: led = 8'b10000000;
default: led = 8'b00000000;
endcase
end
// 计数器逻辑,用于产生 1 秒的延时
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
counter <= 26'd0;
decoder_in <= 3'b000;
end else if (counter == COUNT_MAX - 1) begin
counter <= 26'd0;
decoder_in <= decoder_in + 1'b1;
end else begin
counter <= counter + 1'b1;
end
end
endmodule
5.3 代码解析
- 三八译码器:用case语句实现3-to-8译码,
decoder_in
作为输入,led
为输出,只有一个LED为高电平。 - decoder_in:3位二进制,每1秒自增1,范围0~7,循环递增。
- 流水效果:每1秒依次点亮不同的LED,实现流水灯。
5.4 电路原理说明
- 译码器是常用组合逻辑电路,将n位输入转换为2^n位独热输出。
- 本质是组合逻辑,便于扩展和控制,实现独热码点亮。
6. 两种实现方式对比
实现方式 | 原理 | 优点 | 适用场景 |
---|---|---|---|
移位寄存器法 | 时序逻辑、移位 | 结构简单,速度快 | 流动、循环效果 |
三八译码器法 | 组合逻辑、译码 | 易于扩展、直观 | 独热码选择类应用 |
7. 远程实验系统实验现象:
将写好的程序通过远程实验系统下载到FPGA里并根据远程摄像头来观察实验现象。远程下载及固化下面附链接
链接: link
在远程实验系统里可以观察到流水灯的实验现象。