OTFS复现1.0

仅本人记录,代码如下(仿真结果在最后)

function [BER,BLER]=OTFS(velocity_kmph,snrRange,simIterations)
%输入速度(km/h; 信噪比; 迭代次数)
%% %%%%%%%%%%%%%%%%%%%%%%% INPUT PARAMETERS %%%%%%%%%%%%%%%%%%%%%%% %%
% System Parameters系统参数
nSymbolsPerBlock = 32;       % Number of symbols per frame
fSubcarrierSpacing = 62.5e3;   % SC spacing in Hz
nFft = 128;  % FFT size
nCyclicPrefix = floor(nFft * 0.067);  % CP length in samples (6.7% is the calibration assumption defined in 3GPP R1-165989)
samplingRate = nFft * fSubcarrierSpacing;  % Sampling rate

modOrder = 4; % 4 for QPSK, 16 for 16QAM, 64 for 64QAM, 256 for 256QAM
nTxAntennas = 1;
nRxAntennas = 1;

nSubcarriers = nFft;
nBitsPerBlock = nSymbolsPerBlock * nSubcarriers * log2(modOrder);

% Parameter for LTE Channel Coder LTE信道编码参数
turboDecodingNumIterations = 8;
codeRate = 0.5;  % Coding rate of source data bits over transmition redundant data bits
codedTransportBlockSize = nBitsPerBlock * codeRate;
crcBitLength = 24;  % defined in 3GPP TS36.2xx
maxCodeBlockSize = 6144;  % defined in 3GPP TS36.2xx
numCodeBlockSegments = ceil((codedTransportBlockSize - crcBitLength) / maxCodeBlockSize);
if numCodeBlockSegments > 1
    tbs = codedTransportBlockSize-crcBitLength*(numCodeBlockSegments+1);  % CRC24A + CRC24B*numSegments
else
    tbs = codedTransportBlockSize-crcBitLength;  % CRC24A only
end

% Parameters for Scrambler 加扰参数
rnti = hex2dec('003D');
cellId = 0;
frameNo  = 0; % radio frame
codeword = 0;

% Parameter for OFDM Modulator OFDM调制参数
nGuardBands = [(nFft - nSubcarriers)/2; (nFft - nSubcarriers)/2];  
% Number of guard band subcarriers in both sides 两侧保护带子载波数

% Parameter for ChannelEstimator 信道估计参数
activeSubcarrierIndices = 1+nGuardBands(1):nFft-nGuardBands(2);

% Parameters for Fading Channel 衰落信道参数
delaySpread_ns = 300;                  % rms delay spred for TDL channel model only, in nano second 
%仅适用于 TDL 通道模型的 rms 延迟扩展,以纳秒为单位
fCenter = 4e9;                         % center carrier frequency [Hz]
velocity = velocity_kmph*1000/(60*60); % convert km/h -> m/s
waveLength = physconst('lightspeed')/fCenter;
fDoppler = velocity / waveLength;
txCorrMat = 1;
rxCorrMat = 1;


%% %%%%%%%%%%%%%%%%%%%%%%% ALGORITHM SELECTION 算法选择%%%%%%%%%%%%%%%%%%%%%%% %%

% ----- Path Estimator 信道估计 -----
%channelEstimationAlgorithm = 'Pilot-based iterative path estimation'; %导频迭代估计
%channelEstimationAlgorithm = 'PN-based iterative estimation';  %PN序列估计
 channelEstimationAlgorithm = 'Ideal';  %理想信道估计
fprintf('Channel estimation: %s\n', channelEstimationAlgorithm);

% ----- Equalizer 均衡 -----
 equalizerAlgorithm = 'Vectorized equalizer'; 
 eqAlgorithm = 'blockedMMSE'; %MMSE均衡

% equalizerAlgorithm = 'Deconvolutional equalizer';
% eqAlgorithm = 'Wiener';
fprintf('Channel equalization: %s\n', equalizerAlgorithm);
    
% ----- Channel -----
channelModel = 'EVA';
fprintf('Channel profile: %s\n', channelModel);

%---- Channel Coding ----
channelCoding = 'LTE';
%  channelCoding = 'None';
fprintf('Channel coding: %s\n', channelCoding);


