OFDM modulation and OTFS modulation (matlab simulation)

 Bit error rate simulation based on OFDM system

        Orthogonal frequency division multiplexing (OFDM) is one of the multi-carrier modulation technologies. The basic principle is to divide the transmission channel into several orthogonal sub-channels, convert the high-speed data stream into parallel low-speed sub-data streams, and modulate each sub-channel. transmitted on the channel. It can use inverse fast Fourier transform (IFFT) and fast Fourier transform (FFT) to complete the modulation and demodulation of data. Since the rate of data transmission on sub-channels is low, when passing through a wireless frequency selective fading channel, each sub-channel can be regarded as flat fading. As long as appropriate frequency equalization is performed, the impact of fading can be overcome. And by using the periodic cycle characteristics of IFFT, a guard interval of a certain length can be inserted before each transmission symbol to eliminate the impact of multipath channels and prevent inter-code interference.

        This article decided to use the OFDM system to build the simulation system. First, because the principles of OFDM modulation and demodulation were explained in detail in the digital communication class, it is easier to continue to study in depth. Second, the understanding of OFDM system simulation can be deepened by studying the simulation principles of the OFDM system. Understanding of course content. The general process of OFDM is shown in the figure below.

Figure 3-4 System module block diagram

As can be seen from the system module in the figure above, the input data stream first undergoes serial-to-parallel conversion to realize the distinction of OFDM time-frequency blocks, and then converts the frequency domain signal into a time domain transmission signal through constellation mapping and IFFT transformation. Finally, a cyclic prefix is ​​added and up-converted. emission. The receiver performs the opposite operation after down-conversion. This article first performs simulation under Gaussian white noise channel. Without loss of generality, the simulation conditions are set as follows

Table simulation parameter settings

parameter

value

Number of system subcarriers

512

Number of simulation frames

100

Number of OFDM symbols per frame

6

Modulation system

4,16,64

cyclic prefix

16

cyclic suffix

16

signal-to-noise ratio

0-20dB

FFT length

64

Set the simulation conditions in the above table in MATLAB, use the program to generate random messages, and go through the processes of serial-to-parallel conversion, IFFT and FFT, constellation mapping and adding cyclic prefixes and suffixes in the system block diagram to realize the construction of a basic OFDM communication system. This article first Considering the additive Gaussian white noise channel, the figure below shows the time domain diagram and frequency domain diagram of the OFDM transmitted signal. From the figure below, it can be seen that the time domain emission waveform of the OFDM signal generated by IFFT and the subcarriers generated by the superposition of multiple carriers It has the same effect, demonstrating the correctness of the theoretical analysis.

(a) Time domain waveform (b) Frequency domain waveform

Figure OFDM time-frequency domain diagram display

After down-conversion, the receiver performs decyclic prefix and FFT transformation on the received signal, and then performs constellation mapping. The following figure shows the receiver constellation mapping.

 

(a) QPSK                                            (b)16QAM

Figure OFDM receiving constellation diagram

As can be seen from the above figure, when the received signal-to-noise ratio is 10dB, the receiving constellation diagram of QPSK is obviously clearer than the 16QAM constellation diagram. Increasing the modulation order of the signal will increase the bit error rate at the receiving end. The following figure shows The bit error rate of different modulation methods changes with the signal-to-noise ratio.

Figure bit error rate under different modulation methods

It can be seen from the changing trend in the above figure that as the modulation method increases, the bit error rate gradually increases. When the modulation order is too large, the communication bit error rate requirements cannot be met. Therefore, certain improvements are needed in the OFDM system. At present, The main ways to reduce the system bit error rate are: (1) insert pilots to estimate and equalize the channel; (2) add spreading codes and use frequency resources to increase the bit error rate; (3) perform channel coding and use Convolutional codes are used to achieve certain error correction functions. The figure below shows the internal structural block diagram of the more complex transceiver of the OFDM system:

Figure 3-5 OFDM transceiver structural block diagram

The improved OFDM system will have certain channel estimation and equalization capabilities, error correction capabilities, and anti-noise interference capabilities. The following figure shows the update process.

(a) Add convolutional code (b) Add spreading code

(c) Add pilot

Figure OFDM system update process

