0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

数字混频原理及程序设计

FPGA设计论坛 来源:CSDN技术社区 作者:FPGADesigner 2022-04-21 10:59 次阅读

混频原理

混频就是把两个不同的频率信号混合,得到第三个频率。在模拟电路中经常见到的就是把接收机接收到的高频信号,经过混频变成中频信号,再进行中频放大,以提高接收机的灵敏度。

数字电路中最简单的混频便是两个信号做乘法,可以得到它们的和频信号与差频信号。数字混频在通信的调制、解调、DUC(数字上变频)、DDC(数字下变频)等系统中应用广泛。通常把其中一个信号称为本振信号(local oscillator),另一个信号称为混频器的输入信号。

程序设计

本文的程序设计参考自杜勇老师的书《数字滤波器MATLABFPGA实现-Altera/Verilog版》,对其中部分设计细节做了修改。杜勇老师的这个系列共有三本书,很推荐大家购买学习。不过可能由于篇幅有限,杜勇老师在书中对设计的一些细节和思想没有做详细介绍,博主在本文中和大家讨论讨论。

程序设计系统时钟5MHz,625kHz的输入信号与625kHz的本振信号做混频,根据混频原理会得到1.25MHz的和频信号与0Hz(直流),将直流滤除掉得到1.25MHz的有效信号。

设计的顶层模块接口如下所示:

module Mixer

(

input clk, //5MHz系统时钟

input rst_n, //低电平有效复位信号

input [9:0] din, //输入信号

output [9:0] s_oc, //本振信号,625kHz

output out_valid, //NCO输出有效信号

output [19:0] dout //混频输出信号

);

程序中首先生成本振信号。Quartus和Vivado中都提供了类似功能的IP核:Vivado中叫DDS(Direct Digital Synthesizers)Compiler;Quartus中叫NCO(Numerically controlled oscillators)。下面以实例化NCO为例,具体的设计方法在下文讲解。

wire [9:0] oc_sin;

oc oc

