📄 gsm_ddc_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_ddc_cic_model.m
% This is a model for the multi-carrier(MC) GSM DDC (Digital DownConverter).
% 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 = 1024; % 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 = 1;
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
max_carr = 8; % Max carriers for filter design
n_ch = n_carr*2; % Number of channels required for carriers
max_ch = max_carr*2; % Number of channels required for carriers
fsym = (1.625e6)/6; % Symbol rate
m_ddc = 256; % Total rate change of DDC
fadc = fsym*m_ddc; % Sample rate of ADC
clk_os = 4; % Oversampling rate of clock, w.r.t. ADC rate
fclk = fadc*clk_os; % Clock rate, based on specified multiple
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_ddc/m_pfir/m_cfir; % Rate change of CIC
fs_pfir = fsym*m_pfir; % Input sampling frequency of PFIR
fs_cfir = fs_pfir*m_cfir; % Input sampling frequency of CFIR
fs_cic = fs_cfir*m_cic; % Input sampling frequency of CIC
fs_dds = fs_cic; % Sampling frequency of DDS
dds_bits = 20; % Bitwidth of DDS outputs
%% Sysgen model parameters
tsamp=4; % 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
adc_start = 5; % Start point for processing ADC samples
samp_offset = 1; % Offset in number of input samples between model mixer
% input values and the Sysgen mixer input values
dds_start = (adc_start+samp_offset)*clk_os+1;
% Sample offset of DDS based on start point and sample
% offset defined above.
% This value corresponds to an arbitrary phase
% shift for modelling purposes.
%% Run filter design
[ hcic_ddc hcfir_ddc hpfir_ddc ] = gsm_ddc_cic_filters(...
fclk,max_ch,...
fs_cic,m_cic,...
use_cfir,fs_cfir,m_cfir,...
use_pfir,fs_pfir,m_pfir,...
ShowPlots);
%% Model parameters
carriers = [ -0.9e6; -0.3e6; 0.3e6; 0.9e6 ]; % Column vector of mixing frequencies
if length(carriers)~=n_carr, error('Insufficient 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;
%% Load pre-saved multi-channel input from DUC simulation
if (exist('ddc_input.mat'))
load('ddc_input.mat');
else
error('Input signal file not found!');
end
adc_quant = quantizer('fixed','round','saturate',[16,15]);
adc_output = quantize(adc_quant,ddc_input);
clear ddc_input;
if ShowPlots>=1
spec=spectrum.welch('Hamming',spec_win*m_pfir*m_cfir*m_cic/2,50);
adc_output_psd = psd(spec,adc_output,'Fs',fadc,'Centerdc',true);
figure;
plot(adc_output_psd.Frequencies/1e6,10.*log10(adc_output_psd.Data/max(adc_output_psd.Data)));
title('DDC Input Power Spectral Density');
xlabel('Frequency (MHz)');
ylabel('Relative Power (dB/Hz)');
grid on;
axis([-3 3 -100 0]);
end
%% Trim variables
clear adc_output_psd adc_quant;
%% DDS
if use_captured_dds_output==1
display('Using captured Xilinx DDS output');
if exist('ddc_dds_out')
display('Using captured Xilinx DDS output from Workspace');
else
if exist('ddc_dds_out.mat')
load ddc_dds_out.mat;
else
sim('ddc_dds_capture.mdl',tsim);
save ddc_dds_out.mat ddc_dds_out;
end
end
dds_tolerance=1e-5;
sinusoid = analyze_ddc_dds(ddc_dds_out,dds_start,carriers,fs_cic,dds_bits,dds_tolerance,ShowPlots);
else
display('Using ideal sinusoid carriers');
sinusoid = gen_ddc_sinusoid(carriers,fs_dds,size(adc_output,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 ddc_dds_out dds_quant ph;
%% Complex Mixer
% Chop first few ADC samples to match DDS start point
adc_output=adc_output(adc_start:end);
% Mutiply the iq data matrix by the sinusoid matrix
mix_length = min(size(adc_output,1),size(sinusoid,1));
downmixed = repmat(adc_output(1:mix_length),[1,n_carr]).*sinusoid(1:mix_length,:);
mult_quant = quantizer('fixed','floor','wrap',[17,16]);
downmixed = quantize(mult_quant,downmixed);
if ShowPlots>=3
spec=spectrum.welch('Hamming',spec_win*m_pfir*m_cfir*m_cic,50);
for iii=1:length(carriers)
mixed_psd = psd(spec,downmixed(:,iii),'Fs',fs_cic,'Centerdc',true);
figure;
plot(mixed_psd.Frequencies/1e6,10.*log10(mixed_psd.Data/max(mixed_psd.Data)));
title(sprintf('Down-Converted Power Spectral Density, Carrier %d',iii));
xlabel('Frequency (MHz)');
ylabel('Relative Power (dB/Hz)');
grid on;
axis([-3 3 -100 0]);
end
end
%% Trim variables
sinusoid = sinusoid(1:keep_size,:); % Keep for SG TB
save results/sinusoid.mat sinusoid;
adc_output = adc_output(1:keep_size,:); % Keep for SG TB
save results/adc_output.mat adc_output;
clear adc_output sinusoid mixed_psd mult_quant mix_length;
%% Model-to-Sysgen sample matching at CIC input
% Match up CIC input samples between model and Sysgen implementation
% 5 stages required to be filled, 3 of these come from the difference in
% data sample loading latency in Sysgen, a further two can be achieved by
% removing 2 of the zero samples inserted to model the channel.
% This could also be achieved by providing an initial state to the CIC
% filter function.
downmixed_cic = downmixed(3:end,:);
%% Trim variables
downmixed = downmixed(1:keep_size,:); % Keep for SG TB
save results/downmixed.mat downmixed;
%% CIC
% Perform the CIC filtering
ycic_ddc = filter(hcic_ddc,downmixed_cic);
%cic_quant=quantizer('fixed','floor','wrap',[30,5]);
%ycic_ddc = quantize(cic_quant,double(ycic_ddc));
ycic_ddc_norm = double(ycic_ddc)/gain(hcic_ddc);
%cic_quant=quantizer('fixed','floor','wrap',[18,17]);
%ycic_ddc_norm = quantize(cic_quant,double(ycic_ddc_norm));
if ShowPlots>=2
spec=spectrum.welch('Hamming',spec_win*m_pfir*m_cfir,50);
for iii=1:length(carriers)
cic_psd = psd(spec,ycic_ddc_norm(:,iii),'Fs',fs_cfir,'Centerdc',true);
figure;
plot(cic_psd.Frequencies/1e6,10.*log10(cic_psd.Data/max(cic_psd.Data)));
title(sprintf('DDC CIC Output Power Spectral Density, Channel %d',iii));
xlabel('Frequency (MHz)');
ylabel('Relative Power (dB/Hz)');
grid on;
axis([-3 3 -100 0]);
end
end
%% Trim variables
ycic_ddc = ycic_ddc(1:(keep_size/m_cic),:); % Keep for SG TB
save results/ycic_ddc.mat ycic_ddc;
clear ycic_ddc downmixed cic_quant cic_psd;
%% CFIR
cfir_quant=quantizer('fixed','convergent','wrap',[17,16]);
cfir_quant1=quantizer('fixed','floor','wrap',[37,34]);
% Pad with a single zero sample to match up phases with SG model
ycic_ddc_norm = [ zeros(1,n_carr) ; ycic_ddc_norm ];
%ycic_ddc_norm = ycic_ddc_norm(2:end,:);
yc_ddc = filter(hcfir_ddc,ycic_ddc_norm);
if use_cfir==1
yc_ddc1=quantize(cfir_quant1,double(yc_ddc));
yc_ddc=double(yc_ddc)/2;
yc_ddc=quantize(cfir_quant,double(yc_ddc));
end
if ShowPlots>=2
%spec3=spectrum.welch('Hamming',spec_win*m_pfir,50);
spec=spectrum.burg(64);
for iii=1:length(carriers)
cfir_psd = psd(spec,yc_ddc(:,iii),'Fs',fs_pfir,'Centerdc',true);
figure;
plot(cfir_psd.Frequencies/1e3,10.*log10(cfir_psd.Data/max(cfir_psd.Data)));
title(sprintf('DDC CFIR Output Power Spectral Density, Channel %d',iii));
xlabel('Frequency (kHz)');
ylabel('Relative Power (dB/Hz)');
grid on;
hold on; plot_mcgsm_rx_mask(2*fs_pfir/1e3,'kHz',[0],'slack'); hold off;
axis([-fs_pfir/1e3 fs_pfir/1e3 -100 0]);
end
end
%% Trim variables
% Trim off padded zero sample from CIC output and keep for SG TB
ycic_ddc_norm = ycic_ddc_norm(2:(keep_size/m_cic),:);
save results/ycic_ddc_norm.mat ycic_ddc_norm
clear ycic_ddc_norm cfir_psd cfir_quant;
yc_ddc1 = yc_ddc1(1:(keep_size/m_cic/m_cfir),:); % Keep for SG TB
save results/yc_ddc1.mat yc_ddc1
clear yc_ddc1 cfir_quant1;
%% PFIR;
pfir_quant=quantizer('fixed','convergent','wrap',[18,16]);
yp_ddc = filter(hpfir_ddc,yc_ddc);
if use_pfir==1
yp_ddc=double(yp_ddc)/1; % No scaling of PFIR coefficients
yp_ddc=quantize(pfir_quant,double(yp_ddc));
end
if ShowPlots>=2
%spec2=spectrum.welch('Hamming',spec_win,50);
spec=spectrum.burg(64);
for iii=1:length(carriers)
pfir_psd = psd(spec,yp_ddc(:,iii),'Fs',fsym,'Centerdc',true);
figure;
plot(pfir_psd.Frequencies/1e3,10.*log10(pfir_psd.Data/max(pfir_psd.Data)));
title(sprintf('DDC PFIR Output Power Spectral Density, Channel %d',iii));
xlabel('Frequency (kHz)');
ylabel('Relative Power (dB/Hz)');
grid on;
hold on; plot_mcgsm_rx_mask(2*fsym/1e3,'kHz',[0],'slack'); hold off;
axis([-fsym/1e3 fsym/1e3 -100 0]);
end
end
%% Trim variables
yc_ddc = yc_ddc(1:(keep_size/m_cic/m_cfir),:); % Keep for SG TB
save results/yc_ddc.mat yc_ddc
clear yc_ddc pfir_quant pfir_psd;
%% Scaler
scale_matrix = repmat(scale_vector,[n_carr,1]).*eye(n_carr);
scaled_yp_ddc = yp_ddc*scale_matrix;
%% Trim variables
yp_ddc = yp_ddc(1:(keep_size/m_cic/m_cfir/m_pfir),:); % Keep for SG TB
save results/yp_ddc.mat yp_ddc
clear yp_ddc
%% Save output to file for analysis
save results/ddc_output.mat scaled_yp_ddc;
scaled_yp_ddc = scaled_yp_ddc(1:(keep_size/m_cic/m_cfir/m_pfir),:); % Keep for SG TB
save results/scaled_yp_ddc.mat scaled_yp_ddc
clear scaled_yp_ddc iii ShowPlots tout spec spec_win spec_ord;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -