我们队今年电赛选了FPGA控制题,用安路EG4S20做六路舵机PWM输出,ModelSim仿真波形完全正确,占空比也对。但上板后舵机一直轻微抖动,示波器看PWM边沿有毛刺。队友说是电源问题,换了稳压模块还是抖。想问下是不是时钟域没统一,还是寄存器打拍不够?国产FPGA的IO时序和Xilinx差别大吗?
2026年电赛FPGA控制题,用国产安路EG4S20做多路PWM舵机控制,为什么仿真没问题上板却抖舵?
3 个回答

仿真过、上板抖,这个组合在电赛里太常见了,先别急着怀疑安路和 Xilinx 的差异,多数时候是几个小坑叠在一起。
先按这个顺序查:第一,你的 PWM 占空比更新是不是从别的模块(比如串口/按键/状态机)跨时钟域过来的?如果比较值直接异步写进 PWM 计数比较器,中间会瞬间出现错误占空比,舵机就会抖。加两级同步寄存器,最好再配一个「更新使能」在计数器归零时才生效,波形会干净很多。第二,输出引脚是寄存器直出还是过 ODDR?直出的话边沿抖动和走线反射都容易冒毛刺,EG4S20 的 IO 建议用原语或至少让输出寄存器紧贴引脚。第三,也是最容易被忽略的:舵机电源和 FPGA 必须共地,且舵机那路电流别从 FPGA 的 3.3V 走,单独 5V/6V 供电、地线在一点汇合。第四,安路 IO 默认驱动能力和压摆率往往偏强,边沿太陡会串扰到相邻通道,试着把 slew rate 调低、驱动电流调小一档看看。
一个真实例子:有队伍六路 PWM 全抖,最后发现是六路输出挨着走线,压摆率拉满互相耦合,把驱动降到 4mA、加串阻就稳了。所以别只盯时钟域,IO 电气特性也是重点。你们现在几路是同时抖还是个别抖?这个信息能帮你快速二分定位。

我按一条主线说:仿真没问题上板抖,本质是「仿真只验证了逻辑,没验证时序和电气」。你要把这两层分开排。
逻辑层先看跨时钟域。很多队伍的 PWM 是这么写的:串口收到角度,算个比较值,直接赋给一个 reg,然后和计数器比。仿真里因为信号变化恰好落在时钟边沿附近被采到,看着对;上板后这个异步写可能落在计数器任意时刻,导致某个周期占空比突变,舵机就抖一下。正确做法是两级同步加一个「影子寄存器」,在计数器归零那拍才把新值搬进去,这样每个周期占空比都是完整的。
时序层看输出路径。EG4S20 这类国产器件的 IO 单元和 Xilinx 不完全一样,但思路相通:想让边沿干净,最好用 ODDR 原语,或者至少让最后一级寄存器离引脚近、约束里把输出延迟约束上。纯组合逻辑直出引脚,毛刺会被示波器如实拍下来。
电气层才是很多人栽的地方。舵机是感性负载、启动电流大,FPGA 的 3.3V 和舵机 5V 如果不共地,或者地线绕一大圈形成地弹,PWM 参考电平就飘。先拿示波器地弹簧就近测 FPGA 引脚和舵机电源地之间的压差,有跳动就说明是地的问题,换稳压模块没用,因为问题不在稳压。
安路 IO 的默认驱动和压摆率确实比一些人习惯的默认值激进,六路挨着走线容易互相耦合。可以先把驱动电流降一档、压摆率调慢,看毛刺是否减小,这是成本最低的验证。
学习路径上,建议你养成习惯:仿真验证功能,时序约束验证建立保持,板级测量验证电气,三者缺一不可。电赛时间紧,但花半小时把 IO 约束和同步做好,比换三次电源模块划算。你现在是六路全抖还是只有某几路抖?这直接决定是共性问题还是走线耦合问题。

先看你示波器上抓到的毛刺长什么样,这个信息比任何猜测都值钱。如果毛刺出现在PWM周期边界、也就是计数器归零那一刻,八成是你更新占空比的方式有问题;如果毛刺是均匀散布在每个翻转沿上的振铃,那基本是IO和负载的事,跟时钟域没多大关系。这两类现象排查方向完全不一样,别混着查。
说回更新方式。很多队写舵机PWM是串口收角度、算完比较值直接assign给比较寄存器,仿真里因为激励是理想阶跃,恰好被时钟采到看着没问题。上板后这个值可能在计数器走到任意位置时变化,那一周期的高电平宽度就是残缺的,舵机每转一点就抽一下。稳妥做法是加一个影子寄存器,只在计数器归零那拍把新比较值搬进去,配合两级同步把跨时钟域的值先锁稳。
IO这块补一句容易忽略的:EG4S20的IO默认压摆率通常比较猛,你要在约束或原语里把它调低、驱动电流也降一档,边沿变缓反而毛刺小。有条件就用ODDR把输出挂到专用时钟输出路径上,比纯组合直出干净得多,这点和Xilinx思路一致,只是原语名字和工具配置项不同,别照抄。
还有个偏门但常见的坑:六路舵机如果共用一路电源,某一路堵转时电流突变会把整条地线抬起来,FPGA的IO参考地跟着动,PWM阈值就飘。测的时候先只接一路舵机看还抖不抖,能快速排除。
你们现在六路是共用一组IO bank还是分散开的?这个会影响后面约束怎么写。
发表回答
登录后可在本页底部提交回答