SU200P 风扇与 LED 控制实验说明
配套工程:
led_dip_sw_fan工程环境:Vivado 2026.1 目标器件:xcsu200p-sbva1024-2-e
1. 实验目的
本实验使用 SU200P 开发板上的 FPGA 完成以下内容:
- 使用 PWM 控制 8 个板载 LED 同步实现呼吸效果;
- 使用 SW8 八位拨码开关分别控制 8 个 LED 是否参与呼吸显示;
- 使用 5 个普通按键统一关闭 LED 输出,使用复位按键 SW13 复位呼吸状态;
- 根据温度值计算风扇占空比,并输出约 25 kHz 的四线风扇 PWM;
- 通过仿真观察 LED PWM、输入控制、复位和不同温度下的风扇 PWM;
- 完成工程综合、实现、PDI 生成和板级下载验证。
2. 设计概况
设计基于纯 RTL 搭建,以 Top.v 为综合顶层,主要包含 LED 呼吸灯和风扇 PWM 两个功能模块。顶层同时接收 SW8 八位拨码开关、5 个普通按键和 SW13 复位按键,并完成 LED 输出控制。涉及的主要文件如下:
<samp>工程文件说明</samp>
| 文件 | 作用 |
|---|---|
led_dip_sw_fan.xpr | Vivado 工程入口 |
led_dip_sw_fan.srcs/sources_1/new/Top.v | 综合顶层,连接时钟、拨码开关、按键、LED 和风扇模块 |
led_dip_sw_fan.srcs/sources_1/new/pwm_led.v | LED 呼吸灯 PWM 模块 |
led_dip_sw_fan.srcs/sources_1/new/pwm_fan.v | 温度控制风扇 PWM 模块 |
led_dip_sw_fan.srcs/sim_1/new/tb_top.sv | 自检仿真测试文件 |
led_dip_sw_fan.srcs/constrs_1/new/IO.xdc | FPGA 管脚和电平标准约束 |
bit/Top.pdi | 发布用器件下载文件;本次修改后需重新生成并更新 |

<kbd>工程结构</kbd>
3. 设计原理
3.1 系统时钟与复位
板载时钟器件提供约 266.67 MHz 的 LVDS 差分时钟给FPGA芯片。顶层通过 IBUFDS 将该差分时钟转换为内部单端工作时钟,用于内容LED 和风扇驱动模块。
<samp>时钟与复位信号</samp>
| 信号 | FPGA 管脚 | 说明 |
|---|---|---|
sys_clk_p | V28 | 266.67 MHz 差分时钟正端 |
sys_clk_n | 与 V28 配对 | 差分时钟负端 |
rst_n | F23 | 复位按键SW13,低电平有效复位 |
rst_n 为复位信号,由复位按键SW13提供。按键低电平有效,当按键按下时,模块将会被复位,LED PWM 状态、风扇计数器和风扇占空比均清零;松开后两个模块重新开始工作。

<kbd>复位按键(低电平有效)</kbd>
3.2 LED 呼吸灯
pwm_led.v 使用 14 位计数器 cnt 产生 PWM 周期,使用 duty 表示当前高电平宽度,并通过 dir 控制亮度增加或减小。参数 PWM_PERIOD 为 16330。
PWM 频率约为:
<p align="center"><strong>f_LED_PWM = 266.67 MHz ÷ 16330 ≈ 16.33 kHz</strong></p>
每完成一个 PWM 周期,duty 改变 1。当亮度从 0 增加到 16330,再减小到 0 时形成一次完整呼吸:
<p align="center"><strong>T_breath = (2 × 16330 × 16330) ÷ (266.67 × 10⁶) ≈ 2.00 s</strong></p>
8 个 LED 共用同一个 PWM,因此同步渐亮和渐暗。LED 与 FPGA 的对应关系如下:
<samp>LED与FPGA关键对应关系</samp>
| verilog端口 | FPGA 管脚 | 板上器件 |
|---|---|---|
led[0] | B17 | LED1 |
led[1] | C18 | LED2 |
led[2] | B18 | LED3 |
led[3] | E17 | LED4 |
led[4] | D17 | LED5 |
led[5] | D16 | LED6 |
led[6] | C17 | LED7 |
led[7] | E16 | LED8 |
3.3 拨码开关控制
开发板上的 SW8 是一个八位拨码开关,原理图信号为 GPIO_DIP_SW_B0~B7。每一路输入均带有下拉电阻:拨码开关断开时,FPGA 读到低电平;拨到导通位置时,FPGA 读到高电平。

