diff --git a/gm_soc_rfsoc_top_sw.slx b/gm_soc_rfsoc_top_sw.slx index d879585..1ea281b 100644 Binary files a/gm_soc_rfsoc_top_sw.slx and b/gm_soc_rfsoc_top_sw.slx differ diff --git a/referencedmodels/soc_rfsoc_fpga.slx b/referencedmodels/soc_rfsoc_fpga.slx index fc7714d..185ebd8 100644 Binary files a/referencedmodels/soc_rfsoc_fpga.slx and b/referencedmodels/soc_rfsoc_fpga.slx differ diff --git a/referencedmodels/soc_rfsoc_proc.slx b/referencedmodels/soc_rfsoc_proc.slx index 8e9ec1b..81a3d00 100644 Binary files a/referencedmodels/soc_rfsoc_proc.slx and b/referencedmodels/soc_rfsoc_proc.slx differ diff --git a/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/H2OSua_mS0xjdXaWfBnHyck-21gd.xml b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/H2OSua_mS0xjdXaWfBnHyck-21gd.xml new file mode 100644 index 0000000..99772b4 --- /dev/null +++ b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/H2OSua_mS0xjdXaWfBnHyck-21gd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/H2OSua_mS0xjdXaWfBnHyck-21gp.xml b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/H2OSua_mS0xjdXaWfBnHyck-21gp.xml new file mode 100644 index 0000000..30d408b --- /dev/null +++ b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/H2OSua_mS0xjdXaWfBnHyck-21gp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/JqwYLo5GblI8poXmmZbdb_aYTFEd.xml b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/JqwYLo5GblI8poXmmZbdb_aYTFEd.xml new file mode 100644 index 0000000..99772b4 --- /dev/null +++ b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/JqwYLo5GblI8poXmmZbdb_aYTFEd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/JqwYLo5GblI8poXmmZbdb_aYTFEp.xml b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/JqwYLo5GblI8poXmmZbdb_aYTFEp.xml new file mode 100644 index 0000000..9120801 --- /dev/null +++ b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/JqwYLo5GblI8poXmmZbdb_aYTFEp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/RXeEMtO1rvf1M4FZ4WQYgEYXNWwd.xml b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/RXeEMtO1rvf1M4FZ4WQYgEYXNWwd.xml new file mode 100644 index 0000000..99772b4 --- /dev/null +++ b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/RXeEMtO1rvf1M4FZ4WQYgEYXNWwd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/RXeEMtO1rvf1M4FZ4WQYgEYXNWwp.xml b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/RXeEMtO1rvf1M4FZ4WQYgEYXNWwp.xml new file mode 100644 index 0000000..9851f07 --- /dev/null +++ b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/RXeEMtO1rvf1M4FZ4WQYgEYXNWwp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/blA3YKEoExNhkStPRYdGnolk6EEd.xml b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/blA3YKEoExNhkStPRYdGnolk6EEd.xml new file mode 100644 index 0000000..99772b4 --- /dev/null +++ b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/blA3YKEoExNhkStPRYdGnolk6EEd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/blA3YKEoExNhkStPRYdGnolk6EEp.xml b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/blA3YKEoExNhkStPRYdGnolk6EEp.xml new file mode 100644 index 0000000..50f774a --- /dev/null +++ b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/blA3YKEoExNhkStPRYdGnolk6EEp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/m22K5zpY6141aoh1hLcPr44fTCUd.xml b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/m22K5zpY6141aoh1hLcPr44fTCUd.xml new file mode 100644 index 0000000..99772b4 --- /dev/null +++ b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/m22K5zpY6141aoh1hLcPr44fTCUd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/m22K5zpY6141aoh1hLcPr44fTCUp.xml b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/m22K5zpY6141aoh1hLcPr44fTCUp.xml new file mode 100644 index 0000000..9b0224c --- /dev/null +++ b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/m22K5zpY6141aoh1hLcPr44fTCUp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/qDXBwbCFcQDhtGei0v0jECxk4HAd.xml b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/qDXBwbCFcQDhtGei0v0jECxk4HAd.xml new file mode 100644 index 0000000..99772b4 --- /dev/null +++ b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/qDXBwbCFcQDhtGei0v0jECxk4HAd.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/qDXBwbCFcQDhtGei0v0jECxk4HAp.xml b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/qDXBwbCFcQDhtGei0v0jECxk4HAp.xml new file mode 100644 index 0000000..e823214 --- /dev/null +++ b/resources/project/Abllu374wtDd3IliE-5ZoGpf8mM/qDXBwbCFcQDhtGei0v0jECxk4HAp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/soc_rfsoc_top.slx b/soc_rfsoc_top.slx index ac57ffa..0b89631 100644 Binary files a/soc_rfsoc_top.slx and b/soc_rfsoc_top.slx differ diff --git a/utilities/ntext4.m b/utilities/ntext4.m new file mode 100644 index 0000000..bf3697f --- /dev/null +++ b/utilities/ntext4.m @@ -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 diff --git a/utilities/plotspectrum.m b/utilities/plotspectrum.m new file mode 100644 index 0000000..d9e0268 --- /dev/null +++ b/utilities/plotspectrum.m @@ -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 + 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 + + diff --git a/utilities/programBoard.m b/utilities/programBoard.m new file mode 100644 index 0000000..79bf2e7 --- /dev/null +++ b/utilities/programBoard.m @@ -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'); \ No newline at end of file diff --git a/utilities/rxadcfs.m b/utilities/rxadcfs.m new file mode 100644 index 0000000..0ab7ee1 --- /dev/null +++ b/utilities/rxadcfs.m @@ -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 + diff --git a/utilities/rxspectrum.m b/utilities/rxspectrum.m new file mode 100644 index 0000000..e30ca9e --- /dev/null +++ b/utilities/rxspectrum.m @@ -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 + diff --git a/utilities/txspectrum.m b/utilities/txspectrum.m new file mode 100644 index 0000000..3917821 --- /dev/null +++ b/utilities/txspectrum.m @@ -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