实验一:两种方式实现流水灯(3-8译码器与移位器)


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
在这里插入图片描述

在这里插入图片描述
在远程实验系统里可以观察到流水灯的实验现象。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值