The above figure shows the bit error rate curve after adding convolution codes, spreading codes and pilots in sequence under the 16QAM modulation method. Obviously, as different methods are added and improved, the bit error rate drops significantly. Among them, Figure (a) shows the bit error rate comparison chart after adding channel coding. This paper adds (2,1,4), (2,1,5), (2,1,7) convolutional codes respectively. The basic principle of convolutional codes is to increase the coupling between each symbol. It is a memory code and has a certain error correction ability. As can be seen from the above figure, the longer the register for adding coding, the better the performance, but the corresponding structure is also The more complex it becomes, the following figure shows the basic diagram of (2,1,3) convolutional code

Figure (2,1,3) Schematic diagram of convolutional code

Figure (b) shows the bit error rate comparison chart after adding the spreading code. The essence of the spreading code is to use bandwidth resources in exchange for transmission reliability. It has a good suppression effect on noise during the process of spreading and despreading. , this article shows the effects of adding 3rd and 4th order m-sequences respectively. The results show that adding spreading codes can further reduce the bit error rate. The higher the order of the m-sequence, the better the effect of suppressing noise. Not only in the field of communications, but also in the field of navigation, it also plays a role in encryption and ranging, and is a core element of the current navigation system.

Figure (c) shows the bit error rate after adding channel estimation. It can be found from the figure that adding pilots for channel estimation can further reduce the bit error rate. The basic principle of pilots is to mix pilot sequences into data codes. Through difference fitting, the channel response is estimated and compensated and equalized to reduce the impact of the channel on signal transmission. The figure below shows several basic pilot insertion methods.

Picture pilot insertion

 Bit error rate simulation based on OTFS system

In the above performance analysis of the OFDM system, the channel modeling is relatively simple and the influence of Doppler frequency shift in high-speed mobile scenarios is not considered. However, the channel with frequency selective fading is more in line with the modeling and analysis of real scenarios. For further analysis The performance and shortcomings of OFDM modulation make it easy to find improvement methods and strategies. This article uses the high-speed mobile scenario as the background, adds the simulation parameters shown in the following table, and uses the jakes model to generate a single-path flat Rayleigh fading channel.

Table simulation parameter settings

parameter

value

Relative velocity

120 km/h

subcarrier spacing

1.5 kHz

System bandwidth

10^3 kHz

Figure Rayleigh fading channel simulation

The modulation waveforms used in fifth-generation (5G) communication systems are based on orthogonal frequency division multiplexing (OFDM). In high-mobility scenarios, communication reliability and data rates will significantly decrease. Compared with OFDM, orthogonal time-frequency space (OTFS) modulation is robust to the Doppler shift of the channel. R. Hadani proposed a new modulation method - orthogonal time-frequency space (OTFS) modulation. The basic process framework is as follows

Figure OTFS basic process

OTFS modulation technology modulates data in the Delay Doppler domain instead of the traditional time-frequency domain (TF). Relying on the signal representation of the DD domain, it has the advantages of strong Doppler resistance and delay resistance for highly dynamic and complex environments. By transforming the unit from the TF domain to the DD domain, the desired properties such as signal separability, compactness, stability, and possibly sparsity can be achieved. These properties can be exploited for accurate channel estimation and low training overhead as well as low-complexity signal detection.

Figure OTFS diagram

Compared with OFDM systems, OTFS requires an additional OTFS conversion at the transmitting and receiving locations to complete the conversion between the Doppler-delay domain and the time-frequency domain. As shown in the figure above, using the DD domain to modulate information makes the distinction between different signals clearer and is more suitable for communication in high-speed motion scenarios. However, the core idea is still similar: load information on a domain that is more susceptible to signal processing. For example, in traditional OFDM systems, for frequency-selective multipath scenarios, signal processing directly in the time domain will be very complicated. However, by loading information on subcarriers, the difficulty of signal processing will be greatly reduced due to the flatness of each subcarrier. Compared with OFDM, OTFS also takes time variability into account.

Figure OTFS performance comparison

The above figure shows the comparison of bit error rates between OFDM and OTFS modulation under the same environmental parameters. From the above figure, it can be found that in high-speed mobile scenarios, the OFDM bit error rate increases significantly, and OFDM is difficult to adapt to high-speed mobile scenarios. It can also be seen from the above figure that OTFS shows better bit error rate performance than OFDM in high-speed mobile scenarios, and the bit error rate is significantly reduced after adding encoding, and the bit error performance is improved by more than 50%.

