OpenCores
URL https://opencores.org/ocsvn/turbocodes/turbocodes/trunk

Subversion Repositories turbocodes

[/] [turbocodes/] [trunk/] [src/] [myhdl/] [trellis.py] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 dbrochart
######################################################################
2
####                                                              ####
3
####  trellis.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 myhdl import Signal, posedge, negedge, intbv, always
44
 
45
trans2state = [[0, 6, 1, 7], [2, 4, 3, 5], [5, 3, 4, 2], [7, 1, 6, 0], [1, 7, 0, 6], [3, 5, 2, 4], [4, 2, 5, 3], [6, 0, 7, 1]]
46
state2trans = [[0, 2, 1, 3], [1, 3, 0, 2], [2, 0, 3, 1], [3, 1, 2, 0], [2, 0, 3, 1], [3, 1, 2, 0], [0, 2, 1, 3], [1, 3, 0, 2]]
47
 
48
def trellis1(clk, rst, selState, selTrans, selStateL2, selStateL1, stateL1, selTransL2, l = 20):
49
    """ First trellis.
50
 
51
    l           -- first trellis length
52
    clk, rst    -- in  : clock and negative reset
53
    selState    -- in  : selected state at time 0
54
    selTrans    -- in  : 8 selected transitions (1 per state) at time 0
55
    selStateL2  -- out : selected state at time (l - 2)
56
    selStateL1  -- out : selected state at time (l - 1)
57
    stateL1     -- out : 4 possible states at time (l - 1)
58
    selTransL2  -- out : selected transition at time (l - 2)
59
 
60
    """
61
    reg = [[Signal(intbv(0, 0, 4)) for i in range(8)] for j in range(l)]
62
    free = intbv(255, 0, 256)
63
    freeBeg = [bool(1) for i in range(8)]
64
    pastState = [intbv(0, 0, 8) for i in range(8)]
65
    pathIdReg = [Signal(intbv(i, 0, 8)) for i in range(8)]
66
    pathId = [intbv(0, 0, 8) for i in range(8)]
67
    freePathId = intbv(0, 0, 8)
68
    current_state = intbv(0, 0, 8)
69
    outState_l2 = intbv(0, 0, 8)
70
    outState_l1 = intbv(0, 0, 8)
71
    state_l3 = intbv(0, 0, 4)
72
    state_l2 = intbv(0, 0, 4)
73
    state_l1 = intbv(0, 0, 4)
74
    @always(clk.posedge, rst.negedge)
75
    def trellis1Logic():
76
        if rst.val == 0:
77
            for i in range(4):
78
                stateL1[i].next = 0
79
            selStateL1.next = 0
80
            selStateL2.next = 0
81
            selTransL2.next = 0
82
            for i in range(8):
83
                pathIdReg[i].next = i
84
                for j in range(l):
85
                    reg[j][i].next = 0
86
        else:
87
            free = intbv(255)
88
            for i in range(8):
89
                pastState[i] = trans2state[i][int(selTrans[i].val)]
90
                pathId[i] = pathIdReg[pastState[i]].val
91
                free[int(pathId[i])] = 0
92
            freeBeg = [bool(1) for i in range(8)]
93
            for i in range(8):
94
                current_state = intbv(i)
95
                if freeBeg[int(pathId[int(current_state)])] == 1:
96
                    reg[0][int(pathId[int(current_state)])].next = current_state[2:0]
97
                    freeBeg[int(pathId[i])] = 0
98
                    pathIdReg[int(current_state)].next = pathId[int(current_state)]
99
                    for j in range(l - 1):
100
                        reg[j + 1][int(pathId[int(current_state)])].next = reg[j][int(pathId[int(current_state)])].val
101
                else:
102
                    if free[0] == 1:
103
                        freePathId = 0
104
                    if free[2:0] == 2:
105
                        freePathId = 1
106
                    if free[3:0] == 4:
107
                        freePathId = 2
108
                    if free[4:0] == 8:
109
                        freePathId = 3
110
                    if free[5:0] == 16:
111
                        freePathId = 4
112
                    if free[6:0] == 32:
113
                        freePathId = 5
114
                    if free[7:0] == 64:
115
                        freePathId = 6
116
                    if free[8:0] == 128:
117
                        freePathId = 7
118
                    reg[0][freePathId].next = current_state[2:0]
119
                    free[freePathId] = 0
120
                    pathIdReg[int(current_state)].next = freePathId
121
                    for j in range(l - 1):
122
                        reg[j + 1][freePathId].next = reg[j][int(pathId[int(current_state)])].val
123
            state_l3 = reg[l - 3][int(pathId[int(selState.val)])].val
124
            state_l2 = reg[l - 2][int(pathId[int(selState.val)])].val
125
            state_l1 = reg[l - 1][int(pathId[int(selState.val)])].val
126
            outState_l2[2] = state_l3[1] ^ (state_l3[0] ^ state_l2[1])
127
            outState_l2[2:0] = state_l2
128
            outState_l1[2] = state_l2[1] ^ (state_l2[0] ^ state_l1[1])