<kbd>8路拨码开关电路</kbd>
顶层使用下式生成 LED 输出:
assign led = (key) ? 8'h00 : ({8{pwm_out}} & ~gpio_sw);
当五个普通按键全部松开时,gpio_sw[i] 只控制同序号的 led[i]:拨码位为 0 时,对应 LED 跟随呼吸 PWM;拨码位为 1 时,对应 LED 被屏蔽并保持熄灭。因此,SW8 的每一位都可以独立选择一个 LED 是否参与同步呼吸。拨码开关只影响最终 LED 输出,不会暂停或清零 pwm_led 内部的计数和亮度状态。
<samp>拨码开关与LED对应关系</samp>
| Verilog 端口 | SW8 位号 | FPGA 管脚 | 对应 LED | LED 驱动管脚 |
|---|---|---|---|---|
gpio_sw[0] | 1 | AD27 | LED1 | B17 |
gpio_sw[1] | 2 | AC27 | LED2 | C18 |
gpio_sw[2] | 3 | AC28 | LED3 | B18 |
gpio_sw[3] | 4 | AD28 | LED4 | E17 |
gpio_sw[4] | 5 | AC30 | LED5 | D17 |
gpio_sw[5] | 6 | AD29 | LED6 | D16 |
gpio_sw[6] | 7 | AG8 | LED7 | C17 |
gpio_sw[7] | 8 | AH8 | LED8 | E16 |
3.4 按键控制
开发板上设计有SW6、SW7、SW9、SW11 和 SW12 五路用户按键,按键按下时为高电平,释放为低电平。

