当前位置: 首页 > news >正文

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。

三、整体工程模块架构

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

  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、仿真文件可参考原文开源工程,适合零基础复刻学习。

http://www.gsyq.cn/news/1521604.html

相关文章:

  • 列表与元组区别、常用方法及使用场景(生产选型指南)
  • Notebook到生产环境的ML模型部署实战:7个致命细节与防御体系
  • YashanDB v22.1深度体验:除了‘国产替代’,它的HTAP和云原生特性到底香不香?
  • 抖音直播内容永久保存的终极解决方案:从单场录制到自动化采集系统
  • 基于YOLOv5的智能象棋助手:Vin象棋完整使用指南
  • 告别Unity,用C#和OpenTK从零撸一个3D旋转立方体(.NET 8 + VS2022保姆级教程)
  • WASI 0.3 发布:异步成 WebAssembly 组件原生特性,多工具链即将支持
  • Cursor Free VIP:如何快速实现AI编程助手永久免费激活的完整指南
  • 【无人机覆盖】基于分解和扫描线策略对多边形区域进行凹度感知覆盖路径规划附matlab代码
  • 机器学习项目五道硬门槛:问题可解性、数据可信度、目标对齐、基线确认与部署预演
  • 机器学习三大数学支柱:线性代数、微积分与概率论的工程化解读
  • 美国奥兰多迪士尼魔法王国烟花秀,童话照进现实瞬间
  • C 语言通用动态数组:无需存储容量和结构体,实现方法大揭秘!
  • 3步搭建Windows专业级Syslog日志服务器:Visual Syslog Server终极指南
  • 让数据分析长出牙齿:可操作、可归因、实时驱动业务增长
  • GitHub功能大揭秘:多领域平台服务与知识地图工具的实用指南
  • LabelImg汉化包替换后总报错?可能是你的PyQt5资源编译姿势不对(附完整排错流程)
  • 解锁创维盒子E900V22C的完全体:开启adb root权限后,这5个玩法让旧盒子焕发新生
  • AI资讯简报如何做到真正实用?从信息过载到可执行工作流
  • DeepSeek OCR本地部署:文档识别成本降低96%的工程实践
  • AI模型选型的真成本:Fine-tuning、蒸馏与迁移学习的产线级ROI对比
  • 算法不是AI:普通人可理解的决策流水线
  • 2026双金属耐磨管行业深度分析:电厂、矿山场景下耐用型管材厂商对比与案例解析 - 优质品牌商家
  • 别再被Kafka Kerberos认证的`sasl.kerberos.service.name`搞晕了!一个配置项引发的‘血案’与避坑指南
  • 终极GitHub加速指南:5分钟让你的下载速度飙升10倍
  • 2026亚洲弹性学制EMBA客观测评与理性选型指南
  • 汇编调试不求人:DOSBox搭配Debug命令实战指南(从Hello World到单步追踪)
  • Java 流式编程(Stream)完整详解
  • 从DDR3到DDR4,你的老电脑升级内存划算吗?实测性能提升与兼容性全解析
  • Triton模型服务化与持续可观测性实战指南