In summary, OTFS modulation, as a new modulation method, has considerable potential in improving transmission reliability in future high-speed mobile scenarios. However, at the same time, there are still many problems that need to be solved in OTFS modulation, such as channel estimation and modulation complexity. Currently, OFDM systems are widely used in 5G communications, and existing OFDM systems will remain the mainstream modulation method for a long time to come.

OFDM MATLAB code

%%   OFDM通信系统演示模型
%   Copyright 2023, NUDT
%
%   nudt   
%
%   说明:
%       OFDM通信演示模型
%
%   输入:
%       无
%   输出:
%       无
%
%   原始作者:Tim Liu
%   建立日期:2023年11月20日
%
%   更新历史:
%

clear;

%--------------------------------------------------------------------------
% 定义仿真参数
%--------------------------------------------------------------------------
M = 16;                         % 调制阵列大小
k = log2(M);                    % 每个符号的比特数
cpSize = 0.07;                  % OFDM循环前缀大小
scs = 15e3;                     % 子载波间距,单位赫兹
Bw = 10e6;                      % 系统带宽,单位赫兹
ofdmSym = 14;                   % 每个子帧的OFDM符号数
EbNo = (-3:1:30)';              % 每比特能量与噪声功率之比的范围
velocity = 120;                 % 移动接收机相对于发送机的速度,单位千米/小时
codeRate = 2/4;                 % 使用的FEC编码效率
maxIterations = 25;             % LDPC解码器的最大迭代次数
totalBits = 1e6;                % 模拟的总比特数
repeats = 1;                    % 仿真重复次数 

%--------------------------------------------------------------------------
% 初始化仿真组件
%--------------------------------------------------------------------------

% 初始化OFDM调制/解调变量
numSC = pow2(ceil(log2(Bw/scs))); % 计算最接近的2的幂的OFDM子载波数
cpLen = floor(cpSize * numSC);    % 计算循环前缀长度
numDC = (numSC - 12);             % 计算数据载波数

% 初始化AWGN信道
awgnChannel = comm.AWGNChannel('NoiseMethod','Variance', 'VarianceSource','Input port');
errorRate = comm.ErrorRate('ResetInputPort',true);
errorRate1 = comm.ErrorRate('ResetInputPort',true);

% 初始化LDPC编码器/解码器
parityCheck_matrix = dvbs2ldpc(codeRate);               
ldpcEncoder = comm.LDPCEncoder(parityCheck_matrix);     
ldpcDecoder = comm.LDPCDecoder(parityCheck_matrix);     
ldpcDecoder.MaximumIterationCount = maxIterations;      
noCodedbits = size(parityCheck_matrix,2);               

% 创建用于存储误差数据的向量
berOFDM = zeros(length(EbNo),3); 
berCOFDM = zeros(length(EbNo),3);
berOTFS = zeros(length(EbNo),3);
berCOTFS = zeros(length(EbNo),3);
errorStats_coded = zeros(1,3);
errorStats_uncoded = zeros(1,3);

for repetition=1:repeats                                % 使用每次不同信道重复仿真
    
    % 生成和编码数据
    [dataIn, dataBits_in, codedData_in, packetSize, numPackets, numCB] = dataGen(k,numDC,ofdmSym,totalBits,codeRate,ldpcEncoder);
    
    % 生成瑞利衰落信道脉冲响应
    txSig_size = zeros((numSC+cpLen),ofdmSym);                       
    rayChan = multipathChannel(cpSize, scs, txSig_size, velocity); 

    % QAM调制
    qamTx = qammod(dataIn,M,'InputType','bit','UnitAveragePower',true);    
    parallelTx = reshape(qamTx,[numDC,ofdmSym*packetSize]);                
    guardbandTx = [zeros(1,ofdmSym*packetSize); parallelTx];
    guardbandTx = [guardbandTx(1:(numDC/2),:); zeros(11,ofdmSym*packetSize); guardbandTx((numDC/2)+1:end,:)];
    
