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

Subversion Repositories mkjpeg

[/] [mkjpeg/] [trunk/] [design/] [mdct/] [FDCT.vhd] - Blame information for rev 54

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 25 mikel262
-------------------------------------------------------------------------------
2
-- File Name :  FDCT.vhd
3
--
4
-- Project   : JPEG_ENC
5
--
6
-- Module    : FDCT
7
--
8
-- Content   : FDCT
9
--
10
-- Description : 2D Discrete Cosine Transform
11
--
12
-- Spec.     : 
13
--
14
-- Author    : Michal Krepa
15
--
16
-------------------------------------------------------------------------------
17
-- History :
18
-- 20090301: (MK): Initial Creation.
19
-------------------------------------------------------------------------------
20
 
21
-------------------------------------------------------------------------------
22
-------------------------------------------------------------------------------
23
----------------------------------- LIBRARY/PACKAGE ---------------------------
24
-------------------------------------------------------------------------------
25
-------------------------------------------------------------------------------
26
 
27
-------------------------------------------------------------------------------
28
-- generic packages/libraries:
29
-------------------------------------------------------------------------------
30
library ieee;
31
  use ieee.std_logic_1164.all;
32
  use ieee.numeric_std.all;
33
 
34
-------------------------------------------------------------------------------
35
-- user packages/libraries:
36
-------------------------------------------------------------------------------
37
library work;
38
  use work.JPEG_PKG.all;
39
-------------------------------------------------------------------------------
40
-------------------------------------------------------------------------------
41
----------------------------------- ENTITY ------------------------------------
42
-------------------------------------------------------------------------------
43
-------------------------------------------------------------------------------
44
entity FDCT is
45
  port
46
  (
47
        CLK                : in  std_logic;
48
        RST                : in  std_logic;
49
        -- CTRL
50
        start_pb           : in  std_logic;
51
        ready_pb           : out std_logic;
52
        fdct_sm_settings   : in  T_SM_SETTINGS;
53
 
54
        -- BUF_FIFO
55
        bf_fifo_rd         : out std_logic;
56
        bf_fifo_q          : in  std_logic_vector(23 downto 0);
57
        bf_fifo_hf_full    : in  std_logic;
58
 
59
        -- ZIG ZAG
60
        zz_buf_sel         : in  std_logic;
61
        zz_rd_addr         : in  std_logic_vector(5 downto 0);
62
        zz_data            : out std_logic_vector(11 downto 0);
63
        zz_rden            : in  std_logic;
64
 
65
        -- HOST
66
        img_size_x         : in  std_logic_vector(15 downto 0);
67
        img_size_y         : in  std_logic_vector(15 downto 0);
68
        sof                : in  std_logic
69
    );
70
end entity FDCT;
71
 
72
-------------------------------------------------------------------------------
73
-------------------------------------------------------------------------------
74
----------------------------------- ARCHITECTURE ------------------------------
75
-------------------------------------------------------------------------------
76
-------------------------------------------------------------------------------
77
architecture RTL of FDCT is
78
 
79
  constant C_Y_1       : signed(14 downto 0) := to_signed(4899,  15);
80
  constant C_Y_2       : signed(14 downto 0) := to_signed(9617,  15);
81
  constant C_Y_3       : signed(14 downto 0) := to_signed(1868,  15);
82
  constant C_Cb_1      : signed(14 downto 0) := to_signed(-2764, 15);
83
  constant C_Cb_2      : signed(14 downto 0) := to_signed(-5428, 15);
84
  constant C_Cb_3      : signed(14 downto 0) := to_signed(8192,  15);
85
  constant C_Cr_1      : signed(14 downto 0) := to_signed(8192,  15);
86
  constant C_Cr_2      : signed(14 downto 0) := to_signed(-6860, 15);
87
  constant C_Cr_3      : signed(14 downto 0) := to_signed(-1332, 15);
88
 
89
 
90
  signal mdct_data_in      : std_logic_vector(7 downto 0);
91
  signal mdct_idval        : std_logic;
92
  signal mdct_odval        : std_logic;
93
  signal mdct_data_out     : std_logic_vector(11 downto 0);
