OSDN Git Service

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