- Added utilities for frequency planning

- Changed freq plane to: Fs 4096, int/dec 8X, Mixers 768
This commit is contained in:
canisio
2026-03-27 12:50:10 -03:00
parent d5bbdfb435
commit 584db6233c
22 changed files with 838 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="design"/>
</Category>
</Info>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="txspectrum.m" type="File"/>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="design"/>
</Category>
</Info>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="plotspectrum.m" type="File"/>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="design"/>
</Category>
</Info>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="rxadcfs.m" type="File"/>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="design"/>
</Category>
</Info>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="ntext4.m" type="File"/>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="design"/>
</Category>
</Info>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="programBoard.m" type="File"/>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="design"/>
</Category>
</Info>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="rxspectrum.m" type="File"/>

Binary file not shown.

81
utilities/ntext4.m Normal file
View File

@@ -0,0 +1,81 @@
function t=ntext4(x,y,txt,NVargs)
arguments
x (1,1) double
y (1,1) double
txt string = ""
end
arguments
NVargs.?matlab.graphics.primitive.Text
end
varargin = namedargs2cell(NVargs);
t=text(x,y,txt,varargin{:});
% A variable to distinguish if the User changed the font size or these
% functions.
addprop(t,"ResizingText_changingFontSize");
%The original sizes needed for the calculation
addprop(t,"ResizingText_rFontSize");
addprop(t,"ResizingText_rFontUnits");
addprop(t,"ResizingText_origAxisSize");
% A listener to listen for changes in the axes size
addprop(t,"ResizingText_axisL");
t.ResizingText_changingFontSize = false; % Since we are building it we
% aren't yet changing the size
t.CreateFcn = @(S,~) initializeListeners(S);
initializeListeners(t)
end
function initializeListeners(t)
fontSizeListenerCB(t); % Stores values since we aren't change size.
a = t.Parent;
axisL = listener(a,"SizeChanged", @(~,~) axesListenerCB(t));
t.ResizingText_axisL=axisL;
addlistener(t,"FontSize","PostSet", @(~,~) fontSizeListenerCB(t));
addlistener(t,"Parent","PostSet", @(~,~) parentListenerCB(t));
end
function axesListenerCB(t)
a = t.Parent;
axesUnits = a.Units;
fontUnits = t.FontUnits;
a.Units = "pixels";
t.FontUnits = t.ResizingText_rFontUnits;
rFontSize = t.ResizingText_rFontSize;
axSize = t.ResizingText_origAxisSize;
curhsize = axSize(3);
curvsize = axSize(4);
t.ResizingText_changingFontSize=true;
t.FontSize = min(rFontSize*a.Position(3)/curhsize,rFontSize*a.Position(4)/curvsize);
t.ResizingText_changingFontSize=false;
t.FontUnits = fontUnits;
a.Units = axesUnits;
end
function fontSizeListenerCB(t)
if ~t.ResizingText_changingFontSize
t.ResizingText_rFontSize = t.FontSize;
t.ResizingText_rFontUnits = t.FontUnits;
if ~isempty(t.Parent)
a = t.Parent;
aUnits = a.Units;
a.Units = "pixels";
t.ResizingText_origAxisSize = t.Parent.Position;
a.Units = aUnits;
end
end
end
function parentListenerCB(t)
a = t.Parent;
aUnits = a.Units;
a.Units = "pixels";
t.ResizingText_origAxisSize = t.Parent.Position;
a.Units = aUnits;
end

58
utilities/plotspectrum.m Normal file
View File

