尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
FPGA定点量化实战:取整、饱和与抖动的Verilog实现
量化这个词在FPGA开发里几乎无处不在。做图像处理要量化像素做高速ADC采样要量化波形做FFT频谱分析要量化中间结果做通信接收机要量化基带信号。可真正能把量化做明白的人不多。我见过不少同事在定点化时直接用截断truncation完事结果输出波形上多了一个固定偏置或者图像亮度整体偏了折腾半天才意识到是舍入方式的问题也见过有人忽略了溢出输出从最大值一下子跳变到最小值在FFT频谱上炸出一片谐波。这种问题调试起来极费时间而且很难一眼看出来。这篇内容就针对FPGA定点量化中最核心的三个动作展开取整Rounding、抖动Dither、饱和Saturation。我会结合自己在FPGA开发中的实际经历把原理、Verilog实现、参数选择逻辑和排查经验一并讲清楚。适合正在做图像处理、信号采集、数字信号处理相关FPGA项目的人读也适合刚入门FPGA、搞不清定点数到底怎么处理的同学参考。1. 量化问题的本质定点数转换并不是“丢掉几位”那么简单1.1 量化误差从哪来任何连续信号或者高精度数值一旦要装进有限位宽的寄存器里就必然产生量化。FPGA里的数据从ADC采样进来那一刻起就是有限精度的经过乘法器、CORDIC、FFT运算后位宽会迅速膨胀必须在某个节点把多余的位去掉否则资源爆炸、时序收敛不了。量化步长由最低有效位LSB决定。假设定点数格式为Qm.n即m位整数位、n位小数位那么量化步长 Δ 2^(−n)量化误差e Q(x) − x它的范围取决于取整方式。如果直接截断误差范围是 [−Δ, 0]均值是 −Δ/2。这个负的均值就是直流偏置的来源。而如果采用四舍五入round-half-up误差范围是 [−Δ/2, Δ/2]均值为0但前提是输入分布恰好均匀如果信号有直流分量或者输入概率分布不对称误差的统计特性会变复杂。理解量化误差不只是为了算比特数。误差的均值决定了系统有没有直流偏置误差的方差决定了量化噪声功率误差与输入信号的相关性决定了输出谱上会不会出现杂散。这些指标直接决定了你选舍入方式、加不加抖动、饱和范围怎么设。1.2 FPGA处理链路中量化发生的位置看几个典型场景。第一个是图像处理链路。CMOS或红外探测器输出的RAW数据通常12bit做去噪、畸变校正、边缘检测时卷积核累加结果会超出16bit又要在输出端转回8bit或12bit。如果直接截断低位图像会出现整体偏亮或偏暗的偏移边缘检测的梯度值也会因为偏置而产生误检。这就是网上常有人问“fpga边缘检测特征提取”结果总是有固定条纹的原因之一。第二个是高速ADC采样与FFT频谱分析。ADC采样后的12bit数据经过抽取滤波、加窗、FFT后中间数据的位宽可能膨胀到24bit甚至32bit但输出显示只需要16bit甚至8bit。FFT蝶形运算中的截断会直接产生噪声底抬升如果乘法器输出不做饱和处理溢出回绕会在频谱上制造大量镜像谐波整个频谱看起来像“长了毛刺”。第三个是通信物理层。基带I/Q信号经过数字下变频、匹配滤波、AGC后定点化时必须考虑信号本身的动态范围和瞬时峰值。通信系统里SFDR无杂散动态范围和EVM误差向量幅度是硬指标舍入方式、抖动注入的选择直接影响这些指标能不能达标。在这些场景里量化不是“选个位数”就完事而是要在精度、资源、时序、噪声性能之间做权衡。下面按取整、饱和、抖动三个动作分别展开。2. 取整Rounding从截断到收敛舍入的实现细节2.1 截断Truncation为何不推荐截断是FPGA里最廉价的“取整”——直接把低位切掉一个连线都不用加零资源、零延迟。但从信号处理角度它有三个问题。第一误差均值不为零。截断相当于向下取整误差都在 [−Δ, 0] 区间内波动时间平均后会产生 −Δ/2 的固定偏置。如果信号是一个围绕0振荡的正弦波截断后波形会整体下移半个LSB在频谱上表现为直流分量增大。第二小信号时误差占比大。LSB是固定值信号幅度越小量化噪声相对于信号就越大。一个幅度只有2个LSB的正弦波被截断后有效位可能只剩1bit失真非常严重。第三在某些算法中表现为极限环振荡。比如IIR滤波器中的截断会在输出为零附近产生周期性小幅度振荡这种振荡不是输入信号引起的而是舍入误差与反馈结构共同导致的。数字控制里的死区效应很多也是截断导致的。如果项目对信噪比要求不高截断省资源确实香但只要涉及频谱质量、图像均匀性、控制环路稳定性的需求就得考虑更合适的舍入方式。2.2 四舍五入Round Half Up的实现和边界最常见的改进方案是加0.5LSB再截断。假设要从N位小数舍入到M位小数MN保留部分的位宽为P M 整数位宽舍去位数为K N − M那么经典写法是wire signed [DW-1:0] data_in; wire signed [PW-1:0] data_out; // K DW - PW, 这是要丢弃的位数 wire signed [DW-1:0] tmp data_in (1 (K-1)); assign data_out tmp[DW-1:K];这里的思路是先去判断丢弃部分最高位即待舍弃部分的第一位是否为1。如果为1说明小数部分大于等于半个LSB进位后截断就等于四舍五入如果为0直接截断。这个操作对正数是没问题的但补码负数要特别小心。举个例子4bit有符号数原来值 −5二进制补码是1011。如果舍入到只剩2bit整数去掉2bit小数加1即0.5LSB的进位后变成1100再截断高2位得到11即−1。但−5舍入到离它最近的2bit格点应该是−1−4与−8之间更接近−4不对−5与−4距离1与−8距离3所以应该到−4即二进制1100的整数部分100就是−4。这里其实有意思的是加上0.5LSB再截断对负数的舍入结果会产生偏差因为补码负数在截断时符号位不变但数值方向与整数部分截断不符。工程上更稳妥的做法是分正负处理正数加半LSB后截断负数先取绝对值加半LSB截断再恢复符号。代价是多几个比较器和MUX但结果语义清晰不容易引入隐性偏置。2.3 收敛舍入Round Half Even与Verilog实现四舍五入的误差均值在输入均匀分布时为0但它有个特点恰好处于半LSB上的值总是被舍入到远离零的方向正数变大负数变小如果信号存在大量恰好半LSB的采样点会在统计上产生微弱偏置。要彻底规避就得用收敛舍入也叫银行家舍入、Round Half Even。规则很简单如果丢弃部分恰好等于一半LSB则向偶数方向舍入否则按就近舍入。这样平均下来半LSB上的舍入有一半向上、一半向下统计偏置趋近于零。对音频、高精度测量、需要在长积分后保持零偏置的控制环路来说这是最稳的选择。Verilog实现也很直白module round_half_even #( parameter DW 16, // 输入数据位宽 parameter PW 8 // 输出数据位宽 )( input wire signed [DW-1:0] din, output reg signed [PW-1:0] dout ); localparam K DW - PW; // 丢弃位数 wire discard_gt_half |(din[K-1:0] ~(1 (K-1))); // 丢弃部分除最高位外是否有1 wire discard_is_half (din[K-1:0] (1 (K-1))); // 丢弃部分恰好是0.5LSB wire keep_lsb din[K]; // 保留部分最低位 always (*) begin if (discard_is_half) begin if (keep_lsb) dout din[DW-1:K] 1b1; // 保留位是奇数进位变偶数 else dout din[DW-1:K]; // 保留位是偶数直接舍 end else if (discard_gt_half) dout din[DW-1:K] 1b1; else dout din[DW-1:K]; end endmodule这段代码里要注意两点。第一discard_gt_half的判断逻辑是丢弃部分除了最高位半LSB位之外还有任意一个1说明丢弃部分大于0.5LSB。第二discard_is_half判断是否恰好为半LSB此时看保留部分的LSB是奇数还是偶数决定进位还是舍去。这个模块可以在组合逻辑里直接用也可以插入寄存器做流水处理取决于时序需要。通过实际使用经验和统计数据来看收敛舍入的资源开销大概比直接截断多几十个LUT比加半LSB的四舍五入多十几个LUT但换来的统计偏置改善在许多应用里很值。尤其是做DC blocker、积分器、相位累加器的同学建议优先用这种方案。2.4 关于LSB对齐与有效位数的实用建议实现舍入时要反复确认小数点对齐。定点数格式不统一是FPGA开发中一大痛点。我的习惯是在RTL代码里用localparam显式定义每个信号的整数位宽和小数位宽例如localparam DIN_W 16; localparam DIN_F 14; // 14bit小数 localparam DOUT_W 12; localparam DOUT_F 10; // 10bit小数这样做的好处是模块间数据位宽变化时通过参数化可以自动适配减少复制粘贴导致的错误。舍入前先确认输入与输出的Q格式是否匹配输出整数位是否够容纳进位溢出——如果舍入后数值超出了输出整数位宽必须先饱和否则溢出依然会发生。3. 饱和Saturation溢出回绕是调试现场最常见的“灵异事件”3.1 回绕Wrap-around会带来什么后果不用饱和处理时定点数加法、乘法在溢出后会按补码回绕。一个8bit有符号数127 1 的结果不是128而是−128。从波形上看就是一个正在上升的信号突然跌到最低点继续上升。这类现象在图像上表现为“白色区域出现黑色噪点”在频谱上表现为“宽带杂散抬高”在控制环路上表现为“输出抖动甚至发散”。回绕最阴险的地方在于它往往不是持续不变的。只有信号幅度超过满量程的那几个采样点会出现跳变其他时间看起来正常导致排查时很难复现。我之前做FPGA网卡测速相关项目时统计模块里的计数器溢出回绕导致速率显示异常查了很久才定位——不是逻辑错了是饱和没加。3.2 有符号数饱和的对称性设计有符号数饱和一般把输出限制在最大正数和最大负数之间。以8bit为例正饱和值为 8sd127负饱和值为 8sd−128。这样看起来对称但注意负饱和值比正饱和值多1个LSB对于一个满幅正弦信号正半周会被削到127负半周削到−128统计均值会略微偏负。如果要求信号无直流偏置可以设置成正负饱和范围对称即负饱和取 −8sd127然后把超出范围的值都限制到边界。对称饱和在图像和通信应用里更合理但实现时要额外对−128这种极端值做判断。下面这段代码实现的就是对称饱和的通用模块module saturate #( parameter DW 16, // 输入位宽 parameter PW 12 // 输出位宽 )( input wire signed [DW-1:0] din, output reg signed [PW-1:0] dout ); localparam signed [PW-1:0] MAX_POS (1 (PW-1)) - 1; localparam signed [PW-1:0] MAX_NEG -(1 (PW-1)) 1; // 对称饱和 always (*) begin if (din MAX_POS) dout MAX_POS; else if (din MAX_NEG) dout MAX_NEG; else dout din[PW-1:0]; end endmodule这段代码里比较器用的是有符号比较FPGA工具链会映射成对应的DSP或LUT逻辑。资源消耗不大但要注意比较器的输入与输出位宽不同需要保证比较时数值语义一致建议把中间值扩展为输入位宽再与输入位宽版本的饱和度边界比较避免位宽截断后比较符号出错。3.3 先饱和还是先舍入顺序不同结果不同量化链路里饱和和舍入的先后顺序是有讲究的。如果先舍入再饱和那么舍入的进位在接近满量程时可能溢出必须依赖后面的饱和来兜底如果先饱和再舍入那么在边界附近的数据可能被提前截断舍入进位后依然可能越过饱和边界导致输出超过边界。从工程惯例出发我更推荐先舍入、后饱和舍入产生的进位由饱和逻辑统一收口边界条件只需要在一处处理逻辑更清晰。顺序实现时饱和模块的输入位宽要覆盖舍入后的进位位宽例如输入17bit、舍入后16bit、输出14bit饱和比较时按16bit语义进行。3.4 不同应用场景中饱和策略的差异并不是所有场景都“一刀切”饱和到对称范围。这里整理几个常见场景的经验方便对号入座应用场景饱和策略原因图像像素输出无符号饱和到[0, 255]或原始位宽范围像素值本身非负负值无物理意义FIR滤波器输出对称饱和到输出位宽范围保持信号动态范围避免负半周偏置CORDIC旋转结果有时不饱和保留溢出位由后续模块处理CORDIC输出可能超过一个bit先保留精度再统一处理累加器/积分器一般不饱和用宽位累加后定期截断饱和会引入非线性影响控制环路稳定性NCO相位累加器必须回绕不需要饱和相位天然是模运算回绕就是取模从这个表可以看出来饱和不是“加一个保险”而是与算法结构配合的主动设计。相位累加器用回绕不是忘记加饱和而是模运算本身的正确表达控制环路的积分器用宽位累加然后截断则是为了避免饱和非线性带来的极限环或停滞。4. 抖动Dither用一点噪声换取可观的动态范围4.1 量化噪声与信号相关时会出现什么量化误差本质上与输入信号相关。当信号幅度很小、采样点数很少时量化误差会表现出很强的周期性在频谱上形成与信号相关的谐波和杂散。一个典型的例子给1bit输出加一个幅度只有0.1LSB的低频正弦波输出就是一串等间隔的方波脉冲频谱上sinc包络内的某些频点会出现明显的梳状谱而这些频率分量与输入正弦波直接相关。图像里也有类似现象。8bit显示器显示一个缓慢变化的暗区渐变色时会出现肉眼可见的条带banding原因就是量化步长过大、相邻像素值跳变不连续。本质上都是量化误差和信号高度相关的结果。4.2 TPDF抖动的基本原理解决思路是在量化前加入一个已知统计特性的随机噪声让量化误差变成一个与信号不相关的随机量。这样做的结果是量化噪声从“与信号相关的谐波/杂散”变为“平坦的噪声底”虽然噪声功率没有消失但输出频谱质量大幅提高。对ADC测试、音频处理、高精度测量来说用一点点噪声功率换掉杂散和失真非常划算。抖动噪声的幅度分布很关键。最简单的是均匀分布抖动PDF为矩形幅度在 ±0.5LSB 之间更好的是三角分布抖动TPDFTriangular Probability Density Function即两个独立的均匀分布随机数相加。TPDF的峰峰值为 ±1LSB方差为 LSB²/6量化后误差的标准差比不加抖动时大一些但误差的功率谱密度完全平坦且与信号完全不相关。为什么TPDF是经典选择因为量化噪声输入为TPDF时输出的总噪声功率近似为 LSB²/6误差与信号的相关度在理论上降到0且任意阶距的特性都优于单均匀分布。在FPGA里实现TPDF也简单两个LFSR分别生成随机数相加后作为抖动信号。4.3 FPGA中的TPDF抖动实现一个实用的FPGA抖动模块结构如下module tpdf_dither #( parameter DW 16, // 数据位宽 parameter OUTW 10, // 量化输出位宽 parameter LFSR_W 16 )( input wire clk, input wire rst_n, input wire signed [DW-1:0] din, output reg signed [OUTW-1:0] dout ); reg [LFSR_W-1:0] lfsr1; reg [LFSR_W-1:0] lfsr2; wire signed [1:0] dither_sample; // 三角分布范围 -1, 0, 1 以LSB为单位 // 两个不同本原多项式的LFSR always (posedge clk or negedge rst_n) begin if (!rst_n) begin lfsr1 16hACE1; lfsr2 16hB4C3; end else begin lfsr1 {lfsr1[LFSR_W-2:0], lfsr1[15] ^ lfsr1[14] ^ lfsr1[12] ^ lfsr1[3]}; lfsr2 {lfsr2[LFSR_W-2:0], lfsr2[15] ^ lfsr2[13] ^ lfsr2[11] ^ lfsr2[7]}; end end // 两个均匀分布相加 三角分布 wire b1 lfsr1[0]; // 0或1 wire b2 lfsr2[0]; // 0或1 wire signed [1:0] tpdf $signed({1b0, b1}) $signed({1b0, b2}) - 2sd1; // tpdf范围-1, 0, 1对应 ±1 LSB 的TPDF wire signed [DW1:0] dither_sum $signed(din) $signed({{(DW-1){tpdf[1]}}, tpdf}); // 加抖动后再做舍入这里选择收敛舍入或四舍五入均可 wire signed [DW-2:0] rounded dither_sum[DW1:2]; // 等价于除以4映射为LSB always (posedge clk or negedge rst_n) begin if (!rst_n) dout 0; else dout saturated_round(rounded); // 加饱和逻辑 end endmodule这段代码的思路是两条独立LFSR各产生1bit随机数相加后的结果 −1、0、1可以看作TPDF抖动两个均匀分布之和均值0三角分布。将抖动信号扩展到位宽后加到输入数据上再整体量化到目标位宽。注意代码里加法位宽多扩了两bit是为了容纳抖动加法后的进位防止加抖动本身再引入溢出。4.4 什么时候不该用抖动抖动不是灵丹妙药以下场景我一般不加抖动。控制环路里尽量不加。控制环带宽比较低抖动噪声虽然被量化打散但会直接注入环路变成输出端的抖动或稳态误差。控制环路需要的是低噪声、低延迟、无偏置这恰恰是TPDF抖动的反面。此时宁可多保留几位中间位宽也不加噪声。恒定直流输出或低速测量场景慎用。如果你输出一个恒定值抖动会在输出端表现为一个随机上下跳变把原本稳定的读数变得忽大忽小。低速测量仪器通常需要的是平均后稳定而不是单点噪声性能好。涉及误码率的数字通信链路需谨慎。加抖动后接收端的眼图噪声底必然抬高如果你本来就不存在明显的量化杂散问题加抖动属于白白损失SNR。通常只有当量化位宽过低比如4bit以下、非线性失真影响系统指标时才考虑用抖动换取SFDR。5. 组合起来一个完整的量化模块设计实例5.1 参数化量化模块的设计思路在实际FPGA项目里取整、饱和、抖动通常会放在同一个可参数化的模块里统一封装方便到处调用。一个理想的定点量化模块对外接口只需要输入数据、输出数据、几个位宽参数内部则按“可选抖动 → 舍入 → 饱和”的固定流水线处理。我自己常用的一组参数设计如下参数取值范围说明DIN_WIDTH8~32输入数据位宽DOUT_WIDTH4~24输出数据位宽FRAC_BITS_IN0~DIN_WIDTH输入小数位宽FRAC_BITS_OUT0~DOUT_WIDTH输出小数位宽ROUND_MODE0/1/20截断1四舍五入2收敛舍入DITHER_EN0/1是否启用TPDF抖动SAT_MODE0/1/20不饱和1非对称饱和2对称饱和设计要点是舍入丢弃的位数 K (DIN_WIDTH − FRAC_BITS_IN) − (DOUT_WIDTH − FRAC_BITS_OUT)正数表示需要右移截位负数表示左移扩展位宽。模块内部必须对K的正负分别处理避免生成移位寄存器时出现位宽反转的错误。5.2 基于参数化模块的RTL示例下面给一个简洁版的量化核心逻辑按照“加抖动可选→ 舍入 → 饱和”顺序实现module quantize #( parameter DIN_WIDTH 24, parameter DOUT_WIDTH 16, parameter FRAC_IN 20, parameter FRAC_OUT 12, parameter ROUND_MODE 2, // 0: trunc, 1: half_up, 2: half_even parameter DITHER_EN 0, parameter SAT_MODE 2 // 0: none, 1: asym, 2: sym )( input wire clk, input wire rst_n, input wire signed [DIN_WIDTH-1:0] din, output reg signed [DOUT_WIDTH-1:0] dout ); localparam INT_IN DIN_WIDTH - FRAC_IN; localparam INT_OUT DOUT_WIDTH - FRAC_OUT; localparam K_SHIFT (FRAC_IN - FRAC_OUT); // 需要丢弃的小数位 // 第一步可选TPDF抖动 wire signed [DIN_WIDTH1:0] din_dith; generate if (DITHER_EN) begin : gen_dither reg [15:0] lfsr_a, lfsr_b; wire signed [1:0] tpdf; always (posedge clk or negedge rst_n) begin if (!rst_n) begin lfsr_a 16hF0F0; lfsr_b 16h0FF0; end else begin lfsr_a {lfsr_a[14:0], lfsr_a[15] ^ lfsr_a[13] ^ lfsr_a[12] ^ lfsr_a[10]}; lfsr_b {lfsr_b[14:0], lfsr_b[15] ^ lfsr_b[12] ^ lfsr_b[11] ^ lfsr_b[9]}; end end wire b1 lfsr_a[0]; wire b2 lfsr_b[0]; assign tpdf $signed({1b0, b1}) $signed({1b0, b2}) - 2sd1; assign din_dith $signed(din) $signed({{(DIN_WIDTH-1){tpdf[1]}}, tpdf}); end else begin : gen_no_dither assign din_dith $signed({{2{din[DIN_WIDTH-1]}}, din}); end endgenerate // 第二步舍入到目标小数位 wire signed [DIN_WIDTH1:0] din_shifted; wire signed [DIN_WIDTH1- (FRAC_IN-FRAC_OUT):0] rounded_tmp; // 实际实现中根据ROUND_MODE选择对应逻辑这里简化示意 // 以 half_even 为例将低K_SHIFT位送入 round_half_even 得到输出 // 第三步饱和到目标整数位宽 // 若 INT_OUT 实际整数位宽则进行饱和处理 endmodule实际工程中舍入和饱和逻辑应当按前文模块拆开组合这里展示的是模块级的整合时序。为了避免组合逻辑过长量化模块一般拆成两级流水第一级完成抖动加法与舍入第二级完成饱和与输出寄存。5.3 Testbench验证量化误差与动态性能写testbench是验证量化模块正确性的关键一步。网上经常搜“fpga如何正确写testbench”这里结合量化场景给出几条经验。第一验证统计偏置。向模块输入一个无直流的正弦波幅度约满量程的80%分别统计截断、四舍五入、收敛舍入三种模式的输出均值。截断模式均值应约为 −0.5LSB四舍五入和收敛舍入应接近0。如果收敛舍入模式下均值明显偏离0先检查输入数据分布是否覆盖了足够的量化电平——当正弦波幅度很小、只跨越几个LSB时统计结果不具备代表性。第二验证饱和边界。把输入设置为满量程附近的直流分别检查最大值、最小值、加1后的输出是否被正确钳位。饱和逻辑最常见的bug是中间位宽扩展不够比较器把正数当负数导致负饱和方向错误。测试用例至少应包括最大值、最大值1、最小值、最小值−1、符号交叉点0与−1之间。第三验证抖动效果。对加抖动模块输入一个低于一个LSB幅度的小信号连续采样N点做FFT观察频谱。不加抖动时频谱上能看到明显的谐波簇加TPDF抖动后谐波消失噪声底变得平坦。这个测试在FPGA里可以用ILA抓数据回PC分析也可以直接在仿真里用$fwrite导出数据到文本再用Python或MATLAB处理。第四验证时序收敛。量化模块的舍入逻辑包含比较器和加法器在较高时钟频率下容易成为关键路径。建议在模块内部对输入先打一拍中间操作打一拍输出再打一拍用三级流水化解组合延迟。代价是增加两拍latency但在大部分信号链路中可接受。5.4 常见问题排查速查表现象可能原因排查与对策输出信号整体偏置使用截断导致直流偏置改为四舍五入或收敛舍入输出高频杂散明显量化误差与信号相关加入TPDF抖动输出出现反向跳变溢出回绕增加饱和处理饱和输出不对称有符号数负极值多1改用对称饱和策略加抖动后噪声底高抖动幅度过大或分布不对确认TPDF范围为±1LSB舍入进位后越过饱和值先饱和后舍入或边界没留余量调整为先舍入后饱和仿真通过但上板结果不对中间位宽截断不一致用参数化约束所有信号位宽避免硬编码直流输入却输出方波抖动在恒定输入下仍生效对恒定输出路径禁用抖动这8条算是量化模块调试中最高频的坑。前两条最容易忽略因为输出看起来只是“不太对”很难直接指向量化问题后面几条则是逻辑层面的硬错误只要仿真用例构造充分基本能提前发现。5.5 一点体会有关FPGA量化这件事我在多个项目里踩过不少坑。个人最大的感受是量化策略必须在设计一开始就定下来不能等代码写完了再补。中途改舍入模式或者加饱和牵扯到的不只是某个模块而是整个数据通路的位宽一致性和仿真参考模型。特别是做图像处理或ADC数据链路时前级模块的舍入方式会影响后级模块的噪声底这种蝴蝶效应越到后期越难收拾。另外不要迷信某一篇论文或某个IP核的默认配置。不同算法对噪声形态的容忍度差别很大图像处理往往更讨厌结构性的条带和伪轮廓所以加抖动效果立竿见影音频处理更关注THDN和动态范围收敛舍入配合TPDF是稳妥组合控制环路则宁可多留位宽也不加饱和和抖动。理解你所在场景的需求再决定每个参数怎么配才是正确的思路。做FPGA定量的乐趣在于每个选择都有明确的成本和收益位宽换精度抖动换SFDR饱和换稳定性。把这些权衡吃透你写的代码就不再是“碰运气能跑”而是每个bit都心里有数。希望这篇内容对你手上的项目有实际帮助。
RELATED

