📄 gsm_duc_cic_model.m
字号:
%*******************************************************************************
% DISCLAIMER OF LIABILITY
%
% This text/file contains proprietary, confidential
% information of Xilinx, Inc., is distributed under license
% from Xilinx, Inc., and may be used, copied and/or
% disclosed only pursuant to the terms of a valid license
% agreement with Xilinx, Inc. Xilinx hereby grants you a
% license to use this text/file solely for design, simulation,
% implementation and creation of design files limited
% to Xilinx devices or technologies. Use with non-Xilinx
% devices or technologies is expressly prohibited and
% immediately terminates your license unless covered by
% a separate agreement.
%
% Xilinx is providing this design, code, or information
% "as-is" solely for use in developing programs and
% solutions for Xilinx devices, with no obligation on the
% part of Xilinx to provide support. By providing this design,
% code, or information as one possible implementation of
% this feature, application or standard, Xilinx is making no
% representation that this implementation is free from any
% claims of infringement. You are responsible for
% obtaining any rights you may require for your implementation.
% Xilinx expressly disclaims any warranty whatsoever with
% respect to the adequacy of the implementation, including
% but not limited to any warranties or representations that this
% implementation is free from claims of infringement, implied
% warranties of merchantability or fitness for a particular
% purpose.
%
% Xilinx products are not intended for use in life support
% appliances, devices, or systems. Use in such applications is
% expressly prohibited.
%
% Any modifications that are made to the Source Code are
% done at the user抯 sole risk and will be unsupported.
%
%
% Copyright (c) 2008 Xilinx, Inc. All rights reserved.
%
% This copyright and support notice must be retained as part
% of this text at all times.
%
%*******************************************************************************
%% gsm_duc_model.m
% This is a model for the multi-carrier(MC) GSM DUC (Digital UpConverter).
% The model attempts to replicate the hardware as much as possible, by
% quantizing appropriately.
%% Set analysis options
if ~exist('ShowPlots')
ShowPlots = 2; % Show filter response and PSD plots
% 0 = None
% 1 = Essential (input, output, etc.)
% 2 = Moderate (Main filter reponses and data nodes)
% 3 = Detailed (selected filter responses)
% 4 = All (include filter design exploration)
end
spec_win = 8192; % Window for Welch spectral estimation
%% Verification parameters
keep_size = 160000; % Size of output vector to keep for verification
% Other vectors are sized accordingly
%% Specify the structural options
use_pfir = 0;
use_cfir = 1;
use_captured_dds_output = 1;
quantize_ideal_sinusoid = 0;
%% Set-up the design parameters
n_carr = 4; % Number of carriers to support
n_ch = n_carr*2; % Number of channels required for carriers
fsym = (1.625e6)/6; % Symbol rate
m_duc = 256; % Total rate change of DUC
fdac = fsym*m_duc; % Sample rate of DAC
clk_os = 4; % Oversampling rate of clock, w.r.t. DAC rate
fclk = fdac*clk_os; % Clock rate, based on specified multiple
m_gmsk = 8; % Oversampling rate of GMSK baseband modulator
if use_pfir==1
m_pfir = 2; % Rate change of Pulse shaping FIR
else
m_pfir = 1; % No PFIR, no rate change
end
m_cfir = 2; % Rate change of CIC Compensation FIR
m_cic = m_duc/m_gmsk/m_pfir/m_cfir; % Rate change of CIC
fs_gmsk = fsym*m_gmsk; % Output sampling frequency of GMSK modulator
fs_pfir = fs_gmsk*m_pfir; % Output sampling frequency of PFIR
fs_cfir = fs_pfir*m_cfir; % Output sampling frequency of CFIR
fs_cic = fs_cfir*m_cic; % Output sampling frequency of CIC
fs_dds = fs_cic; % Sampling frequency of DDS
dds_bits = 21; % Bitwidth of DDS outputs
%% Sysgen model parameters
tsamp=128; % Period of input samples to the model - all other sample
% periods are calculated from this value.
tsim=2e6; % Total simulation time for Sysgen model runs
%% Model parameters
carriers = [ -0.9e6; -0.3e6; 0.3e6; 0.9e6 ]; % Column vector of mixing frequencies
if length(carriers)~=n_carr, error('Not enough values specified in carrier frequency vector!'); end
scale_vector=[ 1.0 1.0 1.0 1.0 ]; % Scale factors for each carrier [0:1]
scale_quant = quantizer('fixed','round','wrap',[18,16]);
scale_vector = quantize(scale_quant,scale_vector);
%% Trim variables
clear scale_quant;
%% Run filter design
[ hcic_duc hcfir_duc hpfir_duc ] = gsm_duc_cic_filters(...
fclk,n_ch,...
fs_cic,m_cic,...
use_cfir,fs_cfir,m_cfir,...
use_pfir,fs_pfir,m_pfir,...
ShowPlots);
%% Generate multi-channel GMSK input
% Run Simulink GMSK model to generate input data
if exist('gmsk_data_comp')
display('Using GMSK data from Workspace');
else
sim('gmsk_mod.mdl',tsim);
gmsk_data_comp = zeros(size(gmsk_data.signals.values,1),n_carr);
for carrier=1:8
gmsk_data_comp(:,carrier) = gmsk_data.signals.values(:,2*carrier-1) + j*gmsk_data.signals.values(:,2*carrier);
end; clear carrier;
% GMSK data is already quantized to [12,11], but this stage ensures it.
gmsk_quant = quantizer('fixed','round','wrap',[12,11]);
gmsk_data_comp = quantize(gmsk_quant,gmsk_data_comp);
end
if ShowPlots>=1
spec=spectrum.welch('Hamming',spec_win,50);
gmsk_psd = psd(spec,gmsk_data_comp(:,1),'Fs',fs_gmsk,'Centerdc',true);
figure;
plot(gmsk_psd.Frequencies/1e3,10.*log10(gmsk_psd.Data/max(gmsk_psd.Data)));
title('GMSK Power Spectral Density');
xlabel('Frequency (kHz)');
ylabel('Relative Power (dB/Hz)');
grid on;
hold on; plot_mcgsm_tx_mask(fs_gmsk/1e3,'kHz',[0]); hold off;
axis([-1000 1000 -100 0]);
end
%% Trim variables
save results/gmsk_data_comp.mat gmsk_data_comp;
clear gmsk_psd gmsk_quant;
%% PFIR;
pfir_quant=quantizer('fixed','convergent','wrap',[17,16]);
yp_duc = filter(hpfir_duc,gmsk_data_comp(:,1:n_carr));
gmsk_data_comp = gmsk_data_comp(1:(keep_size/m_cic/m_cfir/m_pfir),:); % Keep for SG TB
if use_pfir==1
yp_duc=quantize(pfir_quant,yp_duc);
end
if ShowPlots>=2 && use_pfir==1
spec=spectrum.welch('Hamming',spec_win*m_pfir,50);
pfir_psd = psd(spec,yp_duc(:,1),'Fs',fs_pfir,'Centerdc',true);
figure;
plot(pfir_psd.Frequencies/1e3,10.*log10(pfir_psd.Data/max(pfir_psd.Data)));
title('DUC PFIR Output Power Spectral Density');
xlabel('Frequency (kHz)');
ylabel('Relative Power (dB/Hz)');
grid on;
hold on; plot_mcgsm_tx_mask(fs_pfir/1e3,'kHz',[0]); hold off;
axis([-1000 1000 -100 0]);
end
%% Trim variables
clear gmsk_data_comp pfir_quant pfir_psd;
%% CFIR
cfir_quant=quantizer('fixed','convergent','wrap',[18,17]);
yc_duc = filter(hcfir_duc,yp_duc);
yp_duc = yp_duc(1:(keep_size/m_cic/m_cfir),:); % Keep for SG TB
if use_cfir==1
yc_duc=quantize(cfir_quant,double(yc_duc));
end
if ShowPlots>=2 && use_cfir==1
spec=spectrum.welch('Hamming',spec_win*m_pfir*m_cfir,50);
cfir_psd = psd(spec,yc_duc(:,1),'Fs',fs_cfir,'Centerdc',true);
figure;
plot(cfir_psd.Frequencies/1e3,10.*log10(cfir_psd.Data/max(cfir_psd.Data)));
title('DUC CFIR Output Power Spectral Density');
xlabel('Frequency (kHz)');
ylabel('Relative Power (dB/Hz)');
grid on;
hold on; plot_mcgsm_tx_mask(fs_cfir/1e3,'kHz',[0]); hold off;
axis([-1000 1000 -100 0]);
end
%% Trim variables
save results/yp_duc.mat yp_duc;
clear yp_duc cfir_psd cfir_quant;
%% Scaler
scale_matrix = repmat(scale_vector,[n_carr,1]).*eye(n_carr);
scaled_yc_duc = yc_duc*scale_matrix;
%% Trim variables
yc_duc = yc_duc(1:(keep_size/m_cic),:); % Keep for SG TB
save results/yc_duc.mat yc_duc;
clear yc_duc scale_vector scale_matrix;
%% CIC;
ycic_duc = filter(hcic_duc,scaled_yc_duc);
scaled_yc_duc = scaled_yc_duc(1:(keep_size/m_cic),:); % Keep for SG TB
cic_quant=quantizer('fixed','floor','wrap',[18,5]);
ycic_duc = quantize(cic_quant,double(ycic_duc));
ycic_duc_norm = double(ycic_duc)/gain(hcic_duc);
%%ycic_duc = ycic_duc(1:keep_size,:); % Keep for SG TB
%cic_quant=quantizer('fixed','floor','wrap',[18,17]);
%ycic_duc_norm = quantize(cic_quant,double(ycic_duc_norm));
if ShowPlots>=2
spec=spectrum.welch('Hamming',spec_win*m_pfir*m_cfir*m_cic,50);
cic_psd = psd(spec,ycic_duc_norm(:,1),'Fs',fs_cic,'Centerdc',true);
figure;
plot(cic_psd.Frequencies/1e6,10.*log10(cic_psd.Data/max(cic_psd.Data)));
title('DUC CIC Output Power Spectral Density');
xlabel('Frequency (MHz)');
ylabel('Relative Power (dB/Hz)');
grid on;
hold on; plot_mcgsm_tx_mask(fs_cic/1e6,'MHz',[0]); hold off;
axis([-2 2 -100 0]);
end
%% Trim variables
save results/ycic_duc.mat ycic_duc;
save results/scaled_yc_duc.mat scaled_yc_duc;
clear scaled_yc_duc ycic_duc cic_quant cic_psd;
%% DDS
if use_captured_dds_output==1
display('Using captured Xilinx DDS output');
dds_start=697; % Sample offset of DDS at first valid sample for mixing
% Determined empirically from implementation, refer to
% documentation. This value corresponds to an arbitrary
% shift in phase for modelling purposes.
if exist('duc_dds_out')
display('Using captured Xilinx DDS output from Workspace');
else
if exist('duc_dds_out.mat')
load duc_dds_out.mat;
else
sim('duc_dds_capture.mdl',tsim);
save duc_dds_out.mat duc_dds_out;
end
end
dds_tolerance=1e-5;
sinusoid = analyze_duc_dds(duc_dds_out,dds_start,carriers,fs_cic,dds_bits,dds_tolerance,ShowPlots);
else
display('Using ideal sinusoid carriers');
sinusoid = gen_duc_sinusoid(carriers,fs_dds,size(ycic_duc_norm,1),dds_bits);
if quantize_ideal_sinusoid==1
dds_quant = quantizer('fixed','floor','wrap',[dds_bits,dds_bits]);
sinusoid = quantize(dds_quant, sinusoid);
end
end
%% Trim variables
clear duc_dds_out dds_quant ph;
%% Complex Mixer
% Mutiply the iq data matrix by the sinusoid matrix
mix_length = min(size(ycic_duc_norm,1),size(sinusoid,1));
upmixed = ycic_duc_norm(1:mix_length,:).*sinusoid(1:mix_length,:);
%mult_quant = quantizer('fixed','floor','wrap',[18,17]);
%upmixed = quantize(mult_quant,upmixed);
if ShowPlots>=3
spec=spectrum.welch('Hamming',spec_win*m_pfir*m_cfir*m_cic,50);
mixed_psd = psd(spec,upmixed(:,1),'Fs',fs_cic,'Centerdc',true);
figure;
plot(mixed_psd.Frequencies/1e6,10.*log10(mixed_psd.Data/max(mixed_psd.Data)));
title('Up-Converted Single Channel Power Spectral Density');
xlabel('Frequency (MHz)');
ylabel('Relative Power (dB/Hz)');
grid on;
hold on; plot_mcgsm_tx_mask(fs_cic/1e6,'MHz',[ carriers(1)/1e6 ]); hold off;
axis([-2 2 -100 0]);
end
%% Trim variables
ycic_duc_norm = ycic_duc_norm(1:keep_size,:); % Keep for SG TB
save results/ycic_duc_norm.mat ycic_duc_norm;
sinusoid = sinusoid(1:keep_size,:); % Keep for SG TB
save results/sinusoid.mat sinusoid;
clear ycic_duc_norm sinusoid mixed_psd mult_quant mix_length;
%% Multi-channel Summation
mc_upmixed = sum(upmixed,2);
% Quantize summation
sum_quant = quantizer('fixed','floor','wrap',[18,15]);
mc_upmixed=quantize(sum_quant,mc_upmixed);
if ShowPlots>=1
spec=spectrum.welch('Hamming',spec_win*m_pfir*m_cfir*m_cic,50);
mc_mixed_psd = psd(spec,mc_upmixed,'Fs',fs_cic,'Centerdc',true);
figure;
plot(mc_mixed_psd.Frequencies/1e6,10.*log10(mc_mixed_psd.Data/max(mc_mixed_psd.Data)));
title('DUC Multi-Channel Power Spectral Density');
xlabel('Frequency (MHz)');
ylabel('Relative Power (dB/Hz)');
grid on;
hold on; plot_mcgsm_tx_mask(fs_cic/1e6,'MHz',carriers.'/1e6); hold off;
axis([-3 3 -100 0]);
end
%% Trim variables
save results/upmixed.mat upmixed
clear upmixed mc_mixed_psd sum_quant;
%% Save output to file for use with DDC
% Before we save composite_iq, we scale it up to emulate the action of an
% automatic gain control, and prepend a few zeroes to model system latency.
ddc_input = 0.99.*mc_upmixed./max(abs(mc_upmixed));
ddc_input = [ zeros(8,1) ; ddc_input ];
% Save it to a file for use with the DDC model
if (exist('../../ddc/model')), save ../../ddc/model/ddc_input.mat ddc_input; end
if (exist('../../../ddc/model')), save ../../../ddc/model/ddc_input.mat ddc_input; end
% ddc_input_i = real(ddc_input);
% ddc_input_q = imag(ddc_input);
% if (exist('../../ddc/sysgen/v5'))
% save ../../ddc/sysgen/v5/ddc_input.mat ddc_input_i; end
%% Trim variables
clear ddc_input ddc_input_i ddc_input_q ShowPlots tout spec spec_win spec_ord;
mc_upmixed = mc_upmixed(1:keep_size,:); % Keep for SG TB
save results/mc_upmixed.mat mc_upmixed; clear mc_upmixed;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -