首页›行业资讯›基于ALINX ZYNQ7010核心板的调制信号解调设计
← 返回行业资讯
技术教程

基于ALINX ZYNQ7010核心板的调制信号解调设计

电子发烧友 Elecfans ·
基于ALINX ZYNQ7010核心板实现调制信号解调设计。
本文为原文全文(约 4615 字),原文配图已同步至站内;细节以原文为准。

本设计基于ALINX ZYNQ7010核心板, DAC 904和 AD 9226模块,采用 verilog 语言实现AM、ASK、FM、FSK、PSK调制 信号 的解调和对应参数的估计,同时含有部分框图和步骤解答,相信对电赛辅导和指导毕业设计有一定的帮助。本文只粘贴必要代码,不提供源文件,目的为培养大家的自我探知能力,需要源文件需私信我,同时IP核的配置我也是从各大平台自学的,就不一一赘述,本文只贴出配置参数,不含具体配置步骤,不会配置的请借鉴其他帖子经验。

输入信号分别为AM/FM/ASK/FSK/PSK,所有信号的载频均为1MHz,幅度为10Vpp。设计的具体要求如下:

(1)AM 信号,其正弦调制信号频率 F =1-5kHz。Ma为0.3-0.8,测量并显示该 AM 信号的调幅系数Ma,误差不大于0.1 ;输出解调信号Uo 无明显失真,幅度大于200mV。

(2)FM 信号,其正弦调制信号频率 F =1-5kHz,Mf为2-5,估计并显示该 FM波的调频系数Mf ,误差不大于0.3 ;输出解调信号Uo无明显失真,幅度大于200mV。

(3)ASK/FSK/PSK信号,三者均传输二进制不归零(NRZ)码,码速率 Rc 可为 6kbps、8kbps、10kbps 中的一种;要求装置能够自主识别并显示Um的键控方式,并输出解调后的波形。

4e3276a0-d0fe-11f1-90a1-92fbcf53809c.png
4e3276a0-d0fe-11f1-90a1-92fbcf53809c.png

二、 FPGA 的数据类型简介

在 FPGA 设计中,所有数据均以二进制形式流转。数据位宽的定义需综合考量 算法 动态范围及 接口 器件的物理限制,比如本设计用到的DAC904为14bit(16384深度),就需要开辟[13:0]的位宽,对应模块的14个数据引脚的输出,而AD9226为12bit(4096深度)则需开辟[11:0]的位宽,对应模块的12个数据引脚的输出。此外,在多模块级联传输过程中,由于不同模块对数据精度的要求不同,必须严格进行位宽匹配管理。这通常涉及截位处理以防止数据溢出,或符号位扩展以保留运算精度。合理的位宽规划与截位策略,是保障系统信噪比(SNR)与运算效率的关键。

三、 时钟 (Clocking Wizard IP核)

时钟是FPGA系统的核心。为避免亚稳态并确保数据可靠传输,设计上优先保证各模块时钟同源;对于异步时钟域,则采用FIFO进行缓存处理。针对DAC904与AD9226器件间的频率差异,本设计采取降频策略,将DAC904的工作频率调整至与AD9226一致的65MHz,从而实现全局时钟同步。由于开发板仅提供125MHz板载时钟,因此需利用分频器从中提取所需的65MHz工作时钟。

本设计的Clocking Wizard IP核具体配置参数如下:

4e87f332-d0fe-11f1-90a1-92fbcf53809c.png
4e87f332-d0fe-11f1-90a1-92fbcf53809c.png
4ee0c930-d0fe-11f1-90a1-92fbcf53809c.png
4ee0c930-d0fe-11f1-90a1-92fbcf53809c.png

本设计的AM/ASK解调采用包络解调的方法,具体为:

4f5c45e2-d0fe-11f1-90a1-92fbcf53809c.png
4f5c45e2-d0fe-11f1-90a1-92fbcf53809c.png

AM/ASK解调模块的源码为:

