亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> VHDL

FPGA入门实战:LED闪烁教程(VHDL与Verilog)

简介

欢迎来到实战指南,带您在FPGA上用VHDL或Verilog创建简单LED闪烁器。例程演示核心FPGA概念:并发进程、频率合成、多路复用器逻辑——均由25MHz时钟驱动。

项目概览

频率选择真值表

使能开关1开关2LED驱动频率
0--(禁用)
100100Hz
10150Hz
11010Hz
1111Hz

信号定义

信号名方向描述
i_clock输入25MHz系统时钟
i_enable输入LED使能开关(逻辑0=关)
i_switch_1输入频率选择位1
i_switch_2输入频率选择位0
o_led_drive输出LED驱动信号

设计理念

四独立计数器进程并发运行,各在目标频率翻转局部信号。即使特定频率未选中,其计数器仍持续运行——这是FPGA并发标志。

开关实现组合多路复用器将所需翻转信号路由至LED驱动器。LED_EN开关作有效高位门控,使能低时LED关闭。

框图

FPGA入门实战:LED闪烁教程(VHDL与Verilog)

VHDL实现

下方为满足规格的完整注释VHDL模块。计数器常数按公式计算:
count = (时钟频率 / 目标频率) × 0.5 以达50%占空比。

 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity tutorial_led_blink is port ( i_clock : in std_logic; i_enable : in std_logic; i_switch_1 : in std_logic; i_switch_2 : in std_logic; o_led_drive : out std_logic ); end tutorial_led_blink; architecture rtl of tutorial_led_blink is -- 频率常数(半周期计数) constant c_CNT_100HZ : natural := 125000; -- 25MHz / 100Hz × 0.5 constant c_CNT_50HZ : natural := 250000; -- 25MHz / 50Hz × 0.5 constant c_CNT_10HZ : natural := 1250000; -- 25MHz / 10Hz × 0.5 constant c_CNT_1HZ : natural := 12500000; -- 25MHz / 1Hz × 0.5 -- 计数器信号 signal r_CNT_100HZ : natural range 0 to c_CNT_100HZ; signal r_CNT_50HZ : natural range 0 to c_CNT_50HZ; signal r_CNT_10HZ : natural range 0 to c_CNT_10HZ; signal r_CNT_1HZ : natural range 0 to c_CNT_1HZ; -- 翻转输出 signal r_TOGGLE_100HZ : std_logic := '0'; signal r_TOGGLE_50HZ : std_logic := '0'; signal r_TOGGLE_10HZ : std_logic := '0'; signal r_TOGGLE_1HZ : std_logic := '0'; -- 多路复用器选择 signal w_LED_SELECT : std_logic; begin -- 100Hz翻转进程 p_100_HZ : process (i_clock) is begin if rising_edge(i_clock) then if r_CNT_100HZ = c_CNT_100HZ-1 then r_TOGGLE_100HZ <= not r_TOGGLE_100HZ; r_CNT_100HZ <= 0; else r_CNT_100HZ <= r_CNT_100HZ + 1; end if; end if; end process p_100_HZ; -- 50Hz翻转进程 p_50_HZ : process (i_clock) is begin if rising_edge(i_clock) then if r_CNT_50HZ = c_CNT_50HZ-1 then r_TOGGLE_50HZ <= not r_TOGGLE_50HZ; r_CNT_50HZ <= 0; else r_CNT_50HZ <= r_CNT_50HZ + 1; end if; end if; end process p_50_HZ; -- 10Hz翻转进程 p_10_HZ : process (i_clock) is begin if rising_edge(i_clock) then if r_CNT_10HZ = c_CNT_10HZ-1 then r_TOGGLE_10HZ <= not r_TOGGLE_10HZ; r_CNT_10HZ <= 0; else r_CNT_10HZ <= r_CNT_10HZ + 1; end if; end if; end process p_10_HZ; -- 1Hz翻转进程 p_1_HZ : process (i_clock) is begin if rising_edge(i_clock) then if r_CNT_1HZ = c_CNT_1HZ-1 then r_TOGGLE_1HZ <= not r_TOGGLE_1HZ; r_CNT_1HZ <= 0; else r_CNT_1HZ <= r_CNT_1HZ + 1; end if; end if; end process p_1_HZ; -- 基于开关输入的多路复用器 w_LED_SELECT <= r_TOGGLE_100HZ when (i_switch_1 = '0' and i_switch_2 = '0') else r_TOGGLE_50HZ when (i_switch_1 = '0' and i_switch_2 = '1') else r_TOGGLE_10HZ when (i_switch_1 = '1' and i_switch_2 = '0') else r_TOGGLE_1HZ; -- 使能开关门控LED驱动 o_led_drive <= w_LED_SELECT and i_enable; end rtl; 