@@ -0,0 +1,58 @@
function h = plotspectrum(type, centers, bandwidth, color, unit, varargin)
for n = 1:numel(centers)
center = centers(n);
switch type
case 'sym'
x = [-1, -1, 0, 1, 1] * (bandwidth/2) + center;
y = [ 0, 0.5, 1, 0.5, 0];
case 'asym'
x = [-1, -1, 1, 1] * (bandwidth/2) + center;
y = [0, 0.5, 1, 0];
case 'asymflip'
x = [-1, -1, 1, 1] * (bandwidth/2) + center;
y = [0, 1, 0.5, 0];
otherwise
error('Invalid type.');
end
switch unit
case 'Hz'
factor = 1;
case 'kHz'
factor = 1e3;
case 'MHz'
factor = 1e6;
case 'GHz'
factor = 1e9;
otherwise
error('Invalid unit');
end
tmp = patch(x/factor, y, color, varargin{:});
if n == 1
h = tmp;
else
h = [h, tmp]; %#ok<AGROW>
end
end
switch unit
case 'Hz'
xlabel('Frequency (Hz)', 'FontWeight', 'bold')
case 'kHz'
xlabel('Frequency (kHz)', 'FontWeight', 'bold')
case 'MHz'
xlabel('Frequency (MHz)', 'FontWeight', 'bold')
case 'GHz'
xlabel('Frequency (GHz)', 'FontWeight', 'bold')
otherwise
error('Invalid unit');
end
a = gca;
a.XAxis.FontWeight = 'bold';
end

15
utilities/programBoard.m Normal file
View File

@@ -0,0 +1,15 @@
%% Manual Board Solution Files Download
h = zynq('linux','192.168.1.101');
h.putFile('design_1_wrapper.bit','/mnt');
h.putFile('soc_prj.output.dtb','/mnt');
h.putFile('RF_Init.cfg','/mnt');
h.putFile('init.sh','/mnt');
%%
h.system('fw_setbitstream /mnt/design_1_wrapper.bit');
h.system('fw_setdevicetree /mnt/soc_prj.output.dtb');
pause(0.1)
h.system('cp /mnt/RF_Init.cfg /mnt/hdlcoder_rd/RF_Init.cfg');
h.system('reboot');

91
utilities/rxadcfs.m Normal file
View File

@@ -0,0 +1,91 @@
function T = rxadcfs(fl, fh, mts)
%Use this function to find allowable frequencies
%
%%
% SYNTAX: T = rxadcfs(fl, fh, mts(optional));
%
% DESCRIPTION: Apply the bandpass sampling theorem and Nyquist sampling theorem
% to calculate all good sampling rates to avoid spectral overlap.
%
% INPUT: - fl (real double)
% Lowest frequency of the real-valued bandpass signal. Unit =
% Hz.
%
% - fh (real double)
% Highest frequency of the real-valued bandpass signal. Unit =
% Hz.
% - mts set to 1 to limit results for use with multi tile
% sync enables
%
% OUTPUT: - T (table)
% Table of all good sampling rates. Valid columns are:
%
% T.theory = either 'Bandpass' (for Bandpass sampling theorem)
% or 'Nyquist' (for Nyquist sampling theorem).
%
% T.n = n is variable in the Bandpass sampling theorem and n
% is an integer. n is NaN for Nyquist sampling theorem.
%
% T.Fs_LO_Hz = lowest sampling rate in Hz.
%
% T.Fs_HI_Hz = highest sampling rate in Hz.
%
%% Initialize s.
s = struct;
s.Theory = categorical({});
s.n = [];
s.Fs_LO_Hz = [];
s.Fs_HI_Hz = [];
if (nargin == 3) && mts == 1
mtsList = [737.28, 1474.56, 1966.08, 2457.6, 2949.12, 3072, 3932.16, 4669.44, 4915.2, 5898.24, 6144];
%% Bandpass Sampling Theorem. Calculate all good sampling rates.
for n = floor(fh / (fh - fl)) : -1 : 2
% look for valid mts frequencies only if selected
for mtsIndex = 1:length(mtsList)
if mtsList(mtsIndex)*1e6 >= 2 * fh / n && mtsList(mtsIndex)*1e6 <= 2 * fl / (n - 1)
s.Theory(end+1, 1) = 'Bandpass';
s.n(end+1, 1) = n;
s.Fs_LO_Hz(end+1, 1) = mtsList(mtsIndex);%2 * fh / n;
s.Fs_HI_Hz(end+1, 1) = mtsList(mtsIndex);%2 * fl / (n - 1);
end %if mtsList...
end %for mtsIndex...
end %for n = floor...
else
%% Bandpass Sampling Theorem. Calculate all good sampling rates.
for n = floor(fh / (fh - fl)) : -1 : 2
s.Theory(end+1, 1) = 'Bandpass';
s.n(end+1, 1) = n;
s.Fs_LO_Hz(end+1, 1) = 2 * fh / n;
s.Fs_HI_Hz(end+1, 1) = 2 * fl / (n - 1);
end
end
if (nargin == 3) && mts == 1
mtsList = [737.28, 1474.56, 1966.08, 2457.6, 2949.12, 3072, 3932.16, 4669.44, 4915.2, 5898.24, 6144];
%% Nyquist Sampling Theorem. Calculate all good sampling rates.
for mtsIndex = 1:length(mtsList)
if mtsList(mtsIndex)*1e6 >= 2 * fh && mtsList(mtsIndex)*1e6 <= inf
s.Theory(end+1, 1) = 'Nyquist';
s.n(end+1, 1) = NaN;
s.Fs_LO_Hz(end+1, 1) = mtsList(mtsIndex);%2 * fh;
s.Fs_HI_Hz(end+1, 1) = mtsList(mtsIndex);%Inf;
end
end
else
%% Nyquist Sampling Theorem. Calculate all good sampling rates.
s.Theory(end+1, 1) = 'Nyquist';
s.n(end+1, 1) = NaN;
s.Fs_LO_Hz(end+1, 1) = 2 * fh;
s.Fs_HI_Hz(end+1, 1) = Inf;
end
%% Convert s to T.
T = struct2table(s);
end

