混频:两个不同频率之间的混合,得到第三个频率。在数字信号处理中用来完成频谱搬移求和,是数字信号处理中的基本元件之一。例如通信中的混频合路:常见的数字混频器结构如下,由移频模块和求和模块组成。比如信号a、b是输入的两个单音信号,b是上一节讲到的nco信号,使用复乘将a、b信号进行搬移,然后求和。 频谱搬移的过程如下,输入信号data_in,与nco产生的单音信号进行复乘得到data_out;
将data_in与data_out的频谱放到一起如下,可以看到频谱搬移的过程。
频谱搬移在计算上就是复乘:(i+q*j)*(cos+sin*j)=(cos*i-sin*q)+(sin*i+cos*q)*j,用xilinx片子实现的话我们还是选择dsp48,其结构如下:
其中用到了dsp的级联,可以参考之前dsp48e1详细讲解的文章:fpga的底层资源之dsp48e1和xilinx dsp48e1仿真。这里不再详细描述。
代码实现如下:
首先的端口声明:
// ============================================================// file name: cm_mix// version : v1.0// data : 2022/11/6// author : fpga干货分享// ============================================================// 功能:数字混频器 (i+q*j)*(cos+sin*j) = (cos*i - sin*q) + (sin*i + cos*q)*j// delay // ============================================================`timescale 1ns/1psmodule cm_mix #( parameter c_data_with = 16 ) // ( input wire i_sys_clk , // 输入时钟 input wire i_rst_in , // 输入复位 高有效 input wire [6:0] i_phase , // 初始相位 input wire [7:0] i_freq , // 频率,步进,1代表1m input wire [c_data_with-1:0] i_data_in_i , // 输入数据 实部i input wire [c_data_with-1:0] i_data_in_q , // 输入除数 虚部q output reg [c_data_with-1:0] o_data_out_i , // 输出数据 实部i output reg [c_data_with-1:0] o_data_out_q );// 输出除数 虚部q // ============================================================// 内部参数// ============================================================// ============================================================// 变量// ============================================================wire [10:0] s_sin_out ;wire [10:0] s_cos_out ;reg [c_data_with-1:0] s_data_in_q ;reg [10:0] s_sin_out_d ;reg [10:0] s_cos_out_d ;wire [47:0] s_pcout_cos_i ;wire [47:0] s_dsp_out_i ;wire [47:0] s_pcout_sin_i ;wire [47:0] s_dsp_out_q ; 然后调用上一篇文章中的nco模块fpga数字信号处理之verilog实现nco(代码及仿真):
cm_nco_100 cm_nco_100 ( .i_sys_clk (i_sys_clk ) , /// 工作时钟 100m .i_rst_n (!i_rst_in ) , /// 复位信号,用来清相位 .i_phase (i_phase ) , /// 初始相位 .i_freq (i_freq ) , /// 频率,步进,1代表1m .o_sin_out (s_sin_out ) , /// 输出正弦值 .o_cos_out (s_cos_out ) /// 输出余弦值); 接着打拍并调用乘法器:
always @(posedge i_sys_clk ) if(i_rst_in) begin s_data_in_q <= 'd0 ; s_sin_out_d <= 'd0 ; s_cos_out_d <= 'd0 ; end else begin s_data_in_q <= i_data_in_q ; s_sin_out_d <= s_sin_out ; s_cos_out_d <= s_cos_out ; end // ============================================================// (cos*i - sin*q)// ============================================================//cos*icm_dsp48e1 #( .c_data_with_a (c_data_with ), .c_data_with_b (11 ), .c_data_with_c (48 ), .c_data_with_d (25 ))u0_cm_dsp48e1( .i_clk (i_sys_clk ) , // clk .i_rst (i_rst_in ) , // rst .i_a (i_data_in_i ) , // [29:0] .i_b (s_cos_out ) , // [17:0] .i_c (48'd0 ) , // [47:0] .i_d (25'd0 ) , // [24:0] .i_pcin (48'd0 ) , // [47:0] 只能直连pcout .i_alumode (4'd0 ) , // [3:0] .i_inmode (5'b00101 ) , // [4:0] .i_opmode (7'b0000101 ) , // [6:0] .o_p ( ) , // [47:0] .o_pcout (s_pcout_cos_i ) // [47:0] 只能直连pcin );//pcin - sin*qcm_dsp48e1 #( .c_data_with_a (c_data_with ), .c_data_with_b (11 ), .c_data_with_c (48 ), .c_data_with_d (25 ))u1_cm_dsp48e1( .i_clk (i_sys_clk ) , // clk .i_rst (i_rst_in ) , // rst .i_a (s_data_in_q ) , // [29:0] .i_b (s_sin_out_d ) , // [17:0] .i_c (48'd0 ) , // [47:0] .i_d (25'd0 ) , // [24:0] .i_pcin (s_pcout_cos_i ) , // [47:0] 只能直连pcout .i_alumode (4'b0011 ) , // [3:0] .i_inmode (5'b00101 ) , // [4:0] .i_opmode (7'b0010101 ) , // [6:0] .o_p (s_dsp_out_i ) , // [47:0] .o_pcout ( ) // [47:0] 只能直连pcin ); // ============================================================// (sin*i + cos*q)// ============================================================//sin*icm_dsp48e1 #( .c_data_with_a (c_data_with ), .c_data_with_b (11 ), .c_data_with_c (48 ), .c_data_with_d (25 ))u2_cm_dsp48e1( .i_clk (i_sys_clk ) , // clk .i_rst (i_rst_in ) , // rst .i_a (i_data_in_i ) , // [29:0] .i_b (s_sin_out ) , // [17:0] .i_c (48'd0 ) , // [47:0] .i_d (25'd0 ) , // [24:0] .i_pcin (48'd0 ) , // [47:0] 只能直连pcout .i_alumode (4'd0 ) , // [3:0] .i_inmode (5'b00101 ) , // [4:0] .i_opmode (7'b0000101 ) , // [6:0] .o_p ( ) , // [47:0] .o_pcout (s_pcout_sin_i ) // [47:0] 只能直连pcin );//pcin + cos*qcm_dsp48e1 #( .c_data_with_a (c_data_with ), .c_data_with_b (11 ), .c_data_with_c (48 ), .c_data_with_d (25 ))u3_cm_dsp48e1( .i_clk (i_sys_clk ) , // clk .i_rst (i_rst_in ) , // rst .i_a (s_data_in_q ) , // [29:0] .i_b (s_cos_out_d ) , // [17:0] .i_c (48'd0 ) , // [47:0] .i_d (25'd0 ) , // [24:0] .i_pcin (s_pcout_sin_i ) , // [47:0] 只能直连pcout .i_alumode (4'b0000 ) , // [3:0] .i_inmode (5'b00101 ) , // [4:0] .i_opmode (7'b0010101 ) , // [6:0] .o_p (s_dsp_out_q ) , // [47:0] .o_pcout ( ) // [47:0] 只能直连pcin ); 最后四舍五入后输出:
/// 四合五入输出always @(posedge i_sys_clk ) if(i_rst_in) begin o_data_out_i <= 'd0; o_data_out_q <= 'd0; end else begin o_data_out_i <= s_dsp_out_i[10+:c_data_with] + s_dsp_out_i[9]; o_data_out_q <= s_dsp_out_q[10+:c_data_with] + s_dsp_out_q[9]; endendmodule
对代码的详细讲解参考b站视频:
【fpga数字信号处理之verilog实现数字混频器】 https://www.bilibili.com/video/bv1hg411b7rb/?share_source=copy_web&vd_source=9736f43bc2eebc284f4fbbe5805247a7
ChatGPT是一个好的因果推理器吗?
led防爆投光灯和防爆泛光灯存在什么区别
国产替代|SE8025T高精度时钟芯片,可替代RX8025T(EPSON),P=P直接替代
Google已关闭了Google的辅助电子邮件应用程序Inbox
SIP协议在嵌入式Linux中的实现
FPGA数字信号处理之verilog实现混频器
数字串在计算机内的表示与存储
地平线车规级高算力计算芯片助力哪吒汽车打造大众消费市场智能化产品
关于讯飞对人机交互的未来的展望
3840×2160P60 30倍会议摄像机解决方案介绍
温控电源的原理是什么
2020年汽车总销量下滑,但电动汽车逆风增长43%
2019人工智能预计投资频数回落至2018年一半
先积集成获评“2023年市级专精特新中小企业”
基于Small RTOS51的营养液输液系统
2023年人工智能大会,让小美AI城看到发展方向
测温仪的定律及原理
各国制造业水平究竟如何、准备是否充分?
多维度强劲提升!研扬新品GENE-ADP6
区块链的特性有怎样的意义