Verilog实现

下方为等效Verilog模块。设计理念相同——四独立always块各在特定频率翻转,开关驱动组合多路复用器。

 module tutorial_led_blink ( i_clock, i_enable, i_switch_1, i_switch_2, o_led_drive ); input i_clock; input i_enable; input i_switch_1; input i_switch_2; output o_led_drive; // 频率参数(半周期计数) parameter c_CNT_100HZ = 125000; parameter c_CNT_50HZ = 250000; parameter c_CNT_10HZ = 1250000; parameter c_CNT_1HZ = 12500000; // 计数器寄存器 reg [31:0] r_CNT_100HZ = 0; reg [31:0] r_CNT_50HZ = 0; reg [31:0] r_CNT_10HZ = 0; reg [31:0] r_CNT_1HZ = 0; // 翻转寄存器 reg r_TOGGLE_100HZ = 1'b0; reg r_TOGGLE_50HZ = 1'b0; reg r_TOGGLE_10HZ = 1'b0; reg r_TOGGLE_1HZ = 1'b0; // 多路复用器选择 reg r_LED_SELECT; wire w_LED_SELECT; // 100Hz翻转块 always @(posedge i_clock) begin if (r_CNT_100HZ == c_CNT_100HZ-1) begin r_TOGGLE_100HZ <= ~r_TOGGLE_100HZ; r_CNT_100HZ <= 0; end else r_CNT_100HZ <= r_CNT_100HZ + 1; end // 50Hz翻转块 always @(posedge i_clock) begin if (r_CNT_50HZ == c_CNT_50HZ-1) begin r_TOGGLE_50HZ <= ~r_TOGGLE_50HZ; r_CNT_50HZ <= 0; end else r_CNT_50HZ <= r_CNT_50HZ + 1; end // 10Hz翻转块 always @(posedge i_clock) begin if (r_CNT_10HZ == c_CNT_10HZ-1) begin r_TOGGLE_10HZ <= ~r_TOGGLE_10HZ; r_CNT_10HZ <= 0; end else r_CNT_10HZ <= r_CNT_10HZ + 1; end // 1Hz翻转块 always @(posedge i_clock) begin if (r_CNT_1HZ == c_CNT_1HZ-1) begin r_TOGGLE_1HZ <= ~r_TOGGLE_1HZ; r_CNT_1HZ <= 0; end else r_CNT_1HZ <= r_CNT_1HZ + 1; end // 组合多路复用器 always @(*) begin case ({i_switch_1, i_switch_2}) 2'b11: r_LED_SELECT <= r_TOGGLE_1HZ; 2'b10: r_LED_SELECT <= r_TOGGLE_10HZ; 2'b01: r_LED_SELECT <= r_TOGGLE_50HZ; 2'b00: r_LED_SELECT <= r_TOGGLE_100HZ; endcase end // 使能门控驱动LED assign o_led_drive = r_LED_SELECT & i_enable; endmodule 

仿真与验证

编程FPGA前,运行行为仿真(如ModelSim、VCS、Vivado Simulator)。验证各翻转信号符合预期周期,多路复用器按开关组合正确路由信号。早期仿真消除昂贵硬件调试,确认50%占空比维持。

结语

本教程演示如何构建紧凑可复用LED闪烁器,可适配其他定时任务。同一基于计数器的频率合成模式可扩展至更复杂状态机,是FPGA开发者基础技能。

VHDL

  1. 掌握预防性维护:优化PM计划的策略
  2. 升级润滑剂分析计划:释放资产可靠性巅峰潜能
  3. 预防性维护计划优化10大实证策略:从无效到高效的转型指南
  4. Ultiboard PCB设计全攻略:从工具栏到实战的完整教程
  5. KiCad PCB设计实战教程:掌握开源EDA全流程开发
  6. 高效预防性维护程序设计六步法:从人员授权到持续迭代
  7. FPGA 开发入门:在 Xilinx Artix-7 上构建 4 位加法器
  8. 嵌入式 FPGA (eFPGA) 技术:革新 ASIC 与 SoC 设计
  9. C# Hello World — 构建你的第一个C#应用程序
  10. C# Hello World:构建你的第一个控制台应用程序
  11. 你的第一个 VHDL 程序:分步 Hello World 教程
  12. Verilog 入门:数字电路设计完整教程