Skip to content

Instantly share code, notes, and snippets.

@in3otd
Created December 8, 2017 19:59
Show Gist options
  • Save in3otd/b70cd82609e7c3cefed77f130c717247 to your computer and use it in GitHub Desktop.
Save in3otd/b70cd82609e7c3cefed77f130c717247 to your computer and use it in GitHub Desktop.
GNU Octave script to test the de-embedding component
1;
% directory where qucsator and qucsconv are located
global qucsdir = "~/usr/local/bin/";
global freq = 1e9;
function val = isodd(n)
val = (mod(n,2) == 1);
endfunction
function val = iseven(n)
val = (mod(n,2) == 0);
endfunction
function Sr = randomS(n, spfname)
% generate random S-parameters matrix
global freq;
Sr = randn(n) + j*randn(n);
fsid = fopen(spfname, 'w');
% write header
fprintf(fsid, '# GHz S RI R 50\n');
% write frequency
fprintf(fsid, '%f\t', freq/1e9);
for i = 1:n
nv = 0;
for j = 1:n
fprintf(fsid, '%f %f\t', real(Sr(i,j)), imag(Sr(i,j)));
nv = nv + 1;
if (nv == 4)
fprintf(fsid, '\n');
nv = 0;
endif
endfor
fprintf(fsid, '\n');
endfor
fclose(fsid);
endfunction
function maxdelta = test_de_embedding(nPorts)
global freq;
global qucsdir;
% generate random S-parameters input
spfname = sprintf('test.s%ip', nPorts);
randomS(nPorts, spfname);
% generate netlist
fid = fopen('testnetlist.txt', 'w');
% left-side sources
for i = 1:2:nPorts
fprintf(fid, 'Pac:P%i i%i gnd Num="%i" Z="50 Ohm" P="0 dBm" f="1 GHz" Temp="26.85"\n', i, i, i);
endfor
% right-side sources
for i = 2:2:nPorts
fprintf(fid, 'Pac:P%i o%i gnd Num="%i" Z="50 Ohm" P="0 dBm" f="1 GHz" Temp="26.85"\n', i, i, i);
endfor
% de-embedding component
fprintf(fid, 'SPDfile:XD1');
for i = 1:nPorts
if isodd(i) % odd
fprintf(fid, ' i%i', i);
else % even
fprintf(fid, ' m%i', i);
endif
endfor
fprintf(fid, ' gnd File="{%s}" Data="rectangular" Interpolator="linear" duringDC="open"\n', spfname);
% embedding component
fprintf(fid, 'SPfile:X1');
for i = 1:nPorts
if (mod(i,2) == 1) % odd
fprintf(fid, ' m%i', i+1);
else % even
fprintf(fid, ' o%i', i);
endif
endfor
fprintf(fid, ' gnd File="{%s}" Data="rectangular" Interpolator="linear" duringDC="open"\n', spfname);
% simulation component
fprintf(fid, '.SP:SP1 Type="list" Values="[1 GHz; 2 GHz]" Noise="no" NoiseIP="1" NoiseOP="2" saveCVs="no" saveAll="no"\n');
% apparently qucsconv does not work well with just a single frequency
%fprintf(fid, '.SP:SP1 Type="const" Values="[1 GHz]" Noise="no" NoiseIP="1" NoiseOP="2" saveCVs="no" saveAll="no"\n');
% done with test netlist file
fclose(fid);
% run qucsator
[status, output] = system ([qucsdir "qucsator -i testnetlist.txt -o testnetlist.dat"]);
% convert result to .mat format
[status, output] = system ([qucsdir "qucsconv -if qucsdata -of matlab -i testnetlist.dat -o testnetlist.mat"]);
% load results
load("testnetlist.mat");
% compute error
% S(n+1,n) and S(n,n+1) should be 1, all the others should be 0
maxdelta = 0;
% check results
for i = 1:nPorts
for j = 1:nPorts
val = eval(sprintf('S_%i_%i(1)', i, j));
%printf('S_%i_%i(1)=%f\n', i, j, val);
if ((isodd(i) && (j == (i+1))) || (iseven(i) && (i == (j+1))))
% S(n+1,n) and S(n,n+1) should be 1
%printf('(1) S_%i_%i(1)=%f\n', i, j, val);
delta = val - 1;
else
% others Snm should be 0
%printf('(0) S_%i_%i(1)=%f\n', i, j, val);
delta = val;
endif
if (abs(delta) > abs(maxdelta))
maxdelta = delta;
endif
endfor
endfor
%printf('max delta = %e\n', maxdelta);
endfunction
% test de-embedding for a different number of ports
for p=2:2:40
printf('[%i ports]\terror = %e\n', p, test_de_embedding(p));
endfor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment