Main Content

This model shows how to use the Convolutional Encoder and Viterbi Decoder blocks to simulate a punctured coding system. The complexity of a Viterbi decoder increases rapidly with the code rate. Puncturing is a technique that allows the encoding and decoding of higher rate codes using standard rate 1/2 encoders and decoders.

The example is somewhat similar to the one that appears in Soft-Decision Decoding, which shows convolutional coding without puncturing.

This example contains these blocks.

Bernoulli Binary Generator: Create a sequence of random bits to use as a message.

Convolutional Encoder: Encode the message using the convolutional encoder.

BPSK Modulator Baseband: Modulate the encoded message.

AWGN Channel: Pass the modulated signal through a noisy channel.

Error Rate Calculation: Compute the number of discrepancies between the original and recovered messages.

Open the example, doc_punct_conv_code, by entering the following at the MATLAB^{®} command prompt.

doc_punct_conv_code

The Bernoulli Binary Generator block produces the information
source for this simulation. The block generates a frame of three random bits at each
sample time. The **Samples per frame** parameter determines the
number of rows of the output frame.

The Convolutional Encoder block encodes the data from the Bernoulli Binary Generator. This example uses the same code as described in Soft-Decision Decoding.

The puncture pattern is specified by the **Puncture vector**
parameter in the mask. The puncture vector is a binary column vector. A 1 indicates
that the bit in the corresponding position of the input vector is sent to the output
vector, while a 0 indicates that the bit is removed.

For example, to create a rate 3/4 code from the rate 1/2, constraint length 7 convolutional code, the optimal puncture vector is [1 1 0 1 1 0].' (where the .' after the vector indicates the transpose). Bits in positions 1, 2, 4, and 5 are transmitted, while bits in positions 3 and 6 are removed. Now, for every 3 bits of input, the punctured code generates 4 bits of output (as opposed to the 6 bits produced before puncturing). This makes the rate 3/4.

In this example, the output from the Bernoulli Binary Generator is a column vector of length 3. Because the rate 1/2 Convolutional Encoder doubles the length of each vector, the length of the puncture vector must divide 6.

The AWGN Channel block simulates transmission over a noisy channel. The parameters for the block are set in the mask as follows:

The

**Mode**parameter for this block is set to`Signal to noise ratio (Es/No)`

.The

**Es/No**parameter is set to 2 dB. This value typically is changed from one simulation run to the next.The preceding modulation block generates unit power signals so the

**Input signal power**is set to 1 Watt.The

**Symbol period**is set to 0.75 seconds because the code has rate 3/4.

In this simulation, the Viterbi Decoder block is set to accept
unquantized inputs. As a result, the simulation passes the channel output through a
Simulink^{®}
Complex to Real-Imag block that extracts the real part of the complex
samples.

The Viterbi Decoder block is configured to decode the same rate 1/2 code specified in the Convolutional Encoder block.

In this example, the decision type is set to `Unquantized`

. For
codes without puncturing, you would normally set the **Traceback
depth** for this code to a value close to 40. However, for decoding
punctured codes, a higher value is required to give the decoder enough data to
resolve the ambiguities introduced by the punctures.

Since the punctured bits are not transmitted, there is no information to indicate their values. As a result they are ignored in the decoding process.

The **Puncture vector** parameter indicates the locations of the
punctures or the bits to ignore in the decoding process. Each 1 in the puncture
vector indicates a transmitted bit while each 0 indicates a puncture or the bit to
ignore in the input to the decoder.

In general, the two **Puncture vector** parameters in the
Convolutional Encoder and Viterbi Decoder must be
the same.

The Error Rate Calculation block compares the decoded bits to the original source bits. The output of the Error Rate Calculation block is a three-element vector containing the calculated bit error rate (BER), the number of errors observed, and the number of bits processed.

In the mask for this block, the **Receive delay** parameter is
set to 96, because the **Traceback depth** value of 96 in the
Viterbi Decoder block creates a delay of 96. If there were other
blocks in the model that created delays, the **Receive delay**
would equal the sum of all the delays.

BER simulations typically run until a minimum number of errors have occurred, or
until the simulation processes a maximum number of bits. The Error Rate
Calculation block uses its **Stop simulation** mode to
set these limits and to control the duration of the simulation.

Generating a bit error rate curve requires multiple simulations. You can perform
multiple simulations using the `sim`

command. Follow these
steps:

In the model window, remove the Display block and the line connected to its port.

In the AWGN Channel block, set the

**Es/No**parameter to the variable name`EsNodB`

.In the Error Rate Calculation block, set

**Output data**to`Workspace`

and then set**Variable name**to`BER_Data`

.Save the model in your working directory under a different name, such as

`my_punct_conv_code.slx`

.Execute the following code, which runs the simulation multiple times and gathers results.

CodeRate = 0.75; EbNoVec = [2:.5:5]; EsNoVec = EbNoVec + 10*log10(CodeRate); BERVec = zeros(length(EsNoVec),3); for n=1:length(EsNoVec), EsNodB = EsNoVec(n); sim('my_commpunctcnvcod'); BERVec(n,:) = BER_Data; end

To confirm the validity of the results, compare them to an established performance
bound. The bit error rate performance of a rate *r* =
(*n*-1)/*n* punctured code is bounded above by
the expression:

$${P}_{b}\le \frac{1}{2(n-1)}{\displaystyle \sum}_{d={d}_{free}}^{\infty}{\omega}_{d}\text{erfc}\left(\sqrt{\text{rd}({\text{E}}_{\text{b}}{\text{/N}}_{\text{0}})}\right)$$

In this expression, `erfc`

denotes the complementary error
function, *r* is the code rate, and both
*d _{free}* and
ω

The following commands compute an approximation of this bound using the first
seven terms of the summation (the values used for `nerr`

are found
in Table 2 of reference [ 2 ]:

dist = [5:11]; nerr = [42 201 1492 10469 62935 379644 2253373]; CodeRate = 3/4; EbNo_dB = [2:.02:5]; EbNo = 10.0.^(EbNo_dB/10); arg = sqrt(CodeRate*EbNo'*dist); bound = nerr*(1/6)*erfc(arg)';

To plot the simulation and theoretical results in the same figure, use the commands below.

berfit(EbNoVec',BERVec(:,1)); % Curve-fitted simulation results hold on; semilogy(EbNo_dB,bound,'g'); % Theoretical results legend('Simulated BER','Fit for simulated BER',... 'Theoretical bound on BER')

In some cases, at the lower bit error rates, you might notice simulation results that appear to indicate error rates slightly above the bound. This can result from simulation variance (if fewer than 500 bit errors are observed) or from the finite traceback depth in the decoder.

[1] Yasuda, Y., K. Kashiki, and Y. Hirata, "High Rate Punctured Convolutional Codes for Soft Decision Viterbi Decoding," IEEE Transactions on Communications, Vol. COM-32, March, 1984, pp. 315-319.

[2] Begin, G., Haccoun, D., and Paquin, C., "Further results on High-Rate Punctured Convolutional Codes for Viterbi and Sequential Decoding," IEEE Transactions on Communications, Vol. 38, No. 11, November, 1990, p. 1923.