module AM_Demodulation(

input wire clk_65m,

input wire rs t_n,

input wire signed [11:0] data,

output wire [13:0] AM_ASK_data

// ================= 包络提取部分 =================

wire signed [11:0] abs12 = data[11] ? (~data + 1'b1) : data;

wire signed [15:0] abs16 = {abs12, 4'b0000};

wire signed [15:0] lpf_out16;

AM_LPF envelope_fil te r (

.clk_enable(1'b1),

.filter_in(abs16),

.filter_out(lpf_out16)

// assign env_out_16 = lpf_out16;

//================= 输出波形逻辑 =================

reg signed [13:0] AM_ASK_data_reg;

wire signed [13:0] env_for_dac = lpf_out16[15:2];

always @(posedge clk_65m or negedge rst_n) begin

if (!rst_n) begin

AM_ASK_data_reg <= 14'sd0;

AM_ASK_data_reg <= env_for_dac;

wire signed [13:0] AM_g ai n = 14'd20;

wire signed [13:0] AM_ASK_data_reg_out = AM_ASK_data_reg << 4;

assign AM_ASK_data = {~AM_ASK_data_reg_out[13], AM_ASK_data_reg_out[12:0]}-14'd3300;

//.clk(clk_65m), // input wire clk

//.probe0(data), // input wire [11:0] probe0

//.probe1(env_out_16) // input wire [15:0] probe1

整流处理其实非常简单,即取平均值然后补高位到 滤波器 的输入位宽即可。

其中,AM_LPF选用1阶低通IIR巴特沃斯滤波器,采样频率为65000kHz,截止频率为100kHz,具体参数由 matlab 的fdatool工具生成,具体配置已贴出:

4fb111b2-d0fe-11f1-90a1-92fbcf53809c.png
4fb111b2-d0fe-11f1-90a1-92fbcf53809c.png

注意:要设置为直接Ⅱ型转置,二阶节,点击设计滤波器,得到滤波器后点击上方编辑->转换结构->Direct-Form Ⅱ Transposed,SOS,直到滤波器结构转换完成,点击左下角设置量化参数,滤波器算法设为定点,最后点击应用,直到量化完成后再点击上方目标->生成HDL...,打开滤波器生成工具,language选verilog,在Global Set ti ngs里的Reset asserted level设为 Ac tive-low(因为本系统所有复位都是低电平有效),然后选择滤波器生成的位置,找到对应的.v文件即可

500a7388-d0fe-11f1-90a1-92fbcf53809c.png
500a7388-d0fe-11f1-90a1-92fbcf53809c.png

五、VIVADO ROM IP核

ROM 是只读存储器(Read-Only Memory)的简称,是一种只能读出事先所存数据的固态 半导体 存储器。其特性是一旦储存资料就无法再将之改变或删除,且资料不会因为 电源 关闭而消失。而事实上在 FPGA 中通过 IP 核生成的 ROM 或 RAM 调用的都是 FPGA 内部的 RAM 资源,掉电内容都会丢失,用 IP 核生成的 ROM 模块只是提前添加了数据文件(.coe 格式),在 FPGA 运行时通过数据文件给 ROM 模块初始化。https://blog.csdn.net/yishuihanq/article/details/130767125

在基于 DAC904 的正弦波发生架构中,数字域的离散特性决定了 模拟 输出的台阶效应。由于 DAC904 为14bit 分辨率,其数字输入码可表示 =16384个量化等级。结合其 ±5V 的基准量程(峰峰值 10V),系统的最小量化步长(LSB)计算如下:

这意味着,FPGA 每输出一个递增的数字码,模拟电压仅改变约 0.6mV。一个标准的满幅正弦波,其波峰对应 +5V(数字码 16383),波谷对应 -5V(数字码 0 或补码形式),整个周期内将包含 16384 个离散的电平采样点。

波形数据的产生我用的忘记是谁开发的软件了,如有侵权请联系,用matlab直接生成coe文件也可,需注意数据集是有符号类型还是无符号类型。 链接: https://pan.baidu.com/s/1XYoQW VR FX-wA8fMdy-slvA?pwd=1111 提取码: 1111

我们一般用Matlab提前生成需要的波形数据(一般为满幅波形,即与深度相等),存储到coe文件中,在ROM核中进行对应的配置,就可以将波形数据存放到程序之中,之后就可调用了。

该模块采用数字锁相鉴频环路结构,主要包括 数控 振荡器 、鉴相器、低通滤波器以及环路滤波器等部分。

数控振荡器模块:由ROM IP核和相位累加器构成,通过输入的频率控制字和相位控制字控制ROM IP核输出不同频率和相位的余弦参考信号。

鉴相器模块:由乘法器实现,输入信号与本地余弦信号进行相乘运算,产生鉴相器输出,该输出包括低频误差以及两倍频分量,在程序中先对乘法的结果取高位,然后送入滤波器滤去高频部分,只留下相位误差。

低通滤波器模块:依旧1阶低通IIR巴特沃斯滤波器,采样频率为65MHz,截止频率为100kHz。

环路滤波器模块:经过低通滤波后相位误差进入环路滤波器模块,产生频率控制量,此频率控制量同时用于NCO频偏调整以及作为FM/FSK解调结果输出,具体参数(C1、C2)需要根据实际情况进行调节。

module FM_demodulation(

input signed [11:0] data,

output [13:0] FM_FSK_data

// 65MHz采样率下, 1MHz = (1e6/65e6) * 2^32 ≈ 66076419

localparam [31:0] PHASE_STEP_1MHZ = 32'd66076419; // 中心 频率 1MHz

localparam [31:0] INITIAL_FREQ = PHASE_STEP_1MHZ; // 初始频率1MHz

wire [11:0] phase_addra;

wire signed [11:0] cos_out;

wire signed [23:0] pd_mult_out; // 鉴相器(乘法器)输出

wire signed [31:0] freq_control; // 环路滤波器输出(频率控制字)

wire signed [15:0] lpf_out_full; // 低通滤波器输出

wire signed [11:0] phase_error; // 截位后的相位误差

// ================= 环路滤波器模块 =================

// 接收鉴相误差,输出频率控制字控制NCO

loop_filter_FM loop_filter_inst (

.theta(phase_error), // 输入相位误差

.delta(freq_control) // 输出频率调整量 (此信号即为FM解调结果)

// ================= NCO (数控振荡器) =================

PhaseAccumulator nco (

.PhaseOffset(12'd0),

.PhaseStep(INITIAL_FREQ + $unsigned(freq_control)), // 跟踪输入信号频率

.MemAddr(phase_addra)

// 产生本地载波 (FM PLL只需要一路余弦或正弦即可完成鉴相)

rom_sin_12bit cos_rom (

.addra(phase_addra + 12'd1024), // cos相位偏移

.douta(cos_out)

// 将 ROM 输出的无符号偏移二进制码转为有符号二进制补码

阅读原文 →
来源:电子发烧友 Elecfans

本页摘要由 AI 辅助整理,经编辑审核后发布;AI 仅用于提炼与分类,原文均附来源链接。