详细程序及原理参考原文:

FPGA学习(二)——实现AM信号调制与解调 - 子木的文章 - 知乎 https://zhuanlan.zhihu.com/p/37203478

  1. 使用的软件是Vivado 2016.4
  2. 实验室板卡是Nexys Video

一、写在前面

仿真可实现,VIO可用。

1.本篇记录的是如何进行AM信号的调制与解调,

其主要步骤包括:

  1. 分频器(Frequency divider)的产生
  2. 载波信号(Carrier signal)的产生
  3. 调制信号(Modulated signal)的产生
  4. 含直流分量(DC component)的调制信号
  5. 已调信号(Modulated signal)的产生
  6. 相干解调(Coherent demodulation)
  7. 滤除直流分量(DC component)
  8. 中间还有截位操作

2.关于截位:

在FPGA中,随着信号处理的层次加深,对信号进行乘、累加、滤波等运算后,可能输入时仅为8位位宽的信号会扩展成几十位位宽,位宽越宽,占用的硬件资源就越多,但位宽超过一定范围后,位宽的增宽并不会对处理精度带来显著的改善,这时就需要对信号进行截位。

3.关于滤波器设计

两种方法:

一是相干解调时需要低通滤波器;

二是可采用对已调信号取绝对值的方式(包络检波)也需要低通滤波器。

二、对过程的要求:

(1)载波信号频率范围:1M-10MHz,分辨率0.01MHz;

(2)调制信号为单频正弦波信号,频率范围:1kHz-10kHz,分辨率0.01kHz;

(3)调制深度0-1.0,步进0.1,精度优于5%;

(4)调制信号和解调信号位宽为___8___位,其他信号位宽自定义,解调误差优于1%(可利用MATLAB对数据进行验证);

三、原理分析

1.调制与解调原理

//已调信号输出:out=Add_1_out*dds_zb_out

//含直流分量的调制信号:Add_1_out=mult_1_out+1280(8位调制信号的幅值)

//可控的直流分量输出:mult_1_out=dds_tz_out*ma(Ma/10为调制深度)

//载波信号输出:DDS>>dds_compiler_zb>>dds_zb_out>>频率控制字fre_word_zb,16bits,输出位宽8bits

//无直流分量的调制信号输出:DDS>>dds_compiler_tz>>dds_tz_out>>频率控制字fre_word_tz,16bits,输出位宽8bits

2.根据要求设计信号参数

1)载波信号频率范围:1M-10MHz,分辨率0.01MHz

DDS工作时钟选择40MHz,dds_zb_out:频率控制字16位,输出8位,原理见:

子木:FPGA学习(一)——产生频率可控的正弦波​zhuanlan.zhihu.com

(2)调制信号为单频正弦波信号,频率范围:1kHz-10kHz,分辨率0.01kHz

DDS工作时钟选择10MHz,dds_tz_out:频率控制字为16位,输出8位

(3)调制深度0-1.0,步进0.1,精度优于5%;

ma定义就不多说了,这里得到的方法是在已知调制信号输出位宽的前提下(已调信号幅值绝对值为128)

其中Ma取值为1~10,之间的整数。

(4)调制信号和解调信号位宽为___8___位,其他信号位宽自定义,解调误差优于1%(可利用MATLAB对数据进行验证);

使用截位的方法,使解调信号输出8位。

四、分频器(Frequency divider)设计

由于DDS工作时钟选择40MHz,将100MHz分为40MHz和10MHz即可。详见下面这篇中的分频器设计部分:

子木:FPGA学习(一)——产生频率可控的正弦波​zhuanlan.zhihu.com

五、产生载波信号(Carrier signal)

1.实现方式:DDS IP核

2.变量名:

工作时钟:clk_40m

载波频率控制字:fre_word_zb

载波输出信号:dds_zb_out

原理见上一篇!

六、产生无直流分量(DC component)调制信号(Modulated signal)

1.实现方式:DDS IP核

2.变量名:

工作时钟:clk_10m

调制信号频率控制字:sfre_word_tz

无直流分量的调制信号输出:dds_tz_out

原理见上一篇!

七、产生含直流分量的调制信号

1.由Ma控制调制信号,再加上固定的直流分量即可。

ma  dds_tz_out+1280。

2.实现方式:乘法器 IP核:mult_1和加法器IP核:Add

3.变量名:

调制深度控制变量:ma

Ma控制的调制信号输出:mult_1_out

直流分量:1280

含直流分量的调制信号输出:Add_1_out

八、输出已调信号(Modulated signal)

1.载波与含直流分量的调制信号相乘

2.实现方式:乘法器IP核:mult_2

