You are on page 1of 30

Project report

On

Convolutional Encoder and Viterbi Decoder


(With verilog simulation and Fpga implementation)

UNDER THE GUIDANCE OF

DR. SUMAM DAVID

SUBMITTED BY,

Satish kumar.G 05MI16F

Department of Electronics and Communication Engineering

National Institute of Technology Karnataka, Surathkal–575025


CONTENTS

1: INTRODUCTION AND DEFINITIONS


1.1 Important definitions………………………………………………………..02

2: CONVOLUTIONAL ENCODER..……………………………………………….…03

3: THE VITERBI ALGORITHM

3.1 The Viterbi algorithm……………………………………………………….05


3.2 Understanding Viterbi decoding…………………......…………………. ….06

4: VITERBI DECODER IMPLEMENTATION

4.1 Working of the Viterbi algorithm…………………………………………...09


4.2 Internal architecture of Viterbi decoder……………………………….…….09
4.3 Branch metric unit…………………………………………………………..10
4.4 Path metric unit……………………………………………………………..10
4.5 Survivor path unit…………………………………………………………...11
4.6 Permutation network based path history unit……………………………….12

5: SIMULATION OF VITERBI ALGORITHM

5.1 Description of modules used in implementation……………………………13


5.2 Algorithmic flow of implementation…………………………………. …... 14
5.3 Hardware descreption of various modules……………………………….….15

6 : EXPERIMENTAL RESULTS AND CONCLUSIONS

6.1 Synthesis report……………………………………………………………..23


6.2 RTL Schematic……………………………………………………………...24
6.3 Output plots…………………………………………………………………25
6.4 Conclusions………………………………………………………………….27

7 : REFERENCES…………………………………………………………....................28
1 Introduction and Definitions

In digital communication system, the transmitted data is presented in


binary form that is modulated to analog waveforms and transmitted through a channel to
a receiver. In the channel the noise and interference corrupt the transmitted signal, which
is mapped back to binary bits in the receiver. Some bit errors may occur if the
interference is too strong so channel coding is often used to prevent these errors. The
channel coding means that extra bits are added to the transmitted data and these bits are
then used when reconstructing transmitted data sequence in the receiver. There are many
different methods for channel coding like linear block codes and convolutional codes.

Fig (1.1): A Typical communication system

In block coding, the encoder accepts a k-bit message block and generates
an n-bit code word. Thus, code words are produced on a block by block basis. A
provision has to be made in the encoder to buffer an entire message block buffer
generating the associated code word. Generally, we have the message coming in serially
rather than in blocks, in which case the use of the buffer may be undesirable. In such
situations, convolutional coding might be preferred.
A convolutional code is generated by passing the information sequence to
be transmitted through a linear finite state shift register. Hence, the block of n code digits
generated by a convolutional encoder at a time depends not only on the block of K-
message bits at that time, but also on N-1 previous blocks of data.
An advantage of convolutional coding is that it can be applied to a
continuous data stream as well as to blocks of data. Like block codes, convolutional
codes can be designed to either detect or correct errors. However, as data is retransmitted
in blocks, block codes are better suited for error detection and convolutional codes are
mainly used for error correction.

1.1 IMPORTANT DEFINITIONS :


The following terms are vital to the understanding of convolutional codes.
Hard-decision/soft-decision decoding: Hard-decision decoding means that the
demodulator is quantized to two levels: zero and one. If you derive more than two
quantization levels from the demodulator, then the decoder is soft-decision decoding.
Code rate R(=k/n): Number of bits into convolutional encoder (k)/ number of bits in
output symbol which corresponds not only current input bit, but also previous (K –1)
ones
Constraint length K : It denotes the “length” of the convolutional encoder, i.e., no of k-
bit stages are available to feed the combinatorial logic that produces the output symbols
Branch Metric: Difference between the received sequence and the branch word is called
the Branch metric.
Path Metric: Branch metric accumulates to form Path metric.
2 Convolutional Encoder

Convolutional coding has been used in communication systems including