(

.phi_inc_i (16'd8192), //相位增量,对应625kHz

.clk (clk),

.reset_n (rst_n),

.clken (1'b1), //时钟允许信号

.fsin_o (oc_sin), //本振正弦信号

.out_valid (out_valid) //输出有效标志

);

接下来用乘法进行混频。我们都知道计算机中有带符号数signed和无符号数unsigned,还知道计算机经常以二进制补码的形式的表示带符号数。

在FPGA设计中,不管是Altera还是Xilinx,它们的IP核几乎都是采用二进制补码带符号数,也有很多的ADCDAC芯片的数据接口也采用的是二进制补码。因此,在设计中,我们要清楚什么时候用什么数值表示法。

比如NCO的输出为带符号数二进制补码,假设混频的输入信号也是带符号数二进制补码,则在整个混频程序设计中都要保持这个数值表示方法,否则就会出错。

在下面的方法1中,再定义一个带符号的寄存器将输入信号转换为带符号数是很有必要的:“wire signed [9:0] din_s = din;”。如果不这样做,直接使用乘法运算符“*”,会被综合为无符号数乘法,得到的就是错误的结果。

当然也可以用方法2,乘法器IP核可以选择计算方式是“signed”还是“unsigned”,将乘法器设置为signed也可以完成正确的计算。

//----------------------------------------------------

// 乘法实现混频,方法1,转换为带符号数后再相乘

//----------------------------------------------------

//reg signed [19:0] mult;

//wire signed [9:0] din_s = din;

//wire signed [9:0] oc_sin_s = oc_sin;

//

//always @(posedge clk or negedge rst_n)

// if (!rst_n) mult <= 20'd0;

// else mult <= din_s * oc_sin_s;

//----------------------------------------------------

// 乘法实现混频,方法2,调用乘法器IP核,设置为signed

//----------------------------------------------------

wire signed [19:0] mult;

mult1 mult1_inst (

.clock ( clk ),

.dataa ( din ),

.datab ( oc_sin ),

.result ( mult )

);

接下来滤除混频后的直流信号。由于乘法的运算结果为带符号数,接下来的计算使用到的寄存器都应申明为signed。

需要强调的是,signed和unsigned的申明只是告诉设计的运算如何看待这个寄存器中的数,并不能改变寄存器的值。比如“11”这个值,如果申明为signed,运算将其视作-1,如果申明为unsigned,运算将其视作3。因为有符号数和无符号数的运算法则是不一样的,所以错误的申明会导致结果计算错误。

reg signed [19:0] m1,m2,m3,m4,m5,m6,m7;

// 5MHz/625kHz=8; 缓存连续8个点的值

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

wire signed [22:0] madd = mult+m1+m2+m3+m4+m5+m6+m7; //一个周期

wire signed [19:0] mean = madd[22:3]; //舍掉低3bit,相当于除8,得到

wire signed [19:0] mt = mult - mean; //滤除直流分量

assign dout = mt;

assign s_oc = oc_sin;

endmodule

上面滤除直流分量的方法并不通用,由于5Mhz的系统时钟是625kHz信号的8倍,所以连续8个点的平均值便是直流分量。不过程序设计思路还是可以学习,比如依次移位缓存数据、截高位做除法这些小技巧。

NCO IP核的使用

在Quartus中打开该IP核,配置界面如下。后面的Quartus版本中将IP核集成到了qsys中,配置界面略有不同,但设置的参数之类的基本一样。

b8bf9420-c119-11ec-bce3-dac502259ad0.jpg

设定好相位累加器精度、角度分辨率、幅度精度、系统时钟和输出信号频率,便可以得到一个相位增量值(phase increment value),在实例化NCO模块时传入的便是这个值。实际的输出频率和设定的频率会存在一定误差,下方便展示了输出信号的频域和时域图形。总体来说设置比较简单。

如果需要仿真,在生成IP核前一定要在“Set up simulation”中选中“Generate Simulation Model”和“Generate netlist”,如下图所示。否则在导入ModelSim时会失败,无法进行仿真。

b8f14290-c119-11ec-bce3-dac502259ad0.jpg

DDS Compiler IP核的使用

基本配置

在Vivado中打开DDS Compiler IP核,配置界面如下:

b9212956-c119-11ec-bce3-dac502259ad0.jpg

这个IP核的配置选项更丰富,提供的功能也更强大。我这里只介绍下本设计用到的功能,其余具体信息可以参考Xilinx官方文档pg141。

同样设定系统时钟,Parameter Selection选择“System Parameters”,这种设计方式可以直接设置无杂散动态范围、频率分辨率、输出频率等系统级的参数,和Quartus的NCO IP核很像。另外一种“Hardware Parameters”设计方式需要自己设定输出数据和相移的位宽,输出频率、相位偏移等值需要自己计算对应的二进制数值。这两种设计方式向不同需求的设计者提供。

pg141中给出了总线位宽与系统参数之间的转换关系公式。

b937137e-c119-11ec-bce3-dac502259ad0.jpg

相位增量和相位偏移都可以设置为可编程的“Programmable”和“Streaming”方式,本设计只需要产生625kHz固定频率的本振信号,设置为“Fixed”即可(所需资源少)。在“Summary”中可以看到整个DDS系统的详细信息。

位宽问题

需要提醒的是系统最终的实际信号位宽和总线接口位宽并不一致。IP核的位宽只会是8的倍数,多余的位数会移符号为填充,如下图所示。

b95fcefe-c119-11ec-bce3-dac502259ad0.jpg

更直观的感受,看一个DDS Compiler IP核的仿真:

b973b6d0-c119-11ec-bce3-dac502259ad0.jpg

可以看到相移虽然有16bit的位宽,但是有效的只有低10bit,高位都是符号为。为了更好的观察相位值,新建一个“virtual bus“,将低10bit加到bus中,如下图所示:

b9a58674-c119-11ec-bce3-dac502259ad0.jpg

可以清楚的看到相位和幅度之间的关系。

产生sin与cos信号

很多系统中需要sin和cos信号(如解调系统中的本振信号),在DDS中设置为“Sine and Cosine”输出时,sin和cos信号会共用数据总线,sin使用高字节,cos使用低字节,格式如下:

b9bc26ae-c119-11ec-bce3-dac502259ad0.jpg

产生带有相位偏移的信号

如果需要生成带有可调初始相位(也叫相位偏移Phase Offset)的信号,在DDS中将“Phase Offset Programmability”设置为“Streaming”,IP核端口会增加一个PHASE输入通道,该通道数据总线的有效位宽与设置的频率分辨率(Frequency Resolution)有关,可以在Summary界面中看到位宽(Phase Width)。该数据总线与360°相位之间线性对应。比如Phase Width为16Bits,则0对应0°,FFFF对应360°,7FFF对应180°,以此类推。

NCO和DDS是经常用到的IP核,在后面的“FPGA数字信号处理“系列介绍的其它系统中,也会经常出现,因此需要熟悉掌握这两个IP核的使用。

原文标题:FPGA学习-数字信号处理数字混频

文章出处:【微信公众号:FPGA设计论坛】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1625

    文章

    21665

    浏览量

    601751
  • 程序设计
    +关注

    关注

    3

    文章

    261

    浏览量

    30366
  • 数字混频
    +关注

    关注

    0

    文章

    4

    浏览量

    7462

原文标题:FPGA学习-数字信号处理数字混频

文章出处:【微信号:gh_9d70b445f494,微信公众号:FPGA设计论坛】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    FPGA数字信号处理--数字混频

    以简单的数字混频为例,介绍在FPGA程序设计中很重要的二进制原码、补码;有符号数、无符号数的问题。本文不是像课本那样介绍这些基础概念,而是介绍很实际的设计方法。
    发表于 09-25 09:42

    介绍在FPGA程序设计中很重要的二进制原码

    这是数字信号处理系列的第一篇,以简单的数字混频为例,介绍在FPGA程序设计中很重要的二进制原码、补码;有符号数、无符号数的问题。本文不是像课本那样介绍这些基础概念,而是介绍很实际的设计
    发表于 07-23 06:38

    C#程序设计与案例教程

    C#程序设计与案例教程全书共分九章,按C#知识的系统性,由浅入深安排内容,全面介绍了C# 语言基础,面向对象程序设计,GUI程序设计,图形、图像与多媒体,数据库程序设计
    发表于 10-22 11:05 158次下载
    C#<b class='flag-5'>程序设计</b>与案例教程

    基于VxWorks的Zinc程序设计

    基于VxWorks的Zinc程序设计
    发表于 03-29 12:31 22次下载

    JAVA程序设计之教程

    JAVA程序设计之教程
    发表于 04-10 14:46 0次下载
    JAVA<b class='flag-5'>程序设计</b>之教程

    DSP程序设计

    DSP程序设计:(1)DSP C语言程序设计(2)C语言与汇编语言混合编程(3)DSP程序烧写13.1 DSP C语言程序设计DSP支持使用ANCI C进行
    发表于 10-27 14:11 67次下载

    Matlab使用方法和程序设计

    Matlab使用方法和程序设计 实验一 Matlab使用方法和程序设计一、
    发表于 10-17 00:18 5375次阅读
    Matlab使用方法和<b class='flag-5'>程序设计</b>

    数字电位器AD8402与8031的接口电路及程序设计

    数字电位器AD8402与8031的接口电路及程序设计 文介绍数字电位器AD8402与8031的接口电路及程序设计和使用注意事项。
    发表于 03-14 15:17 2108次阅读
    <b class='flag-5'>数字</b>电位器AD8402与8031的接口电路及<b class='flag-5'>程序设计</b>

    最简单的C程序设计_ 顺序程序设计

    最简单的c语言程序设计,提供ppt教程,简单易懂
    发表于 12-02 09:37 0次下载

    音频信号数字化光纤通信实验系统的程序设计与实现

    音频信号数字化光纤通信实验系统的程序设计与实现
    发表于 01-04 17:13 22次下载

    Java并发程序设计教程

    Java并发程序设计教程
    发表于 03-19 11:23 2次下载

    面向对象的程序设计总结与过程化程序设计有什么区别?

    面向对象程序设计(简称OOP)技术最近几年在计算机领域得到了迅猛发展,它是程序设计方法的一场革命。与传统的结构化程序设计(面向过程程序设计)相比,它具有许多优点,其中最主要的是,面向对
    发表于 09-19 14:12 0次下载
    面向对象的<b class='flag-5'>程序设计</b>总结与过程化<b class='flag-5'>程序设计</b>有什么区别?

    简单的C程序设计教程之顺序程序设计的资料概述

    本文档的主要内容详细介绍的是简单的C程序设计教程之顺序程序设计的资料概述。
    发表于 11-16 16:17 4次下载
    简单的C<b class='flag-5'>程序设计</b>教程之顺序<b class='flag-5'>程序设计</b>的资料概述

    VB程序设计电子教程之图形程序设计的详细资料说明

    本文档的详细介绍的是VB程序设计电子教程之图形程序设计的详细资料说明主要内容包括了:1.图形程序设计基础,2.常用画图方法,3.动画程序设计初步
    发表于 03-01 11:01 13次下载
    VB<b class='flag-5'>程序设计</b>电子教程之图形<b class='flag-5'>程序设计</b>的详细资料说明

    JAVA程序设计教程之JSP程序设计实验

    本文档的主要内容详细介绍的是JAVA程序设计教程之JSP程序设计实验。
    发表于 11-05 15:34 6次下载
    JAVA<b class='flag-5'>程序设计</b>教程之JSP<b class='flag-5'>程序设计</b>实验