3.变量名:

含直流分量的调制信号输入:Add_1_out

载波输入信号:dds_zb_out

已调信号输出:out

九、相干解调(或包络检波)(Coherent demodulation)

1.相干解调:载波与已调信号相乘

1.2实现方式:乘法器IP核:DM_Mul

1.3变量名:

已调信号输入:AM_out

载波输入信号:carrier_out

解调信号输出:DM_out

2.包络检波:对输出的已调波截位为8位,再取绝对值。

2.1实现方式:取绝对值

2.2变量名:

截位输出:AM_out_clk(8位)

取绝对值后的输出:AM_abs(8位)

十、滤除高频分量(High frequency component)

1.FIR低通滤波器:设置阶数和输入输出信号位宽

2.实现方式:

2.1 MATLAB生成coe文件

2.2 FIR IP核:fir

3.变量名:

滤波器输信号:{8'b0,AM_abs} (由设置输入信号位宽决定)

滤波器输出信号:signal_dm

十一、对滤波器输出信号进行截位

reg [7:0] signal_dm_8;
always @ (posedge sysclk)
beginsignal_dm_8 <= signal_dm[21:14];
end

十二、滤除直流

1.根据波形,设置可由vio控制的变量,改变输出的解调信号,使解调误差最低。

2.具体原理见程序

十三、VIO设置

四个通过vio控制的输入变量:

调制深度:ma

载波频率控制字:fre_word_zb

调制信号频率控制字:fre_word_tz

解调信号中的直流:dc

消除失真的参数:Au

十四、ILA设置

1.需要用ila观测的输出(括号里的变量)

滤波器输出信号// .probe5(signal_dm)

调制信号// .probe0(dds_tz_out), // input wire [7:0] probe0

已调信号的截位输出// .probe1(AM_out_clk), // input wire [7:0] probe1

滤波器输出信号的截位输出// .probe2(signal_dm_8), // input wire [7:0] probe2

去除直流的解调信号// .probe3(signal_dm_8_ac), // input wire [7:0] probe3

无失真的解调信号// .probe4(signal_dm_8_ac_ma), // input wire [7:0] probe4

2.ila观测深度应尽量大才能更好的观察波形

十三、仿真波形

下面是单独ma=1时的输出,截位还未来得及修改。

十三、所有代码

1.主程序

`timescale 1ns / 1ps
//
// Company:
// Engineer: 子木QQ2417677728
//
// Create Date: 2018/05/26 15:48:17
// Design Name:
// Module Name: LSY_2015105408
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module LSY_2015105408(input wire sysclk,
input wire [15:0] fre_word_zb,//610.3515625
input wire [15:0] fre_word_tz,//152.58789062
input wire [3:0] ma,
output wire [20:0] out  );wire clk_40m;wire clk_10m;clk_wiz_0 clk(// Clock out ports.clk_out1(clk_40m),     // output clk_out1.clk_out2(clk_10m),     // output clk_out2// Clock in ports.clk_in1(sysclk));      // input clk_in1//         wire [15 : 0] fre_word_zb;     //下载恢复wire [7 : 0] dds_zb_out;dds_compiler_zb dds_zb (.aclk(clk_40m),                                // input wire aclk.s_axis_phase_tvalid(1),  // input wire s_axis_phase_tvalid.s_axis_phase_tdata(fre_word_zb),    // input wire [15 : 0] s_axis_phase_tdata.m_axis_data_tvalid(m_axis_data_tvalid),    // output wire m_axis_data_tvalid.m_axis_data_tdata(dds_zb_out)      // output wire [7 : 0] m_axis_data_tdata);//          wire [15 : 0] fre_word_tz;     //下载恢复wire [7 : 0] dds_tz_out;dds_compiler_tz dds_tz (.aclk(clk_10m),                                // input wire aclk.s_axis_phase_tvalid(1),  // input wire s_axis_phase_tvalid.s_axis_phase_tdata(fre_word_tz),    // input wire [15 : 0] s_axis_phase_tdata.m_axis_data_tvalid(m_axis_data_tvalid),    // output wire m_axis_data_tvalid.m_axis_data_tdata(dds_tz_out)      // output wire [7 : 0] m_axis_data_tdata);//            wire    [3:0]   ma;              //下载恢复wire    [11:0]   mult_1_out;                                                                                        //修改位宽mult_1 mult_1 (.CLK(sysclk),  // input wire CLK.A(ma),      // input wire [3 : 0] A.B(dds_tz_out),      // input wire [7 : 0] B                                                                 //修改位宽.P(mult_1_out)      // output wire [11 : 0] P                                                                //修改位宽);wire    [12:0]   Add_1_out;Add Add_1 (.A(mult_1_out),      // input wire [11 : 0] A                                                                //修改位宽.B(12'd1280),      // input wire [11 : 0] B.CLK(sysclk),  // input wire CLK.S(Add_1_out)      // output wire [12 : 0] S                                                                 //修改位宽);
//        wire   [20:0]     out;             //下载恢复  mult_2 mult_2 (.CLK(sysclk),  // input wire CLK.A(Add_1_out),      // input wire [12 : 0] A                                                                //修改位宽.B(dds_zb_out),      // input wire [7 : 0] B                                                                  //修改位宽.P(out)      // output wire [20 : 0] P                                                                         //修改位宽);
reg [7:0] AM_out_clk;always @ (posedge sysclk)beginAM_out_clk <= {out[20],out[18:12]};end reg [7:0] AM_abs;
always @ (posedge sysclk)beginif(AM_out_clk[7])AM_abs<= {1'b0,~AM_out_clk[6:0]};elseAM_abs <= AM_out_clk;endwire [31 : 0] signal_dm;
fir fir (.aclk(sysclk),                              // input wire aclk.s_axis_data_tvalid(1),  // input wire s_axis_data_tvalid.s_axis_data_tready(s_axis_data_tready),  // output wire s_axis_data_tready.s_axis_data_tdata({8'b0,AM_abs}),    // input wire [15 : 0] s_axis_data_tdata.m_axis_data_tvalid(m_axis_data_tvalid),  // output wire m_axis_data_tvalid.m_axis_data_tdata(signal_dm)    // output wire [31 : 0] m_axis_data_tdata
);
reg [7:0] signal_dm_8_ac;
reg [7:0] signal_dm_8;
always @ (posedge sysclk)
beginsignal_dm_8 <= signal_dm[21:14];signal_dm_8_ac <= signal_dm_8 - (6'd46) ;
end//wire [7:0] dc;
//always @ (posedge sysclk)
//beginsignal_dm_8_ac <= signal_dm_8 - dc ;
//    signal_dm_8_ac <= signal_dm_8 - (6'd32) ;
//endreg [7:0] signal_dm_8_ac_ma;
always @ (posedge sysclk)
begin
//    signal_dm_8_ac_ma <= signal_dm_8_ac*Au  ;signal_dm_8_ac_ma <= signal_dm_8_ac*(3'd5)  ;
end//vio_0 vio (
//  .clk(sysclk),                // input wire clk
//  .probe_out0(ma),  // output wire [3 : 0] probe_out0
//  .probe_out1(fre_word_zb),  // output wire [15 : 0] probe_out1
//  .probe_out2(fre_word_tz),  // output wire [15 : 0] probe_out2
//  .probe_out3(dc),  // output wire [7 : 0] probe_out3
//  .probe_out4(Au)  // output wire [7 : 0] probe_out4
//);//ila_0 ila (
//  .clk(sysclk), // input wire clk//   .probe0(dds_tz_out), // input wire [7:0]  probe0
//  .probe1(AM_out_clk), // input wire [7:0]  probe1
//  .probe2(signal_dm_8), // input wire [7:0]  probe2
//  .probe3(signal_dm_8_ac), // input wire [7:0]  probe3
//  .probe4(signal_dm_8_ac_ma), // input wire [7:0]  probe4
//  .probe5(signal_dm) // input wire [31:0]  probe5
//);endmodule

2.仿真程序

`timescale 1ns / 1psmodule tb();reg sysclk;reg     [3:0]     Ma;reg     [15 : 0]  word_zb;reg     [15 : 0]  word_tz;wire    [20 : 0]  out;LSY_2015105408 test(.sysclk(sysclk),.ma(Ma),.fre_word_zb(word_zb),.fre_word_tz(word_tz),.out(out));initialbeginsysclk = 0;forever#5 sysclk = ~sysclk;endinitialbegin#0 word_zb = 16'd16384; word_tz = 16'd13;Ma = 4'd5;end
endmodule

3.约束文件

set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports sysclk]create_clock -period 10.000 -name sysclk -waveform {0.000 5.000} [get_ports *sysclk*]

