OSDN Git Service

Merge branch 'debugging' into net-mjpeg
[fpga-leon-mjpeg/leon-mjpeg.git] / grlib-gpl-1.0.22-b4095 / lib / kuri / mjpeg / idct2.vhd
1 ------------------------------------------------------------------------------
2 --  Copyright (C) 2011, Kenichi Kurimoto
3 --
4 --  This program is free software; you can redistribute it and/or modify
5 --  it under the terms of the GNU General Public License as published by
6 --  the Free Software Foundation; either version 2 of the License, or
7 --  (at your option) any later version.
8 --
9 --  This program is distributed in the hope that it will be useful,
10 --  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 --  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 --  GNU General Public License for more details.
13 --
14 --  You should have received a copy of the GNU General Public License
15 --  along with this program; if not, write to the Free Software
16 --  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
17 -----------------------------------------------------------------------------
18 -- Entity:      idct2
19 -- File:        idct2.vhd
20 -- Author:      Kenichi Kurimoto 
21 -- Description: 2nd IDCT calculation for jpeg decode
22 ------------------------------------------------------------------------------
23
24 library ieee;
25 use ieee.std_logic_1164.all;
26 use ieee.numeric_std.all;
27
28 library grlib;
29 use grlib.stdlib.all;
30
31 entity idct2 is
32     port ( rst : in  std_ulogic;
33            clk : in  std_ulogic;
34            ready1 : out std_logic;
35            strobe1 : in std_logic;
36            coeffin : in  std_logic_vector (15 downto 0);
37            outdata : out  std_logic_vector (7 downto 0);
38            ready2 : in std_logic;
39            strobe2 : out std_logic;
40            startgen : in std_logic
41            );
42 end idct2;
43
44 architecture rtl of idct2 is
45
46 function mysigned_mul(a,b : std_logic_vector) return std_logic_vector is
47 variable z : std_logic_vector(a'length + b'length -1 downto 0);
48 begin
49     z := std_logic_vector(signed(a) * signed(b));
50     return(z);
51 end;
52
53
54 function mysigned_add(a,b : std_logic_vector) return std_logic_vector is
55 variable ex_a : std_logic_vector(a'length downto 0);
56 variable ex_b : std_logic_vector(b'length downto 0);
57 variable z1 : std_logic_vector(a'length downto 0);
58 variable z2 : std_logic_vector(b'length downto 0);
59 begin
60     ex_a := a(a'left) & a;
61     ex_b := b(b'left) & b;
62     if( a'length > b'length)then
63        z1 := std_logic_vector(signed(ex_a) + signed(ex_b));
64        return(z1);
65     else
66        z2 := std_logic_vector(signed(ex_a) + signed(ex_b));
67        return(z2);
68     end if;
69 end;
70
71 function round1(indata : std_logic_vector(32 downto 0)) return std_logic_vector is
72 variable judge :std_logic;
73 variable z : std_logic_vector(14 downto 0);
74 begin
75         judge := indata(17);
76         if (judge = '0') then
77                 z := indata(32 downto 18);
78         else 
79                 z := indata(32 downto 18) + 1;
80         end if;
81         return(z);
82 end;
83
84 function round2(indata : std_logic_vector(32 downto 0); pol : std_logic) return std_logic_vector is
85 variable judge : std_logic;
86 variable tmpdata : std_logic_vector(32 downto 0);
87 variable z : std_logic_vector(14 downto 0);
88 begin
89         if (pol = '1') then
90                 tmpdata := not indata + 1 ;
91         else
92                 tmpdata := indata;
93         end if;
94         judge := tmpdata(17);
95         if (judge = '1') then
96                 z := tmpdata(32 downto 18) + 1;
97         else
98                 z := tmpdata(32 downto 18);
99         end if;
100         return(z);
101 end;
102
103 constant S_ZERO : SIGNED := "0000000000";
104 constant S_TWOFIVEFIVE : SIGNED := "0011111111";
105
106 function round3(indata : std_logic_vector(17 downto 0)) return std_logic_vector is
107 variable judge : std_logic;
108 variable z : std_logic_vector(12 downto 0);
109 variable value : integer;
110 begin
111         judge := indata(4);
112         value := 0;
113         if (judge = '0') then
114                 z := indata(17 downto 5);
115         else
116                 z := indata(17 downto 5) + 1;
117         end if;
118   if notx(z) then       value := to_integer(signed(z)); end if;
119    if (value < -128) then
120        return("10000000");
121    end if;
122    if(value > 127) then
123        return("01111111");
124    end if;      
125         return(z(7 downto 0));
126 end;
127
128                         
129
130 subtype coeff23 is std_logic_vector(16 downto 0);
131 type coeff_array1 is array(0 to 31) of coeff23;
132 constant coeff_rom : coeff_array1 :=
133
134 ("01011010100000101","01011010100000101","01011010100000101","01011010100000101",
135  "01111101100010101","01101010011011011","01000111000111010","00011000111110001",
136  "01110110010000011","00110000111111000","11001111000001001","10001001101111101",
137  "01101010011011011","11100111000001111","10000010011101100","10111000111000111",
138  "01011010100000101","10100101011111100","10100101011111100","01011010100000101",
139  "01000111000111010","10000010011101100","00011000111110001","01101010011011011",
140  "00110000111111000","10001001101111101","01110110010000011","11001111000001001",
141  "00011000111110001","10111000111000111","01101010011011011","10000010011101100");
142
143
144 type tablereg_type is array (0 to 3) of std_logic_vector(16 downto 0);
145 type accumulator_type is array (0 to 7) of std_logic_vector(17 downto 0);
146 type resultreg_type is array (0 to 7) of std_logic_vector(7 downto 0);
147
148
149 type d_reg is record
150    inreg : std_logic_vector(15 downto 0);
151         accumulator : accumulator_type;
152         result_reg : resultreg_type;
153 end record;
154
155 type c_reg is record
156         counter : std_logic_vector(6 downto 0);
157 end record;
158
159 type all_reg is record
160         data_reg : d_reg;
161         control_reg : c_reg;
162 end record;
163         
164 type node1_array is array (0 to 3) of std_logic_vector(16 downto 0);
165 type node2_array is array (0 to 3) of std_logic_vector(32 downto 0);
166 type node3_array is array (0 to 7) of std_logic_vector(14 downto 0);
167 type node4_array is array (0 to 7) of std_logic_vector(17 downto 0);
168 type node5_array is array (0 to 7) of std_logic_vector(18 downto 0);
169 type node6_array is array (0 to 7) of std_logic_vector(7 downto 0);
170         
171 signal r, rin : all_reg;
172 --signal sig_node1_0 : std_logic_vector(16 downto 0);
173 --signal sig_node2_0 : std_logic_vector(32 downto 0);
174 --signal sig_node3_0 : std_logic_vector(14 downto 0);
175 --signal sig_node4_0 : std_logic_vector(17 downto 0);
176 --signal sig_node5_0 : std_logic_vector(18 downto 0);
177 --signal sig_node6_0 : std_logic_vector(7 downto 0);
178 --signal sig_node1_3 : std_logic_vector(16 downto 0);
179 --signal sig_node2_3 : std_logic_vector(32 downto 0);
180 --signal sig_node3_4 : std_logic_vector(14 downto 0);
181 --signal sig_node4_4 : std_logic_vector(17 downto 0);
182 --signal sig_node5_4 : std_logic_vector(18 downto 0);
183 --signal sig_node6_4 : std_logic_vector(7 downto 0);
184
185
186 begin
187
188 comb : process(r, rst, strobe1, ready2, coeffin, startgen)
189         variable v : all_reg;
190         variable node1 : node1_array;
191         variable node2 : node2_array;
192         variable node3 : node3_array;
193         variable node4 : node4_array;
194   variable node5 : node5_array;
195         variable node6 : node6_array;
196         variable node7 : std_logic_vector(9 downto 0);
197         variable node8 : std_logic_vector(9 downto 0);
198         variable pol : std_logic;
199
200         variable count_num : integer;
201         variable vstrobe2 : std_logic;
202         variable vready1 : std_logic;
203 begin
204         
205         v := r;
206         vstrobe2 := '0';
207         count_num := to_integer(unsigned(r.control_reg.counter));
208         
209         v.data_reg.inreg := coeffin;
210         
211         case count_num is
212         when 2 | 10 | 18 | 26 | 34 | 42 | 50 | 58 =>
213                 node1(0) := coeff_rom(4);
214                 node1(1) := coeff_rom(5);
215                 node1(2) := coeff_rom(6);
216                 node1(3) := coeff_rom(7);
217         when 3 | 11 | 19 | 27 | 35 | 43 | 51 | 59 =>
218                 node1(0) := coeff_rom(8);
219                 node1(1) := coeff_rom(9);
220                 node1(2) := coeff_rom(10);
221                 node1(3) := coeff_rom(11);
222         when 4 | 12 | 20 | 28 | 36 | 44 | 52 | 60 =>
223                 node1(0) := coeff_rom(12);
224                 node1(1) := coeff_rom(13);
225                 node1(2) := coeff_rom(14);
226                 node1(3) := coeff_rom(15);
227         when 5 | 13 | 21 | 29 | 37 | 45 | 53 | 61 =>
228                 node1(0) := coeff_rom(16);
229                 node1(1) := coeff_rom(17);
230                 node1(2) := coeff_rom(18);
231                 node1(3) := coeff_rom(19);
232         when 6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 =>
233                 node1(0) := coeff_rom(20);
234                 node1(1) := coeff_rom(21);
235                 node1(2) := coeff_rom(22);
236                 node1(3) := coeff_rom(23);
237         when 7 | 15 | 23 | 31 | 39 | 47 | 55 | 63 =>
238                 node1(0) := coeff_rom(24);
239                 node1(1) := coeff_rom(25);
240                 node1(2) := coeff_rom(26);
241                 node1(3) := coeff_rom(27);
242         when 8 | 16 | 24 | 32 | 40 | 48 | 56 | 64 =>
243                 node1(0) := coeff_rom(28);
244                 node1(1) := coeff_rom(29);
245                 node1(2) := coeff_rom(30);
246                 node1(3) := coeff_rom(31);              
247         when others =>
248                 node1(0) := coeff_rom(0);
249                 node1(1) := coeff_rom(1);
250                 node1(2) := coeff_rom(2);
251                 node1(3) := coeff_rom(3);
252         end case;
253         
254         for i in 0 to 3 loop
255            node2(i) := mysigned_mul(node1(i), r.data_reg.inreg);
256            node3(i) := round1(node2(i));
257         end loop;
258         
259         
260 --      when 3 | 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | ..... | 65 
261 -- when 2   4   6   8   10   12   14   16   18   20   22           64  
262
263         if((count_num mod 2) = 0 and (count_num >= 2) and (count_num <= 64))then
264                 pol := '1';
265         else
266                 pol := '0';
267         end if;
268                         
269         node3(4) := round2(node2(3), pol);
270         node3(5) := round2(node2(2), pol);
271         node3(6) := round2(node2(1), pol);
272         node3(7) := round2(node2(0), pol);
273         
274         if((count_num = 1) or (count_num = 9) or (count_num = 17) or (count_num = 25) or (count_num = 33) or (count_num = 41) or (count_num = 49) or (count_num = 57)) then
275                 for i in 0 to 7 loop
276                    node4(i) := (others => '0');
277                 end loop;
278         else
279            for i in 0 to 7 loop
280               node4(i) := r.data_reg.accumulator(i);
281            end loop;
282         end if;
283
284    for i in 0 to 7 loop
285       node5(i) := mysigned_add(node3(i), node4(i));
286       v.data_reg.accumulator(i) := node5(i)(17 downto 0);
287       node6(i) := round3(r.data_reg.accumulator(i));
288    end loop;
289         
290         if((count_num = 9) or (count_num = 17) or (count_num = 25) or (count_num = 33) or (count_num = 41) or (count_num = 49) or (count_num = 57) or (count_num = 65)) then
291                 for i in 0 to 7 loop
292                    v.data_reg.result_reg(i) := node6(i);
293                 end loop;
294         else
295            for i in 0 to 6 loop
296               v.data_reg.result_reg(i) := r.data_reg.result_reg(i+1);
297            end loop;
298            v.data_reg.result_reg(7) := (others => '0');
299         end if;
300
301         node7 := mysigned_add(r.data_reg.result_reg(0),"010000000");
302
303    if((count_num >= 10) and (count_num <= 73))then
304       vstrobe2 := '1';
305    end if; 
306
307 -- controller part
308    if ((count_num = 0 and strobe1 = '1') or count_num /= 0) then
309        v.control_reg.counter := std_logic_vector(to_unsigned(count_num + 1,7));
310        if(count_num = 73)then
311            v.control_reg.counter := (others => '0');
312        end if;
313    end if;
314    vready1 := '0';
315    if(ready2 = '1' and count_num <= 63)then
316        vready1 := '1';
317    end if;
318    
319 -- reset part
320    if rst = '0' or startgen = '1' then
321        v.data_reg.inreg := (others => '0');
322        for i in 0 to 7 loop
323           v.data_reg.accumulator(i) := (others => '0');
324           v.data_reg.result_reg(i) := (others => '0');
325        end loop;
326        v.control_reg.counter := (others => '0');
327    end if; 
328          
329 -- signal
330         outdata <= node7(7 downto 0);
331         strobe2 <= vstrobe2;
332         ready1 <= vready1;
333         rin <= v;
334
335 -- debug
336 --   sig_node1_0 <= node1(0);
337 --   sig_node2_0 <= node2(0);
338 --   sig_node3_0 <= node3(0);
339 --   sig_node4_0 <= node4(0);
340 --   sig_node5_0 <= node5(0);
341 --   sig_node6_0 <= node6(0);
342 --   sig_node1_3 <= node1(3);
343 --   sig_node2_3 <= node2(3);
344 --   sig_node3_4 <= node3(4);
345 --   sig_node4_4 <= node4(4);
346 --   sig_node5_4 <= node5(4);
347 --   sig_node6_4 <= node6(4);
348 end process;
349
350 -- registers
351 reg : process(clk)
352 begin
353         if rising_edge(clk) then
354                 r <= rin;
355         end if;
356 end process;
357
358 end rtl;
359