deep space communications and wireless communications. Convolutional codes offer an
alternative to block codes for transmission over a noisy channel. Convolutional coding
can be applied to a continuous input stream (which cannot be done with block codes), as
well as blocks of data. A convolutional encoder is a Mealy machine, where the output is a
function of the current state and the current input. It consists of one or more shift registers
and multiple XOR gates. XOR gates are connected to some stages of the shift registers as
well as to the current input to generate the output.

Fig (2.1): Convolutional Encoder

The encoder in figure2.1 produces two bits of encoded information for


each bit of input information, so it is called a rate 1/2 encoder. A convolutional encoder is
generally characterized in (n, k, m) format with a rate of k/n, where
-- N is number of outputs of the encoder
-- K is number of inputs of the encoder
-- M is number of flip-flops of the longest shift register of the encoder
The stream of information bits flows in to the shift register from one end
and is shifted out at the other end. The location of stages as well as the number of
memory elements determines the minimum hamming distance. Minimum Hamming
distance determines the maximal number of correctable bits. Interconnection functions
for different rates and different number of memory elements and their minimum
hamming distances are available.

Fig (2.2): State Diagram for the Convolutional Encoder

The operation of a convolutional encoder can be easily understood with


the aid of a state diagram. The state diagram is a graph of the possible states of the
encoder and the transitions from one state to another state. Figure 2.2 represents the state
diagram of the encoder shown in Figure 2.1. Figure 2.2 depicts state transitions and the
corresponding encoded outputs. As there are two memory-elements in the circuit, there
are four possible states that the circuit can assume. These four states are represented as S0
through S3. Each state’s information (i.e. the contents of flip-flops for the state) along
with an input generates an encoded output code. For each state, there can be two outgoing
transitions; one corresponding to a ‘0’ input bit and the other corresponding to a ‘1’ input
bit.
3 The Viterbi Algorithm

The Viterbi decoding algorithm was proposed by Viterbi in 1967 is a


decoding process for convolutional codes. Viterbi decoding is one of two types of
decoding algorithms used with convolutional encoding-the other type is sequential
decoding. Sequential decoding has the advantage that it can perform very well with long-
constraint-length convolutional codes, but it has a variable decoding time. Viterbi
decoding algorithm has the advantage that it has a fixed decoding time. It is well suited to
hardware decoder implementation. But its computational requirements grow
exponentially as a function of the constraint length, usually limited to constraint lengths
of K = 9 or less.

3.1 THE VITERBI ALGORITHM


For years, convolutional coding with Viterbi decoding has been the
predominant FEC technique used in space communications. The algorithm can be applied
to a host of problems encountered in the design of communication systems. The Viterbi
decoding algorithm is based on maximum likelihood decoding. Perhaps the single most
important concept to aid in understanding the Viterbi algorithm is the trellis diagram. A
typical trellis diagram is shown in Fig 3.1

Fig (3.1): Trellis diagram for the encoder


The four possible states of the encoder are depicted as four rows of
horizontal dots. For a 15-bit message with two encoder memory flushing bits, there are
17 time instants in addition to t = 0, which represents the initial condition of the encoder.
The solid lines connecting dots in the diagram represent state transitions when the input
bit is a one. The dotted lines represent state transitions when the input bit is a zero. Also,
since the initial condition of the encoder is State 002 and the two memory flushing bits
are zeroes, the arrows start out at State 002 and end up at the same state
Each state can be reached from two paths and the longer of the two is
discarded for an optimum path search. This is done with the help of accumulated path
metric. This computation is performed for each of the 2K-1 nodes at each time ti, where
K is the constraint length of the decoder. As we move deeper into the trellis, only a single
path survives. This path gives us the original information that was encoded.

3.2 UNDERSTANDING VITERBI DECODING


For understanding the Viterbi decoding algorithm working, we're going to
use hard-decision symbol inputs to keep things simple. Suppose we receive the above
encoded message with a couple of bit errors:

Each time we receive a pair of channel symbols, we're going to compute a