129
            outState_l1[2:0] = state_l1
130
            selStateL1.next = outState_l1
131
            selStateL2.next = outState_l2
132
            selTransL2.next = state2trans[int(outState_l2)][int(state_l1)]
133
            for i in range(4):
134
                stateL1[i].next = trans2state[int(outState_l2)][i]
135
            if __debug__:
136
                # Monitor: checks that in the first trellis, from each of the 8 states (trellis' beginning) we arrive at the same state (trellis' end).
137
                #          (Ignore this message until every iteration is fully started)
138
                diff = 0
139
                ref = intbv(0)
140
                tmp = intbv(0)
141
                state_l2_deb = reg[l - 2][int(pathId[7])].val
142
                state_l1_deb = reg[l - 1][int(pathId[7])].val
143
                ref[2] = state_l2_deb[1] ^ (state_l2_deb[0] ^ state_l1_deb[1])
144
                ref[2:0] = state_l1_deb
145
                for i in range(7):
146
                    state_l2_deb = reg[l - 2][int(pathId[i])].val
147
                    state_l1_deb = reg[l - 1][int(pathId[i])].val
148
                    tmp[2] = state_l2_deb[1] ^ (state_l2_deb[0] ^ state_l1_deb[1])
149
                    tmp[2:0] = state_l1_deb
150
                    if ref != tmp:
151
                        diff = 1
152
                if diff == 1:
153
                    print "WARNING: all paths don't arrive at same state at end of first trellis (you should think about increasing its length)"
154
    return trellis1Logic
155
 
156
def trellis2(clk, rst, selState, state, selTrans, weight, llr0, llr1, llr2, llr3, a, b, m = 10, q = 8):
157
    """ Second trellis and revision logic.
158
 
159
    m           -- second trellis length
160
    q           -- accumulated distance width
161
    clk, rst    -- in  : clock and negative reset
162
    selState    -- in  : selected state at time (l - 1)
163
    state       -- in  : 4 possible states at time (l - 1)
164
    selTrans    -- in  : 8 selected transitions (1 per state) at time (l - 1)
165
    weight      -- in  : four weights sorted by transition code at time (l - 1)
166
    llr0        -- out : LLR for (a, b) = (0, 0) at time (l + m - 1)
167
    llr1        -- out : LLR for (a, b) = (0, 1) at time (l + m - 1)
168
    llr2        -- out : LLR for (a, b) = (1, 0) at time (l + m - 1)
169
    llr3        -- out : LLR for (a, b) = (1, 1) at time (l + m - 1)
170
    a, b        -- out : decoded values of (a, b) at time (l + m - 1)
171
 
172
    """
173
    reg = [[Signal(intbv(0, 0, 4)) for i in range(8)] for j in range(m)]
174
    free = intbv(255, 0, 256)
175
    freeBeg = [bool(1) for i in range(8)]
176
    pastState = [intbv(0, 0, 8) for i in range(8)]
177
    pathIdReg = [Signal(intbv(i, 0, 8)) for i in range(8)]
178
    pathId = [intbv(0, 0, 8) for i in range(8)]
179
    freePathId = intbv(0, 0, 8)
180
    revWeight = [[Signal(intbv(0, 0, 2**q)) for i in range(m)] for j in range(4)]
181
    revWeightTmp = [[intbv(0, 0, 2**q) for i in range(m)] for j in range(4)]
182
    revWeightFilt = [intbv(0, 0, 2**q) for j in range(3)]
183
    op = [intbv(0, 0, 2**q) for i in range(4)]
184
    tmp = [intbv(0, 0, 2**q) for i in range(4)]
185
    tmp4 = intbv(0, 0, 2**(q+1))
186
    notZero = [[intbv(0, 0, 4) for i in range(3)] for j in range(2)]
187
    ind = [[intbv(0, 0, 4) for i in range(3)] for j in range(2)]
188
    minTmp = [bool(0) for i in range(3)]
189
    @always(clk.posedge, rst.negedge)
190
    def trellis2Logic():
191
        if rst.val == 0:
192
            for i in range(4):
193
                for j in range(m):
194
                    revWeight[i][j].next = 0
195
            a.next = 0
196
            b.next = 0
197
            llr0.next = 0
198
            llr1.next = 0
199
            llr2.next = 0
200
            llr3.next = 0
201
            for i in range(8):
202
                pathIdReg[i].next = i
203
                for j in range(m):
204
                    reg[j][i].next = 0
205
        else:
206
            free = intbv(255)
207
            for i in range(8):
208
                pastState[i] = trans2state[i][int(selTrans[i].val)]
209
                pathId[i] = pathIdReg[pastState[i]].val
210
                free[int(pathId[i])] = 0
211
            freeBeg = [bool(1) for i in range(8)]
212
            for i in range(8):
213
                if freeBeg[int(pathId[i])] == 1:
214
                    reg[0][int(pathId[i])].next = selTrans[i].val
215
                    freeBeg[int(pathId[i])] = 0
