Main Content

Vorwärtsfehlerkorrektur bei einem 16-QAM-Signal verwenden

Dieses Beispiel erweitert das Beispiel Impulsformung bei einem 16-QAM-Signal verwenden so, dass die Leistungsverbesserung der BER (Bit Error Rate, Bitfehlerrate) bei Verwendung der Vorwärtsfehlerkorrektur-Codierung (Forward Error Correction, FEC) angezeigt wird.

Dieses Beispiel veranschaulicht, wie mithilfe einer Kommunikationsverbindung, die aus einem Basisband-Modulator, einem Kanal, einem Demodulator, Impulsformung, Raised-Cosine-Filterung und Fehlerkorrektur besteht, ein Binärdatenstrom verarbeitet wird.

Simulationsumgebung einrichten

In diesem Beispiel wird, um eine genauere BER-Schätzung zu erreichen, die Anzahl der zu verarbeitenden Bits gegenüber dem im Beispiel Impulsformung bei einem 16-QAM-Signal verwenden verwendeten Wert erhöht. Die anderen Simulationsvariablen stimmen mit den Einstellungen in jenem Beispiel überein.

Definieren Sie die Simulationsparameter für ein 16-QAM-Modulationsschema mit Raised-Cosine-Filterung und einem AWGN-Kanal.

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

Zufallsdaten generieren

Verwenden Sie die Funktion rng mit ihren Standardeinstellungen oder legen Sie einen statischen Startwert fest, damit das Beispiel wiederholbare Ergebnisse generiert. Verwenden Sie anschließend die Funktion randi, um zufällige binäre Daten zu generieren.

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

Faltungscodierung anwenden

Um Fehler, die durch den mit Rauschen behafteten Kanal entstehen, zu korrigieren, wenden Sie vor Übertragung und Viterbi-Decodierung der empfangenen Daten eine Faltungscodierung auf die Daten an. Der Decoder verwendet einen Algorithmus mit fester Entscheidung, was bedeutet, dass jedes empfangene Datenbit als 0 oder 1 interpretiert wird.

Definieren Sie mit der Funktion poly2trellis ein Faltungscodierungsgitter (Trellis) für eine Coderate von 2/3. Dieses definierte Gitter stellt den Faltungscode dar, der durch die Funktion convenc für die Codierung des binären Vektors dataIn verwendet wird.

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;

Codieren Sie mit dem tPoly-Gitter die Eingabedaten.

dataEnc = convenc(dataIn,tPoly);

Daten modulieren

Verwenden Sie die Funktion bit2int, um die als k-Tupel codierten binären Daten in einen ganzzahligen Wert zu konvertieren.

dataSymbolsIn = bit2int(dataEnc,k);

Verwenden Sie die Funktion qammod, um eine 16-QAM-Modulation anzuwenden.

dataMod = qammod(dataSymbolsIn,M);

Raised-Cosine-Filterung anwenden

Verwenden Sie die Funktion rcosdesign, um einen RRC-Filter zu erstellen.

rrcFilter = rcosdesign(rolloff,filtlen,sps);

Verwenden Sie die Funktion upfirdn, um ein Upsampling des Signals um den Oversampling-Faktor durchzuführen und den RRC-Filter anzuwenden. Die Funktion upfirdn füllt nach dem Upsampling das Signal am Ende mit Nullen auf, um den Filter zu füllen. Danach wendet die Funktion den Filter an.

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

AWGN-Kanal anwenden

Konvertieren Sie mit der Anzahl der Bits pro Symbol (k) und der Anzahl der Abtastungen pro Symbol (sps) das Verhältnis der Energie pro Bit zur Spektraldichte der Rauschleistung (EbNo) in einen SNR-Wert für die Verwendung durch die Funktion awgn. Beim Konvertieren von Eb/N0 in SNR müssen Sie die Anzahl der Informationsbits pro Symbol berücksichtigen. Ohne angewendete FEC entsprach jedes Symbol genau k Bits. Mit angewendeter FEC entspricht jedes Symbol genau (k×codeRate) Informationsbits. Bei der Coderate von 2/3 und den 16-QAM-Übertragungen, die in diesem Beispiel verwendet werden, entsprechen drei Symbole genau 12 codierten Bits und 8 nicht codierten (Informations-)Bits.

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