metric to measure the "distance" between what we received and all of the possible
channel symbol pairs we could have received. The metric we're going to use is the
Hamming distance between the received channel symbol pair and the possible channel
symbol pairs. The Hamming distance is computed by simply counting how many bits are
different between the received channel symbol pair and the possible channel symbol
pairs. The Hamming distance (or other metric) values we compute at each time instant for
the paths between the states at the previous time instant and the states at the current time
instant are called branch metrics. For the first time instant, we're going to save these
results as "accumulated error metric" values, associated with states. For the second time
instant on, the accumulated error metrics will be computed by adding the previous
accumulated error metrics to the current branch metrics.
At t = 1, we received 002. The only possible channel symbol pairs we
could have received are 002 and 112. The Hamming distance between 002 and 002 is zero.
The Hamming distance between 002 and 112 is two. Therefore, the branch metric value
for the branch from State 002 to State 002 is zero, and for the branch from State 002 to
State 102 it's two. Since, the previous accumulated error metric values are equal to zero,
the accumulated metric values for State 002 and for State 102 are equal to the branch
metric values. The accumulated error metric values for the other two states are undefined.
The figure below illustrates the results at t = 1:

Now let's look what happens at t = 2. We received a 112 channel symbol


pair. The possible channel symbol pairs we could have received in going from t = 1 to t =
2 are 002 going from State 002 to State 002, 112 going from State 002 to State 102, 102
going from State 102 to State 01 2, and 012 going from State 102 to State 11 2. The
Hamming distance between 002 and 112 is two, between 112 and 112 is zero, and between
10 2 or 012 and 112 is one. We add these branch metric values to the previous
accumulated error metric values associated with each state that we came from to get to
the current states. At t = 1, we could only be at State 002 or State 102. The accumulated
error metric values associated with those states were 0 and 2 respectively. The figure
below shows the calculation of the accumulated error metric associated with each state, at
t = 2.

At t = 17, the trellis looks like:

The decoding process is accomplished by the following steps:

• First, select the state having the smallest accumulated error metric and save the
state number of that state.

• Iteratively perform the following step until the beginning of the trellis is reached:
Working backward through the state history table, for the selected state, select a
new state which is listed in the state history table as being the predecessor to that
state. Save the state number of each selected state. This step is called trace back.

• Now work forward through the list of selected states saved in the previous steps.
Look up what input bit corresponds to a transition from each predecessor state to
its successor state. That is the bit that must have been encoded by the
convolutional encoder
4 Viterbi Decoder Implementation

This section discusses the different parts of the Viterbi decoder. Analog
signals are quantized and converted into digital signals in the quantization block. The
synchronization block detects the frame boundaries of code words and symbol
boundaries. We assumed that the Viterbi decoder receives successive code symbols, in
which the boundaries of the symbols and the frames have been identified.
4.1: WORKING OF THE VITERBI ALGORITHM
The major tasks in the Viterbi decoding process are as follows:
1. Branch metric computation.
2. State metric update
3. Survivor path recording
4. Output decision generation

4.2: INTERNAL ARCHITECTURE OF VITERBI DECODER


There are three major components in Viterbi decoder, the branch metric
unit (BMU), Add-compare-select unit (ACS), survivor memory unit (SMU) or Trace
Back (TB).

Fig (4.1): Internals of Viterbi decoder (Encoder also shown)


4.3 BRANCH METRIC UNIT
The branch metric unit calculates the branch metrics of the trellis structure
from bit metrics. The branch metrics are difference values between received code symbol
and the corresponding branch words from the encoder trellis. The bit metrics can be
calculated with a separate unit as shown in figure or a look-up table can be used. The
inputs needed for this task are bit metrics, which in this case come from the convolutional
encoder. These encoder branch words are the code symbols that would be expected to
come from the encoder output as a result of the state transitions. In hard-decision
decoding the calculation method is called Hamming distance. The Hamming distance
d(X, Y) between two words X and Y is defined to equal the number of differing
elements. For soft-decision decoding, there is another algorithm called Euclidean
distance. When the input symbol is X and encoder symbol is Y, the Euclidean distance is
calculated from the formula (X-Y)2.

Fig (4.1): Branch Metric computation Block

4.4 PATH METRIC UNIT


