Recognizes if input is ogg or not.
[xiph.git] / theora-fpga / theora_hardware / idctslow.vhd
blob3fbb5a9151669400f3c6f933b0b5ef3af98bef83
1 -------------------------------------------------------------------------------
2 -- Description: Do the iDCTSlow job.
3 -------------------------------------------------------------------------------
5 library std;
6 library ieee;
7 library work;
9 use ieee.std_logic_1164.all;
10 use ieee.numeric_std.all;
11 use work.all;
14 entity IDctSlow is
15 port (Clk,
16 Reset_n : in std_logic;
18 in_request : out std_logic;
19 in_valid : in std_logic;
20 in_data : in signed(15 downto 0);
21 in_quantmat : in signed(15 downto 0);
23 out_requested : in std_logic;
24 out_valid : out std_logic;
25 out_data : out signed(15 downto 0)
27 end entity IDctSlow;
30 architecture rtl of IDctSlow is
31 component dual_syncram
32 generic (
33 DEPTH : positive := 64; -- How many slots
34 DATA_WIDTH : positive := 16; -- How many bits per slot
35 ADDR_WIDTH : positive := 6 -- = ceil(log2(DEPTH))
37 port (
38 clk : in std_logic;
39 wr_e : in std_logic;
40 wr_addr : in unsigned(ADDR_WIDTH-1 downto 0);
41 wr_data : in signed(DATA_WIDTH-1 downto 0);
42 rd1_addr : in unsigned(ADDR_WIDTH-1 downto 0);
43 rd1_data : out signed(DATA_WIDTH-1 downto 0);
44 rd2_addr : in unsigned(ADDR_WIDTH-1 downto 0);
45 rd2_data : out signed(DATA_WIDTH-1 downto 0)
47 end component;
50 subtype ogg_int_16_t is signed(15 downto 0);
51 subtype ogg_int_32_t is signed(31 downto 0);
53 type mem64_t is array (0 to 63) of ogg_int_16_t;
55 signal s_A, s_B, s_C, s_D, s_Ad, s_Bd, s_Cd, s_Dd, s_E, s_F, s_G, s_H : ogg_int_16_t;
56 signal s_Ed, s_Gd, s_Add, s_Bdd, s_Fd, s_Hd : ogg_int_16_t;
58 signal row_loop : std_logic;
60 -- FSMs
61 type state_t is (readIn,idct,writeOut);
62 signal state : state_t;
64 type idct_state_t is (idct_st1, idct_st2, idct_st3, idct_st4,
65 idct_st5, idct_st6, idct_st7, idct_st8,
66 idct_st9, idct_st10, idct_st11, idct_st12,
67 idct_st13, idct_st14, idct_st15, idct_st16);
68 signal idct_state : idct_state_t;
70 type wout_state_t is (wout_st1, wout_st2, wout_st3);
71 signal wout_state : wout_state_t;
73 -- Memory
75 signal mem_we : std_logic;
76 signal mem_waddr : unsigned(5 downto 0);
77 signal mem_wdata : ogg_int_16_t;
78 signal mem_raddr1 : unsigned(5 downto 0);
79 signal mem_rdata1 : ogg_int_16_t;
80 signal mem_raddr2 : unsigned(5 downto 0);
81 signal mem_rdata2 : ogg_int_16_t;
83 -- Handshake
84 subtype tiny_int is integer range 0 to 63;
85 signal count : tiny_int;
86 signal s_in_request : std_logic;
87 signal s_out_valid : std_logic;
90 type dezigzag_t is array (0 to 63) of unsigned(5 downto 0);
91 constant dezigzag_index : dezigzag_t := (
92 "000000", "000001", "001000", "010000", "001001",
93 "000010", "000011", "001010", "010001", "011000",
94 "100000", "011001", "010010", "001011", "000100",
95 "000101", "001100", "010011", "011010", "100001",
96 "101000", "110000", "101001", "100010", "011011",
97 "010100", "001101", "000110", "000111", "001110",
98 "010101", "011100", "100011", "101010", "110001",
99 "111000", "111001", "110010", "101011", "100100",
100 "011101", "010110", "001111", "010111", "011110",
101 "100101", "101100", "110011", "111010", "111011",
102 "110100", "101101", "100110", "011111", "100111",
103 "101110", "110101", "111100", "111101", "110110",
104 "101111", "110111", "111110", "111111" );
108 -- cos(n*pi/16) or sin(8-n)*pi/16)
109 constant xC1S7 : ogg_int_32_t := "00000000000000001111101100010101";
110 constant xC2S6 : ogg_int_32_t := "00000000000000001110110010000011";
111 constant xC3S5 : ogg_int_32_t := "00000000000000001101010011011011";
112 constant xC4S4 : ogg_int_32_t := "00000000000000001011010100000101";
113 constant xC5S3 : ogg_int_32_t := "00000000000000001000111000111010";
114 constant xC6S2 : ogg_int_32_t := "00000000000000000110000111111000";
115 constant xC7S1 : ogg_int_32_t := "00000000000000000011000111110001";
118 begin
120 -- Data matrix 8 x 8 x 16 bits
121 mem : dual_syncram
122 generic map( DEPTH => 64, DATA_WIDTH => 16, ADDR_WIDTH => 6 )
123 port map(clk, mem_we, mem_waddr, mem_wdata, mem_raddr1, mem_rdata1, mem_raddr2, mem_rdata2 );
125 in_request <= s_in_request;
126 out_valid <= s_out_valid;
127 out_data <= mem_rdata1;
130 process(clk)
132 procedure ReadIn is
133 begin
134 s_out_valid <= '0'; -- came from WriteOut, out_valid must be 0
135 s_in_request <= '1';
137 if( s_in_request = '1' and in_valid = '1' )then
138 mem_waddr <= dezigzag_index( count );
139 mem_wdata <= "*"( in_data, in_quantmat )(15 downto 0);
140 mem_we <= '1';
142 if( count = 63 )then
143 state <= idct;
144 s_in_request <= '0';
145 count <= 0;
146 else
147 count <= count + 1;
148 end if;
150 end if;
151 end procedure ReadIn;
154 procedure WriteOut is
155 begin
156 case wout_state is
157 when wout_st1 =>
158 wout_state <= wout_st2;
159 mem_raddr1 <= to_unsigned(count,6);
161 when wout_st2 => -- Wait for the memory delay
162 wout_state <= wout_st3;
163 s_out_valid <= '0';
165 when wout_st3 =>
166 s_out_valid <= '1';
168 if( out_requested = '1' )then
169 if( count = 63 )then
170 wout_state <= wout_st1;
171 state <= readIn; -- on readIn state must set out_valid to 0
172 count <= 0;
173 else
174 wout_state <= wout_st2;
175 mem_raddr1 <= to_unsigned(count + 1,6);
176 count <= count + 1;
177 end if;
178 end if;
180 when others => null;
181 end case;
182 end procedure WriteOut;
186 procedure Idct is
187 variable adjust: integer range 0 to 8;
188 variable adjidx : integer range 0 to 8;
189 variable shift : integer range 0 to 4;
190 begin
191 if (row_loop = '1') then
192 adjust := 0;
193 shift := 0;
194 adjidx := 1;
195 else
196 adjust := 8;
197 shift := 4;
198 adjidx := 8;
199 end if;
201 case idct_state is
202 when idct_st1 =>
203 idct_state <= idct_st2;
204 mem_raddr1 <= to_unsigned(1*adjidx + count,6);
205 mem_raddr2 <= to_unsigned(7*adjidx + count,6);
206 when idct_st2 =>
207 idct_state <= idct_st3;
208 mem_raddr1 <= to_unsigned(3*adjidx + count,6);
209 mem_raddr2 <= to_unsigned(5*adjidx + count,6);
210 when idct_st3 =>
211 idct_state <= idct_st4;
212 s_A <= "*"(xC1S7,mem_rdata1)(31 downto 16) + "*"(xC7S1,mem_rdata2)(31 downto 16);
213 s_B <= "*"(xC7S1,mem_rdata1)(31 downto 16) - "*"(xC1S7,mem_rdata2)(31 downto 16);
214 mem_raddr1 <= to_unsigned(3*adjidx + count,6);
215 mem_raddr2 <= to_unsigned(5*adjidx + count,6);
217 when idct_st4 =>
218 idct_state <= idct_st5;
219 s_C <= "*"(xC3S5,mem_rdata1)(31 downto 16) + "*"(xC5S3,mem_rdata2)(31 downto 16);
220 s_D <= "*"(xC3S5,mem_rdata2)(31 downto 16) - "*"(xC5S3,mem_rdata1)(31 downto 16);
221 mem_raddr1 <= to_unsigned(0*adjidx + count,6);
222 mem_raddr2 <= to_unsigned(4*adjidx + count,6);
223 when idct_st5 =>
224 idct_state <= idct_st6;
225 s_Ad <= "*"(xC4S4,(s_A - s_C))(31 downto 16);
226 s_Bd <= "*"(xC4S4,(s_B - s_D))(31 downto 16);
227 s_Cd <= s_A + s_C;
228 s_Dd <= s_B + s_D;
229 mem_raddr1 <= to_unsigned(2*adjidx + count,6);
230 mem_raddr2 <= to_unsigned(6*adjidx + count,6);
232 when idct_st6 =>
233 idct_state <= idct_st7;
234 s_E <= "*"(xC4S4,(mem_rdata1 + mem_rdata2))(31 downto 16);
235 s_F <= "*"(xC4S4,(mem_rdata1 - mem_rdata2))(31 downto 16);
237 when idct_st7 =>
238 idct_state <= idct_st8;
239 s_G <= "*"(xC2S6,mem_rdata1)(31 downto 16) + "*"(xC6S2,mem_rdata2)(31 downto 16);
240 s_H <= "*"(xC6S2,mem_rdata1)(31 downto 16) - "*"(xC2S6,mem_rdata2)(31 downto 16);
242 when idct_st8 =>
243 idct_state <= idct_st9;
244 s_Ed <= s_E - s_G + adjust;
245 s_Gd <= s_E + s_G + adjust;
246 s_Add <= s_F + s_Ad + adjust;
247 s_Fd <= s_F - s_Ad + adjust;
248 s_Bdd <= s_Bd - s_H;
249 s_Hd <= s_Bd + s_H;
251 when idct_st9 =>
252 idct_state <= idct_st10;
253 mem_waddr <= to_unsigned(0*adjidx + count,6);
254 mem_wdata <= shift_right(s_Gd + s_Cd,shift);
255 mem_we <= '1';
257 when idct_st10 =>
258 idct_state <= idct_st11;
259 mem_waddr <= to_unsigned(7*adjidx + count,6);
260 mem_wdata <= shift_right(s_Gd - s_Cd,shift);
261 mem_we <= '1';
263 when idct_st11 =>
264 idct_state <= idct_st12;
265 mem_waddr <= to_unsigned(1*adjidx + count,6);
266 mem_wdata <= shift_right(s_Add + s_Hd,shift);
267 mem_we <= '1';
269 when idct_st12 =>
270 idct_state <= idct_st13;
271 mem_waddr <= to_unsigned(2*adjidx + count,6);
272 mem_wdata <= shift_right(s_Add - s_Hd,shift);
273 mem_we <= '1';
275 when idct_st13 =>
276 idct_state <= idct_st14;
277 mem_waddr <= to_unsigned(3*adjidx + count,6);
278 mem_wdata <= shift_right(s_Ed + s_Dd,shift);
279 mem_we <= '1';
281 when idct_st14 =>
282 idct_state <= idct_st15;
283 mem_waddr <= to_unsigned(4*adjidx + count,6);
284 mem_wdata <= shift_right(s_Ed - s_Dd,shift);
285 mem_we <= '1';
287 when idct_st15 =>
288 idct_state <= idct_st16;
289 mem_waddr <= to_unsigned(5*adjidx + count,6);
290 mem_wdata <= shift_right(s_Fd + s_Bdd,shift);
291 mem_we <= '1';
293 when idct_st16 =>
294 idct_state <= idct_st1;
295 mem_waddr <= to_unsigned(6*adjidx + count,6);
296 mem_wdata <= shift_right(s_Fd - s_Bdd,shift);
297 mem_we <= '1';
299 if (row_loop = '1') then
300 if ( count = 56 ) then
301 count <= 0;
302 row_loop <= '0';
303 else
304 count <= count + 8;
305 end if;
306 else
307 if ( count = 7 ) then
308 count <= 0;
309 row_loop <= '1';
310 state <= writeOut;
311 else
312 count <= count + 1;
313 end if;
314 end if;
315 when others => null;
316 end case;
317 end procedure Idct;
320 begin
322 if(clk'event and clk = '1') then
323 if( Reset_n = '0' ) then
324 state <= readIn;
325 idct_state <= idct_st1;
326 wout_state <= wout_st1;
327 s_in_request <= '0';
328 count <= 0;
329 s_out_valid <= '0';
330 row_loop <= '1';
331 mem_we <= '0';
333 mem_waddr <= "000000";
334 mem_wdata <= "0000000000000000";
335 mem_raddr1 <= "000000";
336 mem_raddr2 <= "000000";
337 else
338 mem_we <= '0';
339 case state is
340 when readIn => ReadIn;
341 when idct => Idct;
342 when writeOut => WriteOut;
343 when others => ReadIn; state <= readIn;
344 end case;
345 end if;
346 end if;
347 end process;
349 end rtl;