Main Content

La traduction de cette page n'est pas à jour. Cliquez ici pour voir la dernière version en anglais.

Utiliser la correction d’erreur sans voie de retour sur un signal 16-QAM

Cet exemple est une extension de l’exemple Utiliser la mise en forme d’impulsion sur un signal 16-QAM, pour montrer l’amélioration de performance du taux d’erreur bit (BER) avec l’utilisation du codage de correction d’erreur sans voie de retour (FEC).

Cet exemple explique comment traiter un stream de données binaires en utilisant un lien de communication comportant un modulateur en bande de base, un canal, un démodulateur, une mise en forme d’impulsions, un filtrage en cosinus surélevé et la correction d’erreur.

Établir le framework de simulation

Dans cet exemple, pour obtenir une estimation du BER plus exacte, le nombre de bits à traiter est augmenté par rapport à la valeur utilisée dans l’exemple Utiliser la mise en forme d’impulsion sur un signal 16-QAM. D’autres variables de simulation correspondent aux paramètres de cet exemple.

Définissez les paramètres de simulation pour un schéma de modulation 16-QAM avec un filtrage en cosinus surélevé et un canal AWGN.

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

Générer des données aléatoires

Configurez la fonction rng sur son état par défaut, ou sur n’importe quelle valeur statique initiale, pour que cet exemple génère des résultats reproductibles. Puis, utilisez la fonction randi pour générer des données binaires aléatoires.

rng default;                     % Use default random number generator
dataIn = randi([0 1],numBits,1); % Generate vector of binary data

Appliquer l’encodage convolutif

Pour corriger les erreurs qui découlent du canal bruité, appliquez le codage convolutif aux données avant l'émission et le décodage Viterbi aux données reçues. Ce décodeur utilise un algorithme à décision dure, ce qui signifie que chaque donnée reçue est interprétée soit comme 0, soit comme 1.

Définissez un treillis de code convolutif pour un code de rendement de 2/3 en utilisant la fonction poly2trellis. Le treillis défini représente le code convolutif utilisé par la fonction convenc pour encoder le vecteur binaire 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;

Encodez les données d’entrée en utilisant le treillis tPoly.

dataEnc = convenc(dataIn,tPoly);

Moduler les données

Utilisez la fonction bit2int pour convertir les données binaires encodées en k-tuple en valeurs entières.

dataSymbolsIn = bit2int(dataEnc,k);

Utilisez la fonction qammod pour appliquer la modulation 16-QAM.

dataMod = qammod(dataSymbolsIn,M);

Appliquer le filtrage en cosinus surélevé

Utilisez la fonction rcosdesign pour créer un filtre RRC.

rrcFilter = rcosdesign(rolloff,filtlen,sps);

Utilisez la fonction upfirdn pour suréchantillonner le signal par le facteur de suréchantillonnage et appliquez le filtre RRC. La fonction upfirdn complète le signal suréchantillonné avec des zéros à la fin pour nettoyer le filtre. Puis, la fonction applique le filtre.

txSignal = upfirdn(dataMod,rrcFilter,sps,1);

Appliquer le canal AWGN

En utilisant le nombre de bits par symbole (k) et le nombre d’échantillons par symbole (sps), convertissez le rapport de l'énergie par bit sur la densité spectrale de puissance de bruit (EbNo) en une valeur SNR pouvant être utilisée par la fonction awgn. Pendant la conversion de Eb/N0 en SNR, il faut comptabiliser le nombre de bits d’information par symbole. Lorsqu’aucun FEC n'était appliqué, chaque symbole correspondait à k bits. Maintenant que le FEC est appliqué, chaque symbole correspond à k×codeRate bits d’information. Pour le rendement de code de 2/3 et les émissions de modulation 16-QAM utilisés dans cet exemple, trois symboles correspondent à 12 bits codés et 8 bits non-codés (d’information).

EbNo = 10;
snr = EbNo+10*log10(k*codeRate)-10*log10(sps);

Passez le signal filtré à travers un canal AWGN.

rxSignal = awgn(txSignal,snr,'measured');

Recevoir et démoduler le signal

Filtrez le signal reçu en utilisant un filtre RRC. Retirez une portion du signal pour prendre en compte le retard du filtre.

rxFiltSignal = ...
    upfirdn(rxSignal,rrcFilter,1,sps);       % Downsample and filter
rxFiltSignal = ...
    rxFiltSignal(filtlen + 1:end - filtlen); % Account for delay

Utilisez la fonction qamdemod pour démoduler le signal filtré reçu.

dataSymbolsOut = qamdemod(rxFiltSignal,M);

Appliquer le décodage Viterbi

Utilisez la fonction int2bit pour convertir les symboles entiers récupérés en données binaires.

codedDataOut = int2bit(dataSymbolsOut,k); % Return data in column vector

Utilisez la fonction vitdec configurée pour les décisions dure et en mode d’opération continu, pour décoder les données codées par convolution. Le mode d’opération continue maintient l’état interne lorsque le décodeur est invoqué de manière répétée, par exemple à la réception de trames de données qui s’exécutent en boucle. Le mode d’opération continue ajoute également du retard au système. Bien que cet exemple n’utilise pas de boucle, le mode « cont » est utilisé à but d’illustration pour expliquer comment compenser le retard dans cette opération de décodage.

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

Calculer le BER du système

Le retard introduit par les filtres RRC de l'émission et de la réception, est déjà pris en compte dans les données récupérées, mais le retard du décodeur n'est pas encore pris en compte. Le mode d’opération continue du décodeur Viterbi provoque un retard dont la durée en bits est égale à la longueur du retour inverse traceBack, multiplié par le nombre de streams en entrée de l’encodeur. Pour le rendement de code de 2/3 utilisé dans cet exemple, l’encodeur a deux streams en entrée, donc le retard est 2×traceBack bits. En conséquence, les deux bits 2×traceBack dans le vecteur décodé dataOut, sont des zéros. En calculant le BER, ignorer les deux premiers bits 2×traceBack dans dataOut et les derniers bits 2×traceBack dans le vecteur d'origine dataIn.

Utilisez la fonction biterr pour calculer le nombre d’erreurs et le BER en comparant dataIn etdataOut. Pour le même Eb/N0 de 10 dB, moins d’erreurs ont lieu lorsque le FEC est inclus dans la chaîne de traitement.

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 4.30e-05, based on 43 errors.

En savoir plus sur les retards

L’opération de décodage de cet exemple induit un retard qui entraine un décalage entre la sortie du décodeur et l’entrée. L’information de temps n’apparait pas explicitement dans cet exemple, et la longueur du retard dépend des opérations spécifiques qui sont effectuées. Les retards ont lieu dans diverses opérations de systèmes de communications, dont le décodage convolutif, l’entrelacement et le désentrelacement convolutif, l’égalisation et le filtrage. Pour trouver la durée du retard causé par des fonctions et opérations spécifiques, veuillez consulter leurs documentations. Pour plus d’informations sur les retards, voir Delays of Convolutional Interleavers et Fading Channels.

Sujets associés