<kbd>用户按键电路</kbd>
工程使用这五个按键屏蔽LED输出,当任意一个按键被按下时,顶层会将8路 LED 输出置为 8'h00;只有五个按键全部松开后,LED 才会继续显示当前呼吸阶段。五个按键只用于屏蔽 LED 输出,不会清零 pwm_led 内部状态。
原理图中的 GPIO_SW_W、GPIO_SW_N、GPIO_SW_S、GPIO_SW_C 和 GPIO_SW_E 是硬件网络名称,不代表本实验将它们作为方向键使用。实验操作和现象说明统一按板上丝印 SW6、SW7、SW9、SW11 和 SW12 识别,五路信号均作为相互独立的普通按键处理。
<samp>用户按键</samp>
| Verilog端口 | 按键 | FPGA 管脚 |
|---|---|---|
key[0] | SW9 | G24 |
key[1] | SW7 | J23 |
key[2] | SW11 | F24 |
key[3] | SW12 | F25 |
key[4] | SW6 | E24 |
普通按键的控制优先级高于拨码开关。只要 SW6、SW7、SW9、SW11 或 SW12 中任意一个按下,8 个 LED 都会立即熄灭;全部松开后,各 LED 再按照 SW8 当前状态恢复显示。
3.5 风扇 PWM
设计通过 pwm_fan.v 产生约 25 kHz PWM用于驱动风扇。由于顶层传入的时钟频率 CLK_FREQ 为 266670000,模块预设的PWM频率 PWM_FREQ 为 25000,因此整数计数周期为:
<p align="center"><strong>PWM_PERIOD = CLK_FREQ ÷ PWM_FREQ = 266670000 ÷ 25000 = 10666</strong></p>
实际 PWM 频率约为:
<p align="center"><strong>f_FAN_PWM = CLK_FREQ ÷ PWM_PERIOD = 266670000 ÷ 10666 ≈ 25.002 kHz</strong></p>
PWM用于驱动风扇为主控散热,因此PWM的占空比被设置为与温度相关。温度与 duty_cycle 的对应关系如下:
<samp>温度与PWM占空比</samp>
| 温度输入 | duty_cycle | 说明 |
|---|---|---|
| 小于 40 | 0 | 停转区间 |
| 40~80 | (temp_input-40)×6 | 线性调速区间 |
| 大于 80 | 255 | 接近全速区间 |
设计顶层将温度设定为了固定值 temp_input=80,因此:
<p align="center"><strong>duty_cycle = (80 − 40) × 6 = 240</strong></p>
PWM 比较阈值采用 (duty_cycle × PWM_PERIOD) >> 8,等效除以 256。当前温度 80 ℃对应 9999 个高电平计数,高电平比例约为 93.75%。duty_cycle=255 时高电平比例约为 99.6%,并非严格的持续高电平。
4. 仿真验证
4.1 运行仿真
- 启动 Vivado 2026.1;
- 打开
led_dip_sw_fan.xpr; - 确认 Design Sources 顶层为
Top,Simulation Sources 顶层为tb_top; - 选择 Run Simulation → Run Behavioral Simulation;
- 等待测试运行到
$finish; - 查看 Tcl Console、
simulate.log和波形窗口。
4.2 测试内容
tb_top.sv 采用自动判定方式,覆盖以下内容:
- 低有效异步复位能否清零 LED 和风扇状态;
- 两次完整的 LED 亮度扫描;
- 亮度 0、1、8165、16329 和 16330 下的完整 PWM 帧;
- SW8 全为 0、全为 1,以及八种单独一位置 1 时的 LED 输出;
- 5 位按键信号的全部 32 种组合;
- SW6、SW7、SW9、SW11 和 SW12 分别按下和松开时,呼吸状态是否连续;
- 温度 30、50、70 和 90 下的风扇占空比及 PWM 高电平计数。
测试平台通过层次化访问加速 LED 亮度扫描,并通过 force 临时替换顶层固定的温度值。因此仿真中的四个温度只用于验证 pwm_fan 映射,综合后的板级设计仍固定为温度 80℃。
4.3 仿真波形分析
4.3.1 总体波形

<kbd>LED与风扇总体仿真波形</kbd>
总体波形按测试平台的执行顺序展示了两轮加速亮度扫描、典型亮度 PWM 帧、中途复位、输入控制和四个温度点的风扇 PWM 验证。拨码开关的 10 种状态持续时间很短,在本图的约 700 μs 时间尺度下集中在复位之后,具体对应关系见下一幅局部波形。
LED 波形中的 duty 会依次出现 0、1、8165、16329 和 16330 等数值。这些跳变由测试平台主动设置,用于缩短仿真时间并检查最低亮度、中间亮度、接近最大亮度和最大亮度等边界情况,并非计数器工作异常。完成这些定点检查后,duty 出现 8165、8166、8167 的连续变化,则是呼吸灯模块恢复运行后的正常自增过程。
4.3.2 拨码开关控制波形

<kbd>SW8 拨码开关控制 LED 的局部仿真波形</kbd>
红框内 key 保持为 00,pwm_out 轨迹保持高电平,因此可以直接观察拨码开关对 LED 输出的屏蔽作用。gpio_sw 依次取 00、FF、01、02、04、08、10、20、40 和 80,对应的 led 依次为 FF、00、FE、FD、FB、F7、EF、DF、BF 和 7F。结果表明,某一拨码位为 1 时,同序号 LED 输出变为 0;其余位仍保持高电平。
10 种状态检查完成后,gpio_sw=01 时将 key 置为 01,led 立即由 FE 变为 00;key 恢复为 00 后,led 回到 FE,说明普通按键的全局关闭优先级高于拨码开关。随后在 pwm_out=0 时施加 gpio_sw=80,led 仍为 00,也符合呼吸 PWM 低电平阶段的预期结果。
4.3.3 按键控制波形

