Build out MATLAB test framework and core integration coverage
This commit is contained in:
@@ -1,11 +1,120 @@
|
||||
classdef Pulseformer_test < matlab.unittest.TestCase
|
||||
% Test class for Pulseformer
|
||||
classdef Pulseformer_test < IMDDTestCase
|
||||
methods (Test, TestTags = {'unit', 'fast', 'transmit', 'pulseformer'})
|
||||
function constructorStoresConfiguredProperties(testCase)
|
||||
pf = Pulseformer( ...
|
||||
"fdac", 64e9, ...
|
||||
"fsym", 16e9, ...
|
||||
"pulse", pulseform.rrc, ...
|
||||
"pulselength", 12, ...
|
||||
"alpha", 0.2, ...
|
||||
"matched", 1);
|
||||
|
||||
methods (Test)
|
||||
function testExample(testCase)
|
||||
% Example test case for Pulseformer
|
||||
% Add your test code here
|
||||
testCase.verifyTrue(true);
|
||||
testCase.verifyEqual(pf.fdac, 64e9);
|
||||
testCase.verifyEqual(pf.fsym, 16e9);
|
||||
testCase.verifyEqual(pf.pulse, pulseform.rrc);
|
||||
testCase.verifyEqual(pf.pulselength, 12);
|
||||
testCase.verifyEqual(pf.alpha, 0.2);
|
||||
testCase.verifyEqual(pf.matched, 1);
|
||||
end
|
||||
|
||||
function processUsesSymbolRateFallbackAndUpdatesSignalMetadata(testCase)
|
||||
fsym = 16e9;
|
||||
fdac = 64e9;
|
||||
tx = makeInformationsignal([1; 0; -1; 1; 1; 0], []);
|
||||
pf = Pulseformer( ...
|
||||
"fdac", fdac, ...
|
||||
"fsym", fsym, ...
|
||||
"pulse", pulseform.rc, ...
|
||||
"pulselength", 8, ...
|
||||
"alpha", 0.35, ...
|
||||
"matched", 0);
|
||||
|
||||
rx = pf.process(tx);
|
||||
expected = expectedPulseformerOutput(pf, tx);
|
||||
|
||||
testCase.verifyClass(rx, 'Informationsignal');
|
||||
testCase.verifyEqual(rx.signal, expected, "AbsTol", 1e-12);
|
||||
testCase.verifyEqual(rx.fs, fdac);
|
||||
testCase.verifyEqual(height(rx.logbook), height(tx.logbook) + 1);
|
||||
testCase.verifyEqual(string(rx.logbook.Description(end)), "Applied Pulseshaping");
|
||||
end
|
||||
|
||||
function matchedAndUnmatchedProcessingPreserveTheSameRealWaveform(testCase)
|
||||
tx = makeInformationsignal([1; 0; 0; -1; 1; -1; 0; 1], 16e9);
|
||||
|
||||
unmatched = Pulseformer( ...
|
||||
"fdac", 32e9, ...
|
||||
"fsym", 16e9, ...
|
||||
"pulse", pulseform.rrc, ...
|
||||
"pulselength", 10, ...
|
||||
"alpha", 0.15, ...
|
||||
"matched", 0);
|
||||
matched = Pulseformer( ...
|
||||
"fdac", 32e9, ...
|
||||
"fsym", 16e9, ...
|
||||
"pulse", pulseform.rrc, ...
|
||||
"pulselength", 10, ...
|
||||
"alpha", 0.15, ...
|
||||
"matched", 1);
|
||||
|
||||
rxUnmatched = unmatched.process(tx);
|
||||
rxMatched = matched.process(tx);
|
||||
|
||||
testCase.verifyEqual(length(rxUnmatched.signal), length(rxMatched.signal));
|
||||
testCase.verifyEqual(rxUnmatched.signal, rxMatched.signal, "AbsTol", 1e-12);
|
||||
testCase.verifyEqual(rxUnmatched.signal, expectedPulseformerOutput(unmatched, tx), "AbsTol", 1e-12);
|
||||
testCase.verifyEqual(rxMatched.signal, expectedPulseformerOutput(matched, tx), "AbsTol", 1e-12);
|
||||
end
|
||||
|
||||
function processPreservesLengthForIntegerRateConversion(testCase)
|
||||
tx = makeInformationsignal((1:5).', []);
|
||||
pf = Pulseformer( ...
|
||||
"fdac", 20e9, ...
|
||||
"fsym", 5e9, ...
|
||||
"pulse", pulseform.rc, ...
|
||||
"pulselength", 6, ...
|
||||
"alpha", 0.25, ...
|
||||
"matched", 0);
|
||||
|
||||
rx = pf.process(tx);
|
||||
|
||||
testCase.verifyEqual(length(rx.signal), 20);
|
||||
testCase.verifyEqual(rx.fs, 20e9);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function sig = makeInformationsignal(values, fs)
|
||||
base = Signal(values);
|
||||
sig = Informationsignal(values, "fs", fs, "logbook", base.logbook);
|
||||
end
|
||||
|
||||
function expected = expectedPulseformerOutput(pf, signalclass_in)
|
||||
if isprop(signalclass_in, 'fs') && ~isempty(signalclass_in.fs)
|
||||
f_in = signalclass_in.fs;
|
||||
else
|
||||
f_in = pf.fsym;
|
||||
end
|
||||
|
||||
[p, q] = rat(pf.fdac / f_in);
|
||||
fs_intermediate = f_in * p;
|
||||
sps_filter = fs_intermediate / pf.fsym;
|
||||
|
||||
if pf.pulse == pulseform.rc
|
||||
filtertype = 'normal';
|
||||
else
|
||||
filtertype = 'sqrt';
|
||||
end
|
||||
|
||||
h = rcosdesign(pf.alpha, pf.pulselength, sps_filter, filtertype);
|
||||
if pf.matched
|
||||
h = conj(fliplr(h));
|
||||
end
|
||||
|
||||
data_out_ = upfirdn(signalclass_in.signal, h, p, q);
|
||||
delay_samples_intermediate = (length(h) - 1) / 2;
|
||||
delay_samples_out = delay_samples_intermediate / q;
|
||||
st = floor(delay_samples_out) + 1;
|
||||
len_out = ceil(length(signalclass_in.signal) * p / q);
|
||||
expected = data_out_(st : st + len_out - 1);
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user