301
utilities/rxspectrum.m Normal file
View File

@@ -0,0 +1,301 @@
function rxspectrum(scenario, fc, bw, fs, fshift, L)
if( nargin == 0)
fprintf('Use this function to plot your Receive spectrum\n');
fprintf('\n');
fprintf('First argument is to run 8 example scenarios.\n');
fprintf('rxpsectrum(1) or rxspectrum(2)...to plot and study various scenarios\n');
fprintf('\n');
fprintf('For custom numbers function can be called as follows\n');
fprintf('rxspectrum([], center frequency, data bandwidth, sampling frequency,shift or carrier frequency, x-axis plotting limit(optional arugment)\n');
elseif (nargin == 1)
%% System Parameters
sys = [];
sys.scenario = scenario;
switch sys.scenario
case 1
% Good Scenario. Nyquist sampling theorem.
%
% The sampling rate of 4 GHz is high enough to satisfy Nyquist sampling
% theorem.
%
% Use Nyquist Zone 1.
sys.fc = 1e9;
sys.bw = 300e6;
sys.fs = 4e9;
sys.fshift = -1e9;
L = 7;
sys.xlim = [-L L];
sys.xticks = -L : L;
case 2
% Good Scenario. Bandpass sampling theorem.
%
% The sampling rate of 3 GHz is not high enough to satisfy Nyquist sampling
% theorem but it is one of the good sampling rates from bandpass sampling
% theorem.
%
% Use Nyquist Zone 2.
sys.fc = 3e9;
sys.bw = 300e6;
sys.fs = 4e9;
sys.fshift = 1e9;
L = 7;
sys.xlim = [-L L];
sys.xticks = -L : L;
case 3
% Bad Scenario.
%
% Sampling rate does not satisfy Nyquist nor bandpass sampling theorem.
%
% Spectrum overlaps (completely or partially).
sys.fc = 3e9;
sys.bw = 300e6;
sys.fs = 2.4e9; % Complete Overlap
% sys.fs = 5.8e9; % Partial Overlap
sys.fshift = -0.6e9;
L = 10;
sys.xlim = [-L L];
sys.xticks = -L : L;
case 4
% Bad Scenario.
%
% Sampling rate satisifies bandpass sampling theorem but spectra touch each
% other.
%
% Unless we have an ideal brick wall lowpass filter, we cannot recover the
% signal at 3 GHz.
sys.fc = 3e9;
sys.bw = 300e6;
sys.fs = 5.7e9;
sys.fshift = 2.7e9;
L = 10;
sys.xlim = [-L L];
sys.xticks = -L : L;
case 5
% Solution to scenario 4. Spectra no longer touch either other.
%
% But we cannot use Xilinx hard IP decimate-by-2.
sys.fc = 3e9;
sys.bw = 300e6;
sys.fs = 3.4e9;
sys.fshift = 0.4e9;
L = 8;
sys.xlim = [-L L];
sys.xticks = -L : L;
case 6
% Solution to scenario 5. Spectra no longer touch either other and we can
% use Xilinx hard IP decimate-by-2.
sys.fc = 3e9;
sys.bw = 300e6;
sys.fs = 4e9;
sys.fshift = 1e9;
L = 8;
sys.xlim = [-L L];
sys.xticks = -L : L;
case 7
% Same problem even with Nyquist sampling theorem.
sys.fc = 1.5e9;
sys.bw = 300e6;
sys.fs = 4e9;
sys.fshift = -1.5e9;
L = 7;
sys.xlim = [-L L];
sys.xticks = -L : L;
case 8
sys.fc = 1.5e9;
sys.bw = 300e6;
sys.fs = 2e9;
sys.fshift = -0.5e9;
L = 7;
sys.xlim = [-L L];
sys.xticks = -L : L;
otherwise
error('Invalid sys.scenario');
end % switch
end %if(nargin == 1)
if (nargin == 5)
%% System Parameters
sys = [];
sys.scenario = scenario;
sys.fc = fc;
sys.bw = bw;
sys.fs = fs;
sys.fshift = fshift;
L = 7;
sys.xlim = [-L L];
sys.xticks = -L : L;
end
if (nargin == 6)
%% System Parameters
sys = [];
sys.scenario = scenario;
sys.fc = fc;
sys.bw = bw;
sys.fs = fs;
sys.fshift = fshift;
sys.xlim = [-L L];
sys.xticks = -L : L;
end
sys.xunit = 'GHz';
%%
if isempty(findobj('Number', sys.scenario))
figure(sys.scenario)
set(gcf, 'Position', [27 82 1180 638])
else
figure(sys.scenario)
clf
end
%%
Nsubplots = 5;
subplot(Nsubplots, 1, 1);
xlim(sys.xlim);
xticks(sys.xticks);
set(gca, 'Position', [0.04 0.8720 0.9277 0.09])
plotspectrum('asym', sys.fc, sys.bw, 'r', sys.xunit);
plotspectrum('asymflip', -sys.fc, sys.bw, 'r', sys.xunit);
title(sprintf('Analog Bandpass Signal (Center = %.2f GHz. BW = %d MHz.)', ...
sys.fc/1e9, sys.bw/1e6), 'FontSize', 12);
plotannotations(sys.fs, 1);
set(get(gca, 'XAxis'), 'FontSize', 11);
%%
subplot(Nsubplots, 1, 2);
xlim(sys.xlim);
xticks(sys.xticks);
set(gca, 'Position', [0.04 0.6720 0.9277 0.09])
title(sprintf('Sampling Images (Towards +ve Frequencies). Fs = %.2f GHz.', ...
sys.fs/1e9), 'FontSize', 12);
for n = 1:8
f1 = sys.fc + n*sys.fs;
f2 = -sys.fc + (n*sys.fs);
plotspectrum('asym', f1, sys.bw, 'b', sys.xunit);
plotspectrum('asymflip', f2, sys.bw, 'b', sys.xunit);
end
set(get(gca, 'XAxis'), 'FontSize', 11);
%%
subplot(Nsubplots, 1, 3);
xlim(sys.xlim);
xticks(sys.xticks);
set(gca, 'Position', [0.04 0.4720 0.9277 0.09])
title(sprintf('Sampling Images (Towards -ve Frequencies). Fs = %.2f GHz.', ...
sys.fs/1e9), 'FontSize', 12);
for n = -1:-1:-8
f1 = sys.fc + n*sys.fs;
f2 = -sys.fc + (n*sys.fs);
plotspectrum('asym', f1, sys.bw, 'c', sys.xunit);
plotspectrum('asymflip', f2, sys.bw, 'c', sys.xunit);
end
set(get(gca, 'XAxis'), 'FontSize', 11);
%%
subplot(Nsubplots, 1, 4);
xlim(sys.xlim);
xticks(sys.xticks);
set(gca, 'Position', [0.04 0.2720 0.9277 0.09])
title(sprintf('Real Digital Signal (Fs = %.2f GHz. BW %d MHz.)', ...
sys.fs/1e9, sys.bw/1e6), 'FontSize', 12)
n = -8:8;
f1 = sys.fc + n*sys.fs;
f2 = -sys.fc + (n*sys.fs);
plotspectrum('asym', f1, sys.bw, 'r', sys.xunit);
plotspectrum('asymflip', f2, sys.bw, 'r', sys.xunit);
plotannotations(sys.fs, 0);
set(get(gca, 'XAxis'), 'FontSize', 11);
%%
subplot(Nsubplots, 1, 5);
xlim(sys.xlim);
xticks(sys.xticks);
set(gca, 'Position', [0.04 0.0720 0.9277 0.09])
title(sprintf(['Complex Baseband Signal (Fs = %.2f GHz. BW %d MHz. ', ...
'fshift = %.2f GHz)'], sys.fs/1e9, sys.bw/1e6, sys.fshift/1e9), ...
'FontSize', 12);
f1 = f1 + sys.fshift;
f2 = f2 + sys.fshift;
plotspectrum('asym', f1, sys.bw, 'r', sys.xunit);
plotspectrum('asymflip', f2, sys.bw, 'r', sys.xunit);
plotannotations(sys.fs, 0);
set(get(gca, 'XAxis'), 'FontSize', 11);
Fs = sys.fs / 1e9;
x = [-Fs/2, -Fs/4, -Fs/4, Fs/4, Fs/4, Fs/2];
y = [0.25, 0.25, 0.75, 0.75, 0.25, 0.25];
hold on
plot(x, y, 'k--', 'LineWidth', 2)
end
% ------------------------------------------------------------------------------
% Helper Functions
% ------------------------------------------------------------------------------
function plotannotations(fs, zone)
%% Plot DC.
xline(0, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
y = 0.9;
addtext1(0, y, '0')
%% Plot fs/2.
xline(fs/2/1e9, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
xline(-fs/2/1e9, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
addtext1(0 + fs/2/1e9, y, 'Fs/2')
addtext1(0 - fs/2/1e9, y, '-Fs/2')
%% Plot fs.
xline(fs/1e9, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
xline(-fs/1e9, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
addtext1(0 + fs/1e9, y, 'Fs')
addtext1(0 - fs/1e9, y, '-Fs')
%% Plot 3*fs/2.
xline(fs*1.5/1e9, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
xline(-fs*1.5/1e9, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
addtext1(0 + 1.5*fs/1e9, y, '3*Fs/2')
addtext1(0 - 1.5*fs/1e9, y, '-3*Fs/2')
% %% Plot ...
% ntext4(0 + 1.6*fs/1e9, 0.6, '...', 'FontSize', 30, 'FontWeight', 'bold');
% ntext4(0 - 1.7*fs/1e9, 0.6, '...', 'FontSize', 30, 'FontWeight', 'bold');
% %%
% if zone == 1
% addtext2(0.7, 0.65, {'Nyquist', 'Zone 1'})
% addtext2(0.7 + fs/2/1e9, 0.65, {'Nyquist', 'Zone 2'})
% % addtext2(0.7 + fs/1e9, 0.65, {'Nyquist', 'Zone 3'})
% end
end
function addtext1(x, y, t)
h = ntext4(x, y, t);
h.FontSize = 15;
h.FontWeight = 'bold';
h.HorizontalAlignment = 'center';
end
function addtext2(x, y, t)
h = ntext4(x, y, t);
h.FontSize = 15;
h.FontWeight = 'bold';
h.Color = [0 0.4470 0.7410];
h.HorizontalAlignment = 'center';
end

244
utilities/txspectrum.m Normal file
View File

@@ -0,0 +1,244 @@
function txspectrum(scenario, bw, fs, fshift, L)
if nargin == 0
fprintf('Use this function to plot your Transmit spectrum\n');
fprintf('\n');
fprintf('First argument is to run 5 example scenarios. \n');
fprintf('txpsectrum(1) or txspectrum(2)...to plot and study various scenarios\n');
fprintf('\n');
fprintf('For custom numbers function can be called as follows\n');
fprintf('txspectrum([], data bandwidth, sampling frequency,shift or carrier frequency, x-axis plotting limit(optional arugment)\n');
elseif (nargin == 1)
%% System Parameters
sys = [];
sys.scenario = scenario;
switch sys.scenario
case 1
% Use Nyquist Zone 1 to tx signal at center frequency = 1 GHz with Fs = 4
% GHz.
sys.fs = 4e9;
sys.bw = 400e6;
sys.fshift = 1e9;
L = 7;
sys.xlim = [-L L];
sys.xticks = -L : L;
case 2
% Use Nyquist Zone 2 to tx signal at center frequency = 3 GHz with Fs = 4
% GHz.
sys.fs = 4e9;
sys.bw = 400e6;
sys.fshift = -1e9;
L = 7;
sys.xlim = [-L L];
sys.xticks = -L : L;
case 3
% This is a difficult scenario. We want to tx the signal at center frequency
% = 1.8 GHz. But with Fs = 4 GHz, there is also a copy of the spectrum
% centered at 2.2 GHz touching the spectrum at 1.8 GHz. Unless we have a
% ideal brick-wall analog lowpass filter, we cannot remove the spectrum at
% 2.2 GHz.
%
sys.fs = 4e9;
sys.bw = 400e6;
sys.fshift = 1.8e9;
L = 7;
sys.xlim = [-L L];
sys.xticks = sort([-L : -3, -1 : 1, 3:L, 1.8, -1.8, 2.2, -2.2]);
case 4
% This scenario is a solution to scenario 3. There are two key ideas:
%
% (1) When converting complex baseband signal to real bandpass signal, use
% a value of fshift that is large enough to avoid overlap between the
% spectra at +ve frequency and -ve frequency. In our example, the
% complex baseband signal has frequency content from -200 MHz to 200
% MHz, so we can pick fshift = -400 MHz and the spectrum at -400 MHz
% does not overlap with the spectrum at 400 MHz.
%
% (2) Digital signal's spectrum repeats every Fs. Use this fact to create
% spectrum at higher frequency. We have the desired spectrum at -0.4
% GHz and so use Fs = 2.2 GHz to create the spectrum at -0.4 GHz + 2.2
% GHz = 1.8 GHz.
%
% In this scenario, we use a lower sampling rate of 2.2 GHz and use Nyquist
% zone 2 to transmit our signal at 1.8 GHz. Now there is a resonable gap
% between the spectrum at 1.8 GHz and the spectrum at 2.6 GHz and we can
% rely on a bandpass filter to filter everything except the the spectrum at
% 1.8 GHz.
%
sys.fs = 2.2e9;
sys.bw = 400e6;
sys.fshift = -0.4e9;
L = 5;
sys.xlim = [-L L];
sys.xticks = sort([-L : L, 1.8, -1.8, 2.2, -2.2, 0.4, -0.4, 2.6, -2.6]);
case 5
% Better solution than scenario 4.
sys.fs = 2.6e9;
sys.bw = 400e6;
sys.fshift = -0.8e9;
L = 5;
sys.xlim = [-L L];
sys.xticks = sort([-L : L, 1.8, -1.8, 2.2, -2.2, 0.4, -0.4, 2.6, -2.6]);
otherwise
error('Invalid sys.scenario');
end
elseif (nargin == 4) %if(nargin == 1)
%% System Parameters
sys = [];
sys.scenario = scenario;
sys.bw = bw;
sys.fs = fs;
sys.fshift = fshift;
L = 7;
sys.xlim = [-L L];
sys.xticks = -L : L;
elseif (nargin == 5)
%% System Parameters
sys = [];
sys.scenario = scenario;
sys.bw = bw;
sys.fs = fs;
sys.fshift = fshift;
sys.xlim = [-L L];
sys.xticks = -L : L;
end
sys.xunit = 'GHz';
%%
if nargin > 0
if isempty(findobj('Number', sys.scenario))
figure(sys.scenario)
set(gcf, 'Position', [227 140 1231 617])
else
figure(sys.scenario)
clf
end
%%
subplot(311)
xlim(sys.xlim);
xticks(sys.xticks);
set(gca, 'Position', [0.0463 0.7521 0.9277 0.18])
f1 = 0 + (-4:4)*sys.fs;
plotspectrum('asym', f1, sys.bw, 'r', sys.xunit);
s = sprintf('Complex Baseband (Fs = %.2f GHz. BW = %d MHz)', ...
sys.fs/1e9, sys.bw/1e6);
plotannotations(sys.fs, s)
addtext3(-4.5, 1.15, '|Z(f)|')
%%
subplot(312)
xlim(sys.xlim);
xticks(sys.xticks);
set(gca, 'Position', [0.0463 0.4221 0.9277 0.18])
f1 = f1 + sys.fshift;
plotspectrum('asym', f1, sys.bw, 'r', sys.xunit);
s = sprintf('Complex Bandpass (Fs = %.2f GHz. ', sys.fs/1e9);
if abs(sys.fshift) >= 1e9
s = [s, sprintf('fshift = %.2f GHz)', sys.fshift/1e9)];
else
s = [s, sprintf('fshift = %d MHz)', sys.fshift/1e6)];
end
plotannotations(sys.fs, s)
addtext3(-4.5, 1.15, '|U(f)|')
%%
subplot(313)
xlim(sys.xlim);
xticks(sys.xticks);
set(gca, 'Position', [0.0463 0.0921 0.9277 0.18])
f2 = -f1;
plotspectrum('asym', f1, sys.bw, 'r', sys.xunit);
plotspectrum('asymflip', f2, sys.bw, 'r', sys.xunit);
s = sprintf('Real Bandpass (Fs = %.2f GHz)', sys.fs/1e9);
plotannotations(sys.fs, s)
addtext3(-4.5, 1.15, '|S(f)| = |Y(f)|')
end
end
% ------------------------------------------------------------------------------
% Helper Functions
% ------------------------------------------------------------------------------
function plotannotations(fs, titlestr)
%% Plot DC.
xline(0, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
y = 0.9;
addtext1(0, y, '0')
%% Plot fs/2.
xline(fs/2/1e9, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
xline(-fs/2/1e9, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
addtext1(0 + fs/2/1e9, y, 'fs/2')
addtext1(0 - fs/2/1e9, y, '-fs/2')
%% Plot fs.
xline(fs/1e9, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
xline(-fs/1e9, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
addtext1(0 + fs/1e9, y, 'fs')
addtext1(0 - fs/1e9, y, '-fs')
%% Plot 3*fs/2.
xline(fs*1.5/1e9, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
xline(-fs*1.5/1e9, 'LineWidth', 3, 'Color', 'g', 'LineStyle', '--')
addtext1(0 + 1.5*fs/1e9, y, '3*fs/2')
addtext1(0 - 1.5*fs/1e9, y, '-3*fs/2')
%% Plot ...
ntext4(0 + 1.6*fs/1e9, 0.6, '...', 'FontSize', 30, 'FontWeight', 'bold');
ntext4(0 - 1.7*fs/1e9, 0.6, '...', 'FontSize', 30, 'FontWeight', 'bold');
%%
addtext2(fs/4/1e9, 0.7, {'Nyquist', 'Zone 1'})
addtext2(fs/4/1e9 + fs/2/1e9, 0.7, {'Nyquist', 'Zone 2'})
% addtext2(fs/4/1e9 + fs/1e9, 0.7, {'Nyquist', 'Zone 3'})
%% Title.
title(titlestr, 'FontSize', 12);
%%
h = gca;
h.XAxis.FontSize = 11;
end
function addtext1(x, y, t)
h = ntext4(x, y, t);
h.FontSize = 15;
h.FontWeight = 'bold';
h.HorizontalAlignment = 'center';
end
function addtext2(x, y, t)
h = ntext4(x, y, t);
h.FontSize = 15;
h.FontWeight = 'bold';
h.Color = [0 0.4470 0.7410];
h.HorizontalAlignment = 'center';
end
function addtext3(x, y, t)
h = ntext4(x, y, t);
h.FontSize = 20;
h.FontWeight = 'bold';
h.Color = 'r';
h.HorizontalAlignment = 'center';
end