1 |
7 |
dbrochart |
----------------------------------------------------------------------
|
2 |
|
|
---- ----
|
3 |
|
|
---- trellis2_synth.vhd ----
|
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 |
|
|
architecture synth of trellis2 is
|
44 |
|
|
signal revWeight : ARRAY_4xTREL2_LEN;
|
45 |
|
|
signal pathIdReg : ARRAY8d;
|
46 |
|
|
signal reg : ARRAY_TREL2_LENx8;
|
47 |
|
|
begin
|
48 |
|
|
process (clk, rst)
|
49 |
|
|
variable free : std_logic_vector(7 downto 0);
|
50 |
|
|
variable freeBeg : std_logic_vector(7 downto 0);
|
51 |
|
|
variable pastState : ARRAY8d;
|
52 |
|
|
variable pathId : ARRAY8d;
|
53 |
|
|
variable freePathId : INT3BIT;
|
54 |
|
|
variable op : ARRAY4a;
|
55 |
|
|
variable tmp : ARRAY4a;
|
56 |
|
|
variable revWeightTmp : ARRAY_4xTREL2_LEN;
|
57 |
|
|
variable revWeightFilt : ARRAY3a;
|
58 |
|
|
variable notZero : ARRAY6b;
|
59 |
|
|
variable minTmp : std_logic_vector(0 to 2);
|
60 |
|
|
variable ind : ARRAY6b;
|
61 |
|
|
variable tmp4 : std_logic_vector(ACC_DIST_WIDTH downto 0);
|
62 |
|
|
begin
|
63 |
|
|
if rst = '0' then
|
64 |
|
|
for i in 0 to 3 loop
|
65 |
|
|
for j in 0 to TREL2_LEN - 1 loop
|
66 |
|
|
revWeight(i * TREL2_LEN + j) <= (others => '0');
|
67 |
|
|
end loop;
|
68 |
|
|
end loop;
|
69 |
|
|
a <= '0';
|
70 |
|
|
b <= '0';
|
71 |
|
|
llr0 <= (others => '0');
|
72 |
|
|
llr1 <= (others => '0');
|
73 |
|
|
llr2 <= (others => '0');
|
74 |
|
|
llr3 <= (others => '0');
|
75 |
|
|
for i in 0 to 7 loop
|
76 |
|
|
pathIdReg(i) <= i;
|
77 |
|
|
for j in 0 to TREL2_LEN - 1 loop
|
78 |
|
|
reg(j * 8 + i) <= "00";
|
79 |
|
|
end loop;
|
80 |
|
|
end loop;
|
81 |
|
|
elsif clk = '1' and clk'event then
|
82 |
|
|
free := "11111111";
|
83 |
|
|
for i in 0 to 7 loop
|
84 |
|
|
pastState(i) := TRANS2STATE(i * 4 + conv_integer(unsigned(selTrans(i))));
|
85 |
|
|
pathId(i) := pathIdReg(pastState(i));
|
86 |
|
|
free(pathId(i)) := '0';
|
87 |
|
|
end loop;
|
88 |
|
|
freeBeg := "11111111";
|
89 |
|
|
for i in 0 to 7 loop
|
90 |
|
|
if freeBeg(pathId(i)) = '1' then
|
91 |
|
|
reg(0 * 8 + pathId(i)) <= selTrans(i);
|
92 |
|
|
freeBeg(pathId(i)) := '0';
|
93 |
|
|
pathIdReg(i) <= pathId(i);
|
94 |
|
|
for j in 0 to TREL2_LEN - 2 loop
|
95 |
|
|
reg((j + 1) * 8 + pathId(i)) <= reg(j * 8 + pathId(i));
|
96 |
|
|
end loop;
|
97 |
|
|
else
|
98 |
|
|
if free(0) = '1' then
|
99 |
|
|
freePathId := 0;
|
100 |
|
|
end if;
|
101 |
|
|
if free(1 downto 0) = "10" then
|
102 |
|
|
freePathId := 1;
|
103 |
|
|
end if;
|
104 |
|
|
if free(2 downto 0) = "100" then
|
105 |
|
|
freePathId := 2;
|
106 |
|
|
end if;
|
107 |
|
|
if free(3 downto 0) = "1000" then
|
108 |
|
|
freePathId := 3;
|
109 |
|
|
end if;
|
110 |
|
|
if free(4 downto 0) = "10000" then
|
111 |
|
|
freePathId := 4;
|
112 |
|
|
end if;
|
113 |
|
|
if free(5 downto 0) = "100000" then
|
114 |
|
|
freePathId := 5;
|
115 |
|
|
end if;
|
116 |
|
|
if free(6 downto 0) = "1000000" then
|
117 |
|
|
freePathId := 6;
|
118 |
|
|
end if;
|
119 |
|
|
if free(7 downto 0) = "10000000" then
|
120 |
|
|
freePathId := 7;
|
121 |
|
|
end if;
|
122 |
|
|
reg(0 * 8 + freePathId) <= selTrans(i);
|
123 |
|
|
free(freePathId) := '0';
|
124 |
|
|
pathIdReg(i) <= freePathId;
|
125 |
|
|
for j in 0 to TREL2_LEN - 2 loop
|
126 |
|
|
reg((j + 1) * 8 + freePathId) <= reg(j * 8 + pathId(i));
|
127 |
|
|
end loop;
|
128 |
|
|
end if;
|
129 |
|
|
end loop;
|
130 |
|
|
a <= reg((TREL2_LEN - 1) * 8 + pathId(conv_integer(unsigned(selState))))(1);
|
131 |
|
|
b <= reg((TREL2_LEN - 1) * 8 + pathId(conv_integer(unsigned(selState))))(0);
|
132 |
|
|
for i in 0 to 3 loop
|
133 |
|
|
for j in 0 to TREL2_LEN - 2 loop
|
134 |
|
|
for k in 0 to 3 loop
|
135 |
|
|
if reg(j * 8 + pathId(conv_integer(unsigned(state(k))))) = std_logic_vector(conv_unsigned(i, 2)) and state(k) /= selState then
|
136 |
|
|
op(k) := weight(k);
|
137 |
|
|
else
|
138 |
|
|
op(k) := std_logic_vector(conv_unsigned((2 ** ACC_DIST_WIDTH) - 1, ACC_DIST_WIDTH));
|
139 |
|
|
end if;
|
140 |
|
|
end loop;
|
141 |
|
|
if conv_integer(unsigned(op(0))) < conv_integer(unsigned(op(1))) then
|
142 |
|
|
tmp(0) := op(0);
|
143 |
|
|
else
|
144 |
|
|
tmp(0) := op(1);
|
145 |
|
|
end if;
|
146 |
|
|
if conv_integer(unsigned(op(2))) < conv_integer(unsigned(op(3))) then
|
147 |
|
|
tmp(1) := op(2);
|
148 |
|
|
else
|
149 |
|
|
tmp(1) := op(3);
|
150 |
|
|
end if;
|
151 |
|
|
if conv_integer(unsigned(tmp(0))) < conv_integer(unsigned(tmp(1))) then
|
152 |
|
|
tmp(2) := tmp(0);
|
153 |
|
|
else
|
154 |
|
|
tmp(2) := tmp(1);
|
155 |
|
|
end if;
|
156 |
|
|
if conv_integer(unsigned(tmp(2))) < conv_integer(unsigned(revWeight(i * TREL2_LEN + j))) then
|
157 |
|
|
revWeightTmp(i * TREL2_LEN + j + 1) := tmp(2);
|
158 |
|
|
else
|
159 |
|
|
revWeightTmp(i * TREL2_LEN + j + 1) := revWeight(i * TREL2_LEN + j);
|
160 |
|
|
end if;
|
161 |
|
|
end loop;
|
162 |
|
|
revWeightTmp(i * TREL2_LEN + 0) := weight(i);
|
163 |
|
|
end loop;
|
164 |
|
|
for j in 0 to 1 loop
|
165 |
|
|
if revWeightTmp(0 * TREL2_LEN + j) = std_logic_vector(conv_unsigned(0, ACC_DIST_WIDTH)) then
|
166 |
|
|
notZero(j * 3 + 0) := 1;
|
167 |
|
|
notZero(j * 3 + 1) := 2;
|
168 |
|
|
notZero(j * 3 + 2) := 3;
|
169 |
|
|
elsif revWeightTmp(1 * TREL2_LEN + j) = std_logic_vector(conv_unsigned(0, ACC_DIST_WIDTH)) then
|
170 |
|
|
notZero(j * 3 + 0) := 0;
|
171 |
|
|
notZero(j * 3 + 1) := 2;
|
172 |
|
|
notZero(j * 3 + 2) := 3;
|
173 |
|
|
elsif revWeightTmp(2 * TREL2_LEN + j) = std_logic_vector(conv_unsigned(0, ACC_DIST_WIDTH)) then
|
174 |
|
|
notZero(j * 3 + 0) := 0;
|
175 |
|
|
notZero(j * 3 + 1) := 1;
|
176 |
|
|
notZero(j * 3 + 2) := 3;
|
177 |
|
|
elsif revWeightTmp(3 * TREL2_LEN + j) = std_logic_vector(conv_unsigned(0, ACC_DIST_WIDTH)) then
|
178 |
|
|
notZero(j * 3 + 0) := 0;
|
179 |
|
|
notZero(j * 3 + 1) := 1;
|
180 |
|
|
notZero(j * 3 + 2) := 2;
|
181 |
|
|
end if;
|
182 |
|
|
if conv_integer(unsigned(revWeightTmp(notZero(j * 3 + 0) * TREL2_LEN + j))) <= conv_integer(unsigned(revWeightTmp(notZero(j * 3 + 1) * TREL2_LEN + j))) then
|
183 |
|
|
minTmp(0) := '0';
|
184 |
|
|
else
|
185 |
|
|
minTmp(0) := '1';
|
186 |
|
|
end if;
|
187 |
|
|
if conv_integer(unsigned(revWeightTmp(notZero(j * 3 + 0) * TREL2_LEN + j))) <= conv_integer(unsigned(revWeightTmp(notZero(j * 3 + 2) * TREL2_LEN + j))) then
|
188 |
|
|
minTmp(1) := '0';
|
189 |
|
|
else
|
190 |
|
|
minTmp(1) := '1';
|
191 |
|
|
end if;
|
192 |
|
|
if conv_integer(unsigned(revWeightTmp(notZero(j * 3 + 1) * TREL2_LEN + j))) <= conv_integer(unsigned(revWeightTmp(notZero(j * 3 + 2) * TREL2_LEN + j))) then
|
193 |
|
|
minTmp(2) := '0';
|
194 |
|
|
else
|
195 |
|
|
minTmp(2) := '1';
|
196 |
|
|
end if;
|
197 |
|
|
if minTmp = "000" then
|
198 |
|
|
ind(j * 3 + 0) := 0;
|
199 |
|
|
ind(j * 3 + 1) := 1;
|
200 |
|
|
ind(j * 3 + 2) := 2;
|
201 |
|
|
elsif minTmp = "001" then
|
202 |
|
|
ind(j * 3 + 0) := 0;
|
203 |
|
|
ind(j * 3 + 1) := 2;
|
204 |
|
|
ind(j * 3 + 2) := 1;
|
205 |
|
|
elsif minTmp = "100" then
|
206 |
|
|
ind(j * 3 + 0) := 1;
|
207 |
|
|
ind(j * 3 + 1) := 0;
|
208 |
|
|
ind(j * 3 + 2) := 2;
|
209 |
|
|
elsif minTmp = "011" then
|
210 |
|
|
ind(j * 3 + 0) := 1;
|
211 |
|
|
ind(j * 3 + 1) := 2;
|
212 |
|
|
ind(j * 3 + 2) := 0;
|
213 |
|
|
elsif minTmp = "110" then
|
214 |
|
|
ind(j * 3 + 0) := 2;
|
215 |
|
|
ind(j * 3 + 1) := 0;
|
216 |
|
|
ind(j * 3 + 2) := 1;
|
217 |
|
|
else -- if minTmp = "111" then
|
218 |
|
|
ind(j * 3 + 0) := 2;
|
219 |
|
|
ind(j * 3 + 1) := 1;
|
220 |
|
|
ind(j * 3 + 2) := 0;
|
221 |
|
|
end if;
|
222 |
|
|
end loop;
|
223 |
|
|
for i in 0 to 2 loop
|
224 |
|
|
tmp(3) := revWeightTmp(notZero(0 * 3 + ind(0 * 3 + i)) * TREL2_LEN + 0);
|
225 |
|
|
tmp4 := std_logic_vector(conv_unsigned(conv_integer(unsigned(revWeightTmp(notZero(1 * 3 + ind(1 * 3 + i)) * TREL2_LEN + 1))) + (2 ** (ACC_DIST_WIDTH - 4)), ACC_DIST_WIDTH + 1));
|
226 |
|
|
if conv_integer(unsigned(tmp(3))) < conv_integer(unsigned(tmp4)) then
|
227 |
|
|
revWeightFilt(ind(0 * 3 + i)) := tmp(3);
|
228 |
|
|
else
|
229 |
|
|
revWeightFilt(ind(0 * 3 + i)) := tmp4(ACC_DIST_WIDTH - 1 downto 0);
|
230 |
|
|
end if;
|
231 |
|
|
end loop;
|
232 |
|
|
for i in 0 to 2 loop
|
233 |
|
|
revWeightTmp(notZero(0 * 3 + i) * TREL2_LEN + 0) := revWeightFilt(i);
|
234 |
|
|
end loop;
|
235 |
|
|
for i in 0 to 3 loop
|
236 |
|
|
for j in 0 to TREL2_LEN - 1 loop
|
237 |
|
|
revWeight(TREL2_LEN * i + j) <= revWeightTmp(TREL2_LEN * i + j);
|
238 |
|
|
end loop;
|
239 |
|
|
end loop;
|
240 |
|
|
llr0 <= revWeight(1 * TREL2_LEN - 1);
|
241 |
|
|
llr1 <= revWeight(2 * TREL2_LEN - 1);
|
242 |
|
|
llr2 <= revWeight(3 * TREL2_LEN - 1);
|
243 |
|
|
llr3 <= revWeight(4 * TREL2_LEN - 1);
|
244 |
|
|
end if;
|
245 |
|
|
end process;
|
246 |
|
|
end;
|