对 16-QAM 信号使用前向纠错
此示例对对 16-QAM 信号使用脉冲整形示例进行了扩展,以展示使用前向纠错 (FEC) 编码时误码率 (BER) 性能的改进。
此示例说明如何使用由基带调制器、信道、解调器、脉冲整形、升余弦滤波和纠错组成的通信链路处理二进制数据流。
建立仿真框架
在此示例中,为了实现更准确的 BER 估计,要处理的位数相比对 16-QAM 信号使用脉冲整形示例中使用的值有所增加。其他仿真变量与该示例中的设置一致。
为具有升余弦滤波和 AWGN 信道的 16-QAM 调制方案定义仿真参数。
M = 16; % Modulation order k = log2(M); % Bits per symbol numBits = k*2.5e5; % Total bits to process sps = 4; % Samples per symbol (oversampling factor) filtlen = 10; % Filter length in symbols rolloff = 0.25; % Filter rolloff factor
生成随机数据
将 rng
函数设置为其默认状态或任何静态种子值,以便示例产生可复现的结果。然后,使用 randi
函数生成随机二进制数据。
rng default; % Default random number generator dataIn = randi([0 1],numBits,1); % Generate vector of binary data
应用卷积编码
为了校正由含噪信道引起的错误,在发射前对数据应用卷积编码,并对收到的数据应用 Viterbi 解码。解码器使用硬决策算法,这意味着收到的每个数据位都解释为 0
或 1
。
使用 poly2trellis
函数为 2/3 码率的码定义卷积编码网格。定义的网格表示 convenc
函数用于对二进制向量 dataIn
进行编码的卷积码。
constrlen = [5 4]; % Code constraint length genpoly = [23 35 0; 0 5 13] % Generator polynomials
genpoly = 2×3
23 35 0
0 5 13
tPoly = poly2trellis(constrlen,genpoly); codeRate = 2/3;
使用 tPoly
网格对输入数据进行编码。
dataEnc = convenc(dataIn,tPoly);
调制数据
使用 bit2int
函数将 k
元组编码的二进制数据转换为整数值。
dataSymbolsIn = bit2int(dataEnc,k);
使用 qammod
函数应用 16-QAM 调制。
dataMod = qammod(dataSymbolsIn,M);
应用升余弦滤波
使用 rcosdesign
函数创建一个 RRC 滤波器。
rrcFilter = rcosdesign(rolloff,filtlen,sps);
使用 upfirdn
函数按过采样因子对信号进行上采样并应用 RRC 滤波器。upfirdn
函数会在上采样信号末尾填充零,以刷新滤波器。然后,该函数应用该滤波器。
txSignal = upfirdn(dataMod,rrcFilter,sps,1);
应用 AWGN 信道
使用每符号的位数、每符号的采样数、码率和 convertSNR
函数将每比特能量与噪声功率谱密度之比 (EbNo
) 转换为 SNR 值,以供 awgn
函数使用。将 转换为 SNR 时,必须考虑每符号的信息位数。在不应用 FEC 的情况下,每个符号对应 k
个位。在应用 FEC 后,每个符号对应 (k
codeRate
) 个信息位。对于此示例中使用的 2/3 码率和 16-QAM 发射,三个符号对应 12 个编码位和 8 个未编码(信息)位。
EbNo = 10; snr = convertSNR(EbNo,'ebno', ... samplespersymbol=sps, ... bitspersymbol=k,CodingRate=codeRate);
使滤波后的信号通过 AWGN 信道。
rxSignal = awgn(txSignal,snr,'measured');
接收和解调信号
使用 RRC 滤波器对接收的信号进行滤波。删除信号的一部分以考虑滤波器延迟。
rxFiltSignal = ... upfirdn(rxSignal,rrcFilter,1,sps); % Downsample and filter rxFiltSignal = ... rxFiltSignal(filtlen + 1:end - filtlen); % Account for delay
使用 qamdemod
函数对接收的滤波信号进行解调。
dataSymbOut = qamdemod(rxFiltSignal,M);
应用 Viterbi 解码
使用 int2bit
函数将恢复的整数符号转换为二进制数据。
codedDataOut = int2bit(dataSymbOut,k); % Return data in column vector
使用针对硬决策和连续运算模式配置的 vitdec
函数对卷积编码数据进行解码。当重复调用解码器时(如循环接收数据帧时),连续运算模式保留内部状态。连续运算模式还会给系统引入延迟。尽管此示例不使用循环,但为了说明如何补偿此解码运算中的延迟,使用了 'cont
' 模式。
traceBack = 16; % Decoding traceback length numCodeWords = ... floor(length(codedDataOut)*2/3); % Number of complete codewords dataOut = ... vitdec(codedDataOut(1:numCodeWords*3/2), ... tPoly,traceBack,'cont','hard'); % Decode data
计算系统 BER
发射和接收 RRC 滤波器引入的延迟已在恢复的数据中考虑,但解码器延迟尚未考虑在内。Viterbi 解码器的连续运算模式会产生延迟,其持续时间(以位为单位)等于回溯长度 traceBack
乘以在编码器处的输入流数。对于此示例中使用的 2/3 码率,编码器有两个输入流,因此延迟为 2×traceBack
个位。因此,解码向量 dataOut
中的前 2×traceBack
个位为零。计算 BER 时,丢弃 dataOut
中的前 2×traceBack
个位和原始向量 dataIn
中的后 2×traceBack
个位。
使用 biterr
函数通过比较 dataIn
和 dataOut
来计算错误数和 BER。对于相同的 10 dB ,当处理链中包含 FEC 时,发生的错误更少。
decDelay = 2*traceBack; % Decoder delay, in bits [numErrors,ber] = ... biterr(dataIn(1:end - decDelay),dataOut(decDelay + 1:end)); fprintf('\nThe bit error rate is %5.2e, based on %d errors.\n', ... ber,numErrors)
The bit error rate is 6.40e-05, based on 64 errors.
关于延迟的更多信息
此示例中的解码运算会产生延迟,导致解码器的输出滞后于输入。示例中未明确出现时序信息,且延迟的长度取决于所执行的具体运算。延迟发生在各种通信系统运算中,包括卷积解码、卷积交织和解交织、均衡和滤波。要了解特定函数或运算引起的延迟的持续时间,请参阅这些函数或运算的具体文档。有关延迟的详细信息,请参阅Delays of Convolutional Interleavers和Fading Channels。