%% %%%%%%%%%%%%%%%%%%%%%%% OBJECT GENERATION 目标生成 %%%%%%%%%%%%%%%%%%%%%%% %%

switch channelCoding
    case 'None'
        % Bit Generator
        hBitGenerator = RandomBitGenerator('DataLength', nBitsPerBlock);
        % Symbol Mapper
        hSymbolMapper = QamMapperV2( ...
            'ModOrder', modOrder, ...
            'InputType', 'bit', ...
            'OutputType', 'bit', ...  % 'bit' for uncoded, 'llr' for coded
            'UnitAveragePower', true, ...
            'LLROverflowPrevention', true);
    case 'LTE'
        % Bit Generator
        hBitGenerator = RandomBitGenerator('DataLength', tbs);
        % Symbol Mapper
        hSymbolMapper = QamMapperV2( ...
            'ModOrder', modOrder, ...
            'InputType', 'bit', ...
            'OutputType', 'llr', ...  % 'bit' for uncoded, 'llr' for coded
            'UnitAveragePower', true, ...
            'LLROverflowPrevention', true);
        % Symbol Mapper for uncoded
        hSymbolMapperUncoded = QamMapperV2( ...
            'ModOrder', modOrder, ...
            'InputType', 'bit', ...
            'OutputType', 'bit', ...  % 'bit' for uncoded, 'llr' for coded
            'UnitAveragePower', true, ...
            'LLROverflowPrevention', true);
        % LTE Channel Coder
        hChannelCoder = LteChannelCoder( ...
            'TurboDecodingNumIterations', turboDecodingNumIterations, ... 
            'ModOrder', modOrder, ...
            'NumLayers', 1, ...
            'OutputLength', nBitsPerBlock, ...
            'LinkDirection', 'Downlink', ...
            'RedundancyVersion', 0, ...
            'TBS', tbs);

        % Scrambler
        hScrambler = LteScrambler(rnti, cellId, frameNo, codeword);
end


% OFDM Modulator OFDM调制
hOfdmModulator = CpOfdmModulator(...
    'FFTLength',            nFft, ...
    'NumGuardBandCarriers', nGuardBands, ...
    'NumSymbols',           nSymbolsPerBlock, ...
    'CyclicPrefixLength',   nCyclicPrefix, ...
    'InsertDCNull',         false, ...
    'PilotInputPort',       false, ...
    'PilotOutputPort',      false, ...
    'NumTransmitAntennas',  nTxAntennas, ...
    'NumReceiveAntennas',   nRxAntennas, ...
    'SubcarrierIndexOrder', 'ZeroToFFTSize');

% OTFS Precoder OTFS预编码
hPrecoder = OtfsPrecoder( ...
    'NumDelayBins', nSubcarriers, ...
    'NumDopplerBins', nSymbolsPerBlock, ...
    'NumTransmitAntennas', nTxAntennas, ...
    'NumReceiveAntennas', nRxAntennas);

% Path Estimator 信道估计
switch channelEstimationAlgorithm
    case 'Pilot-based iterative path estimation'
        hEstimator = OtfsPilotResponseBasedPathParameterEstimator( ...
            'DividingNumber', 10, ...
            'CyclicPrefixLength', nCyclicPrefix, ...  % Ncp
            'NumDopplerBins', nSymbolsPerBlock, ...   % N
            'NumDelayBins', nSubcarriers, ...         % M
            'SamplingRate', samplingRate ...
            );
        threshAlpha = 1/50;
        threshBeta = 1/10;
        localUpdateThreshold = 0.01;
    case 'PN-based iterative estimation'
%       threshold = 1/150; % This is the best performance regardless the computation time
        threshold = 1/25;  % This is the same number of paths to be estimated with the proposed CE
        hEstimator = OtfsPNSeqBasedPathParameterEstimator( ...
            'DividingNumber', 10, ...
            'CyclicPrefixLength', nCyclicPrefix, ...  % Ncp
            'NumDopplerBins', nSymbolsPerBlock, ...   % N
            'NumDelayBins', nSubcarriers, ...         % M
            'SamplingRate', samplingRate, ...
            'Threshold', threshold);
    case 'Ideal'
