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

Subversion Repositories mkjpeg

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

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

powered by: WebSVN 2.1.0

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