The PMU calculates new path metric values and decision values. Because each state can
be achieved from two states from the earlier stage, there are two possible path metrics
coming to the current state. The ACS unit, as shown in figure, adds for each of the two
incoming branches the corresponding states path metric, resulting in two new path
metrics. The path with the better metric is chosen and stored as the new path metric for
current state, while generating a decision bit.
Mathematically,
If BM(i;p) + PM(i;p) < BM(j;p) + PM(j;p)
Then Dec(p) = 0 , PM(p) = PM(i) + BM(i;p)
Else
Dec(p) = 1 , PM(p) = PM(j) + BM(j;p) Where BM is branch
metric, PM is path metric and DEC is decision bit
The decision bit indicates what branch was chosen. Because each state can
be achieved from two states from the earlier stage, the decision value is represented by
one bit. If the bit is one the path metric selected is coming from the lower state from
those two possible states in Trellis diagram, and if the decision bit is zero the path metric
selected is coming from the upper state. As the ACS unit needs the results from the
calculations of the previous steps, it forms a feed back loop with the external memory
unit, where the results are stored.

4.5 SURVIVOR PATH UNIT


The survivor path unit stores the decisions of the ACS unit and uses them to compute the
decoded output. The trace-back technique and the register-exchange approaches are two
major techniques used for the path history management .The former takes up less area but
require much more time than the latter, since it needs to search the trace of the survivor
path back sequentially. A relatively new approach called permutation network based path
history unit implements directly the trellis diagram of the given convolutional code. The
resulting circuit has smaller routing area than register-exchange technique and has faster
decoding speed than trace-back method regardless of the constraint length.
In the PNPH unit, the trace-back operation is carried out by an “all-path
broadcast” from the rightmost to the leftmost end rather than exchanging path
information via registers controlled by the decision bits as in the register-exchange
method or by reading previous decision bits recursively as in the trace-back method..
Only those connected survivor paths set by the decision bits stored in the registers can be
reached to their destinations. The trace-back operation delay is limited only to the
propagation time of the combinational circuit.
4.6 PERMUTATION NETWORK BASED PATH HISTORY UNIT
The PNPH unit for an convolutional code is a 5L-stage permutation network with each
stage containing 1-to-2k demultiplexers, where each DeMux corresponds to each node of
the trellis diagram and is associated with a K-bit register and a 2k-input OR gate. The K-
bit register is used to store the decision bits associated with the state node and to
determine the partial survivor path associated with the node. Thus, each registers-
demultiplexer pair determines the part of the survivor path associated its corresponding
state node. The connection between two adjacent stages of the interconnection network is
defined by the next function of the state diagram of the underlying encoder.

New decision-bit values for each state calculated by add-compare-select (ACS)


enter into the rightmost end of corresponding shift register. The shift registers then shift
left one step, which corresponds to the decoding window moving right one position. To
eliminate the requirement of a lot of comparators for deciding the minimum path metric,
all inputs of all rightmost 1-to-2k demultiplexers are set to 1. In general, at least one of
them will propagate to the output end at the leftmost end since all of them will merge into
one according to the merging property of convolutional code.
5 Simulation of Viterbi Algorithm

We have implemented all the modules of convolutional encoder and


Viterbi decoder in verilog HDL. The code comprises of three levels of abstraction
namely, behavioral, dataflow and structural. We give a brief description of all the
modules we have used.

5.1 DESCRIPTION OF MODULES USED IN IMPLEMENTATION


1) Trellis codec:
The top module consisting of convolutional encoder and all the modules of the
Viterbi decoder and the decoded sequence of data with input as the message bits.
2) Convolutional encoder:
We have used a rate ½ convolutional encoder. Hence, it uses a state machine of four
states and generates 2 bit output with 1 bit input.
3) Branch metric unit:
This module computes the metric for each path in the trellis. We have used a look-up
table which gives the output branch metric values, based on the encoded sequence
4) Path metric unit:
This module computes the new path metric value by summing up the incoming path
metric and branch metric values. It also compares the two metrics generated at each
stage and selects the minimum of the two as the new path metric value for that
particular state. Based on the path selected, it generates the selection bits which are
used to trace back the original path by the survivor path unit. A path metric memory is
used to store the path metric values. This forms a feedback loop with path metric unit.
6) Survival path unit:
This module decides the output of the whole decoder. The module compares the
metrics of all the survivors and selects a survivor such that it has the minimum metric.
This is the output of the Viterbi decoder. The spblock module is the basic block
5.2 ALGORITHMIC FLOW OF IMPLEMENTATION