%--------------------------------------------------------------------------
%                       OFDM误码率计算
%--------------------------------------------------------------------------
    
    % 计算信噪比
    snr = EbNo + 10*log10(codeRate*k) + 10*log10(numDC/((numSC)));
    
    % 多载波调制
    frameBuffer = guardbandTx;          
    txframeBuffer = [];                 
    for w = 1:packetSize
        ofdmTx = modOFDM(frameBuffer(:,1:ofdmSym),numSC,cpLen,ofdmSym);    
        frameBuffer(:, 1:ofdmSym) = [];                                    
        txframeBuffer = [txframeBuffer;ofdmTx];                            
    end
    
    % 循环不同的EbNo值
    for m = 1:length(EbNo)
        % 循环传输的数据包
        for j = 1:numPackets
            rxframeBuffer = [];                 
            
            % 逐个传输每个子帧
            for u = 1:packetSize
                
                txSig = txframeBuffer( ((u-1)*numel(ofdmTx)+1) : u*numel(ofdmTx) );
                
                % 将信道应用到输入信号
%                 fadedSig1 = zeros(size(txSig));                    
%                 for i = 1:size(txSig,1)                           
%                     for j = 1:size(txSig,2)                       
%                         fadedSig1(i,j) = txSig(i,j).*rayChan(i,j);
%                     end
%                 end
                fadedSig=txSig;

                % AWGN信道
                release(awgnChannel);
                powerDB = 10*log10(var(fadedSig));            
                noiseVar = 10.^(0.1*(powerDB-snr(m)));        
                rxSig = awgnChannel(fadedSig,noiseVar);       
                
                % 均衡
                eqSig = equaliser(rxSig,fadedSig,txSig,ofdmSym);
                
                % 解调
                rxSubframe = demodOFDM(eqSig,cpLen,ofdmSym);     
                rxframeBuffer = [rxframeBuffer';rxSubframe']';         
            end
            
            parallelRx = rxframeBuffer;
            parallelRx((numDC/2)+1:(numDC/2)+11, :) = [];     
            parallelRx(1:1, :) = [];                          
            qamRx = reshape(parallelRx,[numel(parallelRx),1]); 
            dataOut = qamdemod(qamRx,M,'OutputType','bit','UnitAveragePower',true); 
            codedData_out = randdeintrlv(dataOut,4831);                            
            codedData_out(numel(codedData_in)+1:end) = [];                         
            errorStats_uncoded = errorRate(codedData_in,codedData_out,0);          

            powerDB = 10*log10(var(qamRx));                                   
            noiseVar = 10.^(0.1*(powerDB-(EbNo(m) + 10*log10(codeRate*k) - 10*log10(sqrt(numDC)))));            
            dataOut = qamdemod(qamRx,M,'OutputType', 'approxllr','UnitAveragePower',true,'NoiseVariance',noiseVar);
            codedData_out1 = randdeintrlv(dataOut,4831);                      
            codedData_out1(numel(codedData_in)+1:end) = [];                   
            dataBits_out = [];                                                
            dataOut_buffer = codedData_out1;
            for q = 1:numCB
                dataBits_out = [dataBits_out;ldpcDecoder(dataOut_buffer(1:noCodedbits))]; 
                dataOut_buffer(1:noCodedbits) = [];                                       
            end
            dataBits_out = double(dataBits_out);                              
            errorStats_coded = errorRate1(dataBits_in,dataBits_out,0);        
        
        end
        berOFDM(m,:) = errorStats_uncoded;                                  
        berCOFDM(m,:) = errorStats_coded;                                   
        errorStats_uncoded = errorRate(codedData_in,codedData_out,1);       
        errorStats_coded = errorRate1(dataBits_in,dataBits_out,1);          
    end