end


% OTFS Equalizer OTFS均衡
switch equalizerAlgorithm
    case 'Deconvolutional equalizer'
        hEqualizer = OtfsDeconvolutionalEqualizer( ...
            'NumSymbols', nSymbolsPerBlock, ...       % N
            'CyclicPrefixLength', nCyclicPrefix, ...  % Ncp
            'NumSubcarriers', nSubcarriers, ...       % M
            'SamplingRate', samplingRate, ...
            'DividingNumber', 10, ... 
            'EqualizationAlgorithm', eqAlgorithm);   
    case 'Vectorized equalizer'
        hEqualizer = OtfsVectorizedEqualizer( ...
            'EqualizationAlgorithm', 'MMSE', ...
            'NumSymbols', nSymbolsPerBlock, ...       % N
            'CyclicPrefixLength', nCyclicPrefix, ...  % Ncp
            'NumSubcarriers', nSubcarriers, ...       % M
            'SamplingRate', samplingRate, ...
            'OutputConditionNumber', false, ...
            'EqualizationAlgorithm', eqAlgorithm);   
end


% Fading Channel 衰落信道
hFading = SoSBasedChannel( ...  % based on in-house implementation
    'ChannelModel', channelModel, ...
    'RMSDelaySpread', delaySpread_ns, ...
    'SamplingRate', samplingRate, ...
    'DopplerFrequency', fDoppler, ...
    'NumTxAntennas', nTxAntennas, ...
    'NumRxAntennas', nRxAntennas, ...
    'TxCorrMatrix', txCorrMat, ...
    'RxCorrMatrix', rxCorrMat, ...
    'OutputCIR', true, ...
    'CyclicPrefix', nCyclicPrefix, ...
    'FFTSize', nFft, ...
    'ImpulseSource', 'Input', ...
    'SequentialOrRandomChannel', 'Sequential', ...
    'FDFMethod', 'ApplyFDFToPathParameters');

% AWGN 高斯白噪声
hAwgn = AwgnChannel('N0');

%% %%%%%%%%%%%%%%%%%%%%%%% SIMULATION SETTINGS 仿真设置 %%%%%%%%%%%%%%%%%%%%%%% %%
% Create an empty storage to store simulation status创建一个空存储来存储模拟状态
simstatus = table;  % use table-type variable since it's good to see in the workspace 使用表类型变量,因为在工作区中可以看到
simstatus.SNR = snrRange';
simstatus.BER = nan * zeros(length(snrRange),1);
simstatus.UncodedBER = nan * zeros(length(snrRange),1);
simstatus.BLER = nan * zeros(length(snrRange),1);
simstatus.TotalBitErrors = zeros(length(snrRange),1); 
simstatus.TotalUncodedBitErrors = zeros(length(snrRange),1); 
simstatus.TotalBlockErrors = zeros(length(snrRange),1); 
simstatus.Iteration = zeros(length(snrRange),1);
simstatus.PathCounts = zeros(length(snrRange),1);
simstatus.ComputeTime = zeros(length(snrRange),1);


%% %%%%%%%%%%%%%%%%%%%%%%% START SIMULATION 开始仿真%%%%%%%%%%%%%%%%%%%%%%% %%
% For ideal channel estimation 对于理想信道估计
delayDopplerImpulse = zeros(nSubcarriers, nSymbolsPerBlock);
delayDopplerImpulse(1,1)=sqrt(nSymbolsPerBlock*nSubcarriers);
ddImpulseInTFDomain = hPrecoder.encode(delayDopplerImpulse);
ddImpulseInTimeDomain = hOfdmModulator.modulate(ddImpulseInTFDomain);

% For PN-sequence based channel estimation PN序列估计
switch channelEstimationAlgorithm
    case {'PN-based estimation'}
        txPNSeq = zeros((nCyclicPrefix+nFft)*nSymbolsPerBlock*10,1);  % for long PN sequence