94
  signal odv1              : std_logic;
95
  signal dcto1             : std_logic_vector(11 downto 0);
96 52 mikel262
  signal x_pixel_cnt       : unsigned(15 downto 0);
97
  signal y_line_cnt        : unsigned(15 downto 0);
98 25 mikel262
  signal rd_addr           : std_logic_vector(31 downto 0);
99
  signal input_rd_cnt      : unsigned(5 downto 0);
100
  signal rd_en             : std_logic;
101
  signal rd_en_d1          : std_logic;
102
  signal rdaddr            : unsigned(31 downto 0);
103 52 mikel262
  signal bf_dval           : std_logic;
104
  signal bf_dval_m1        : std_logic;
105
  signal bf_dval_m2        : std_logic;
106 25 mikel262
  signal wr_cnt            : unsigned(5 downto 0);
107
  signal dbuf_data         : std_logic_vector(11 downto 0);
108
  signal dbuf_q            : std_logic_vector(11 downto 0);
109
  signal dbuf_we           : std_logic;
110
  signal dbuf_waddr        : std_logic_vector(6 downto 0);
111
  signal dbuf_raddr        : std_logic_vector(6 downto 0);
112
  signal xw_cnt            : unsigned(2 downto 0);
113
  signal yw_cnt            : unsigned(2 downto 0);
114
 
115
  signal dbuf_q_z1         : std_logic_vector(11 downto 0);
116
  constant C_SIMA_ASZ      : integer := 9;
117
  signal sim_rd_addr       : unsigned(C_SIMA_ASZ-1 downto 0);
118
  signal Y_reg_1           : signed(23 downto 0);
119
  signal Y_reg_2           : signed(23 downto 0);
120
  signal Y_reg_3           : signed(23 downto 0);
121
  signal Cb_reg_1          : signed(23 downto 0);
122
  signal Cb_reg_2          : signed(23 downto 0);
123
  signal Cb_reg_3          : signed(23 downto 0);
124
  signal Cr_reg_1          : signed(23 downto 0);
125
  signal Cr_reg_2          : signed(23 downto 0);
126
  signal Cr_reg_3          : signed(23 downto 0);
127
  signal Y_reg             : signed(23 downto 0);
128
  signal Cb_reg            : signed(23 downto 0);
129
  signal Cr_reg            : signed(23 downto 0);
130
  signal R_s               : signed(8 downto 0);
131
  signal G_s               : signed(8 downto 0);
132
  signal B_s               : signed(8 downto 0);
133
  signal Y_8bit            : unsigned(7 downto 0);
134
  signal Cb_8bit           : unsigned(7 downto 0);
135
  signal Cr_8bit           : unsigned(7 downto 0);
136
  signal cmp_idx           : unsigned(1 downto 0);
137
  signal cur_cmp_idx       : unsigned(1 downto 0);
138
  signal cur_cmp_idx_d1    : unsigned(1 downto 0);
139
  signal cur_cmp_idx_d2    : unsigned(1 downto 0);
140
  signal cur_cmp_idx_d3    : unsigned(1 downto 0);
141
  signal cur_cmp_idx_d4    : unsigned(1 downto 0);
142
  signal cur_cmp_idx_d5    : unsigned(1 downto 0);
143
  signal cur_cmp_idx_d6    : unsigned(1 downto 0);
144
  signal cur_cmp_idx_d7    : unsigned(1 downto 0);
145
  signal cur_cmp_idx_d8    : unsigned(1 downto 0);
146
  signal cur_cmp_idx_d9    : unsigned(1 downto 0);
147
  signal fifo1_rd          : std_logic;
148
  signal fifo1_wr          : std_logic;
149
  signal fifo1_q           : std_logic_vector(11 downto 0);
150
  signal fifo1_full        : std_logic;
151
  signal fifo1_empty       : std_logic;
152
  signal fifo1_count       : std_logic_vector(8 downto 0);
153
  signal fifo1_rd_cnt      : unsigned(5 downto 0);
154
  signal fifo1_q_dval      : std_logic;
155
  signal fifo_data_in      : std_logic_vector(11 downto 0);