%--------------------------------------------------------------------------
%                       OTFS误码率计算
%--------------------------------------------------------------------------

    % 计算信噪比
    snr = EbNo + 10*log10(codeRate*k) + 10*log10(numDC/((numSC))) + 10*log10(sqrt(ofdmSym));
    
    % 多载波调制
    frameBuffer = guardbandTx;          % 创建一个“缓冲区”,以便可以单独调制子帧
    txframeBuffer = [];                 % 初始化矩阵
    for w = 1:packetSize
        otfsTx = ISFFT(frameBuffer(:,1:ofdmSym));       % 对数据的子帧应用OTFS调制
        ofdmTx = modOFDM(otfsTx,numSC,cpLen,ofdmSym);    % 应用OFDM调制
        frameBuffer(:, 1:ofdmSym) = [];                  % 从frameBuffer中删除调制后的数据
        txframeBuffer = [txframeBuffer;ofdmTx];          % 将调制后的子帧添加到传输缓冲区
    end
    
    % 循环遍历不同的EbNo值
    for m = 1:length(EbNo)
        % 循环遍历要传输的数据包
        for j = 1:numPackets
            rxframeBuffer = [];                 % 初始化矩阵
            
            % 单独传输每个子帧
            for u = 1:packetSize
                
                % 从传输缓冲区中移除下一个子帧
                txSig = txframeBuffer( ((u-1)*numel(ofdmTx)+1) : u*numel(ofdmTx) );
                
                % 将信道应用到输入信号
                fadedSig = zeros(size(txSig));                    % 预先分配向量大小
                for i = 1:size(txSig,1)                           % 执行逐元素...
                    for j = 1:size(txSig,2)                       % ...矩阵乘法
                        fadedSig(i,j) = txSig(i,j).*rayChan(i,j);
                    end
                end
                fadedSig = txSig.*rayChan;
                % AWGN信道
                release(awgnChannel);
                powerDB = 10*log10(var(fadedSig));                 % 计算发送信号功率
                noiseVar = 10.^(0.1*(powerDB-snr(m)));             % 计算噪声方差
                rxSig = awgnChannel(fadedSig,noiseVar);            % 通过有噪声的信道传递信号
                
                % 均衡
                eqSig = equaliser(rxSig,fadedSig,txSig,ofdmSym);
                
                % 解调
                otfsRx = demodOFDM(eqSig,cpLen,ofdmSym);           % 应用OFDM解调
                rxSubframe = SFFT(otfsRx);                         % 应用OTFS解调
                rxframeBuffer = [rxframeBuffer';rxSubframe']';     % 将解调后的子帧存储在rx缓冲区中
            end
            % 移除所有空载波
            parallelRx = rxframeBuffer;
            parallelRx((numDC/2)+1:(numDC/2)+11, :) = [];         % 移除中心DC周围的空载波
            parallelRx(1:1, :) = [];                              % 移除索引1处的空载波
            qamRx = reshape(parallelRx,[numel(parallelRx),1]);    % 转换为串行
            
            % 对整个数据包进行无编码解调
            dataOut = qamdemod(qamRx,M,'OutputType','bit','UnitAveragePower',true);% 应用QAM解调
            codedData_out = randdeintrlv(dataOut,4831);                            % 反交织数据
            codedData_out(numel(codedData_in)+1:end) = [];                         % 移除填充位
            errorStats_uncoded = errorRate(codedData_in,codedData_out,0);          % 收集误码统计信息

            % 对整个数据包进行编码解调
            powerDB = 10*log10(var(qamRx));                                   % 计算接收信号功率
            noiseVar = 10.^(0.1*(powerDB-(EbNo(m) + 10*log10(codeRate*k) - 10*log10(sqrt(numDC)))));            % 计算噪声方差
            dataOut = qamdemod(qamRx,M,'OutputType', 'approxllr','UnitAveragePower',true,'NoiseVariance',noiseVar);% 应用QAM解调
            codedData_out1 = randdeintrlv(dataOut,4831);                      % 反交织数据
            codedData_out1(numel(codedData_in)+1:end) = [];                   % 移除填充位
            
            % 解码各个码块
            dataBits_out = [];                                                % 初始化矩阵
            dataOut_buffer = codedData_out1;
            for q = 1:numCB
                dataBits_out = [dataBits_out;ldpcDecoder(dataOut_buffer(1:noCodedbits))]; % 解码数据并将其添加到数据位输出矩阵中
                dataOut_buffer(1:noCodedbits) = [];                                       % 从缓冲区中删除已解码的数据
            end
            dataBits_out = double(dataBits_out);                              % 转换为与errorStats兼容的double类型
            errorStats_coded = errorRate1(dataBits_in,dataBits_out,0);     % 收集误码统计信息

        end
        berOTFS(m,:) = errorStats_uncoded;                                  % 保存无编码BER数据
        berCOTFS(m,:) = errorStats_coded;                                   % 保存编码BER数据
        errorStats_uncoded = errorRate(codedData_in,codedData_out,1);       % 重置误码率计算器
        errorStats_coded = errorRate1(dataBits_in,dataBits_out,1);          % 重置误码率计算器
        
    end
    