%       txPNSeq = zeros((nCyclicPrefix+nFft)*nSymbolsPerBlock*1,1);  % for short PN sequence
        nPNSeq = 1023;
        tmpSeq = repmat(genltegoldseq(nPNSeq, de2bi(31,31)), 1, ceil(length(txPNSeq)/nPNSeq)); 
         % 1023-length with an initial value of 31
        tmpSeq(tmpSeq==0) = -1;  % map 0 or 1 bit into -1 or 1 bit
        txPNSeq = tmpSeq(1:length(txPNSeq))';
    case 'PN-based iterative estimation'
        txPNSeq = zeros((nCyclicPrefix+nFft)*nSymbolsPerBlock,1);
        nPNSeq = 1023;
        tmpSeq = repmat(genltegoldseq(nPNSeq, de2bi(31,31)), 1, ceil(length(txPNSeq)/nPNSeq));  % 1023-length with an initial value of 31  1023 长度,初始值为 31
        tmpSeq(tmpSeq==0) = -1;  % map 0 or 1 bit into -1 or 1 bit
        txPNSeq = tmpSeq(1:length(txPNSeq))';
end


charCount = 49+17;

for snrdb = snrRange
    rng('default');
    rng(106);

    fprintf('\nSNR = %2d dB \n', snrdb);
    snrIndex = find(snrRange==snrdb);
    snr = 10^(snrdb/10);
    noiseVar = 1/snr;    % Total power
    N0 = noiseVar/nFft;  % N0 is the power spectral density of noise per unit of bandwidth, which is band-limited.
    %N0 是每单位带宽的噪声功率谱密度,它是带限的。

    fprintf(repmat(' ', 1, charCount));  % Print spaces in advance to avoid deleting the previously displayed characters
    %提前打印空格,避免删除之前显示的字符
    tic %tic用来保存当前时间,而后使用toc来记录程序完成时间
    
    numBitErrors=[];
    numBitErrorsU=[];
    blockError2=[];
    
    for count = 1:simIterations(snrIndex)
        %% Transmitter 发射端
        % Bit Generation 符号生成
        txBits = hBitGenerator.generate();