156
  signal fifo_rd_arm       : std_logic;
157
 
158
  signal eoi_fdct          : std_logic;
159
  signal bf_fifo_rd_s         : std_logic;
160
  signal start_int         : std_logic;
161
 
162
  signal fram1_data        : std_logic_vector(23 downto 0);
163
  signal fram1_q           : std_logic_vector(23 downto 0);
164
  signal fram1_we          : std_logic;
165
  signal fram1_waddr       : std_logic_vector(5 downto 0);
166
  signal fram1_raddr       : std_logic_vector(5 downto 0);
167 28 mikel262
  signal fram1_rd_d        : std_logic_vector(8 downto 0);
168 25 mikel262
  signal fram1_rd          : std_logic;
169
  signal rd_started        : std_logic;
170
  signal writing_en        : std_logic;
171
 
172
-------------------------------------------------------------------------------
173
-- Architecture: begin
174
-------------------------------------------------------------------------------
175
begin
176
 
177
  zz_data      <= dbuf_q;
178
 
179
  bf_fifo_rd   <= bf_fifo_rd_s;
180
 
181
  -------------------------------------------------------------------
182
  -- FRAM1
183
  -------------------------------------------------------------------
184
  U_FRAM1 : entity work.RAMZ
185
  generic map
186
  (
187
      RAMADDR_W     => 6,
188
      RAMDATA_W     => 24
189
  )
190
  port map
191
  (
192
        d           => fram1_data,
193
        waddr       => fram1_waddr,
194
        raddr       => fram1_raddr,
195
        we          => fram1_we,
196
        clk         => CLK,
197
 
198
        q           => fram1_q
199
  );
200
 
201 52 mikel262
  fram1_we   <= bf_dval;
202 25 mikel262
  fram1_data <= bf_fifo_q;
203
 
204
  -------------------------------------------------------------------
205
  -- FRAM1 process
206
  -------------------------------------------------------------------
207
  p_fram1_acc : process(CLK, RST)
208
  begin
209
    if RST = '1' then
210
      fram1_waddr <= (others => '0');
211
    elsif CLK'event and CLK = '1' then
212
      if fram1_we = '1' then
213
        fram1_waddr <= std_logic_vector(unsigned(fram1_waddr) + 1);
214
      end if;
215
    end if;
216
  end process;
217
 
218
  -------------------------------------------------------------------
219
  -- IRAM read process 
220
  -------------------------------------------------------------------
221
  p_counter1 : process(CLK, RST)
222
  begin
223
    if RST = '1' then
224
      rd_en           <= '0';
225
      rd_en_d1        <= '0';
226 52 mikel262
      x_pixel_cnt     <= (others => '0');
227
      y_line_cnt     <= (others => '0');
228 25 mikel262
      input_rd_cnt    <= (others => '0');
229
      cmp_idx         <= (others => '0');
230
      cur_cmp_idx     <= (others => '0');
231
      cur_cmp_idx_d1  <= (others => '0');
232
      cur_cmp_idx_d2  <= (others => '0');
233
      cur_cmp_idx_d3  <= (others => '0');
234
      cur_cmp_idx_d4  <= (others => '0');
235
      cur_cmp_idx_d5  <= (others => '0');
236
      cur_cmp_idx_d6  <= (others => '0');
237
      cur_cmp_idx_d7  <= (others => '0');
238
      cur_cmp_idx_d8  <= (others => '0');
239
      cur_cmp_idx_d9  <= (others => '0');
240
      eoi_fdct        <= '0';
241
      start_int       <= '0';
242
      bf_fifo_rd_s    <= '0';
243 52 mikel262
      bf_dval         <= '0';
244
      bf_dval_m1      <= '0';
245
      bf_dval_m2      <= '0';
246 25 mikel262
      fram1_rd        <= '0';
247
      fram1_rd_d      <= (others => '0');
248
      fram1_raddr     <= (others => '0');
249
    elsif CLK'event and CLK = '1' then
250
      rd_en_d1 <= rd_en;
251
      cur_cmp_idx_d1 <= cur_cmp_idx;