<kbd>普通按键门控LED的局部仿真波形</kbd>
按键波形中,key=5'b00000 表示五个普通按键均处于松开状态,LED 按当前 PWM 相位在 8'hFF 和 8'h00 之间切换。当 SW9、SW7、SW11、SW12 或 SW6 中任意一个按下时,key 分别出现 01、02、04、08 或 10,顶层立即将 led 置为 8'h00。按键松开、key 回到 00 后,LED 继续显示当前呼吸状态。
波形左侧较密集的绿色区域对应 5 位按键信号全部 32 种组合的快速遍历;右侧则将五个按键逐个按下和松开,便于核对每一路按键的控制结果。按键仅屏蔽 LED 输出,不会复位或暂停 pwm_led 内部的亮度变化。
4.3.4 风扇温度与 PWM
总体波形下半部分依次给出 30 ℃、50 ℃、70 ℃和 90 ℃四个温度点。随着 temp_input 升高,duty_cycle 依次变为 0、60、180 和 255,fan 的高电平持续时间随之增加。由于总体图的时间跨度较大,脉宽差异主要用于定性观察,准确的高电平计数以自检结果和下表为准。
<samp>风扇温度点与PWM仿真结果</samp>
| 温度 | 期望 duty_cycle | 高电平计数/周期 | 约占空比 |
|---|---|---|---|
| 30 | 0 | 0/10666 | 0% |
| 50 | 60 | 2499/10666 | 23.4% |
| 70 | 180 | 7499/10666 | 70.3% |
| 90 | 255 | 10624/10666 | 99.6% |
波形中可重点观察 temp_input、duty_cycle、pwm_counter 和 fan。温度改变后的下一个时钟沿,duty_cycle 更新;随后一个完整风扇 PWM 周期中的高电平宽度随之改变。
LED 仿真采用加速方法,波形总时长不能直接作为实物呼吸周期;实物完整呼吸周期仍约为 2 s。
4.4 仿真结果判定
除了仿真波形,设计还会通过TCL打印仿真结果:
PASS two accelerated sweeps: 0 -> 16330 -> 0; no overflow/underflow
PASS PWM frame: level=0 high_cycles=0 period=16330
PASS PWM frame: level=1 high_cycles=1 period=16330
PASS PWM frame: level=8165 high_cycles=8165 period=16330
PASS PWM frame: level=16329 high_cycles=16329 period=16330
PASS PWM frame: level=16330 high_cycles=16330 period=16330
PASS mid-run asynchronous reset
Breathing period: 533337800 clocks / 266670000 Hz = 1.999991750 seconds
PASS DIP switch: all-zero, all-one and 8 one-hot patterns; key override passed
PASS breathing continues while DIP switch masks LED outputs
PASS LED gate: all 32 key combinations at both PWM levels
PASS all 5 individual press/release sequences; breathing continues while blanked
PASS fan PWM: temp=30 duty=0/255 high_cycles=0 period=10666
PASS fan PWM: temp=50 duty=60/255 high_cycles=2499 period=10666
PASS fan PWM: temp=70 duty=180/255 high_cycles=7499 period=10666
PASS fan PWM: temp=90 duty=255/255 high_cycles=10624 period=10666
ALL LED, DIP SWITCH AND FAN CHECKS PASSED
结果表明 LED PWM、SW8 拨码控制、普通按键优先级、复位和风扇 PWM 均通过行为级仿真。拨码部分检查全 0、全 1 以及八种单独一位置 1,共 10 种状态;同时确认拨码开关只屏蔽 LED 输出,不会暂停内部呼吸计数。
5. 板级验证
5.1 硬件准备与连接
烧录验证之前,需要准备 SU200P 开发板、配套电源、JTAG 下载器和兼容的四线 12 V 风扇。所有接线和跳帽调整均应在断电状态下完成。
- 确认 SW8 的 8 位拨码开关均处于断开位置;
- 将四线风扇连接到 J42;
- 将 J41 的 2–3 脚短接,选择由 FPGA 驱动风扇 PWM;
- 连接 JTAG 下载器;
- 连接开发板电源并上电。

