FPGA数字信号处理(一)数字混频实现详解|NCO/DDS原理、有符号数避坑、直流滤除工程实战
前言
数字混频是软件无线电、调制解调、DDC数字下变频、DUC数字上变频的最基础核心操作。相比于模拟混频,FPGA数字混频精度高、无温漂、配置灵活,是入门FPGA DSP必学案例。
本文基于经典工程:5MHz系统时钟、625kHz输入信号 + 625kHz本振信号混频,完整讲解:
数字混频数学原理
Quartus NCO / Vivado DDS 两大IP核区别与配置
FPGA有符号/无符号数、补码工程致命坑点
两种混频乘法实现方式(纯Verilog / 乘法器IP)
简易均值法直流滤除原理与代码解析
Testbench文件读写仿真方案
一、数字混频核心原理
1.1 混频本质:时域相乘、频域搬移
模拟混频依靠三极管/二极管非线性实现频率变换;数字混频最简单、最标准的方式就是:两个正弦信号直接相乘。
根据三角积化和差公式:
$$\sin\omega_1 t \cdot \sin\omega_2 t = \frac{1}{2}[\cos(\omega_1-\omega_2)t-\cos(\omega_1+\omega_2)t]$$
相乘后会同时产生:
差频分量(低频)
和频分量(高频)
1.2 本文工程参数设计
系统时钟:5MHz
输入信号频率:625kHz
NCO/DDS本振频率:625kHz
混频结果:
差频:625k − 625k =0Hz(直流分量)
和频:625k + 625k =1.25MHz(目标有效信号)
工程最终目的:滤除直流,保留1.25MHz高频和频信号。
二、NCO与DDS本质区别(工程必懂)
很多初学者困惑:Quartus叫NCO,Vivado叫DDS,到底有什么区别?
2.1 概念层级区别
DDS(直接数字频率合成器):是一套完整技术体系,包含相位累加器、LUT波形表、DAC、后置滤波,输出模拟波形。
NCO(数控振荡器):是DDS的纯数字核心部分,只负责:相位累加 + 波形映射,只输出数字波形,无DAC。
简单总结:NCO = 纯数字本振;DDS = NCO + DAC + 模拟输出。
2.2 FPGA厂商IP命名差异(重点)
Altera/Quartus:NCO IP
轻量、简洁,专门用于数字本振、混频
参数少、上手快
Xilinx/Vivado:DDS Compiler IP
功能更强、可配置项极多
支持SFDR、频率分辨率、相位可调、正交sin/cos输出、AXI流式配置
工程等价结论:做数字混频时,Quartus NCO ≈ Vivado DDS。
2.3 DDS/NCO通用频率公式
$$f_{out} = \frac{FTW \times f_{clk}}{2^N}$$
FTW:相位增量字(phi_inc)
f_clk:系统时钟
N:相位累加器位宽
本文16位相位累加、FTW=8192、5MHz时钟,精准输出625kHz。
三、整体工程模块架构
整个数字混频工程分为三级流水线:
NCO/DDS生成本振正弦波(625kHz)
有符号数乘法混频(产生和频+差频)
均值滤波去除直流分量(提纯1.25MHz信号)
3.1 顶层端口定义
module Mixer ( input clk, //5MHz系统时钟 input rst_n, //低电平有效复位 input [9:0] din, //10bit输入信号 output [9:0] s_oc, //NCO本振输出625kHz output out_valid, //本振有效标志 output [19:0] dout //混频最终输出 );
四、NCO本振信号生成(Quartus)
通过NCO IP核生成625kHz标准正弦本振,核心参数为相位增量 16'd8192。
wire [9:0] oc_sin; oc oc ( .phi_inc_i (16'd8192), .clk (clk), .reset_n (rst_n), .clken (1'b1), .fsin_o (oc_sin), .out_valid (out_valid) ); assign s_oc = oc_sin;
Tips:生成IP时必须勾选Generate Simulation Model,否则ModelSim仿真报错。
五、FPGA最关键坑点:有符号数与无符号数运算
这是90%初学者混频出错的根本原因。
5.1 核心规则
NCO/DDS/ADC/DAC输出一律是补码有符号数
Verilog默认变量为无符号数
有符号数 × 无符号数 =错误无符号乘法结果
signed关键字不改变二进制值,只改变运算解析方式。
例如二进制11:
unsigned:当作 3
signed:当作 -1
5.2 两种正确混频乘法写法
方式1:纯代码强制有符号转换(无需IP)
wire signed [9:0] din_s = din; wire signed [9:0] oc_sin_s = oc_sin; reg signed [19:0] mult; always @(posedge clk or negedge rst_n) if(!rst_n) mult <= 20'd0; else mult <= din_s * oc_sin_s;
方式2:调用有符号乘法器IP(工程常用)
wire signed [19:0] mult; mult1 mult1_inst ( .clock (clk), .dataa (din), .datab (oc_sin), .result (mult) );
六、直流滤除原理与代码解析(工程小技巧)
本设计5MHz时钟采样625kHz信号,一个正弦周期恰好8个采样点。
周期内平均值 = 信号直流分量,用“均值相减”即可去直流。
6.1 移位缓存8点数据
reg signed [19:0] m1,m2,m3,m4,m5,m6,m7;
always @ (posedge clk or negedge rst_n) if (!rst_n) begin m1 <= 20'd0;
m2 <= 20'd0; m3 <= 20'd0; m4 <= 20'd0; m5 <= 20'd0; m6 <= 20'd0; m7 <= 20'd0; end
else begin m1 <= mult; m2 <= m1; m3 <= m2; m4 <= m3; m5 <= m4; m6 <= m5; m7 <= m6;
end
6.2 累加求均值、去除直流
// 8点累加 wire signed [22:0] madd = mult+m1+m2+m3+m4+m5+m6+m7; // 右移3位 = 除以8 wire signed [19:0] mean = madd[22:3]; // 原始混频结果 - 直流均值 = 无直流交流信号 wire signed [19:0] mt = mult - mean; assign dout = mt;
⚠️该方法仅适用于采样倍数固定场景,通用性不强,但非常适合新手理解去直流思想。
七、Vivado DDS Compiler IP配置要点
DDS比NCO功能更强,适合复杂通信系统:
System Parameters模式:直接配置时钟、频率、SFDR、频率分辨率,适合新手
Hardware Parameters模式:手动配置位宽、手动计算频率字,适合底层优化
固定频率选择Fixed模式,资源最小
支持输出Sin+Cos正交双路信号,用于解调系统
支持相位动态偏移,可实现相位调制
DDS输出位宽通常为8的整数倍,有效位在低位,高位为符号填充,仿真时建议使用虚拟总线观察有效位。
八、Testbench文件读写仿真方案
本工程配套仿真支持txt激励读取、结果保存,是FPGA DSP仿真通用方法。
8.1 读取txt激励
integer i; reg [9:0] stimulus[1:data_num]; initial begin $readmemb("SinIn.txt", stimulus); i = 0; repeat(data_num) begin i = i + 1; din = stimulus[i]; #clk_period; end end
$readmemb:读取二进制txt;$readmemh:读取十六进制txt。
8.2 仿真数据写入txt
integer file_out; initial begin file_out = $fopen("mixer_out.txt"); if(!file_out) begin $display("file open error"); $finish; end end wire signed [19:0] dout_s = dout; wire rst_write = clk & rst_n; always @(posedge rst_write) begin $fdisplay(file_out,"%d",dout_s); end
九、工程核心总结(面试/复盘必背)
数字混频 = 时域相乘、频域产生和频/差频
NCO是Quartus叫法,DDS是Vivado叫法,工程功能等价
混频出错90%是因为有符号数未统一
FPGA除法尽量用截位/移位,不直接使用除号
周期均值法可简单去除直流,适合定点采样倍数场景
IP仿真必须开启仿真模型,否则仿真失败
十、拓展学习方向
替换均值去直流为 FIR/IIR 低通滤波器,实现通用频谱提纯
基于DDS实现 FSK/ASK/PSK 数字调制
搭建完整 DDC/DUC 软件无线电架构
深入理解DDS杂散、SFDR、频率分辨率指标
完整Quartus工程、Testbench、仿真文件可参考原文开源工程,适合零基础复刻学习。