Leiten Sie das gefilterte Signal durch einen AWGN-Kanal.

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

Signal empfangen und demodulieren

Filtern Sie mit dem RRC-Filter das empfangene Signal. Entfernen Sie einen Teil des Signals, um die Filterverzögerung zu berücksichtigen.

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

Verwenden Sie die Funktion qamdemod, um das empfangene gefilterte Signal zu demodulieren.

dataSymbolsOut = qamdemod(rxFiltSignal,M);

Viterbi-Decodierung anwenden

Verwenden Sie die Funktion int2bit, um die wiederhergestellten ganzzahligen Symbole in binäre Daten zu konvertieren.

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

Verwenden Sie die Funktion vitdec, die für feste Entscheidungen und kontinuierlichen Betrieb konfiguriert wurde, um die faltungscodierten Daten zu decodieren. Im kontinuierlichen Betrieb bleibt der interne Zustand erhalten, wenn der Decoder wiederholt aufgerufen wird, wie zum Beispiel beim Empfang von Datenframes beim Durchlaufen einer Schleife. Im kontinuierlichen Betrieb kommt es auch zu einer zusätzlichen Verzögerung im System. Obwohl in diesem Beispiel keine Schleife verwendet wird, wird der Modus 'cont' verwendet, um zu veranschaulichen, wie die Verzögerung in dieser Decodierungsoperation kompensiert wird.

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 des Systems berechnen

Die durch die zwei RRC-Sende- und -Empfangsfilter verursachte Verzögerung wird in den wiederhergestellten Daten bereits berücksichtigt, die Decoder-Verzögerung allerdings noch nicht. Im kontinuierlichen Betrieb des Viterbi-Decoders entsteht eine Verzögerung mit einer Bitdauer, die der Traceback-Länge, traceBack, multipliziert mit der Anzahl der Eingabedatenströme am Codierer entspricht. Da bei der Coderate von 2/3, die in diesem Beispiel verwendet wird, der Codierer zwei Eingabedatenströme hat, beträgt die Verzögerung 2 × traceBack Bits. Deshalb sind die ersten 2 × traceBack Bits im decodierten Vektor dataOut Nullen. Beim Berechnen der BER müssen Sie die ersten 2 × traceBack Bits in dataOut und die letzten 2 × traceBack Bits im ursprünglichen Vektor dataIn löschen.

Verwenden Sie die Funktion biterr, um die Anzahl der Fehler und die BER durch den Vergleich von dataIn und dataOut zu berechnen. Bei demselben Eb/N0 von 10 dB treten weniger Fehler auf, wenn FEC in der Verarbeitungskette enthalten ist.

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.

Weitere Informationen zu Verzögerungen

Die Decodierungsoperation in diesem Beispiel verursacht eine Verzögerung, die dazu führt, dass die Ausgabe des Decoders hinter der Eingabe zurückliegt. In diesem Beispiel gibt es keine expliziten Informationen zum zeitlichen Ablauf. Außerdem hängt die Dauer der Verzögerung von den ausgeführten Operationen ab. Verzögerungen treten in verschiedenen Operationen eines Kommunikationssystems auf, wie zum Beispiel Faltungsdecodierung, Faltungsverflechtung und -entflechtung, Ausgleich und Filterung. Die Dauer der Verzögerung, die durch bestimmte Funktionen oder Operationen verursacht wird, finden Sie in der Dokumentation für die betreffenden Funktionen bzw. Operationen. Weitere Informationen zu Verzögerungen finden Sie unter Delays of Convolutional Interleavers und Fading Channels.

Verwandte Themen