|
125 | 125 | % file in the top-level directory of this distribution.
|
126 | 126 |
|
127 | 127 | classdef PUSCHBLER < matlab.System
|
128 |
| - properties (Constant) |
129 |
| - %Number of transmit antennas. |
130 |
| - NTxAnts = 1 |
131 |
| - end % of constant properties |
132 |
| - |
133 | 128 | properties (Nontunable)
|
134 | 129 | %Perfect channel estimation flag.
|
135 | 130 | PerfectChannelEstimator (1, 1) logical = true
|
| 131 | + %Number of transmit antennas. |
| 132 | + NTxAnts = 1 |
136 | 133 | %Number of receive antennas.
|
137 | 134 | NRxAnts = 1
|
138 | 135 | %Bandwidth in number of resource blocks.
|
|
197 | 194 | % is set to false.
|
198 | 195 | SRSEstimatorType (1, :) char {mustBeMember(SRSEstimatorType, {'MEX', 'noMEX'})} = 'MEX'
|
199 | 196 | %Flag for emulating O-FH compression.
|
| 197 | + SRSEqualizerType (1, :) char {mustBeMember(SRSEqualizerType, {'ZF', 'MMSE'})} = 'ZF' |
200 | 198 | ApplyOFHCompression (1, 1) logical = false
|
201 | 199 | %Bit-width of the compressed IQ samples.
|
202 | 200 | % Only applies if ApplyOFHCompression is set to true.
|
203 | 201 | CompIQwidth (1, 1) double {mustBeInteger, mustBeInRange(CompIQwidth, 1, 16)} = 9
|
204 | 202 | %Time-domain interpolation strategy ('average', 'interpolate').
|
205 | 203 | % Valid only for SRS estimator.
|
206 |
| - Interpolation (1, :) char {mustBeMember(Interpolation, {'average', 'interpolate'})} = 'average' |
| 204 | + SRSInterpolation (1, :) char {mustBeMember(SRSInterpolation, {'average', 'interpolate'})} = 'average' |
207 | 205 | end % of properties (Nontunable)
|
208 | 206 |
|
209 | 207 | properties % Tunable
|
@@ -639,9 +637,9 @@ function stepImpl(obj, SNRIn, nFrames)
|
639 | 637 | betaDMRS = sqrt(2);
|
640 | 638 |
|
641 | 639 | if useSRSDecoder
|
642 |
| - srsDemodulatePUSCH = srsMEX.phy.srsPUSCHDemodulator; |
| 640 | + srsDemodulatePUSCH = srsMEX.phy.srsPUSCHDemodulator(EqualizerStrategy = obj.SRSEqualizerType); |
643 | 641 | srsChannelEstimate = srsMEX.phy.srsMultiPortChannelEstimator(ImplementationType = obj.SRSEstimatorType, ...
|
644 |
| - Smoothing = 'filter', Interpolation = obj.Interpolation, CompensateCFO = true); |
| 642 | + Smoothing = 'filter', Interpolation = obj.SRSInterpolation, CompensateCFO = true); |
645 | 643 | end
|
646 | 644 |
|
647 | 645 | % %%% Simulation loop.
|
@@ -684,6 +682,10 @@ function stepImpl(obj, SNRIn, nFrames)
|
684 | 682 | % when the correlation is strong for practical synchronization.
|
685 | 683 | offset = 0;
|
686 | 684 |
|
| 685 | + % Long-term RSRP and noise power estimation. |
| 686 | + rsrpLT = 0; |
| 687 | + noiseEstLT = 0; |
| 688 | + |
687 | 689 | % Loop over the entire waveform length.
|
688 | 690 | for nslot = 0:NSlots-1
|
689 | 691 |
|
@@ -896,12 +898,16 @@ function stepImpl(obj, SNRIn, nFrames)
|
896 | 898 |
|
897 | 899 | if useSRSDecoder
|
898 | 900 | if (~perfectChannelEstimator)
|
899 |
| - [estChannelGrid, noiseEst] = srsChannelEstimate(rxGrid, pusch.SymbolAllocation, ... |
| 901 | + [estChannelGrid, noiseEst, extra] = srsChannelEstimate(rxGrid, pusch.SymbolAllocation, ... |
900 | 902 | dmrsLayerIndices, dmrsLayerSymbols, ...
|
901 | 903 | 'CyclicPrefix', carrier.CyclicPrefix, ...
|
902 | 904 | 'SubcarrierSpacing', carrier.SubcarrierSpacing, ...
|
903 | 905 | 'PortIndices', (0:nRxAnts-1)', ...
|
904 | 906 | 'BetaScaling', betaDMRS);
|
| 907 | + |
| 908 | + % Update long-term RSRP and noise power estimation. |
| 909 | + rsrpLT = rsrpLT + extra.RSRP; |
| 910 | + noiseEstLT = noiseEstLT + noiseEst; |
905 | 911 | end
|
906 | 912 |
|
907 | 913 | ulschLLRsInt8 = int8(srsDemodulatePUSCH(rxGrid, estChannelGrid, noiseEst, pusch, ...
|
@@ -959,6 +965,11 @@ function stepImpl(obj, SNRIn, nFrames)
|
959 | 965 | 1e-6*[simThroughputSRS(snrIdx) maxThroughput(snrIdx)]/(usedFrames*10e-3));
|
960 | 966 | fprintf('Throughput(%%) after %.0f frame(s) = %.4f\n', usedFrames, simThroughputSRS(snrIdx)*100/maxThroughput(snrIdx));
|
961 | 967 | fprintf('BLER after %.0f frame(s) = %.4f\n', usedFrames, simBLERSRS(snrIdx)/totalBlocks(snrIdx));
|
| 968 | + |
| 969 | + rsrpLT = rsrpLT / (nslot + 1); |
| 970 | + noiseEstLT = noiseEstLT / (nslot + 1); |
| 971 | + fprintf('Measured SNR = %.1f dB.\n', 10*log10(rsrpLT * pusch.NumLayers / noiseEstLT / betaDMRS^2)); |
| 972 | + |
962 | 973 | end
|
963 | 974 |
|
964 | 975 | end
|
@@ -994,6 +1005,9 @@ function resetImpl(obj)
|
994 | 1005 | end
|
995 | 1006 |
|
996 | 1007 | function releaseImpl(obj)
|
| 1008 | + % Reset simulation results. |
| 1009 | + obj.resetImpl(); |
| 1010 | + |
997 | 1011 | % Release internal system objects.
|
998 | 1012 | release(obj.Channel);
|
999 | 1013 | release(obj.EncodeULSCH);
|
@@ -1026,8 +1040,10 @@ function releaseImpl(obj)
|
1026 | 1040 | flag = isempty(obj.ThroughputMATLABCtr) || strcmp(obj.ImplementationType, 'srs');
|
1027 | 1041 | case {'ThroughputSRS', 'BlockErrorRateSRS'}
|
1028 | 1042 | flag = isempty(obj.ThroughputSRSCtr) || strcmp(obj.ImplementationType, 'matlab');
|
1029 |
| - case 'SRSEstimatorType' |
| 1043 | + case {'SRSEstimatorType', 'SRSInterpolation'} |
1030 | 1044 | flag = strcmp(obj.ImplementationType, 'matlab') || obj.PerfectChannelEstimator;
|
| 1045 | + case 'SRSEqualizerType' |
| 1046 | + flag = strcmp(obj.ImplementationType, 'matlab'); |
1031 | 1047 | case 'CompIQwidth'
|
1032 | 1048 | flag = ~obj.ApplyOFHCompression;
|
1033 | 1049 | otherwise
|
@@ -1062,7 +1078,7 @@ function releaseImpl(obj)
|
1062 | 1078 | ... Compression.
|
1063 | 1079 | 'ApplyOFHCompression', 'CompIQwidth', ...
|
1064 | 1080 | ... Other simulation details.
|
1065 |
| - 'ImplementationType', 'SRSEstimatorType', ... |
| 1081 | + 'ImplementationType', 'SRSEqualizerType', 'SRSEstimatorType', 'SRSInterpolation', ... |
1066 | 1082 | 'QuickSimulation', 'DisplaySimulationInformation', 'DisplayDiagnostics'};
|
1067 | 1083 | groups = matlab.mixin.util.PropertyGroup(confProps, 'Configuration');
|
1068 | 1084 |
|
|
0 commit comments