Quick Start(快速上手)
- 安装 Vivado 2019.2 或更高版本,并确认已添加 Xilinx 器件库(如 Artix-7)。
- 创建一个新的 Vivado 项目,选择器件 xc7a35tcsg324-1(或目标板卡对应型号)。
- 在项目中添加 Verilog 源文件,命名为
pwm_generator.v。 - 编写 PWM 模块代码,包含参数化占空比和频率的接口(详见实施步骤)。
- 编写一个简单的 testbench 文件,实例化 PWM 模块并施加时钟与复位激励。
- 运行行为仿真(Simulation),观察
pwm_out波形:应看到周期固定的方波,高电平宽度随占空比参数变化。 - 为模块添加顶层约束(时钟周期 10 ns,引脚分配至 LED 或 GPIO),综合并实现。
- 生成比特流并下载到 FPGA 板卡,用示波器或逻辑分析仪观察 PWM 输出,或观察 LED 亮度变化(若驱动 LED)。
前置条件与环境
| 项目 | 推荐值 | 说明/替代方案 |
|---|---|---|
| 器件/板卡 | Xilinx Artix-7 (xc7a35tcsg324-1) 或 Zynq-7000 系列 | Altera Cyclone IV / V;Lattice iCE40 |
| EDA 版本 | Vivado 2019.2 / 2020.1 | Quartus Prime 18.0+;Lattice Diamond |
| 仿真器 | Vivado Simulator (xsim) | ModelSim / Questa / Verilator |
| 时钟/复位 | 板载 100 MHz 时钟,低电平有效复位 | 50 MHz 晶振;高电平复位需修改逻辑 |
| 接口依赖 | 至少一个 GPIO 输出(如 LED) | PMOD 扩展口;示波器探头 |
| 约束文件 | XDC 约束:时钟周期 10 ns,引脚分配 | SDC 约束(Altera) |
目标与验收标准
完成本工程后,应达到以下可验证结果:
- 功能点:PWM 输出波形周期可配置(通过参数
PERIOD_CYCLES设置),占空比可通过输入端口duty_cycle动态调整(0~255 对应 0%~100%)。 - 性能指标:最大工作频率 ≥ 100 MHz(基于 Artix-7 速度等级 -1)。
- 资源占用:不超过 32 个 Slice、1 个 BRAM(可选)。
- 验收方式:行为仿真中
pwm_out波形占空比与duty_cycle输入一致;上板后 LED 亮度随duty_cycle变化,或示波器测量占空比误差 < 1%。
实施步骤
工程结构
建议采用以下目录结构:
pwm_project/
├── src/
│ └── pwm_generator.v
├── sim/
│ └── tb_pwm.v
├── constr/
│ └── top.xdc
└── vivado_project/ (Vivado 项目文件)关键模块:pwm_generator.v
核心代码片段如下,注意参数化设计:
module pwm_generator #(
parameter PERIOD_CYCLES = 1000, // 计数器周期(决定 PWM 频率)
parameter DUTY_WIDTH = 8 // 占空比输入位宽
)(
input wire clk,
input wire rst_n,
input wire [DUTY_WIDTH-1:0] duty_cycle, // 0 ~ 2^DUTY_WIDTH-1
output reg pwm_out
);
reg [31:0] counter;
reg [31:0] threshold;
// 计算阈值:threshold = (duty_cycle * PERIOD_CYCLES) / (2^DUTY_WIDTH)
always @(*) begin
threshold = (duty_cycle * PERIOD_CYCLES) >> DUTY_WIDTH;
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
counter <= 0;
pwm_out <= 0;
end else begin
if (counter >= PERIOD_CYCLES - 1)
counter <= 0;
else
counter <= counter + 1;
if (counter < threshold)
pwm_out <= 1;
else
pwm_out <= 0;
end
end
endmodule设计要点:
- 参数化设计:通过
PERIOD_CYCLES和DUTY_WIDTH两个参数,可灵活调整 PWM 频率与占空比分辨率。例如,PERIOD_CYCLES = 1000且时钟 100 MHz 时,PWM 频率为 100 kHz。 - 阈值计算:使用移位操作代替除法,节省资源并提升时序性能。注意
DUTY_WIDTH应保证移位不溢出。 - 计数器清零:当 counter 达到
PERIOD_CYCLES - 1时归零,确保周期准确。 - 输出逻辑:当 counter < threshold 时输出高电平,否则低电平,实现占空比控制。
仿真验证(tb_pwm.v)
编写 testbench 文件,实例化 PWM 模块,施加 100 MHz 时钟与复位,并依次设置 duty_cycle 为 64、128、192,观察输出波形。关键检查点:
- 复位后
pwm_out为低电平。 - 每个周期内高电平宽度与
duty_cycle比例一致(例如 duty_cycle=128 时占空比约 50%)。 - 改变
duty_cycle后,下一周期立即生效。
约束与综合
创建 top.xdc 约束文件,内容示例:
create_clock -period 10.000 [get_ports clk]
set_property PACKAGE_PIN W5 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property PACKAGE_PIN U16 [get_ports pwm_out] # 连接至 LED 或 GPIO
set_property IOSTANDARD LVCMOS33 [get_ports pwm_out]运行综合(Synthesis)与实现(Implementation),检查时序报告,确保建立时间满足要求(通常 slack > 0)。
验证结果
完成实现后,生成比特流并下载至 FPGA。验证方法:
- 仿真验证:运行行为仿真,截图保存波形,标注占空比与理论值对比。
- 上板验证:将
pwm_out连接至 LED,观察亮度随duty_cycle变化;或用示波器测量占空比,误差应 < 1%。
排障指南
- 仿真无输出:检查时钟与复位信号是否正常;确认
duty_cycle输入不为 0。 - 综合时序违规:降低
PERIOD_CYCLES或增加流水线级数;检查时钟约束是否正确。 - 上板后 LED 常亮或常灭:检查引脚分配与约束文件;用示波器测量实际波形。
- 占空比误差大:确认
DUTY_WIDTH与PERIOD_CYCLES匹配;避免阈值计算溢出。
扩展应用
- 多通道 PWM:例化多个模块,每个通道独立控制占空比,用于 RGB LED 或电机控制。
- 频率动态调整:将
PERIOD_CYCLES改为输入端口,实现运行时变频。 - 死区插入:在互补 PWM 输出中加入死区时间,适用于 H 桥驱动。
- 高精度 PWM:使用 Xilinx 原语(如 OSERDES)实现更高分辨率。
参考与附录
- Xilinx UG901:Vivado Design Suite 用户指南(综合与实现)
- Xilinx UG949:Vivado Design Suite 用户指南(约束与时序)
- Verilog IEEE 1364-2001 标准文档
- 附录 A:完整 testbench 代码示例(略)
- 附录 B:不同器件下的约束文件模板(略)



