数字混频

参考链接:
FPGA数字信号处理(一)数字混频(NCO与DDS的使用)
https://blog.csdn.net/fpgadesigner/article/details/80512067
一、混频原理
混频就是把两个不同的频率信号混合,得到第三个频率。在模拟电路中经常见到的就是把接收机接收到的高频信号,经过混频变成中频信号,再进行中频放大,以提高接收机的灵敏度。

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

二、 程序设计
程序设计系统时钟50MHz,1MHz的输入信号与1MHz的本振信号做混频,根据混频原理会得到2MHz的和频信号与0Hz(直流)

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

module top(
    input clk,            //50MHz系统时钟
    input rst_n,          //低电平有效复位信号
    output [19:0] dout    //混频输出信号
    );

理论上用来混频的输入信号应该来自本模块之外,考虑未安装matlab以及简化程序等原因,本工程输入信号和本振信号通过例化两个DDS IP核来产生。

dds_compiler_0 dds_compiler_0_inst1 (
      .aclk(clk),                                // input wire aclk
      .m_axis_data_tvalid(),    // output wire m_axis_data_tvalid
      .m_axis_data_tdata(din),      // output wire [15 : 0] m_axis_data_tdata
      .m_axis_phase_tvalid(),  // output wire m_axis_phase_tvalid
      .m_axis_phase_tdata(m_axis_phase_tdata1)    // output wire [39 : 0] m_axis_phase_tdata
    );   
    
 dds_compiler_1 dds_compiler_0_inst2 (
      .aclk(clk),                                // input wire aclk
      .m_axis_data_tvalid(),    // output wire m_axis_data_tvalid
      .m_axis_data_tdata(s_oc),      // output wire [15 : 0] m_axis_data_tdata
      .m_axis_phase_tvalid(),  // output wire m_axis_phase_tvalid
      .m_axis_phase_tdata(m_axis_phase_tdata2)    // output wire [39 : 0] m_axis_phase_tdata
     );    

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

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

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

在下面的方法1中,一定要定义输入信号和本振信号为有符号型signed,如果不这样做,直接使用乘法运算符“*”,会被综合为无符号数乘法,得到的就是错误的结果。

  /*采用直接相乘的方法*/
    reg  signed [19:0] dout; 
     wire signed [9:0] din;
     wire signed [9:0] s_oc;
     always @(posedge clk or negedge rst_n)
      if (!rst_n) 
            dout <= 20'd0;
     else
            dout <= din * s_oc;  

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

  /*采用直接ip核的方法*/
 wire  signed [19:0] dout;
 wire   [9:0] din;
 wire   [9:0] s_oc;
 mult_gen_0 your_instance_name (
              .CLK(clk),  // input wire CLK
              .A(din),      // input wire [9 : 0] A
              .B(s_oc),      // input wire [9 : 0] B
              .P(dout)      // output wire [19 : 0] P
            ); 

三、测试
工程下载见https://download.csdn.net/download/keilzc/12133386
其中dds配置可参考https://blog.csdn.net/keilzc/article/details/104146629

1、最初采用同一个DDS产生的1MHz正弦信号进行混频
在这里插入图片描述
2、1MHz和3MHz混频得到2MHz和4MHz
在这里插入图片描述
3、5MHz和4MHz混频得到9MHz和1MHz
在这里插入图片描述
4、直接相乘时,其中本振信号未定义为unsigned在这里插入图片描述
注意此时本振信号s_oc虽然为定义为signed,但查看波形时依然可以选择signed,由此也证明signed和unsigned的申明只是告诉设计的运算如何看待这个寄存器中的数,并不能改变寄存器的值。

5、用乘法器相乘时,参数B设置为unsigned
查看波形时dout设置为signed
在这里插入图片描述
查看波形时dout设置为unsigned
在这里插入图片描述
由此可见:一定要正确设置数据类型,因为有符号数和无符号数的运算法则是不一样的,所以错误的申明会导致结果计算错误。

工程下载链接:https://download.csdn.net/download/keilzc/12133386

  • 6
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值