11.12 A Viterbi Decoder

This section describes
an ASIC design for a Viterbi decoder using Verilog. Christeen Gray completed
the original design as her MS thesis at the University of Hawaii (UH) working
with VLSI Technology, using the Compass ASIC Synthesizer and a VLSI Technology
cell library. The design was mapped from VLSI Technology design rules to
Hewlett-Packard design rules; prototypes were fabricated by Hewlett-Packard
(through Mosis) and tested at UH.

11.12.1 Viterbi Encoder

Viterbi encoding
is widely used for satellite and other noisy communications channels.
There are two important components of a channel using Viterbi encoding:
the Viterbi encoder (at the transmitter) and the Viterbi decoder
(at the receiver). A Viterbi encoder includes extra information in the transmitted
signal to reduce the probability of errors in the received signal that may
be corrupted by noise.

I shall describe an encoder
in which every two bits of a data stream are encoded into three bits for
transmission. The ratio of input to output information in an encoder is
the rate of the encoder; this is a rate 2/3 encoder. The following
equations relate the three encoder output bits (Yn2
, Yn1 , and Yn0
) to the two encoder input bits (Xn2
and Xn1 ) at a time nT:

Yn2 = Xn2

Yn1 = Xn1
xor Xn-21

Yn0 = Xn-11

We can write the input bits
as a single number. Thus, for example, if Xn2
= 1 and Xn2 = 0 , we can write Xn
= 2 . Equation 11.1 defines a state machine with two memory elements
for the two last input values for Xn1
: Xn-11 and Xn-21
. These two state variables define four states: {Xn-11,
Xn-21 } , with S0
= { 0, 0}, S1 = {1, 0}, S2
= {0, 1}, and S3 = {1, 1}. The 3-bit
output Yn is a function of the state and current
2-bit input Xn .

The following Verilog code
describes the rate 2/3 encoder. This model uses two D flip-flops as the
state register. When reset (using active-high input signal res
) the encoder starts in state S0 . In Verilog
I represent Yn2 by Y2N
, for example.

Figure 11.3 shows the
state diagram for this encoder. The first four rows of Table 11.6 show
the four different transitions that can be made from state S0
. For example, if we reset the encoder and the input is Xn
= 3 (Xn2 = 1 and Xn1
= 1), then the output will be Yn = 6 (Yn2
= 1 , Yn1 = 1 , Yn0
= 0 ) and the next state will be S1 .

FIGURE 11.3 A
state diagram for a rate 2/3 Viterbi encoder. The inputs and outputs are
shown in binary as Xn2 Xn1
/ Yn2Yn1Yn0
, and in decimal as Xn/ Yn
.

TABLE 11.7 A
sequence of transmitted signals for the rate 2/3 Viterbi encoder

Time

ns

Inputs

State variables

Outputs

Present state

Next state

Xn2

Xn1

Xn-11

Xn-21

Yn2

Yn1

Yn0

0

1

1

x

x

1

x

x

S?

S?

10

1

1

0

0

1

1

0

S0

S1

50

0

0

1

0

0

0

1

S1

S2

150

0

1

0

1

0

0

0

S2

S1

250

1

0

1

0

1

0

1

S1

S2

350

1

1

0

1

1

0

0

S2

S1

450

0

0

1

0

0

0

1

S1

S2

550

0

1

0

1

0

0

0

S2

S1

650

1

0

1

0

1

0

1

S1

S2

750

1

1

0

1

1

0

0

S2

S1

850

0

0

1

0

0

0

1

S1

S2

950

0

1

0

1

0

0

0

S2

S1

Next we transmit the eight possible
encoder outputs (Yn = 0-7 ) as signals
over our noisy communications channel (perhaps a microwave signal to a satellite)
using the signal constellation shown in Figure 11.4. Typically
this is done using phase-shift keying ( PSK) with each signal
position corresponding to a different phase shift in the transmitted carrier
signal.