216
                    pathIdReg[i].next = pathId[i]
217
                    for j in range(m - 1):
218
                        reg[j + 1][int(pathId[i])].next = reg[j][int(pathId[i])].val
219
                else:
220
                    if free[1:0] == 1:
221
                        freePathId = 0
222
                    if free[2:0] == 2:
223
                        freePathId = 1
224
                    if free[3:0] == 4:
225
                        freePathId = 2
226
                    if free[4:0] == 8:
227
                        freePathId = 3
228
                    if free[5:0] == 16:
229
                        freePathId = 4
230
                    if free[6:0] == 32:
231
                        freePathId = 5
232
                    if free[7:0] == 64:
233
                        freePathId = 6
234
                    if free[8:0] == 128:
235
                        freePathId = 7
236
                    reg[0][freePathId].next = selTrans[i].val
237
                    free[freePathId] = 0
238
                    pathIdReg[i].next = freePathId
239
                    for j in range(m - 1):
240
                        reg[j + 1][freePathId].next = reg[j][int(pathId[i])].val
241
            a.next = reg[m - 1][int(pathId[int(selState.val)])].val[1]
242
            b.next = reg[m - 1][int(pathId[int(selState.val)])].val[0]
243
            for i in range(4):
244
                for j in range(m - 1):
245
                    for k in range(4):
246
                        if reg[j][int(pathId[int(state[k].val)])].val == i and state[k].val != selState.val:
247
                            op[k] = weight[k].val
248
                        else:
249
                            op[k] = (2 ** q) - 1
250
                    if op[0] < op[1]:
251
                        tmp[0] = op[0]
252
                    else:
253
                        tmp[0] = op[1]
254
                    if op[2] < op[3]:
255
                        tmp[1] = op[2]
256
                    else:
257
                        tmp[1] = op[3]
258
                    if tmp[0] < tmp[1]:
259
                        tmp[2] = tmp[0]
260
                    else:
261
                        tmp[2] = tmp[1]
262
                    if tmp[2] < revWeight[i][j].val:
263
                        revWeightTmp[i][j + 1] = tmp[2]
264
                    else:
265
                        revWeightTmp[i][j + 1] = revWeight[i][j].val
266
                revWeightTmp[i][0] = weight[i].val
267
            for j in range(2):
268
                if revWeightTmp[0][j] == 0:
269
                    notZero[j] = [1, 2, 3]
270
                elif revWeightTmp[1][j] == 0:
271
                    notZero[j] = [0, 2, 3]
272
                elif revWeightTmp[2][j] == 0:
273
                    notZero[j] = [0, 1, 3]
274
                elif revWeightTmp[3][j] == 0:
275
                    notZero[j] = [0, 1, 2]
276
                if revWeightTmp[int(notZero[j][0])][j] <= revWeightTmp[int(notZero[j][1])][j]:
277
                    minTmp[0] = 0
278
                else:
279
                    minTmp[0] = 1
280
                if revWeightTmp[int(notZero[j][0])][j] <= revWeightTmp[int(notZero[j][2])][j]:
281
                    minTmp[1] = 0
282
                else:
283
                    minTmp[1] = 1
284
                if revWeightTmp[int(notZero[j][1])][j] <= revWeightTmp[int(notZero[j][2])][j]:
285
                    minTmp[2] = 0
286
                else:
287
                    minTmp[2] = 1
288
                if minTmp == [0, 0, 0]:
289
                    ind[j] = [0, 1, 2]
290
                elif minTmp == [0, 0, 1]:
291
                    ind[j] = [0, 2, 1]
292
                elif minTmp == [1, 0, 0]:
293
                    ind[j] = [1, 0, 2]
294
                elif minTmp == [0, 1, 1]:
295
                    ind[j] = [1, 2, 0]
296
                elif minTmp == [1, 1, 0]:
297
                    ind[j] = [2, 0, 1]
298
                elif minTmp == [1, 1, 1]:
299
                    ind[j] = [2, 1, 0]
300
                else:
301
                    print "ERROR: Configuration does not exist", minTmp
302
            for i in range(3):
303
                tmp[3]  = revWeightTmp[int(notZero[0][int(ind[0][i])])][0]
304
                tmp4    = revWeightTmp[int(notZero[1][int(ind[1][i])])][1] + (2 ** (q - 4))
305
                if tmp[3] < tmp4:
306
                    revWeightFilt[int(ind[0][i])] = tmp[3]
307
                else:
308
                    revWeightFilt[int(ind[0][i])] = intbv(tmp4)[q:0]
309
            for i in range(3):
310
                revWeightTmp[int(notZero[0][i])][0] = revWeightFilt[i]
311
            for i in range(4):
312
                for j in range(m):
313
                    revWeight[i][j].next = revWeightTmp[i][j]
314
            llr0.next = revWeight[0][m - 1]
315
            llr1.next = revWeight[1][m - 1]
316
            llr2.next = revWeight[2][m - 1]
317
            llr3.next = revWeight[3][m - 1]
318
    return trellis2Logic

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.