Quick Start 快速上手指南
本指南将引导您从零开始,在 FPGA 上实现一个频率固定、占空比可调的 PWM 信号发生器。整个流程约需 30 分钟(含工具安装时间)。
- 安装 Vivado 或 Quartus Prime 标准版(本文以 Vivado 2023.1 为例)。
- 新建 RTL 工程,选择目标器件(如 XC7A35T-1CSG324C)。
- 编写顶层模块,例化一个计数器与比较器,输出 PWM 信号。
- 添加约束文件(.xdc),将输出引脚连接到 LED 或示波器探头。
- 运行综合(Synthesis)与实现(Implementation)。
- 生成比特流(Bitstream)并下载到 FPGA 板卡。
- 观察 LED 亮度变化或示波器波形,验证占空比可调。
- 通过拨码开关或 UART 输入修改占空比参数,观察实时响应。
前置条件与环境
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| 器件 / 板卡 | Xilinx Artix-7 (XC7A35T) 或 Altera Cyclone IV | 主流入门级 FPGA,资源充足 | 其他 7 系列 / MAX10 均可 |
| EDA 版本 | Vivado 2023.1 或 Quartus Prime 20.1 | 较新版本提供更好的综合优化 | Vivado 2018.3+ / Quartus 17.1+ |
| 仿真器 | Vivado Simulator 或 ModelSim | 支持波形调试与覆盖率分析 | Verilator, Icarus Verilog |
| 时钟 / 复位 | 50 MHz 板载时钟,低有效异步复位 | 常用配置,时序易满足 | 100 MHz / 高有效复位(需调整逻辑) |
| 接口依赖 | JTAG 下载器(如 Digilent HS2) | 用于比特流下载与在线调试 | USB-Blaster / on-board JTAG |
| 约束文件 | 至少包含时钟周期约束与输出引脚分配 | 确保时序收敛与正确映射 | 可使用 Tcl 脚本自动生成 |
| 调试工具 | 逻辑分析仪(ILA / SignalTap)或示波器 | 验证波形质量与占空比精度 | 板载 LED 做视觉验证 |
目标与验收标准
- 功能点:生成频率 1 kHz、占空比 0%–100% 可调的 PWM 信号。
- 性能指标:占空比调节步进 ≤ 1%(分辨率 100 级),输出频率误差 < 5%。
- 资源占用:LUT ≤ 32,FF ≤ 32,无需 DSP slice。
- 验收方式:示波器测量 PWM 周期与高电平时间,与设定值偏差 < 5%。
- 波形特征:上升/下降沿单调,无毛刺(占空比切换时无异常脉冲)。
实施步骤
工程结构
- 顶层模块:
pwm_top.v– 例化计数器、比较器、输入接口。 - 计数器模块:
pwm_counter.v– 实现周期计数器(0 到 PERIOD-1)。 - 占空比输入:
duty_cycle.v– 从外部接口(拨码开关或 UART)读取并同步。 - 输出寄存器:
pwm_out_reg– 在时钟上升沿输出比较结果。
关键模块实现
// pwm_counter.v
module pwm_counter #(
parameter PERIOD = 50000 // 50 MHz / 1 kHz = 50000
)(
input wire clk,
input wire rst_n,
output reg [15:0] cnt
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
cnt <= 16'd0;
else if (cnt == PERIOD - 1)
cnt <= 16'd0;
else
cnt <= cnt + 1'b1;
end
endmodule// pwm_top.v
module pwm_top #(
parameter PERIOD = 50000,
parameter DUTY_WIDTH = 7 // 0-100 级占空比
)(
input wire clk,
input wire rst_n,
input wire [DUTY_WIDTH-1:0] duty_set, // 外部占空比设定值
output reg pwm_out
);
wire [15:0] cnt;
reg [15:0] threshold;
// 例化计数器
pwm_counter #(.PERIOD(PERIOD)) u_counter (
.clk(clk),
.rst_n(rst_n),
.cnt(cnt)
);
// 将 duty_set 映射到阈值(0 ~ PERIOD-1)
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
threshold <= 16'd0;
else
threshold <= (duty_set * (PERIOD - 1)) / 100;
end
// 比较输出
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
pwm_out <= 1'b0;
else
pwm_out <= (cnt < threshold) ? 1'b1 : 1'b0;
end
endmodule约束文件示例(pwm_top.xdc)
# 时钟约束
create_clock -period 20.000 -name sys_clk [get_ports clk]
# 输出引脚分配
set_property PACKAGE_PIN R2 [get_ports pwm_out]
set_property IOSTANDARD LVCMOS33 [get_ports pwm_out]
# 输入引脚(拨码开关示例)
set_property PACKAGE_PIN T1 [get_ports duty_set[0]]
set_property IOSTANDARD LVCMOS33 [get_ports duty_set[0]]综合与实现
在 Vivado 中依次点击 Run Synthesis → Run Implementation。若出现时序违例,检查时钟约束是否正确,或降低时钟频率。综合完成后,查看资源报告确认 LUT/FF 占用符合预期。
生成比特流与下载
点击 Generate Bitstream,完成后使用 Open Hardware Manager 连接 FPGA 板卡,选择比特流文件并下载。
验证结果
下载成功后,用示波器测量 PWM 输出引脚:
- 频率应为 1 kHz ± 5%(即周期 1 ms ± 50 µs)。
- 改变
duty_set值(例如从 0 到 100),高电平时间应线性变化。 - 在占空比切换瞬间,波形不应出现毛刺或异常脉冲。
若使用 LED 验证,占空比从 0% 逐渐增大时,LED 亮度应平滑变亮。
排障指南
- 问题:输出无信号 – 检查时钟是否正常、复位是否释放、约束文件中的引脚分配是否正确。
- 问题:频率偏差大 – 确认 PERIOD 参数计算正确(PERIOD = 时钟频率 / 目标频率)。
- 问题:占空比调节不连续 – 检查
duty_set输入是否同步到时钟域,避免亚稳态。 - 问题:综合后资源超限 – 优化计数器位宽,或使用更小的 PERIOD 值。
扩展与进阶
- 多通道 PWM:例化多个比较器,每个通道独立占空比,共享同一计数器。
- 动态频率切换:将 PERIOD 设为可编程寄存器,实现变频 PWM。
- 死区插入:在互补 PWM 输出中插入死区时间,防止桥臂直通。
- 与微处理器集成:通过 AXI-Lite 接口将 PWM 寄存器映射到 CPU 地址空间,实现软件控制。
参考与附录
- Vivado Design Suite User Guide: Synthesis (UG901)
- Xilinx 7 Series FPGA Libraries Guide (UG953)
- Altera Quartus Prime Handbook Volume 1: Design and Synthesis
- 附录 A:完整工程源码(含仿真 Testbench)可在成电国芯 FPGA 云课堂资源库下载。
通过本指南,您已掌握 FPGA 上 PWM 信号生成的核心原理与实现方法。后续可根据实际需求灵活扩展功能。