252
      cur_cmp_idx_d2 <= cur_cmp_idx_d1;
253
      cur_cmp_idx_d3 <= cur_cmp_idx_d2;
254
      cur_cmp_idx_d4 <= cur_cmp_idx_d3;
255
      cur_cmp_idx_d5 <= cur_cmp_idx_d4;
256
      cur_cmp_idx_d6 <= cur_cmp_idx_d5;
257
      cur_cmp_idx_d7 <= cur_cmp_idx_d6;
258
      cur_cmp_idx_d8 <= cur_cmp_idx_d7;
259
      cur_cmp_idx_d9 <= cur_cmp_idx_d8;
260
      start_int      <= '0';
261
 
262 52 mikel262
      bf_dval_m2     <= bf_fifo_rd_s;
263
      bf_dval_m1     <= bf_dval_m2;
264
      bf_dval        <= bf_dval_m1;
265 25 mikel262
      fram1_rd_d     <= fram1_rd_d(fram1_rd_d'length-2 downto 0) & fram1_rd;
266
 
267
      -- SOF or internal self-start
268
      if (sof = '1' or start_int = '1') then
269
        input_rd_cnt <= (others => '0');
270
        -- enable BUF_FIFO/FRAM1 reading
271
        rd_started <= '1';
272
 
273
        -- component index
274
        if cmp_idx = 3-1 then
275
          cmp_idx <= (others => '0');
276
          -- horizontal block counter
277 52 mikel262
          if x_pixel_cnt = unsigned(img_size_x)-8 then
278
            x_pixel_cnt <= (others => '0');
279 25 mikel262
            -- vertical block counter
280 52 mikel262
            if y_line_cnt = unsigned(img_size_y)-8 then
281
              y_line_cnt <= (others => '0');
282
              -- set end of image flag
283 25 mikel262
              eoi_fdct <= '1';
284
            else
285 52 mikel262
              y_line_cnt <= y_line_cnt + 8;
286 25 mikel262
            end if;
287
          else
288 52 mikel262
            x_pixel_cnt <= x_pixel_cnt + 8;
289 25 mikel262
          end if;
290
        else
291
          cmp_idx <=cmp_idx + 1;
292
        end if;
293
 
294
        cur_cmp_idx     <= cmp_idx;
295
      end if;
296
 
297 52 mikel262
      -- wait until FIFO becomes half full but only for component 0
298
      -- as we read buf FIFO only during component 0
299 25 mikel262
      if rd_started = '1' and (bf_fifo_hf_full = '1' or cur_cmp_idx /= 0) then
300
        rd_en      <= '1';
301
        rd_started <= '0';
302
      end if;
303
 
304
      bf_fifo_rd_s   <= '0';
305
      fram1_rd       <= '0';
306
      -- stall reading from input FIFO and writing to output FIFO 
307
      -- when output FIFO is almost full
308
      if rd_en = '1' and unsigned(fifo1_count) < 256-64 then
309
        -- read request goes to BUF_FIFO only for component 0. 
310
        if cur_cmp_idx = 0 then
311
          bf_fifo_rd_s <= '1';
312
        end if;
313
 
314
        -- count number of samples read from input in one run
315
        if input_rd_cnt = 64-1 then
316
          rd_en        <= '0';
317 52 mikel262
          -- internal restart
318 25 mikel262
          start_int    <= '1' and not eoi_fdct;
319
          eoi_fdct     <= '0';
320
        else
321
          input_rd_cnt <= input_rd_cnt + 1;
322
        end if;
323
        -- FRAM read enable
324
        fram1_rd <= '1';
325
      end if;
326
 
327
      -- increment FRAM1 read address
328 28 mikel262
      if fram1_rd_d(4) = '1' then
329 25 mikel262
        fram1_raddr <= std_logic_vector(unsigned(fram1_raddr) + 1);
330
      end if;
331
 
332
    end if;
333
  end process;
334
 
335
  -------------------------------------------------------------------
336
  -- FDCT with input level shift
337
  -------------------------------------------------------------------
338
  U_MDCT : entity work.MDCT
339
        port map
340
  (
341
                clk          => CLK,
342
                rst          => RST,
343
    dcti         => mdct_data_in,
344
    idv          => mdct_idval,
345
    odv          => mdct_odval,
346
    dcto         => mdct_data_out,
347
    odv1         => odv1,
348
    dcto1        => dcto1
349
        );
350
 
351 28 mikel262
  mdct_idval   <= fram1_rd_d(8);
352 25 mikel262
 
353
  R_s <= signed('0' & fram1_q(7 downto 0));
354
  G_s <= signed('0' & fram1_q(15 downto 8));
355
  B_s <= signed('0' & fram1_q(23 downto 16));
356
 
357
  -------------------------------------------------------------------
358
  -- Mux1
359
  -------------------------------------------------------------------
360
  p_mux1 : process(CLK, RST)
361
  begin
362
    if RST = '1' then
363
      mdct_data_in <= (others => '0');
364
    elsif CLK'event and CLK = '1' then
365
      case cur_cmp_idx_d9 is
366
        when "00" =>
367
          mdct_data_in <= std_logic_vector(Y_8bit);
368
        when "01" =>
369
          mdct_data_in <= std_logic_vector(Cb_8bit);
370
        when "10" =>
371
          mdct_data_in <= std_logic_vector(Cr_8bit);
372
        when others =>
373
          null;
374
      end case;
375
    end if;
376
  end process;
377
 
378
 
379
  -------------------------------------------------------------------
380
  -- FIFO1
381
  -------------------------------------------------------------------
382
  U_FIFO1 : entity work.FIFO
383
  generic map
384
  (
385
        DATA_WIDTH        => 12,
386
        ADDR_WIDTH        => 8
387
  )
388
  port map
389
  (
390
        rst               => RST,
391
        clk               => CLK,
392
        rinc              => fifo1_rd,
393
        winc              => fifo1_wr,
394
        datai             => fifo_data_in,
395
 
396
        datao             => fifo1_q,
397
        fullo             => fifo1_full,
398
        emptyo            => fifo1_empty,
399
        count             => fifo1_count
400
  );
401
 
402
  fifo1_wr     <= mdct_odval;
403
  fifo_data_in <= mdct_data_out;
404
 
405
 
406
 
407
  -------------------------------------------------------------------
408 52 mikel262
  -- FIFO1 rd controller
409 25 mikel262
  -------------------------------------------------------------------
410
  p_fifo_rd_ctrl : process(CLK, RST)
411
  begin
412
    if RST = '1' then
413
      fifo1_rd     <= '0';
414
      fifo_rd_arm  <= '0';
415
      fifo1_rd_cnt <= (others => '0');
416
      fifo1_q_dval <= '0';
417
    elsif CLK'event and CLK = '1' then
418
      fifo1_rd     <= '0';
419
 
420
      fifo1_q_dval <= fifo1_rd;
421
 
422
      if start_pb = '1' then
423
        fifo_rd_arm  <= '1';
424
        fifo1_rd_cnt <= (others => '0');
425
      end if;
426
 
427
      if fifo_rd_arm = '1' then
428
 
429
        if fifo1_rd_cnt = 64-1 then
430
          fifo_rd_arm  <= '0';
431
          fifo1_rd     <= '1';
432
        elsif fifo1_empty = '0' then
433
          fifo1_rd     <= '1';
434
          fifo1_rd_cnt <= fifo1_rd_cnt + 1;
435
        end if;
436
 
437
      end if;
438
    end if;
439
  end process;
440
 
441
  -------------------------------------------------------------------
442
  -- write counter
443
  -------------------------------------------------------------------
444
  p_wr_cnt : process(CLK, RST)
445
  begin
446
    if RST = '1' then
447
      wr_cnt   <= (others => '0');
448
      ready_pb <= '0';
449
      xw_cnt   <= (others => '0');
450
      yw_cnt   <= (others => '0');
451
      writing_en <= '0';
452
    elsif CLK'event and CLK = '1' then
453
      ready_pb <= '0';
454
 
455
      if start_pb = '1' then
456
        wr_cnt <= (others => '0');
457
        xw_cnt <= (others => '0');
458
        yw_cnt <= (others => '0');
459
        writing_en  <= '1';
460
      end if;
461
 
462
      if writing_en = '1' then
463
        if fifo1_q_dval = '1' then
464
          if wr_cnt = 64-1 then
465
            wr_cnt <= (others => '0');
466
            ready_pb <= '1';
467
            writing_en <= '0';
468
          else
469
            wr_cnt <= wr_cnt + 1;
470
          end if;
471
 
472
          if yw_cnt = 8-1 then
473
            yw_cnt <= (others => '0');
474
            xw_cnt <= xw_cnt+1;
475
          else
476
            yw_cnt <= yw_cnt+1;
477
          end if;
478
        end if;
479
      end if;
480
    end if;
481
  end process;
482
 
483
  -------------------------------------------------------------------
484
  -- RGB to YCbCr conversion
485
  -------------------------------------------------------------------
486
  p_rgb2ycbcr : process(CLK, RST)
487
  begin
488
    if RST = '1' then
489
      Y_Reg_1  <= (others => '0');
490
      Y_Reg_2  <= (others => '0');
491
      Y_Reg_3  <= (others => '0');
492
      Cb_Reg_1 <= (others => '0');
493
      Cb_Reg_2 <= (others => '0');
494
      Cb_Reg_3 <= (others => '0');
495
      Cr_Reg_1 <= (others => '0');
496
      Cr_Reg_2 <= (others => '0');
497
      Cr_Reg_3 <= (others => '0');
498
      Y_Reg    <= (others => '0');
499
      Cb_Reg   <= (others => '0');
500
      Cr_Reg   <= (others => '0');
501
    elsif CLK'event and CLK = '1' then
502
      Y_Reg_1  <= R_s*C_Y_1;
503
      Y_Reg_2  <= G_s*C_Y_2;
504
      Y_Reg_3  <= B_s*C_Y_3;
505
 
506
      Cb_Reg_1 <= R_s*C_Cb_1;
507
      Cb_Reg_2 <= G_s*C_Cb_2;
508
      Cb_Reg_3 <= B_s*C_Cb_3;
509
 
510
      Cr_Reg_1 <= R_s*C_Cr_1;
511
      Cr_Reg_2 <= G_s*C_Cr_2;
512
      Cr_Reg_3 <= B_s*C_Cr_3;
513
 
514
      Y_Reg  <= Y_Reg_1 + Y_Reg_2 + Y_Reg_3;
515
      Cb_Reg <= Cb_Reg_1 + Cb_Reg_2 + Cb_Reg_3 + to_signed(128*16384,Cb_Reg'length);
516
      Cr_Reg <= Cr_Reg_1 + Cr_Reg_2 + Cr_Reg_3 + to_signed(128*16384,Cr_Reg'length);
517
 
518
    end if;
519
  end process;
520
 
521
  Y_8bit  <= unsigned(Y_Reg(21 downto 14));
522
  Cb_8bit <= unsigned(Cb_Reg(21 downto 14));
523
  Cr_8bit <= unsigned(Cr_Reg(21 downto 14));
524
 
525
 
526
  -------------------------------------------------------------------
527
  -- DBUF
528
  -------------------------------------------------------------------
529
  U_RAMZ : entity work.RAMZ
530
  generic map
531
  (
532
      RAMADDR_W     => 7,
533
      RAMDATA_W     => 12
534
  )
535
  port map
536
  (
537
        d           => dbuf_data,
538
        waddr       => dbuf_waddr,
539
        raddr       => dbuf_raddr,
540
        we          => dbuf_we,
541
        clk         => CLK,
542
 
543
        q           => dbuf_q
544
  );
545
 
546
  dbuf_data  <= fifo1_q;
547
  dbuf_we    <= fifo1_q_dval;
548
  dbuf_waddr <= (not zz_buf_sel) & std_logic_vector(yw_cnt & xw_cnt);
549
  dbuf_raddr <= zz_buf_sel & zz_rd_addr;
550
 
551
end architecture RTL;
552
-------------------------------------------------------------------------------
553
-- Architecture: end
554
-------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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