The whole program for the convolutional encoder and Viterbi decoder can
be summarized as shown in the following flowchart

(Input data)
ENCODER

(Encoded Data)
BRANCH METRIC
GENERATOR

(Branch
Metric Values)

PATH METRIC
GENERATOR

( Path
D Metric Values)

COMPARE
SELECT UNIT

(Selection Bits)

DECISION
LOGIC CIRCUIT
(SURVIVAL PATH
GENERATOR)

(Decoded Output)
5.3 HARDWARE DESCRIPTION OF VARIOUS MODULES

1) TOP MODULE
`timescale 1ns/1ps
module trellis_codec(out,input_data,clk,reset) ;
output out ;
input input_data,clk,reset ;
wire [1:0] encoded_data ;
wire [15:0] bm_value ;
wire [3:0] pm_new00,pm_new01,pm_new10,pm_new11 ;
wire [3:0] pm_old00,pm_old01,pm_old10,pm_old11 ;
wire [3:0] sel ;

// Module which encodes the input message bits


Encoder module_encode_data
(
encoded_data,input_data,clk,reset
) ;

// Module which generates branch metric value for the encoded output
bmu_memory module_branch_metric_unit
(
bm_value,encoded_data,clk
) ;

// Module which generates the path metric values for all the states
new_pm_generator path_metric_generate_unit
(
sel,
pm_new00,pm_new01,pm_new10,pm_new11,
pm_old00,pm_old01,pm_old10,pm_old11,
bm_value,clk
) ;

// Module which stores the path metric values for all the states
register_set path_metric_store_unit
(
pm_old00,pm_old01,pm_old10,pm_old11,
pm_new00,pm_new01,pm_new10,pm_new11,
clk,reset
) ;

// Module which traces the original data


pnph survival_path_tracing_unit
( out,sel,clk ) ;

endmodule
2) CONVOLUTIONAL ENCODER

module encoder(y,x,clk,reset) ;
output [1:0] y ;
reg [1:0] y ;
input x ;

input clk,reset ;
wire x_1,x_2 ;

dff dff1(x_1,x ,clk) ;


dff dff2(x_2,x_1,clk) ;

initial
y=2'b0 ;

always @
(posedge clk)
if(reset==1)
y=2'b0 ;

else

begin
y[0] = x ^ x_2 ;
y[1] = x_1 ^ x_2 ^ x ;

end

endmodule

2.1) D-FLIPFLOP

module dff(Q,D,clk) ;
output Q ;
input D,clk ;
reg Q ;

initial
Q=0 ;

always @
(posedge clk)
Q = D ;

endmodule
3) BRANCH METRIC UNIT

module bmu_memory(bm_out,encoded_input,clk);
output [15:0] bm_out ;
reg [15:0] bm_out ;
input [1:0] encoded_input ;
input clk ;

initial
bm_out=16'b0000000000000000 ;

always@(negedge clk)
begin

//when received sequence is 00

if(encoded_input[1]==0 && encoded_input[0]==0)


bm_out=16'b0101100001010010 ;

//when received sequence is 01

else if(encoded_input[1]==0 && encoded_input[0]==1)


bm_out=16'b0010010110000101 ;

//when received sequence is 10

else if(encoded_input[1]==1 && encoded_input[0]==0)


bm_out=16'b1000010100100101 ;

//when received sequence is 11

else if(encoded_input[1]==1 && encoded_input[0]==1)


bm_out=16'b0101001001011000 ;

end

endmodule
4) PATH METRIC UNIT

module new_pm_generator
(
sel_bit,
pm_new00,pm_new01,pm_new10,pm_new11,
pm_old00,pm_old01,pm_old10,pm_old11,
bm_value,clk
) ;

Output [3:0] sel_bit ;


reg [3:0] sel_bit ;
output [3:0] pm_new00,pm_new01,pm_new10,pm_new11 ;
reg [3:0] pm_new00,pm_new01,pm_new10,pm_new11 ;
input [3:0] pm_old00,pm_old01,pm_old10,pm_old11 ;
input [15:0] bm_value ;
input clk ;
wire [3:0] sum00,sum01,sum10,sum11,
sum20,sum21,sum30,sum31 ;

assign sum00 = pm_old00+bm_value[3:2] ;


assign sum01 = pm_old01+bm_value[1:0] ;

assign sum10=pm_old10+bm_value[7:6] ;
assign sum11=pm_old11+bm_value[5:4] ;

assign sum20=pm_old00+bm_value[11:10] ;
assign sum21=pm_old01+bm_value[9:8] ;

assign sum30=pm_old10+bm_value[15:14] ;
assign sum31=pm_old11+bm_value[13:12] ;

initial
begin
pm_new00=4'b0000 ;
pm_new01=4'b1000 ;
pm_new10=4'b1000 ;
pm_new11=4'b1000 ;
sel_bit=0 ;
end

always@
(posedge clk)
begin

// Updating path metric value for state 00

if(sum00<=sum01)
begin
pm_new00=sum00 ;
sel_bit[0]=0 ;
end

else
begin
pm_new00=sum01 ;
sel_bit[0]=1 ;
end

// Updating path metric value for state 01

if(sum10<=sum11)
begin
pm_new01=sum10 ;
sel_bit[1]=0 ;
end

else
begin
pm_new01=sum11 ;
sel_bit[1]=1 ;
end

// Updating path metric value for state 10

if(sum20<=sum21)
begin
pm_new10=sum20 ;
sel_bit[2]=0 ;
end

else
begin
pm_new10=sum21 ;
sel_bit[2]=1 ;
end

// Updating path metric value for state 11

if(sum30<=sum31)
begin
pm_new11=sum30 ;
sel_bit[3]=0 ;
end

else
begin
pm_new11=sum31 ;
sel_bit[3]=1 ;
end
end

endmodule
5) PATH METRIC MEMORY
module register_set
(
pm_out00,pm_out01,pm_out10,pm_out11,
pm_in00 ,pm_in01 ,pm_in10 ,pm_in11 ,
clk,reset
) ;

Output [3:0] pm_out00,pm_out01,pm_out10,pm_out11 ;


reg [3:0] pm_out00,pm_out01,pm_out10,pm_out11 ;
input [3:0] pm_in00 ,pm_in01 ,pm_in10 ,pm_in11 ;
input clk,reset ;

initial
begin
pm_out00=4'b0000 ;
pm_out01=4'b1000 ;
pm_out10=4'b1000 ;
pm_out11=4'b1000 ;
end

always@(negedge clk)
begin
if(reset==1)
begin
pm_out00=4'b0000 ;
pm_out01=4'b1000 ;
pm_out10=4'b1000 ;
pm_out11=4'b1000 ;
end

else

begin
pm_out00=pm_in00 ;
pm_out01=pm_in01 ;
pm_out10=pm_in10 ;
pm_out11=pm_in11 ;
end
end

endmodule
6) SURVIVAL PATH UNIT

module pnph(out,sel,clk) ;
output out ;
reg out ;
input [3:0] sel ;
input clk ;

wire sel00,sel01,sel02,sel03 ;
wire sel10,sel11,sel12,sel13 ;
wire sel20,sel21,sel22,sel23 ;
wire sel30,sel31,sel32,sel33 ;
wire sel40,sel41,sel42,sel43 ;
wire sel50,sel51,sel52,sel53 ;
wire sel60,sel61,sel62,sel63 ;
wire sel70,sel71,sel72,sel73 ;
wire sel81,sel82,sel83 ;
wire sel91,sel93 ;

spblock_1 dev0_0(q0_00,q0_01,sel00,sel[0],clk) ;
spblock_1 dev0_1(q0_10,q0_11,sel01,sel[2],clk) ;
spblock_1 dev0_2(q0_20,q0_21,sel02,sel[1],clk) ;
spblock_1 dev0_3(q0_30,q0_31,sel03,sel[3],clk) ;

spblock dev1_0(q1_00,q1_01,sel10,q0_00,q0_10,sel00,clk) ;
spblock dev1_1(q1_10,q1_11,sel11,q0_20,q0_30,sel01,clk) ;
spblock dev1_2(q1_20,q1_21,sel12,q0_01,q0_11,sel02,clk) ;
spblock dev1_3(q1_30,q1_31,sel13,q0_21,q0_31,sel03,clk) ;

spblock dev2_0(q2_00,q2_01,sel20,q1_00,q1_10,sel10,clk) ;
spblock dev2_1(q2_10,q2_11,sel21,q1_20,q1_30,sel11,clk) ;
spblock dev2_2(q2_20,q2_21,sel22,q1_01,q1_11,sel12,clk) ;
spblock dev2_3(q2_30,q2_31,sel23,q1_21,q1_31,sel13,clk) ;

spblock dev3_0(q3_00,q3_01,sel30,q2_00,q2_10,sel20,clk) ;
spblock dev3_1(q3_10,q3_11,sel31,q2_20,q2_30,sel21,clk) ;
spblock dev3_2(q3_20,q3_21,sel32,q2_01,q2_11,sel22,clk) ;
spblock dev3_3(q3_30,q3_31,sel33,q2_21,q2_31,sel23,clk) ;

spblock dev4_0(q4_00,q4_01,sel40,q3_00,q3_10,sel30,clk) ;
spblock dev4_1(q4_10,q4_11,sel41,q3_20,q3_30,sel31,clk) ;
spblock dev4_2(q4_20,q4_21,sel42,q3_01,q3_11,sel32,clk) ;
spblock dev4_3(q4_30,q4_31,sel43,q3_21,q3_31,sel33,clk) ;

spblock dev5_0(q5_00,q5_01,sel50,q4_00,q4_10,sel40,clk) ;
spblock dev5_1(q5_10,q5_11,sel51,q4_20,q4_30,sel41,clk) ;
spblock dev5_2(q5_20,q5_21,sel52,q4_01,q4_11,sel42,clk) ;
spblock dev5_3(q5_30,q5_31,sel53,q4_21,q4_31,sel43,clk) ;

spblock dev6_0(q6_00,q6_01,sel60,q5_00,q5_10,sel50,clk) ;
spblock dev6_1(q6_10,q6_11,sel61,q5_20,q5_30,sel51,clk) ;
spblock dev6_2(q6_20,q6_21,sel62,q5_01,q5_11,sel52,clk) ;
spblock dev6_3(q6_30,q6_31,sel63,q5_21,q5_31,sel53,clk) ;
spblock dev7_0(q7_00,q7_01,sel70,q6_00,q6_10,sel60,clk) ;
spblock dev7_1(q7_10,q7_11,sel71,q6_20,q6_30,sel61,clk) ;
spblock dev7_2(q7_20,q7_21,sel72,q6_01,q6_11,sel62,clk) ;
spblock dev7_3(q7_30,q7_31,sel73,q6_21,q6_31,sel63,clk) ;

spblock dev8_1(q8_10,q8_11,sel81,q7_20,q7_30,sel71,clk) ;
spblock dev8_2(q8_20,q8_21,sel82,q7_01,q7_11,sel72,clk) ;
spblock dev8_3(q8_30,q8_31,sel83,q7_21,q7_31,sel73,clk) ;

spblock dev9_1(q9_10,q9_11,sel91,q8_20,q8_30,sel81,clk) ;
spblock dev9_3(q9_30,q9_31,sel93,q8_21,q8_31,sel83,clk) ;

always@
(q9_10 , q9_11 , q9_30 , q9_31)
out = q9_10 | q9_11 | q9_30 | q9_31 ;

endmodule

6.1) MODULE USED IN SURVIVAL PATH UNIT


module spblock_1(q0,q1,sel_out,sel_in,clk) ;

output q0,q1,sel_out ;
input sel_in,clk ;

wire in=1'b1 ;

dff dev1(sel_out,sel_in,clk) ;
dmux dev2(q0,q1,in,sel_out) ;

endmodule

6.2) MODULE USED IN SURVIVAL PATH UNIT

module spblock(q0,q1,sel_out,d0,d1,sel_in,clk) ;

output q0,q1,sel_out ;
input d0,d1,sel_in,clk ;

dff dev1 (sel_out,sel_in,clk) ;


or (y,d0,d1) ;
dmux dev2 (q0,q1,y,sel_out) ;

endmodule

6.2.2) 2X1 DEMULTIPLEXER


module dmux(q0,q1,in,sel) ;

output q0,q1 ;
input in,sel ;

assign q0 = in &(~sel) ;
assign q1 = in & sel ;

endmodule
6 Experimental Results and Conclusions

The entire code has been compiled and synthesized using xilinx ise8.1.
We have used modelsim to simulate the modules. Finally, we have used virtex to
practically check out the correctness of the entire program.

6.1 SYNTHESIS REPORT

=========================================================================
* Synthesis Options Summary *
=========================================================================
Input File Name : "trellis_codec.prj"
Input Format : mixed
Target Device : xc2vp30-7-ff896

=========================================================================
HDL Synthesis Report
=========================================================================
Macro Statistics
# ROMs : 01
4x16-bit ROM : 01
# Adders/Subtractors : 08
4-bit adder : 08
# Registers : 54
1-bit register : 45
16-bit register : 01
4-bit register : 08
# Comparators : 04
4-bit comparator lessequal : 04
# Xors : 02
1-bit xor2 : 02

=========================================================================
* Advanced HDL Synthesis Report *
=========================================================================

Macro Statistics
# ROMs : 01
4x16-bit ROM : 01
# Adders/Subtractors : 08
4-bit adder : 08
# Registers : 55
Flip-Flops : 55
# Comparators : 04
4-bit comparator lessequal : 04
# Xors : 02
1-bit xor2 : 02
=========================================================================
Device utilization summary:

Selected Device: 2vp30ff896-7

Number of Slices : 87 out of 13696 0%


Number of Slice Flip Flops : 78 out of 27392 0%
Number of 4 input LUTs : 134 out of 27392 0%
Number of bonded IOBs :4 out of 556 0%
Number of GCLKs :1 out of 16 6%

=========================================================================
Timing Summary : Speed Grade: -7

Minimum period: 7.944ns (Maximum Frequency: 125.878MHz)


Minimum input arrival time before clock: 2.007ns
Maximum output required time after clock: 9.974ns
Maximum combinational path delay: No path found

Total memory usage is 172164 kilobytes

Number of errors : 0 ( 0 filtered)


Number of warnings : 9 ( 0 filtered)
Number of infos : 6 ( 0 filtered)

6.2 RTL SCHEMATIC:


6.3 OUTPUT PLOTS :

1)encoder output :

2) Viterbi decoder output without noise:


3) Viterbi decoder output with medium noise:

4) Viterbi decoder output with relatively high noise :


5) Plot from chip scope using Virtex Fpga:

6.4 CONCLUSIONS :

⋅ From the graphs, it is clear that the efficiency of the decoder decreases
with increases in channel noise.
⋅ The latency of the decoder is 200ns (equal to the no of stages in the
pnph unit time’s clock period).
⋅ The maximum frequency at which the decoder works is 125.878MHz (from
synthesis report).
⋅ As an extension to this work, we can look at pipelining the ACS unit and
can think of reconfigurable architecture for implementing convolutional
encoders with different code rates simultaneously.
7 References

1. Anh Dinh, Ralph Mason and Joe Toth,” HIGH SPEED V.32 TRELLIS ENCODER &
DECODER IMPLEMENTATION USING FPGA,”in IEEE transactions on
communications,1999

2. Ming-Bo Lin, “ NEW PATH HISTORY MANAGEMENT CIRCUITS FOR VITERBI


DECODERS,” in IEEE transactions on communications, vol 48, no.10,october 2000

3. A. J. Viterbi, "ERROR BOUNDS FOR CONVOLUTIONAL CODES AND AN


ASYMPTOTICALLY OPTIMUM DECODING ALGORITHM," IEEE Transactions on
Information Theory , vol. IT-13, April, 1967, pp. 260-269.

4. Samirkumar Ranpara,”ON A VITERBI DECODER DESIGN FOR LOW POWER


DISSIPATION,” towards his Master’s thesis submitted to Virginia Polytechnic Institute
and State University.

5. Chip Fleming,”A TUTORIAL ON CONVOLUTIONAL CODING WITH VITERBI


DECODING”

6. S. Lin and D. J. Costello, Error Control Coding. Englewood Cliffs, NJ: Prentice Hall,
1982

You might also like