相关推荐

RK3568平台Rockit多媒体库编译实战:从环境准备到运行测试

RK3568平台Rockit多媒体库编译实战:从环境准备到运行测试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/3 6:51:44
python3安装psutil报错排查:从编译依赖到TaoToken统一Key通道的配置验证

python3安装psutil报错排查:从编译依赖到TaoToken统一Key通道的配置验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/3 6:46:44
适合做 PPT 的 AI 工具怎么选?从资料、结构到可编辑交付的 TaoToken 实测路径

适合做 PPT 的 AI 工具怎么选?从资料、结构到可编辑交付的 TaoToken 实测路径

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/3 6:46:44
MORE NEWS

更多资讯

📰

Android Handler 机制全解析:从消息循环到同步屏障与 ANR

在 Android 中,点击事件、绘制、生命周期回调,最终都要在相应线程上执行。Handler 经常被一句话概括为“切回主线程的工具”,但它真正依托的是一套线程内的消息循环。理解这套机制,才能回答:postDelayed 为什么不是准时…

📰

3DCellForge 模型质量评分机制全解析:如何让你的 AI 3D 模型达到演示级水准

3DCellForge 模型质量评分机制全解析:如何让你的 AI 3D 模型达到演示级水准 【免费下载链接】3DCellForge AI-powered interactive 3D model generation, inspection, and presentation studio. 项目地址: https://gitcode.com/gh_mirrors/3d/3DCellForge 3D…