end

%--------------------------------------------------------------------------
%                           图表
%-------------------------------------------------------------------------- 

% 绘制BER / EbNo曲线
plotGraphs(berOFDM, berCOFDM, berOTFS, berCOTFS, M, numSC, EbNo);

OTFS MATLAB main code 

clear;

%--------------------------------------------------------------------------
% 定义仿真参数
%--------------------------------------------------------------------------
M = 16;                         % 调制阵列大小
k = log2(M);                    % 每个符号的比特数
cpSize = 0.07;                  % OFDM循环前缀大小
scs = 15e3;                     % 子载波间距,单位赫兹
Bw = 10e6;                      % 系统带宽,单位赫兹
ofdmSym = 14;                   % 每个子帧的OFDM符号数
EbNo = (-3:1:30)';              % 每比特能量与噪声功率之比的范围
velocity = 120;                 % 移动接收机相对于发送机的速度,单位千米/小时
codeRate = 2/4;                 % 使用的FEC编码效率
maxIterations = 25;             % LDPC解码器的最大迭代次数
totalBits = 1e6;                % 模拟的总比特数
repeats = 1;                    % 仿真重复次数 

%--------------------------------------------------------------------------
% 初始化仿真组件
%--------------------------------------------------------------------------

% 初始化OFDM调制/解调变量
numSC = pow2(ceil(log2(Bw/scs))); % 计算最接近的2的幂的OFDM子载波数
cpLen = floor(cpSize * numSC);    % 计算循环前缀长度
numDC = (numSC - 12);             % 计算数据载波数

% 初始化AWGN信道
awgnChannel = comm.AWGNChannel('NoiseMethod','Variance', 'VarianceSource','Input port');
errorRate = comm.ErrorRate('ResetInputPort',true);
errorRate1 = comm.ErrorRate('ResetInputPort',true);

% 初始化LDPC编码器/解码器
parityCheck_matrix = dvbs2ldpc(codeRate);               
ldpcEncoder = comm.LDPCEncoder(parityCheck_matrix);     
ldpcDecoder = comm.LDPCDecoder(parityCheck_matrix);     
ldpcDecoder.MaximumIterationCount = maxIterations;      
noCodedbits = size(parityCheck_matrix,2);               

% 创建用于存储误差数据的向量
berOFDM = zeros(length(EbNo),3); 
berCOFDM = zeros(length(EbNo),3);
berOTFS = zeros(length(EbNo),3);
berCOTFS = zeros(length(EbNo),3);
errorStats_coded = zeros(1,3);
errorStats_uncoded = zeros(1,3);

for repetition=1:repeats                                % 使用每次不同信道重复仿真
    
    % 生成和编码数据
    [dataIn, dataBits_in, codedData_in, packetSize, numPackets, numCB] = dataGen(k,numDC,ofdmSym,totalBits,codeRate,ldpcEncoder);
    
    % 生成瑞利衰落信道脉冲响应
    txSig_size = zeros((numSC+cpLen),ofdmSym);                       
    rayChan = multipathChannel(cpSize, scs, txSig_size, velocity); 

    % QAM调制
    qamTx = qammod(dataIn,M,'InputType','bit','UnitAveragePower',true);    
    parallelTx = reshape(qamTx,[numDC,ofdmSym*packetSize]);                
    guardbandTx = [zeros(1,ofdmSym*packetSize); parallelTx];
    guardbandTx = [guardbandTx(1:(numDC/2),:); zeros(11,ofdmSym*packetSize); guardbandTx((numDC/2)+1:end,:)];
    
%--------------------------------------------------------------------------
%                       OFDM误码率计算
%--------------------------------------------------------------------------
    
    % 计算信噪比
    snr = EbNo + 10*log10(codeRate*k) + 10*log10(numDC/((numSC)));
    
    % 多载波调制
    frameBuffer = guardbandTx;          
    txframeBuffer = [];                 
    for w = 1:packetSize
        ofdmTx = modOFDM(frameBuffer(:,1:ofdmSym),numSC,cpLen,ofdmSym);    
        frameBuffer(:, 1:ofdmSym) = [];                                    
        txframeBuffer = [txframeBuffer;ofdmTx];                            
    end
    
    % 循环不同的EbNo值
    for m = 1:length(EbNo)
        % 循环传输的数据包
        for j = 1:numPackets
            rxframeBuffer = [];                 
            
            % 逐个传输每个子帧
            for u = 1:packetSize
                
                txSig = txframeBuffer( ((u-1)*numel(ofdmTx)+1) : u*numel(ofdmTx) );
                
                % 将信道应用到输入信号