基于FPGA的AM信号调制与解调详细步骤相关推荐

  1. matlab进行fm调制与解调,基于matlab的fm信号调制与解调.doc

    基于matlab的fm信号调制与解调.doc 调制就是将基带信号的频谱搬移到信道通带中或者其中的某个频段上的过程,而解调是将信道中来的频带信号恢复为基带信号的反过程.调制的目的是把要传输的模拟信号或数 ...

  2. fsk调制matlab 仿真,基于MATLAB对FSK信号调制与解调的仿真

    基于MATLAB对FSK信号调制与解调的仿真 基于 MATLAB 对 FSK 信号调制与解调的仿真摘要 Matlab 平台的著名仿真环境 Simulink 作为一种种专业和功能强大且操作简单的仿真工具 ...

  3. 基于Matlab的SSB信号调制和解调(内附源码)

    详细原理可参考课设报告:基于matlab的SSB信号调制.传输.解调的仿真-行业报告文档类资源-CSDN下载 调制采用了滤波法和相移法. 代码中有注释,无子函数,可以直接运行. 压缩包中包含了具体的课 ...

  4. 信号的调制与解调matlab仿真,基于MATLAB对信号调制与解调的仿真

    基于MATLAB对信号调制与解调的仿真 2.3 2PSK的基本原理和调制解调实现 数字相移键控,记作PSK(Phase shift-keying ),二进制相位键控记作2PSK. 2PSK就是根据基带 ...

  5. 基于matlab的ldpc编码的构造,基于LDPC编码的GMSK调制与解调及matlab仿真实现(含录像)...

    基于LDPC编码的GMSK调制与解调及matlab仿真实现(含录像)(开题报告,论文10700字,程序代码,录像) 摘 要 随着无线通信技术的不断发展与进步,数字电视广播.移动视频点播等对数据吞吐量要 ...

  6. 基于MATLAB的AM的调制与解调

    基于MATLAB的AM的调制与解调 然后是解调,解调分两步,一步是将调制好的信号与本地载波相乘(与载波同频),然后在通过一个低通滤波器,最后就把信号恢复了. 上面就直接是调制好的信号与本地载波相乘.至 ...

  7. 基于FPGA的通信信号源设计

    verilog实现基于FPGA的通信信号源设计 要求: 能够发射正弦波 对发出的正弦波进行2ask,2fsk,2psk,2dpsk调制 调制时用到PN序列(伪随机序列) 步骤: 第一步:产生两个频率不 ...

  8. 基于matlab实现MSK的调制与解调

    基于matlab实现MSK的调制与解调 1.MSK 2.matlab代码实现MSK调制与解调 filter的创建 3.实验结果 1.MSK 最小频移键控MSK (Minimum Shift Keyin ...

  9. 傅里叶变换应用——信号调制与解调

    傅里叶变换的典型应用主要用于通信的信号调制与解调,信号调制的目的是将信号进行变换,使其便于传输.频率调制是将低频信号调制到高频载波信号上.同步信号解调是接受系统产生同步的高频载波信号进行解调,从调制信 ...

最新文章

  1. Go 学习笔记(46)— Go 标准库之 fmt(输入/输出格式化参数、Printf/Fprintf/Sprintf区别、Println/Fprintln/Sprintln 区别)
  2. IRNet:弱监督实例分割 | 步步为营,隔山打牛
  3. OMG!我居然把新首页设计出来了!
  4. ARM与RISC-V之争,后起之秀的优势在哪儿?
  5. 餐巾计划问题 线性规划与网络流24题之10 费用流
  6. mac 雪豹 10.6 五国
  7. tcpdump源码分析——抓包原理
  8. Equals 和 == 的区别
  9. Spring 三种注入方式
  10. weblogic概览下的上下文根配置_Weblogic服务下获取上下文路劲问题
  11. 从命令式功能到纯功能性,然后再返回:Monads与范围内的延续
  12. c语言中for优化,c – 在For循环中发生了什么GCC优化?
  13. Cocos Shader入门基础六:平面、双面材质与自定义裁剪面 来自虚空的龙
  14. css实现背景图片透明内容不透明
  15. Android VideoView 循环播放视频
  16. 我的框架-Unity3d中的用户数据储存模块UserDB
  17. 如何给自己的公司做一个网站
  18. 4. DBSCAN方法及其应用
  19. Java面向对象编程-模拟购物车模块
  20. 魔法少女 LJJ——线段树

热门文章

  1. 基于长度特征的三文鱼好sea bass的区分,sesbass 比三文鱼长
  2. 万向节死锁 gimbal lock
  3. CSS---内外边距
  4. mysql内存不断被占用,导致每隔一个多月就自动重启,修改数据库配置后,问题解决...
  5. 【Python】 linux中python命令的命令行参数
  6. python统计httpd 进程的内存占用百分比
  7. eclipse 拨打电话、拨号,发短信
  8. String、StringBuilder和StringBuffer
  9. 嵌入式Linux中I2C设备驱动程序的研究与实现
  10. 《C#高级编程》笔记系列第一弹-开篇