<kbd> 硬件连接图</kbd>
5.2 下载步骤
- 进入 Open Hardware Manager;
- 选择 Open Target → Auto Connect;
- 确认识别到
xcsu200p; - 右键器件,选择 Program Device;
- 选择对应的
Top.pdi; - 单击 Program。
JTAG 下载为易失性配置,开发板断电后需要重新下载。
5.3 预期现象与实测结果
下载配套 PDI 并释放复位后,可以依次观察 LED 呼吸、拨码开关、普通按键、复位和风扇输出。下面结合实测照片说明主要现象。
5.3.1 LED 呼吸效果

<kbd>LED呼吸过程中的较低亮度状态</kbd>

<kbd>LED呼吸过程中的较高亮度状态</kbd>
当 SW8 的 8 位拨码开关均处于断开状态,且没有按下普通按键时,LED1~LED8 同步参与呼吸显示。两张照片分别记录了呼吸过程中的不同亮度瞬间,可以看到 8 个 LED 的亮度同步变化。实际观察时,LED 会由暗逐渐变亮,再由亮逐渐变暗,完整呼吸周期约为 2 s。
照片只能记录某一时刻的亮度,判断呼吸功能时应连续观察一个或多个完整周期,确认亮度变化平滑且各 LED 保持同步。
5.3.2 拨码开关控制

<kbd>拨码开关屏蔽单路LED</kbd>
SW8 的每一位分别控制一路 LED 是否输出。图中拨动其中一位后,对应 LED 熄灭,其余 LED 仍保持相同的呼吸节奏。将该位拨回断开状态后,对应 LED 会恢复到当前呼吸亮度,而不是从最低亮度重新开始,这说明拨码开关只屏蔽最终输出,没有停止 pwm_led 内部的亮度计数。
依次拨动 SW8 的第 1~8 位时,应分别影响对应的 LED1~LED8;SW8 全部导通时 8 个 LED 全部熄灭,全部断开时 8 个 LED 均参与呼吸。
5.3.3 普通按键控制

<kbd>普通按键关闭全部LED</kbd>
按下 SW6、SW7、SW9、SW11 或 SW12 中的任意一个普通按键时,顶层门控逻辑关闭全部 LED 输出,因此图中 8 个 LED 同时熄灭。松开按键后,各 LED 按照 SW8 当前状态继续显示;未被拨码开关屏蔽的 LED 恢复当前呼吸亮度。
该现象也验证了普通按键具有高于拨码开关的关闭优先级:只要任意普通按键处于按下状态,无论 SW8 如何设置,LED 输出均保持关闭。
5.3.4 复位与风扇
按下 SW13 时,LED 输出熄灭,LED 呼吸状态和风扇 PWM 状态同时复位;松开后,LED 从最低亮度重新开始呼吸,风扇重新输出 PWM。
当前顶层将温度值固定为 80,风扇占空比约为 93.75%,因此连接 J42 并将 J41 的 2~3 脚短接后,风扇应以较高转速运行。
综合上述现象,LED 呼吸、SW8 分路控制、普通按键统一关闭、SW13 复位和风扇 PWM 功能均与设计预期一致。
6. 总结与扩展
本实验实现了 8 路同步呼吸灯和约 25 kHz 风扇 PWM。SW8 八位拨码开关可分别屏蔽对应 LED,SW6、SW7、SW9、SW11 和 SW12 用于临时熄灭全部 LED,SW13 同时复位 LED 与风扇模块。三类输入各司其职,并由顶层逻辑确定清晰的控制优先级。
自检测试验证了亮度扫描、代表性 LED PWM 帧、SW8 的 10 种状态、普通按键组合、复位以及温度 30、50、70 和 90 下的风扇 PWM。板级验证仍需使用本次修改后重新生成的 PDI。
当前板级设计将温度固定为 80,因此风扇输出约 93.75% 占空比。后续可接入真实温度传感器,修正 40~80 ℃到 0~100% 的映射,并利用风扇测速信号实现闭环转速控制。