%                 fadedSig1 = zeros(size(txSig));                    
%                 for i = 1:size(txSig,1)                           
%                     for j = 1:size(txSig,2)                       
%                         fadedSig1(i,j) = txSig(i,j).*rayChan(i,j);
%                     end
%                 end
                fadedSig=txSig;

                % AWGN信道
                release(awgnChannel);
                powerDB = 10*log10(var(fadedSig));            
                noiseVar = 10.^(0.1*(powerDB-snr(m)));        
                rxSig = awgnChannel(fadedSig,noiseVar);       
                
                % 均衡
                eqSig = equaliser(rxSig,fadedSig,txSig,ofdmSym);
                
                % 解调
                rxSubframe = demodOFDM(eqSig,cpLen,ofdmSym);     
                rxframeBuffer = [rxframeBuffer';rxSubframe']';         
            end
            
            parallelRx = rxframeBuffer;
            parallelRx((numDC/2)+1:(numDC/2)+11, :) = [];     
            parallelRx(1:1, :) = [];                          
            qamRx = reshape(parallelRx,[numel(parallelRx),1]); 
            dataOut = qamdemod(qamRx,M,'OutputType','bit','UnitAveragePower',true); 
            codedData_out = randdeintrlv(dataOut,4831);                            
            codedData_out(numel(codedData_in)+1:end) = [];                         
            errorStats_uncoded = errorRate(codedData_in,codedData_out,0);          

            powerDB = 10*log10(var(qamRx));                                   
            noiseVar = 10.^(0.1*(powerDB-(EbNo(m) + 10*log10(codeRate*k) - 10*log10(sqrt(numDC)))));            
            dataOut = qamdemod(qamRx,M,'OutputType', 'approxllr','UnitAveragePower',true,'NoiseVariance',noiseVar);
            codedData_out1 = randdeintrlv(dataOut,4831);                      
            codedData_out1(numel(codedData_in)+1:end) = [];                   
            dataBits_out = [];                                                
            dataOut_buffer = codedData_out1;
            for q = 1:numCB
                dataBits_out = [dataBits_out;ldpcDecoder(dataOut_buffer(1:noCodedbits))]; 
                dataOut_buffer(1:noCodedbits) = [];                                       
            end
            dataBits_out = double(dataBits_out);                              
            errorStats_coded = errorRate1(dataBits_in,dataBits_out,0);        
        
        end
        berOFDM(m,:) = errorStats_uncoded;                                  
        berCOFDM(m,:) = errorStats_coded;                                   
        errorStats_uncoded = errorRate(codedData_in,codedData_out,1);       
        errorStats_coded = errorRate1(dataBits_in,dataBits_out,1);          
    end