11.12.2 The Received Signal

The noisy signal
enters the receiver. It is now our task to discover which of the eight possible
signals were transmitted at each time step. First we calculate the distance
of each received signal from each of the known eight positions in the signal
constellation. Table 11.8 shows the distances between signals in the
8PSK constellation. We are going to assume that there is no noise in the
channel to illustrate the operation of the Viterbi decoder, so that the
distances in Table 11.8 represent the possible distance measures of
our received signal from the 8PSK signals.

The distances, X, in
the first column of Table 11.8 are the geometric or algebraic distances.
We measure the Euclidean distance, E = X2
shown as B (the binary quantized value of E) in Table 11.8.
The rounding errors that result from conversion to fixed-width binary are
quantization errors and are important in any practical implementation
of the Viterbi decoder. The effect of the quantization error is to add a
form of noise to the received signal.

The following code models
the receiver section that digitizes the noisy analog received signal and
computes the binary distance measures. Eight binary-distance measures, in0-in7
, are generated each time a signal is received. Since each of the distance
measures is 3 bits wide, there are a total of 24 bits (8 ¥
3) that form the digital inputs to the Viterbi decoder.

TABLE 11.8 Distance
measures for Viterbi encoding (8PSK).

Signal

Algebraic distance from
signal 0

X = Distance from
signal 0

Euclidean distance

E = X2

B = binary quantized
value of E

D = decimal value
of B

Quantization error

Q = D
- 1.75 E

0

2 sin (0 π / 8)

0.00

0.00

000

0

0

1

2 sin (1 π / 8)

0.77

0.59

001

1

-0.0325

2

2 sin (2 π / 8)

1.41

2.00

100

4

0.5

3

2 sin (3 π / 8)

1.85

3.41

110

6

0.0325

4

2 sin (4 π / 8)

2.00

4.00

111

7

0

5

2 sin (5 π / 8)

1.85

3.41

110

6

0.0325

6

2 sin (6 π / 8)

1.41

2.00

100

4

0.5

7

2 sin (7 π / 8)

0.77

0.59

001

1

-0.0325

/******************************************************/
/* module viterbi_distances */
/******************************************************/
/* This module simulates the front end of a receiver. Normally the
received analog signal (with noise) is converted into a series of
distance measures from the known eight possible transmitted PSK
signals: s0,...,s7. We are not simulating the analog part or noise in
this version, so we just take the digitally encoded 3-bit signal, Y,
from the encoder and convert it directly to the distance measures.
d[N] is the distance from signal = N to signal = 0
d[N] = (2*sin(N*PI/8))**2 in 3-bit binary (on the scale 2=100)
Example: d[3] = 1.85**2 = 3.41 = 110
inN is the distance from signal = N to encoder signal.
Example: in3 is the distance from signal = 3 to encoder signal.
d[N] is the distance from signal = N to encoder signal = 0.
If encoder signal = J, shift the distances by 8-J positions.
Example: if signal = 2, in0 is d[6], in1 is D[7], in2 is D[0], etc. */
module viterbi_distances
(Y2N,Y1N,Y0N,clk,res,in0,in1,in2,in3,in4,in5,in6,in7);
input clk,res,Y2N,Y1N,Y0N; output in0,in1,in2,in3,in4,in5,in6,in7;
reg [2:0] J,in0,in1,in2,in3,in4,in5,in6,in7; reg [2:0] d [7:0];
initialbegin d[0]='b000;d[1]='b001;d[2]='b100;d[3]='b110;
d[4]='b111;d[5]='b110;d[6]='b100;d[7]='b001; endalways @(Y2N or Y1N or Y0N) begin
J[0]=Y0N;J[1]=Y1N;J[2]=Y2N;
J=8-J;in0=d[J];J=J+1;in1=d[J];J=J+1;in2=d[J];J=J+1;in3=d[J];
J=J+1;in4=d[J];J=J+1;in5=d[J];J=J+1;in6=d[J];J=J+1;in7=d[J];
endendmodule

