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

Subversion Repositories mkjpeg

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

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

powered by: WebSVN 2.1.0

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