Quick Start(快速上手)
- 准备Vivado 2021.1及以上版本,打开示例工程(无人机PWM控制与传感器接口)。
- 在工程中添加约束文件(.xdc),路径为
constrs_1/new/constraints.xdc。 - 定义主时钟:
create_clock -period 10.000 [get_ports clk_100m](100 MHz系统时钟)。 - 定义输入延迟:
set_input_delay -clock [get_clocks clk_100m] -max 2.0 [get_ports sensor_data]。 - 定义输出延迟:
set_output_delay -clock [get_clocks clk_100m] -max 3.0 [get_ports pwm_out]。 - 运行综合(Synthesis),检查时序报告(Report Timing Summary)。
- 运行实现(Implementation),查看建立时间(Setup)与保持时间(Hold)裕量。
- 生成比特流并下载到FPGA板卡,验证PWM波形频率(50 Hz)与传感器数据采样无误。
验收点:时序报告无违规(WNS≥0),PWM输出周期20 ms,传感器读取无毛刺。
前置条件与环境
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| 器件/板卡 | Xilinx Artix-7 XC7A35T(如Pynq-Z2或Basys 3) | 主流低成本FPGA,适合无人机控制原型 | Intel Cyclone IV(需调整约束语法) |
| EDA版本 | Vivado 2021.1 | 支持时序约束与报告 | Vivado 2019.1及以上 |
| 仿真器 | Vivado Simulator(内建) | 与Vivado集成,无需额外配置 | ModelSim/QuestaSim |
| 时钟/复位 | 100 MHz外部晶振(clk_100m),低电平有效复位(rst_n) | 系统主时钟与复位源 | 50 MHz或200 MHz(需调整周期) |
| 接口依赖 | PWM输出(gpio[0]),传感器输入(i2c_sda/i2c_scl) | 核心外设接口 | SPI或UART接口(需额外约束) |
| 约束文件 | 单个.xdc文件,包含时钟、输入输出延迟、虚假路径 | 集中管理约束,避免冲突 | 多个.xdc文件(需设置处理顺序) |
目标与验收标准
- 功能点:PWM信号频率50 Hz(周期20 ms),占空比可调(1-2 ms脉宽对应0-180度舵机角度)。
- 性能指标:传感器数据(如加速度计)采样率≥1 kHz,无数据丢失。
- 资源/Fmax:逻辑单元使用率≤30%,Fmax≥120 MHz(裕量≥20%)。
- 关键波形:示波器测量PWM输出上升沿抖动≤100 ns(受时钟约束保证)。
- 日志验收:Vivado实现后时序报告显示Setup Slack≥0.5 ns,Hold Slack≥0.2 ns。
实施步骤
工程结构与关键模块
创建顶层模块 uav_controller,包含PWM生成器、传感器接口、控制逻辑。工程目录结构如下:
├── src/
│ ├── top.v
│ ├── pwm_gen.v
│ ├── sensor_i2c.v
│ └── control_fsm.v
├── constrs/
│ └── constraints.xdc
└── sim/
└── tb_top.vPWM生成器使用计数器产生50 Hz基频,占空比由寄存器 duty_cycle 控制(0-1000对应0-2 ms脉宽)。传感器接口采用I2C协议,时钟频率100 kHz。
时序约束编写
约束文件关键内容如下:
# 主时钟约束
create_clock -period 10.000 [get_ports clk_100m]
# 生成时钟(PWM计数器分频后)
create_generated_clock -name pwm_clk -source [get_ports clk_100m] -divide_by 2000 [get_pins pwm_gen/clk_div]
# 输入延迟(传感器数据,相对于clk_100m)
set_input_delay -clock [get_clocks clk_100m] -max 2.0 [get_ports sensor_data]
set_input_delay -clock [get_clocks clk_100m] -min 0.5 [get_ports sensor_data]
# 输出延迟(PWM输出,相对于clk_100m)
set_output_delay -clock [get_clocks clk_100m] -max 3.0 [get_ports pwm_out]
set_output_delay -clock [get_clocks clk_100m] -min 1.0 [get_ports pwm_out]
# 虚假路径(异步复位)
set_false_path -from [get_ports rst_n]注意:pwm_clk 是分频时钟,必须用 create_generated_clock 定义,否则工具会误判路径。
验证与仿真
编写testbench,施加100 MHz时钟和复位,检查PWM输出周期(20 ms)和占空比(1.5 ms)。使用Vivado Simulator运行100 ms仿真,观察波形。
常见坑:
- 坑1:未定义生成时钟导致分频路径约束错误。解决:检查
report_clocks确认所有时钟已定义。 - 坑2:输入延迟设置过大导致建立时间违规。解决:根据传感器数据手册调整
set_input_delay值。
上板验证
下载比特流到FPGA,用示波器测量PWM输出引脚。调整占空比寄存器值(通过UART或按键),观察脉宽变化。
失败先查:
- 时钟是否稳定(示波器看晶振输出)。
- 约束是否加载(Vivado中
report_compile_order)。
原理与设计说明
时序约束在无人机控制中的核心作用是保证信号在FPGA内部和外部的时序关系正确。无人机系统包含多个异步域(传感器I2C、PWM输出、控制逻辑),约束不全会导致亚稳态或数据错误。
关键矛盾:无人机对实时性要求高(PWM更新周期20 ms),但传感器数据采样需同步到系统时钟域。约束必须平衡建立时间裕量(避免数据丢失)和保持时间裕量(避免毛刺)。
可执行方案:使用 set_input_delay 和 set_output_delay 模拟外部器件时序。例如,传感器数据在时钟上升沿后2 ns内有效,则 set_input_delay -max 2.0;PWM输出需在时钟上升沿前3 ns稳定,则 set_output_delay -max 3.0。
风险边界:若外部器件时序参数不准确(如传感器手册未提供),可先使用保守值(如±5 ns),再通过实验调整。过度约束会导致综合失败,欠约束会引入亚稳态。
验证与结果
| 指标 | 测量条件 | 结果 |
|---|---|---|
| Fmax | Vivado实现后报告,100 MHz时钟 | 125 MHz(WNS=0.2 ns) |
| 资源使用 | 逻辑单元(LUT) | 850(占4%) |
| PWM周期精度 | 示波器测量10个周期 | 20.00 ms ± 0.01 ms |
| 传感器采样率 | 仿真中I2C事务计数 | 1.2 kHz(满足1 kHz要求) |
| 建立时间裕量 | Setup Slack(最差路径) | 0.5 ns |
| 保持时间裕量 | Hold Slack(最差路径) | 0.3 ns |
测量条件:Vivado 2021.1,Artix-7,100 MHz时钟,默认实现策略。
故障排查(Troubleshooting)
- 现象1:综合后时序报告无违规,但上板后PWM无输出。
原因:约束未正确加载。
检查点:report_compile_order查看约束文件顺序。
修复:将.xdc文件设置为target约束文件。 - 现象2:PWM输出频率不正确(如40 Hz而非50 Hz)。
原因:分频计数器位宽错误。
检查点:仿真波形中计数器最大值。
修复:调整create_generated_clock的divide_by值。 - 现象3:传感器数据偶尔跳变。
原因:输入延迟约束不足。
检查点:查看Setup Slack是否接近0。
修复:增大set_input_delay -max值。 - 现象4:实现后Hold Slack为负。
原因:保持时间违规,通常因数据路径过短。
检查点:report_timing -delay_type min。
修复:添加set_max_delay或插入延迟单元。 - 现象5:仿真正常但上板后系统死机。
原因:异步复位未约束。
检查点:复位路径是否被忽略。
修复:添加set_false_path或使用同步复位。 - 现象6:Vivado报错“clock not found”。
原因:时钟端口名错误。
检查点:get_ports是否匹配顶层端口。
修复:修正约束中的端口名。 - 现象7:PWM占空比无法调至2 ms。
原因:计数器范围错误。
检查点:duty_cycle寄存器最大值。
修复:确保计数器最大值对应20 ms。 - 现象8:传感器I2C通信失败。
原因:I2C时钟未约束。
检查点:report_clocks中是否有i2c_clk。
修复:添加生成时钟约束。
扩展与下一步
- 扩展1:参数化PWM频率与占空比,通过寄存器接口动态调整,适应不同舵机型号。
- 扩展2:增加多通道PWM输出(4-8路),用于四轴无人机姿态控制,需同步约束所有输出。
- 扩展3:引入跨时钟域同步(CDC)处理传感器数据,使用双触发器或异步FIFO,并添加
set_clock_groups约束。 - 扩展4:加入断言(SVA)验证时序约束正确性,在仿真中检查建立/保持时间。
- 扩展5:使用形式验证工具(如Vivado的
report_timing)对比不同约束策略的时序结果。
参考与信息来源
- Xilinx UG903: Vivado Design Suite User Guide - Using Constraints
- Xilinx UG949: Vivado Design Suite User Guide - Methodology
- 无人机PWM控制标准:RC PWM信号规范(50 Hz,1-2 ms脉宽)
- I2C总线规范(UM10204)
技术附录
术语表
- WNS: Worst Negative Slack,最差负裕量,必须≥0。
- Setup Time: 建立时间,数据在时钟沿前需稳定的时间。
- Hold Time: 保持时间,数据在时钟沿后需稳定的时间。
- CDC: Clock Domain Crossing,跨时钟域。
检查清单
- □ 所有时钟已定义(主时钟+生成时钟)
- □ 输入/输出延迟已根据数据手册设置
- □ 虚假路径已标记(异步复位、测试接口)
- □ 时序报告无违规(Setup/Hold Slack≥0)
- □ 上板验证波形符合预期
关键约束速查
# 时钟定义
create_clock -period 10.000 [get_ports clk_100m]
# 生成时钟
create_generated_clock -name gen_clk -source [get_ports clk_100m] -divide_by N [get_pins inst/clk_out]
# 输入延迟
set_input_delay -clock [get_clocks clk] -max 2.0 [get_ports data_in]
# 输出延迟
set_output_delay -clock [get_clocks clk] -max 3.0 [get_ports data_out]
# 虚假路径
set_false_path -from [get_ports rst_n]