The Viterbi decoder takes
the distance measures and calculates the most likely transmitted signal.
It does this by keeping a running history of the previously received signals
in a path memory. The path-memory length of this decoder is 12. By keeping
a history of possible sequences and using the knowledge that the signals
were generated by a state machine, it is possible to select the most likely
sequences.

Table 11.10 shows part of
the simulation results from the testbench, viterbi_test_CDD, in tabular
form. Figure 11.5 shows the Verilog simulator output from the testbench
(displayed using VeriWell from Wellspring).

The system input or message,
X[1:0] , is driven by a counter that repeats the sequence 0, 1, 2, 3, ...
incrementing by 1 at each positive clock edge (with a delay of one time
unit), starting with X equal to 3 at t= 0. The active-high
reset signal, Res , is asserted at t = 60 for 10 time units.
The encoder output, Y[2:0] , changes at t = 151, which is one
time unit (the positive-edge-triggered D flip-flop model contains a one-time-unit
delay) after the first positive clock edge (at t = 150) following the deassertion
of the reset at t = 70. The encoder output sequence beginning at t=
151 is 2, 5, 4, 1, 0, ... and then the sequence
5, 4, 1, 0, ... repeats. This encoder output sequence
is then imagined to be transmitted and received. The receiver module calculates
the distance measures and passes them to the decoder. After 13 positive
clock-edges (1300 time ticks) the transmitted sequence appears at the output,
Out[2:0] , beginning at t = 1451 with 2, 5, 4, 1, 0, ...,
exactly the same as the encoder output.

11.12.4 Verilog Decoder
Model

The Viterbi decoder
model presented in this section is written for both simulation and synthesis.
The Viterbi decoder makes extensive use of vector D flip-flops (registers).
Early versions of Verilog-XL did not support vector instantiations of modules.
In addition the inputs of UDPs may not be vectors and there are no primitive
D flip-flops in Verilog. This makes instantiation of a register difficult
other than by writing a separate module instance for each flip-flop.

The first solution to this
problem is to use flip-flop models supplied with the synthesis tool such
as the following:

asDff #(3) subout0(in0, sub0, clk, reset);

The asDff is a model
in the Compass ASIC Synthesizer standard component library. This statement
triggers the synthesis of three D flip-flops, with an input vector ina
(with a range of three) connected to the D inputs, an output vector sub0
(also with a range of three) connected to the Q flip-flop outputs, a common
scalar clock signal, clk , and a common scalar reset
signal. The disadvantage of this approach is that the names, functional
behavior, and interfaces of the standard components are different for every
software system.

The second solution, in new
versions of Verilog-XL and other tools that support the IEEE standard, is
to use vector instantiation as follows [LRM 7.5.1, 12.1.2]:

myDff subout0[0:2] (in0, sub0, clk, reset);

This instantiates
three copies of a user-defined module or UDP called my Dff
. The disadvantage of this approach is that not all simulators and synthesizers
support vector instantiation.

The third solution (which
is used in the Viterbi decoder model) is to write a model that supports
vector inputs and outputs. Here is an example D flip-flop model:

We use this model by defining
a parameter that specifies the bus width as follows:

dff #(3) subout0(in0, sub0,
clk, reset);

The code that models the entire
Viterbi decoder is listed below (Figure 12.6 on page 578 shows the block
digram). Notice the following:

Comments explain the function of each module.

Each module is about a page or less of code.

Each module can be tested by itself.

The code is as simple as possible avoiding
clever coding techniques.

The code is not flexible,
because bit widths are fixed rather than using parameters. A model with
parameters for rate, signal constellation, distance measure resolution,
and path memory length is considerably more complex. We shall use this Viterbi
decoder design again when we discuss logic synthesis in Chapter 12, test
in Chapter 14, floorplanning and placement in Chapter 16, and routing in
Chapter 17.