FPGA数字信号处理(一)数字混频实现详解|NCO/DDS原理、有符号数避坑、直流滤除工程实战
2026/6/14 4:54:09 网站建设 项目流程

前言

数字混频是软件无线电、调制解调、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。

三、整体工程模块架构

整个数字混频工程分为三级流水线:

  1. NCO/DDS生成本振正弦波(625kHz)

  2. 有符号数乘法混频(产生和频+差频)

  3. 均值滤波去除直流分量(提纯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

九、工程核心总结(面试/复盘必背)

  1. 数字混频 = 时域相乘、频域产生和频/差频

  2. NCO是Quartus叫法,DDS是Vivado叫法,工程功能等价

  3. 混频出错90%是因为有符号数未统一

  4. FPGA除法尽量用截位/移位,不直接使用除号

  5. 周期均值法可简单去除直流,适合定点采样倍数场景

  6. IP仿真必须开启仿真模型,否则仿真失败

十、拓展学习方向

  • 替换均值去直流为 FIR/IIR 低通滤波器,实现通用频谱提纯

  • 基于DDS实现 FSK/ASK/PSK 数字调制

  • 搭建完整 DDC/DUC 软件无线电架构

  • 深入理解DDS杂散、SFDR、频率分辨率指标


完整Quartus工程、Testbench、仿真文件可参考原文开源工程,适合零基础复刻学习。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询