📰

AI 大模型到底怎么“变聪明”的?核心知识点,一篇讲完

这篇文章只讲重点:AI 凭什么“变聪明”、为什么会说胡话、2026 年各家什么格局、普通人怎么用。01 AI 的三大分类判别/分析型:会分类、预测,不创作。刷脸支付、垃圾邮件拦截、推荐算法都是它。生成式:给一句话,生成文字…

📰

汽车空调压缩机台架测试系统原理

一、压缩式空调制冷循环原理汽车空调属于蒸汽压缩式制冷循环,不是制造冷量,而是利用制冷剂相变搬运热量(冷媒循环)。四大部件:压缩机、冷凝器、节流元件、蒸发器。循环流程(制冷):压…

📰

开题报告重点与难点总分不清?用智一刻3步提炼学术突破关键

大四开题答辩现场,评审专家翻开开题报告,最爱提问的质询之一就是:“你的这篇论文,攻关重点究竟在哪里?学术难点又在哪里?” 很多同学在台上一阵语塞。在很多毕业生的观念里,往往误以为哪一章写…

📰

MySQL数据库1:数据库基础

数据库基础 目录 数据库基础 一、卸载MySQL 1.1.停止MySQL服务 1.2.查看MySQL安装包 1.3.卸载MySQL 二、安装MySQL 2.1.安装MySQL 2.2.安全初始化 2.3.登录MySQL 三、数据库的认识 3.1.数据库的概念 3.2.主流的数据库 3.3.使用案例 3.4.服务器、数据库、表 3.5.…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