%--------------------------------------------------------------------------
%                       OTFS误码率计算
%--------------------------------------------------------------------------

    % 计算信噪比
    snr = EbNo + 10*log10(codeRate*k) + 10*log10(numDC/((numSC))) + 10*log10(sqrt(ofdmSym));
    
    % 多载波调制
    frameBuffer = guardbandTx;          % 创建一个“缓冲区”,以便可以单独调制子帧
    txframeBuffer = [];                 % 初始化矩阵
    for w = 1:packetSize
        otfsTx = ISFFT(frameBuffer(:,1:ofdmSym));       % 对数据的子帧应用OTFS调制
        ofdmTx = modOFDM(otfsTx,numSC,cpLen,ofdmSym);    % 应用OFDM调制
        frameBuffer(:, 1:ofdmSym) = [];                  % 从frameBuffer中删除调制后的数据
        txframeBuffer = [txframeBuffer;ofdmTx];          % 将调制后的子帧添加到传输缓冲区
    end
    
    % 循环遍历不同的EbNo值
    for m = 1:length(EbNo)
        % 循环遍历要传输的数据包
        for j = 1:numPackets
            rxframeBuffer = [];                 % 初始化矩阵
            
            % 单独传输每个子帧
            for u = 1:packetSize
                
                % 从传输缓冲区中移除下一个子帧
                txSig = txframeBuffer( ((u-1)*numel(ofdmTx)+1) : u*numel(ofdmTx) );
                
                % 将信道应用到输入信号
                fadedSig = zeros(size(txSig));                    % 预先分配向量大小
                for i = 1:size(txSig,1)                           % 执行逐元素...
                    for j = 1:size(txSig,2)                       % ...矩阵乘法
                        fadedSig(i,j) = txSig(i,j).*rayChan(i,j);
                    end
                end
                fadedSig = txSig.*rayChan;
                % AWGN信道
                release(awgnChannel);
                powerDB = 10*log10(var(fadedSig));                 % 计算发送信号功率
                noiseVar = 10.^(0.1*(powerDB-snr(m)));             % 计算噪声方差
                rxSig = awgnChannel(fadedSig,noiseVar);            % 通过有噪声的信道传递信号
                
                % 均衡
                eqSig = equaliser(rxSig,fadedSig,txSig,ofdmSym);
                
                % 解调
                otfsRx = demodOFDM(eqSig,cpLen,ofdmSym);           % 应用OFDM解调
                rxSubframe = SFFT(otfsRx);                         % 应用OTFS解调
                rxframeBuffer = [rxframeBuffer';rxSubframe']';     % 将解调后的子帧存储在rx缓冲区中
            end
            % 移除所有空载波
            parallelRx = rxframeBuffer;
            parallelRx((numDC/2)+1:(numDC/2)+11, :) = [];         % 移除中心DC周围的空载波
            parallelRx(1:1, :) = [];                              % 移除索引1处的空载波
            qamRx = reshape(parallelRx,[numel(parallelRx),1]);    % 转换为串行
            
            % 对整个数据包进行无编码解调
            dataOut = qamdemod(qamRx,M,'OutputType','bit','UnitAveragePower',true);% 应用QAM解调
            codedData_out = randdeintrlv(dataOut,4831);                            % 反交织数据
            codedData_out(numel(codedData_in)+1:end) = [];                         % 移除填充位
            errorStats_uncoded = errorRate(codedData_in,codedData_out,0);          % 收集误码统计信息

            % 对整个数据包进行编码解调
            powerDB = 10*log10(var(qamRx));                                   % 计算接收信号功率
            noiseVar = 10.^(0.1*(powerDB-(EbNo(m) + 10*log10(codeRate*k) - 10*log10(sqrt(numDC)))));            % 计算噪声方差
            dataOut = qamdemod(qamRx,M,'OutputType', 'approxllr','UnitAveragePower',true,'NoiseVariance',noiseVar);% 应用QAM解调
            codedData_out1 = randdeintrlv(dataOut,4831);                      % 反交织数据
            codedData_out1(numel(codedData_in)+1:end) = [];                   % 移除填充位
            
            % 解码各个码块
            dataBits_out = [];                                                % 初始化矩阵
            dataOut_buffer = codedData_out1;
            for q = 1:numCB
                dataBits_out = [dataBits_out;ldpcDecoder(dataOut_buffer(1:noCodedbits))]; % 解码数据并将其添加到数据位输出矩阵中
                dataOut_buffer(1:noCodedbits) = [];                                       % 从缓冲区中删除已解码的数据
            end
            dataBits_out = double(dataBits_out);                              % 转换为与errorStats兼容的double类型
            errorStats_coded = errorRate1(dataBits_in,dataBits_out,0);     % 收集误码统计信息

        end
        berOTFS(m,:) = errorStats_uncoded;                                  % 保存无编码BER数据
        berCOTFS(m,:) = errorStats_coded;                                   % 保存编码BER数据
        errorStats_uncoded = errorRate(codedData_in,codedData_out,1);       % 重置误码率计算器
        errorStats_coded = errorRate1(dataBits_in,dataBits_out,1);          % 重置误码率计算器
        
    end
    
end

%--------------------------------------------------------------------------
%                           图表
%-------------------------------------------------------------------------- 

% 绘制BER / EbNo曲线
plotGraphs(berOFDM, berCOFDM, berOTFS, berCOTFS, M, numSC, EbNo);

The complete OTFS code can be sent via private message 

Guess you like

Origin blog.csdn.net/weixin_53750855/article/details/134578415