1 |
7 |
dbrochart |
######################################################################
|
2 |
|
|
#### ####
|
3 |
|
|
#### turboTop.py ####
|
4 |
|
|
#### ####
|
5 |
|
|
#### This file is part of the turbo decoder IP core project ####
|
6 |
|
|
#### http://www.opencores.org/projects/turbocodes/ ####
|
7 |
|
|
#### ####
|
8 |
|
|
#### Author(s): ####
|
9 |
|
|
#### - David Brochart(dbrochart@opencores.org) ####
|
10 |
|
|
#### ####
|
11 |
|
|
#### All additional information is available in the README.txt ####
|
12 |
|
|
#### file. ####
|
13 |
|
|
#### ####
|
14 |
|
|
######################################################################
|
15 |
|
|
#### ####
|
16 |
|
|
#### Copyright (C) 2005 Authors ####
|
17 |
|
|
#### ####
|
18 |
|
|
#### This source file may be used and distributed without ####
|
19 |
|
|
#### restriction provided that this copyright statement is not ####
|
20 |
|
|
#### removed from the file and that any derivative work contains ####
|
21 |
|
|
#### the original copyright notice and the associated disclaimer. ####
|
22 |
|
|
#### ####
|
23 |
|
|
#### This source file is free software; you can redistribute it ####
|
24 |
|
|
#### and/or modify it under the terms of the GNU Lesser General ####
|
25 |
|
|
#### Public License as published by the Free Software Foundation; ####
|
26 |
|
|
#### either version 2.1 of the License, or (at your option) any ####
|
27 |
|
|
#### later version. ####
|
28 |
|
|
#### ####
|
29 |
|
|
#### This source is distributed in the hope that it will be ####
|
30 |
|
|
#### useful, but WITHOUT ANY WARRANTY; without even the implied ####
|
31 |
|
|
#### warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ####
|
32 |
|
|
#### PURPOSE. See the GNU Lesser General Public License for more ####
|
33 |
|
|
#### details. ####
|
34 |
|
|
#### ####
|
35 |
|
|
#### You should have received a copy of the GNU Lesser General ####
|
36 |
|
|
#### Public License along with this source; if not, download it ####
|
37 |
|
|
#### from http://www.opencores.org/lgpl.shtml ####
|
38 |
|
|
#### ####
|
39 |
|
|
######################################################################
|
40 |
|
|
|
41 |
|
|
|
42 |
|
|
|
43 |
|
|
from punct import punct
|
44 |
|
|
from iteration import iteration
|
45 |
|
|
from permut import abPermut
|
46 |
|
|
from interleaver import interleaver
|
47 |
|
|
from testbench import ber, randGen, siho
|
48 |
|
|
from misc import delayer
|
49 |
|
|
from clock import rstGen, clkGen, clkDiv
|
50 |
|
|
from coder import coder
|
51 |
|
|
from noiser import noiser
|
52 |
|
|
from limiter import limiter
|
53 |
|
|
from myhdl import Signal, intbv, instances
|
54 |
|
|
|
55 |
|
|
def turboTop(resFile, rate = 12, it = 5, n = 4, r = 5, p = 48, d = 0, mu = 8, sigma = 6, l = 20, m = 10, q = 8):
|
56 |
|
|
""" Turbo decoder top level.
|
57 |
|
|
|
58 |
|
|
resFile -- files where the results will be saved
|
59 |
|
|
rate -- code rate (e.g. 12 for rate 1/2)
|
60 |
|
|
it -- number of iterations for the turbo decoding
|
61 |
|
|
n -- number of bits for the sampling of the signals - a, b, y1, y2
|
62 |
|
|
r -- number of bits for the coding of the extrinsic information
|
63 |
|
|
p -- interleaver frame size in bit couples
|
64 |
|
|
d -- additional delay through the noiser - 0 means the noiser adds 2 clock cycles
|
65 |
|
|
mu -- mean value for the noise distribution (additive noise)
|
66 |
|
|
sigma -- standard deviation of the noise distribution (0 means no noise)
|
67 |
|
|
l -- first trellis' length
|
68 |
|
|
m -- second trellis' length
|
69 |
|
|
q -- number of bits for the coding of the accumulated distances
|
70 |
|
|
|
71 |
|
|
"""
|
72 |
|
|
# Signal declarations:
|
73 |
|
|
clk = Signal(bool(0))
|
74 |
|
|
rst = Signal(bool(1))
|
75 |
|
|
flipflop = Signal(bool(0))
|
76 |
|
|
aClean = Signal(bool(0))
|
77 |
|
|
bClean = Signal(bool(0))
|
78 |
|
|
y1Clean = Signal(bool(0))
|
79 |
|
|
y2Clean = Signal(bool(0))
|
80 |
|
|
aCleanDel = Signal(bool(0))
|
81 |
|
|
bCleanDel = Signal(bool(0))
|
82 |
|
|
y1CleanDel = Signal(bool(0))
|
83 |
|
|
y2CleanDel = Signal(bool(0))
|
84 |
|
|
y1IntDel = Signal(bool(0))
|
85 |
|
|
y2IntDel = Signal(bool(0))
|
86 |
|
|
aNoisy = Signal(int(0))
|
87 |
|
|
bNoisy = Signal(int(0))
|
88 |
|
|
y1Noisy = Signal(int(0))
|
89 |
|
|
y2Noisy = Signal(int(0))
|
90 |
|
|
y1IntNoisy = Signal(int(0))
|
91 |
|
|
y2IntNoisy = Signal(int(0))
|
92 |
|
|
y1Full = Signal(intbv(0, -(2**(n-1)), 2**(n-1)))
|
93 |
|
|
y2Full = Signal(intbv(0, -(2**(n-1)), 2**(n-1)))
|
94 |
|
|
y1IntFull = Signal(intbv(0, -(2**(n-1)), 2**(n-1)))
|
95 |
|
|
y2IntFull = Signal(intbv(0, -(2**(n-1)), 2**(n-1)))
|
96 |
|
|
aLim = [Signal(intbv(0, -(2**(n-1)), 2**(n-1))) for i in range(it + 1)]
|
97 |
|
|
bLim = [Signal(intbv(0, -(2**(n-1)), 2**(n-1))) for i in range(it + 1)]
|
98 |
|
|
y1Lim = [Signal(intbv(0, -(2**(n-1)), 2**(n-1))) for i in range(it + 1)]
|
99 |
|
|
y2Lim = [Signal(intbv(0, -(2**(n-1)), 2**(n-1))) for i in range(it + 1)]
|
100 |
|
|
y1IntLim = [Signal(intbv(0, -(2**(n-1)), 2**(n-1))) for i in range(it + 1)]
|
101 |
|
|
y2IntLim = [Signal(intbv(0, -(2**(n-1)), 2**(n-1))) for i in range(it + 1)]
|
102 |
|
|
z = [[Signal(intbv(0, 0, 2**r)) for i in range(4)] for i in range(it + 1)]
|
103 |
|
|
zSorted = [Signal(intbv(0, 0, 2**r)) for i in range(4)]
|
104 |
|
|
aDec = [Signal(bool(0)) for i in range(it + 1)]
|
105 |
|
|
bDec = [Signal(bool(0)) for i in range(it + 1)]
|
106 |
|
|
aDel = [Signal(bool(0)) for i in range(it + 1)]
|
107 |
|
|
bDel = [Signal(bool(0)) for i in range(it + 1)]
|
108 |
|
|
abInt = [Signal(bool(0)) for i in range(2)]
|
109 |
|
|
y1Int = Signal(bool(0))
|
110 |
|
|
y2Int = Signal(bool(0))
|
111 |
|
|
abCleanPerm = [Signal(bool(0)) for i in range(2)]
|
112 |
|
|
|
113 |
|
|
delayer_ia = [None for i in range(it + 1)]
|
114 |
|
|
delayer_ib = [None for i in range(it + 1)]
|
115 |
|
|
ber_i = [None for i in range(it + 1)]
|
116 |
|
|
iteration_i = [None for i in range(it)]
|
117 |
|
|
|
118 |
|
|
# Reset and clock generation:
|
119 |
|
|
rstGen_i0 = rstGen(rst)
|
120 |
|
|
clkGen_i0 = clkGen(clk)
|
121 |
|
|
|
122 |
|
|
# Random data generation:
|
123 |
|
|
randGen_i0 = randGen(clk, rst, aClean, bClean)
|
124 |
|
|
|
125 |
|
|
# Interleaving and permuting:
|
126 |
|
|
clkDiv_i0 = clkDiv(clk, rst, flipflop)
|
127 |
|
|
abPermut_i0 = abPermut(flipflop, aClean, bClean, abCleanPerm, 1)
|
128 |
|
|
interleaver_i0 = interleaver(clk, rst, abCleanPerm, abInt, p, 0, 0, 2, 2, 0)
|
129 |
|
|
|
130 |
|
|
# Coder:
|
131 |
|
|
coder_i0 = coder(clk, rst, aClean, bClean, y1Clean, y2Clean)
|
132 |
|
|
coder_i1 = coder(clk, rst, abInt[1], abInt[0], y1Int, y2Int)
|
133 |
|
|
|
134 |
|
|
# Additional delay through the channel:
|
135 |
|
|
delayer_i0 = delayer(clk, rst, aClean, aCleanDel, d, 0, 2)
|
136 |
|
|
delayer_i1 = delayer(clk, rst, bClean, bCleanDel, d, 0, 2)
|
137 |
|
|
delayer_i2 = delayer(clk, rst, y1Clean, y1CleanDel, d, 0, 2)
|
138 |
|
|
delayer_i3 = delayer(clk, rst, y2Clean, y2CleanDel, d, 0, 2)
|
139 |
|
|
delayer_i4 = delayer(clk, rst, y1Int, y1IntDel, d, 0, 2)
|
140 |
|
|
delayer_i5 = delayer(clk, rst, y2Int, y2IntDel, d, 0, 2)
|
141 |
|
|
|
142 |
|
|
# Channel noiser:
|
143 |
|
|
noiser_i0 = noiser(clk, rst, aCleanDel, bCleanDel, y1CleanDel, y2CleanDel, y1IntDel, y2IntDel, aNoisy, bNoisy, y1Noisy, y2Noisy, y1IntNoisy, y2IntNoisy, n, mu, sigma)
|
144 |
|
|
|
145 |
|
|
# Decoder:
|
146 |
|
|
limiter_i0 = limiter(aNoisy, bNoisy, y1Noisy, y2Noisy, y1IntNoisy, y2IntNoisy, aLim[0], bLim[0], y1Full, y2Full, y1IntFull, y2IntFull, n)
|
147 |
|
|
punct_i0 = punct(clk, rst, y1Full, y2Full, y1IntFull, y2IntFull, y1Lim[0], y2Lim[0], y1IntLim[0], y2IntLim[0], rate)
|
148 |
|
|
for i in range(it):
|
149 |
|
|
iteration_i[i] = iteration(clk, rst, flipflop, aLim[i], bLim[i], y1Lim[i], y2Lim[i], y1IntLim[i], y2IntLim[i], z[i], z[i + 1], aDec[i + 1], bDec[i + 1], aLim[i + 1], bLim[i + 1], y1Lim[i + 1], y2Lim[i + 1], y1IntLim[i + 1], y2IntLim[i + 1], l, m, q, p, r, n, 2 * i * (l + m + 2) + 2 * i * p + 2)
|
150 |
|
|
|
151 |
|
|
# Bit Error Rate monitoring:
|
152 |
|
|
siho_i0 = siho(aLim[0], bLim[0], aDec[0], bDec[0])
|
153 |
|
|
delayer_ia[0] = delayer(clk, rst, aClean, aDel[0], 1 + d, 0, 2)
|
154 |
|
|
delayer_ib[0] = delayer(clk, rst, bClean, bDel[0], 1 + d, 0, 2)
|
155 |
|
|
ber_i[0] = ber(clk, rst, aDel[0], bDel[0], aDec[0], bDec[0], d + 100, resFile[0])
|
156 |
|
|
for i in range(it):
|
157 |
|
|
delayer_ia[i + 1] = delayer(clk, rst, aClean, aDel[i + 1], (2 * i + 1) * (l + m + 2) + 2 * i * p + d, 0, 2)
|
158 |
|
|
delayer_ib[i + 1] = delayer(clk, rst, bClean, bDel[i + 1], (2 * i + 1) * (l + m + 2) + 2 * i * p + d, 0, 2)
|
159 |
|
|
ber_i[i + 1] = ber(clk, rst, aDel[i + 1], bDel[i + 1], aDec[i + 1], bDec[i + 1], (2 * i + 1) * (l + m + 2) + 2 * i * p + d + 100, resFile[i + 1])
|
160 |
|
|
|
161 |
|
|
return rstGen_i0, clkGen_i0, randGen_i0, clkDiv_i0, abPermut_i0, interleaver_i0, coder_i0, coder_i1, delayer_i0, delayer_i1, delayer_i2, delayer_i3, delayer_i4, delayer_i5, noiser_i0, limiter_i0, punct_i0, siho_i0, delayer_ia, delayer_ib, ber_i, iteration_i
|