基于ZYNQ的双通道矢量信号发生器的数字前端设计零中频架构【附代码】
✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导毕业论文、期刊论文经验交流。✅ 专业定制毕设、代码✅如需沟通交流查看文章底部二维码1基于Golay序列的通道间幅相误差快速校准方案针对零中频架构中双通道发射链路引入的幅度和相位不一致问题设计了基于Golay互补序列的校准模块。Golay128序列具有良好的自相关特性将两通道分别输出该序列后通过单一ADC分时串行接收并经下变频得到基带信号。在校准过程中对接收序列与本地Golay序列进行相关运算由于Golay序列的自相关旁瓣为零相关峰的位置和幅度可精确反映通道时延和增益。利用CORDIC算法从相关峰实虚部计算出幅值比和相位差进而计算补偿系数。整个校准流程在165.92微秒内完成补偿后残余相位误差小于2.5°幅度误差小于0.15dB满足矢量信号发生器的对通道一致性要求。2支持多调制模式的基带信号生成与平方根升余弦滤波在ZYNQ的PL端设计了可灵活配置的多调制模式基带发生器。通过上位机指令可选择BPSK、QPSK、8PSK、16QAM、32QAM、64QAM映射后的符号经过平方根升余弦SRRC成型滤波器滤波器阶数49滚降因子0.35采用多相分解架构实现以降低多速率处理的复杂度。脉冲成型后的I/Q两路数据通过DMA从PS端的DDR3内存中读取波形文件或实时生成再送入AD9361的发射数字接口。AD9361配置为5.11GHz载波12.5MHz带宽输出信号EVM优于2%满足WLAN测试需求。3DDR3波形回放模式与SSH传输控制为了支持任意波形发生设计了波形文件回放模式。PC机通过SSH协议将基带波形文件传输至PS端的Linux系统PS再通过DMA将数据传输至PL端的DDR3控制器。设置了一个两级乒乓缓冲机制每次预先加载两帧数据当一帧数据播放完毕时自动切换到下一帧保证输出不间断。回环测试模式下发射信号经衰减后环回至接收端解调得到的信噪比为38.42dB系统芯片资源利用率LUT为49%BRAM为62%性能良好。import numpy as np import matplotlib.pyplot as plt def golay128_generator(): a [1]; b [1] while len(a) 128: a a b b a [(-1)*x for x in b] return a, b def golay_calibration(ch_a_recv, ch_b_recv, ref_golay): corr_a np.correlate(ch_a_recv, ref_golay, modesame) corr_b np.correlate(ch_b_recv, ref_golay, modesame) peak_idx_a np.argmax(np.abs(corr_a)) peak_idx_b np.argmax(np.abs(corr_b)) complex_gain_a corr_a[peak_idx_a]; complex_gain_b corr_b[peak_idx_b] amp_ratio np.abs(complex_gain_a) / np.abs(complex_gain_b) phase_diff np.angle(complex_gain_a) - np.angle(complex_gain_b) # 校正系数 k_amp 1/amp_ratio; k_phase -phase_diff return k_amp * np.exp(1j*k_phase) # SRRC成型滤波器 def srrc_filter(beta, sps, span): t np.arange(-span*sps, span*sps1) / sps h np.zeros_like(t, dtypefloat) for i, val in enumerate(t): if val 0: h[i] 1 beta*(4/np.pi - 1) elif abs(val) 1/(4*beta): h[i] beta/np.sqrt(2) * ((12/np.pi)*np.sin(np.pi/(4*beta)) (1-2/np.pi)*np.cos(np.pi/(4*beta))) else: h[i] (np.sin(np.pi*val*(1-beta)) 4*beta*val*np.cos(np.pi*val*(1beta))) / (np.pi*val*(1-(4*beta*val)**2)) h / np.sqrt(np.sum(h**2)) return h # 乒乓缓冲控制 class PingPongBuffer: def __init__(self, size): self.buf0 np.zeros(size); self.buf1 np.zeros(size) self.active 0 def fill(self, data, buf_id): if buf_id0: self.buf0 data else: self.buf1 data def read(self): buf self.buf0 if self.active0 else self.buf1 self.active 1 - self.active return buf # AD9361数据接口模拟I/Q 12位 def ad9361_tx(i_data, q_data): return ((i_data.astype(np.int16) 0xFFF) 16) | (q_data.astype(np.int16) 0xFFF)如有问题可以直接沟通
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2584176.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!