接收端
接收端#
发射端发送的光信号在经过光纤信道传输后不仅存在幅度的衰减,还存在由于光纤线性与非线性导致的信号畸变。仿真平台接收端采取一系列DSP算法,包括低通滤波,IQ平衡,色散补偿,自适应滤波,同步,载波相位估计等模块进行修正补偿,完成接收端信息恢复。
接下来介绍在simulation_main函数中有关接收端DSP的代码执行部分。首先通过rx_main.rx函数进入接收端DSP执行阶段。该函数根据接收端参数,对信号进行相应处理,输出信号图像,并最终返回经过接收端DSP处理后的信号序列。之后通过sig_main.sig_rx函数计算信号噪声,并调用相关画图函数画出信号星座图和功率谱密度,至此接收端部分处理完毕。用户可通过调整相应配置文件决定是否画图,保存数据信息。
rx_sig_after_dsp = rx_main.rx(rx_sig, sym_map[rx_para.cut_idx], sym_seq[rx_para.cut_idx], rx_para, plot_para)
sig_para, sig_noise, sig_int = sig_main.sig_rx(rx_sig_after_dsp, sym_map[rx_para.cut_idx],\
bit_seq[rx_para.cut_idx], integer_seq[rx_para.cut_idx], sig_para, plot_para = plot_para)
if sig_para.fig_plot:
plot_para.constellation_points = sig_noise[0].shape[0]
plot_para.front_sym_num = 0
plot_para.get_colour(sig_int)
plot_para.scatter_plot_nPol(sig_noise, sam_num = 1, name = 'Noise_After_DSP', set_c = 0)
plot_para.psd_nPol(sig_noise, name = 'Noise_PSD_After_DSP')
if rx_para.infor_print:
print('---------------- Rx DSP finished ----------------')
生成的信号噪声图像如下所示。
下面详细介绍接收端DSP处理流程,该部分集成在rx_main.rx函数中。同样地,用户可通过调整相应配置文件来决定是否启用某个DSP模块,也可按照示例编写自己的DSP算法嵌入接收端处理流程中。
def rx(rx_sig, sym_map, tx_sig, para, plot_para):
r"""
This function executes signal DSP in receiver.
Parameters: rx_sig: list
Signal sequence of receiver.
sym_map: ndarray
Symbol map.
tx_sig: list
Signal sequence of transmitter.
para:
Receiver parameters, initialized in rxsignal_para.
plot_para:
plot parameters, initialized in sigplot_para.
Return: rx_sig_single: list
The signal sequence of receiver after DSP.
"""
"""
Frontend processing
Multi_sample Compensation
Single_sample Compensation
"""
print_flag = para.infor_print
plot_flag = para.fig_plot
save_flag = para.save_data
data_mode = para.rx_data_mode
# Get started
if save_flag:
pol_name = ['x', 'y']
for i_p in range(para.nPol):
name = 'before_dsp_'+ pol_name[i_p]
para.save_data_func(rx_sig[i_p], name)
if print_flag:
print ("Frontend Start ......")
# Frontend processing
rx_sig, para.sam_now = front_end_processing(rx_sig, para)
if plot_flag:
plot_para.scatter_plot_nPol(rx_sig, sam_num = para.sam_now,\
name = 'Constellation_After_Frontend', set_c = 1, s = 4)
plot_para.sam_rate = para.sam_now * para.sym_rate
plot_para.psd_nPol(rx_sig, name = 'PSD_After_Frontend', sign = para.sym_rate*1.1/2)
if print_flag:
print ("Multi-sample Compensation Start ......")
# Multi_sample Compensation
rx_sig_mul, para = mul_sam_comp(rx_sig, sym_map, para, plot_para)
if plot_flag:
if print_flag:
print(' --MIMO plot--')
plot_para.scatter_plot_nPol(rx_sig_mul, sam_num = para.sam_now,\
name = 'Constellation_After_LC', set_c = 1, s = 4)
if para.mimo:
plot_para.loss_plot_nPol(para.mimo_obj.err[:,0,0], para.mimo_obj.err[:,1,0], name = 'MIMO_Loss')
plot_para.firtap_plot_nPol(para.mimo_obj, name = 'MIMO_Tap')
if save_flag:
pol_name = ['x', 'y']
for i_p in range(para.nPol):
name = 'after_cdc_'+ pol_name[i_p]
para.save_data_func(rx_sig_mul[i_p], name)
if print_flag:
print ("Single-sample Compensation Start ......")
# Single_sample Compensation
rx_sig_single, para = single_sam_comp(rx_sig_mul, sym_map, tx_sig, para, plot_para)
if save_flag:
pol_name = ['x', 'y']
for i_p in range(para.nPol):
name = 'after_dsp_'+ pol_name[i_p]
para.save_data_func(rx_sig_single[i_p], name)
return rx_sig_single
进入rx函数执行阶段,首先确定相应保存标识和信号数据类型,之后首先执行Get_started部分,判断是否保存before_dsp的信号序列,并打印执行进度。
# Get started
if save_flag:
pol_name = ['x', 'y']
for i_p in range(para.nPol):
name = 'before_dsp_'+ pol_name[i_p]
para.save_data_func(rx_sig[i_p], name)
if print_flag:
print ("Frontend Start ......")
Frontend Start ......
之后调用front_end_processing函数,执行接收端DSP的前端处理进程,依次对信号进行归一化,低通滤波,降采样,IQ平衡,帧数检查,再次归一化等操作。同时根据标识保存相应信号图像,打印执行进度。
# Frontend processing
rx_sig, para.sam_now = front_end_processing(rx_sig, para)
if plot_flag:
plot_para.scatter_plot_nPol(rx_sig, sam_num = para.sam_now,\
name = 'Constellation_After_Frontend', set_c = 1, s = 4)
plot_para.sam_rate = para.sam_now * para.sym_rate
plot_para.psd_nPol(rx_sig, name = 'PSD_After_Frontend', sign = para.sym_rate*1.1/2)
if print_flag:
print ("Multi-sample Compensation Start ......")
def front_end_processing(rx_sig, para):
r"""
Filter, Downsampling, IQ Balancing, and Normalization
"""
print_flag = para.infor_print
# normalization
if type(rx_sig[0]) == np.ndarray:
rx_sig = np.array(rx_sig).reshape((4, -1))
rx_sig = rx_sig / np.sqrt(np.var(rx_sig, axis = -1, keepdims=True))
rx_sig = rx_sig - np.mean(rx_sig, axis = -1, keepdims=True)
else:
rx_sig = torch.stack((rx_sig[0].real, rx_sig[0].imag,\
rx_sig[1].real, rx_sig[1].imag), dim = 0)
rx_sig = rx_sig / torch.sqrt(torch.var(rx_sig, dim = -1, keepdims=True))
rx_sig = rx_sig - torch.mean(rx_sig, dim = -1, keepdims=True)
# low_pass filter
if para.lpf:
rx_sig = para.lpf_obj(rx_sig)
if print_flag:
print(' --LPF finish--')
rx_sam_x = rx_sig[0] + 1j * rx_sig[1]
rx_sam_y = rx_sig[2] + 1j * rx_sig[3]
# Down sample
rx_sam_x = resample_fft(rx_sam_x, para.block_upsam/para.sam_now)
rx_sam_y = resample_fft(rx_sam_y, para.block_upsam/para.sam_now)
sam_now = para.block_upsam
if print_flag:
print(' --Downsample to {:.1f} sam/sym--'.format(sam_now))
# IQ Imbalance
if para.iq_balance:
rx_sam_x = para.iq_balance_obj(rx_sam_x)
rx_sam_y = para.iq_balance_obj(rx_sam_y)
if print_flag:
print(' --IQ Imbalancing finish--')
# cheak frame
rx_sam_num = int(sam_now * para.frame_sym_num * para.frame_num)
rx_sam_x = rx_sam_x[0: rx_sam_num]
rx_sam_y = rx_sam_y[0: rx_sam_num]
# normalization
rx_sam_x = norm_1d(rx_sam_x, 1)
rx_sam_y = norm_1d(rx_sam_y, 1)
rx_sig = [rx_sam_x, rx_sam_y]
return rx_sig, sam_now
该部分执行完毕后,相应信号图像和执行进度如下所示。
--LPF finish--
--Downsample to 2.0 sam/sym--
--IQ Imbalancing finish--
Multi-sample Compensation Start ......
之后调用mul_sam_comp函数,执行接收端DSP的多倍采样率补偿进程,依次对信号进行色散补偿,自适应滤波等操作。同时根据标识保存相应信号图像,打印执行进度。
# Multi_sample Compensation
rx_sig_mul, para = mul_sam_comp(rx_sig, sym_map, para, plot_para)
if plot_flag:
if print_flag:
print(' --MIMO plot--')
plot_para.scatter_plot_nPol(rx_sig_mul, sam_num = para.sam_now,\
name = 'Constellation_After_LC', set_c = 1, s = 4)
if para.mimo:
plot_para.loss_plot_nPol(para.mimo_obj.err[:,0,0], para.mimo_obj.err[:,1,0], name = 'MIMO_Loss')
plot_para.firtap_plot_nPol(para.mimo_obj, name = 'MIMO_Tap')
if save_flag:
pol_name = ['x', 'y']
for i_p in range(para.nPol):
name = 'after_cdc_'+ pol_name[i_p]
para.save_data_func(rx_sig_mul[i_p], name)
if print_flag:
print ("Single-sample Compensation Start ......")
def mul_sam_comp(rx_sig, sym_map, para, plot_para):
r"""
Chromatic dispersion compensation, Adaptive filter
"""
print_flag = para.infor_print
plot_flag = para.fig_plot
if para.mimo and para.nPol == 1:
raise AttributeError("MIMO Error: Expect two polarization while you use the single polarization !")
# Chromatic Dispersion Compensation
if para.cdcom:
rx_sig = para.cdcom_obj(rx_sig)
if print_flag:
print(' --CDC finish--')
if plot_flag:
plot_para.scatter_plot_nPol(rx_sig, sam_num = para.sam_now,\
name = 'Constellation_After_CDC', set_c = 1, s = 4)
# adaptive filter
if para.mimo:
rx_sig = para.mimo_obj(x = rx_sig[0], y = rx_sig[1], sym_map = sym_map)
else:
rx_sam_x = resample_fft(rx_sig[0], 1/para.sam_now)
rx_sam_y = resample_fft(rx_sig[1], 1/para.sam_now)
rx_sig = [rx_sam_x, rx_sam_y]
para.sam_now = 1
return rx_sig, para
该部分执行完毕后,相应信号图像和执行进度如下所示。
--CDC finish--
--MIMO_TD_2x2 Training Start!
--MIMO_TD_2x2 Training: 100%|████████████████████████████████████████████████████████| 5120/5120 [00:02<00:00, 2053.94it/s]
--MIMO_TD_2x2 Training end with the running time 2.4935 s
--MIMO_TD_2x2 Tracking Start!
--MIMO_TD_2x2 Tracking: 100%|████████████████████████████████████████████████████████| 2560/2560 [00:01<00:00, 1770.15it/s]
--MIMO_TD_2x2 Tracking end with the running time 1.4468 s
--MIMO plot--
Single-sample Compensation Start ......
最后调用single_sam_comp函数,执行接收端DSP的单倍采样率补偿进程,依次对信号进行同步定帧,载波相位估计等操作。同时根据标识保存相应信号图像,打印执行进度。
# Single_sample Compensation
rx_sig_single, para = single_sam_comp(rx_sig_mul, sym_map, tx_sig, para, plot_para)
if save_flag:
pol_name = ['x', 'y']
for i_p in range(para.nPol):
name = 'after_dsp_'+ pol_name[i_p]
para.save_data_func(rx_sig_single[i_p], name)
def single_sam_comp(rx_sig, sym_map, tx_sig, para, plot_para):
r"""
Synchronization, Carrier phase estimation
"""
print_flag = para.infor_print
plot_flag = para.fig_plot
# Synchronization
if para.synchronization:
rx_sig, corr, frame_results = para.synchron_obj(tx_sig, rx_sig)
# Plot
if plot_flag:
plot_para.scatter_plot_nPol(rx_sig, sam_num = para.sam_now,\
name = 'Constellation_After_SYM', set_c = 0, s = 4)
plot_para.corr_plot(corr, name = 'synchronization')
if print_flag:
if para.synchron_obj.mode == '4x4':
print(' --Tx xi_corr:{:.2f} Tx xq_corr:{:.2f} Tx yi_corr:{:.2f} Tx yq_corr:{:.2f}--'.format(\
frame_results[0], frame_results[1], frame_results[2], frame_results[3]))
else:
print(' --Tx x_corr:{:.2f} Tx y_corr:{:.2f} --'.format(\
frame_results[0], frame_results[1]))
print(' --synchronization finished--')
# Carrier phase estimation
if para.cpe:
rx_sig, phase_hat = para.cpe_obj(rx_sig, tx_sig, sym_map = sym_map)
# Plot
if plot_flag:
if print_flag:
print(' --CPE plot--')
plot_para.scatter_plot_nPol(rx_sig, sam_num = para.sam_now,\
name = 'Constellation_After_CPE', set_c = 0, s = 4)
if print_flag:
print(' --CPE finished--')
return rx_sig, para
该部分执行完毕后,相应信号图像和执行进度如下所示。
--Tx xi_corr:121.88 Tx xq_corr:114.82 Tx yi_corr:89.30 Tx yq_corr:92.90--
--synchronization finished--
--CPE_coarse Start!
--CPE_coarse: 100%|██████████████████████████████████████████████████████████████████| 1024/1024 [00:00<00:00, 2373.18it/s]
--CPE_coarse end with the running time 0.4322 s
--CPE plot--
--CPE finished--
至此,接收端DSP进程执行完毕,最终返回恢复后的信号序列。