%       txBits = zeros(size(txBits));  % FOR TEST
        switch channelCoding
            case 'None'
                txScrampledBits = txBits;
            case 'LTE'
                % Channel Encoding 信道编码
                txCodedBits = hChannelCoder.encode(txBits);
                % Scrambler 加扰
                txScrampledBits = hScrambler.scramble(txCodedBits);
        end
        
         txScrampledBitsLen(count)=length(txScrampledBits);
         
        % Symbol Mapping (QAM modulation) QAM调制
        txSymbols = hSymbolMapper.map(txScrampledBits);

        % OTFS Modulation OTFS调制
        txBlocks = reshape(txSymbols, nSubcarriers, nSymbolsPerBlock);
        txPrecodedBlocks = hPrecoder.encode(txBlocks);
        
        % OFDM Modulation OFDM调制
        txSignals = hOfdmModulator.modulate(txPrecodedBlocks);
        
        %% Channel信道
        % Fading Channel 衰落信道
        switch channelEstimationAlgorithm
            case {'Pilot-based iterative path estimation', 'Ideal'} 
                hFading.initRayleighFading();
                [distortedSignals, cir] = hFading.apply(txSignals, ddImpulseInTimeDomain);
            case 'PN-based iterative estimation'
                [distortedSignals, distortedPNSeq] = hFading.apply(txSignals, txPNSeq);
        end

        % AWGN Channel 高斯白噪声信道
        [noisySignals, ~] = hAwgn.add(distortedSignals, N0);
        
        %% Receiver接收端
        % OFDM Demodulator OFDM解调
        rxPrecodedBlocks = hOfdmModulator.demodulate(noisySignals(1:(nFft+nCyclicPrefix)*nSymbolsPerBlock));
      
        % OTFS Demodulator OTFS解调
        rxBlocks = hPrecoder.decode(rxPrecodedBlocks);
      
        % Equalization (Ideal) 均衡
        switch channelEstimationAlgorithm
            case 'Pilot-based iterative path estimation'
                noisyCir = hAwgn.add(cir, N0);
      chanEst = hPrecoder.decode(hOfdmModulator.demodulate(noisyCir(1:(nFft+nCyclicPrefix)*nSymbolsPerBlock)));
      [estGains, estDopplers, estDelays, estOffsets] = hEstimator.estimate(chanEst, threshAlpha, threshBeta, noiseVar);  rxEqBlocks = hEqualizer.equalize(rxBlocks, estGains, estDopplers, estDelays, estOffsets, noiseVar, localUpdateThreshold);
            case 'PN-based iterative estimation'
 noisyPNSeq = hAwgn.add(distortedPNSeq, noiseVar*sqrt(nSubcarriers));
 [estGains, estDopplers, estDelays, estOffsets] = hEstimator.estimateIteratively(noisyPNSeq, txPNSeq, fDoppler*2);
 rxEqBlocks = hEqualizer.equalize(rxBlocks, estGains, estDopplers, estDelays, estOffsets, noiseVar, 0.01);
            case 'Ideal'
                chanEst = hPrecoder.decode(hOfdmModulator.demodulate(cir(1:(nFft+nCyclicPrefix)*nSymbolsPerBlock)));
                idealGains = hFading.pathRayleighGains;
                idealDopplers = hFading.pathDopplers;
                idealDelays = hFading.pathDelays;
                idealOffsets = hFading.pathOffsets;
  rxEqBlocks = hEqualizer.equalize(rxBlocks, idealGains, idealDopplers, idealDelays, idealOffsets, noiseVar);
        end
        

        rxSymbols = rxEqBlocks(:);
        % Symbol Demapping 符号解映射
        rxSoftBits = hSymbolMapper.demap(rxSymbols, noiseVar);
        % Channel Decoding 信道解码
        switch channelCoding
            case 'None'
                rxUncodedHardBits = rxSoftBits;
                rxHardBits = rxUncodedHardBits;
                if sum(xor(txBits, rxHardBits)) > 0
                    blockError = 1;
                else
                    blockError = 0;
                end
            case 'LTE'
                rxUncodedHardBits = hSymbolMapperUncoded.demap(rxSymbols);
                % Descrambling 解扰
                rxDescrambledBits = hScrambler.descramble(rxSoftBits);
                [rxHardBits, blockError] = hChannelCoder.decode(rxDescrambledBits);
        end
    
        
       % Bit Error Rate 计算误码率
        numBitErrors(count) = sum(xor(txBits, rxHardBits));
        numBitErrorsU(count)= sum(xor(txScrampledBits, rxUncodedHardBits));
        blockError2(count)=blockError;
    end
    
    simstatus.TotalBitErrors(snrIndex) = sum(numBitErrors);
    simstatus.BER(snrIndex) = simstatus.TotalBitErrors(snrIndex)/(simIterations(snrIndex)*nBitsPerBlock);
    simstatus.TotalBlockErrors(snrIndex) = simstatus.TotalBlockErrors(snrIndex) + sum(blockError2);
    simstatus.BLER(snrIndex) = simstatus.TotalBlockErrors(snrIndex)/simIterations(snrIndex);
    
    simstatus.TotalUncodedBitErrors(snrIndex) =  sum(numBitErrorsU);
    simstatus.UncodedBER(snrIndex) = simstatus.TotalUncodedBitErrors(snrIndex)/(simIterations(snrIndex)*txScrampledBitsLen(1));
    
    fprintf('[%5d /%5d] BLER: %1.4f, BER: %1.7f (%9d/ %9d)', simIterations(snrIndex), simIterations(snrIndex), simstatus.BLER(snrIndex), simstatus.UncodedBER(snrIndex), simstatus.TotalUncodedBitErrors(snrIndex), simIterations(snrIndex)*txScrampledBitsLen(1));
    
    computationTime = toc;
    computationTimePerIteration = computationTime/simIterations(snrIndex);
    fprintf('  Computation Time : %f sec. (as per iteration)\n', computationTimePerIteration);
    
    simstatus.ComputeTime(snrIndex) = computationTimePerIteration;
end

BER=simstatus.BER;
BLER=simstatus.BLER;

%% %%%%%%%%%%%%%%%%%%%%%%% function END %%%%%%%%%%%%%%%%%%%%%%% %%
end

OTFS复现1.0_第1张图片

你可能感兴趣的:(数字通信)