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.