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

Subversion Repositories mkjpeg

[/] [mkjpeg/] [trunk/] [tb/] [vhdl/] [MDCTTB_PKG.vhd] - Blame information for rev 25

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

Line No. Rev Author Line
1 25 mikel262
--------------------------------------------------------------------------------
2
--                                                                            --
3
--                          V H D L    F I L E                                --
4
--                          COPYRIGHT (C) 2006                                --
5
--                                                                            --
6
--------------------------------------------------------------------------------
7
--
8
-- Title       : MDCTTB_PKG
9
-- Design      : MDCT Core
10
-- Author      : Michal Krepa
11
--
12
--------------------------------------------------------------------------------
13
--
14
-- File        : MDCTTB_PKG.VHD
15
-- Created     : Sat Mar 5 2006
16
--
17
--------------------------------------------------------------------------------
18
--
19
--  Description : Package for testbench simulation
20
--
21
--------------------------------------------------------------------------------
22
 
23
library IEEE;
24
  use IEEE.STD_LOGIC_1164.all;
25
  use IEEE.STD_LOGIC_ARITH.all;
26
--  use IEEE.NUMERIC_STD.all;
27
  use IEEE.MATH_REAL.all;
28
 
29
library STD;
30
  use STD.TEXTIO.all;
31
 
32
library WORK;
33
  use WORK.MDCT_PKG.all;
34
 
35
package MDCTTB_PKG is
36
 
37
    ----------------------------------------------
38
    -- constant section 1
39
    ----------------------------------------------
40
    constant MAX_IMAGE_SIZE_X : INTEGER := 1280;
41
    constant MAX_IMAGE_SIZE_Y : INTEGER := 1280;
42
    ----------------------------------------------
43
    -- type section
44
    ----------------------------------------------
45
    type MATRIX_TYPE   is array (0 to N-1,0 TO N-1) of REAL;
46
    type I_MATRIX_TYPE is array (0 to N-1,0 TO N-1) of INTEGER;
47
    type COEM_TYPE     is array (0 to N/2-1, 0 to N/2-1)
48
          of SIGNED(ROMDATA_W-1 downto 0);
49
    type VECTOR4       is array (0 to N/2-1) of REAL;
50
    type N_LINES_TYPE  is array (0 to N-1)
51
          of STD_LOGIC_VECTOR(0 to MAX_IMAGE_SIZE_X*IP_W-1);
52
    type IMAGE_TYPE    is array (0 to MAX_IMAGE_SIZE_Y-1,
53
 
54
 
55
    ----------------------------------------------
56
    -- function section
57
    ----------------------------------------------
58
    procedure CMP_MATRIX(ref_matrix   : in I_MATRIX_TYPE;
59
                       dcto_matrix    : in I_MATRIX_TYPE;
60
                       max_error      : in INTEGER;
61
                       error_matrix   : out I_MATRIX_TYPE;
62
                       error_cnt      : inout INTEGER);
63
    function STR(int: INTEGER; base: INTEGER) return STRING;
64
    function COMPUTE_REF_DCT1D(input_matrix : I_MATRIX_TYPE; shift : BOOLEAN
65
                        ) return I_MATRIX_TYPE;
66
    function COMPUTE_REF_IDCT(X : I_MATRIX_TYPE) return I_MATRIX_TYPE;
67
    function COMPUTE_PSNR(ref_input : I_MATRIX_TYPE;
68
                        reconstr_input : I_MATRIX_TYPE) return REAL;
69
    function COMPUTE_PSNR(ref_input : IMAGE_TYPE;
70
                       reconstr_input : IMAGE_TYPE;
71
                       ysize : INTEGER;
72
                       xsize : INTEGER
73
                       ) return REAL;
74
    ----------------------------------------------
75
    -- constant section 2
76
    ----------------------------------------------  
77
    -- set below to true to enable quantization in testbench
78
    constant CLK_FREQ_C        : INTEGER := 50;
79
    constant HOLD_TIME         : TIME := 1 ns;
80
    constant ENABLE_QUANTIZATION_C : BOOLEAN := FALSE;
81
    constant HEX_BASE          : INTEGER := 16;
82
    constant DEC_BASE          : INTEGER := 10;
83
    constant RUN_FULL_IMAGE    : BOOLEAN := FALSE;
84
    constant FILEIN_NAME_C     : STRING := "SOURCE\TESTBENCH\lena512.txt";
85
    constant FILEERROR_NAME_C  : STRING := "SOURCE\TESTBENCH\imagee.txt";
86
    constant FILEIMAGEO_NAME_C : STRING := "SOURCE\TESTBENCH\imageo.txt";
87
    constant MAX_ERROR_1D      : INTEGER := 1;
88
    constant MAX_ERROR_2D      : INTEGER := 4;
89
    constant MAX_PIX_VAL       : INTEGER := 2**IP_W-1;
90
    constant null_data_r       : MATRIX_TYPE :=
91
                          (
92
                          (000.0,000.0,000.0,000.0,000.0,000.0,000.0,000.0),
93
                          (000.0,000.0,000.0,000.0,000.0,000.0,000.0,000.0),
94
                          (000.0,000.0,000.0,000.0,000.0,000.0,000.0,000.0),
95
                          (000.0,000.0,000.0,000.0,000.0,000.0,000.0,000.0),
96
                          (000.0,000.0,000.0,000.0,000.0,000.0,000.0,000.0),
97
                          (000.0,000.0,000.0,000.0,000.0,000.0,000.0,000.0),
98
                          (000.0,000.0,000.0,000.0,000.0,000.0,000.0,000.0),
99
                          (000.0,000.0,000.0,000.0,000.0,000.0,000.0,000.0)
100
                          );
101
 
102
    constant input_data0   : I_MATRIX_TYPE :=
103
                          (
104
                          (139,144,149,153,155,155,155,155),
105
                          (144,151,153,156,159,156,156,156),
106
                          (150,155,160,163,158,156,156,156),
107
                          (159,161,162,160,160,159,159,159),
108
                          (159,160,161,162,162,155,155,155),
109
                          (161,161,161,161,160,157,157,157),
110
                          (162,162,161,163,162,157,157,157),
111
                          (162,162,161,161,163,158,158,158)
112
                          );
113
 
114
    constant input_data1   : I_MATRIX_TYPE :=
115
                          (
116
                          (255,255,255,000,000,255,254,255),
117
                          (255,255,255,000,000,255,254,000),
118
                          (255,255,255,000,000,255,254,255),
119
                          (255,255,255,000,000,255,254,000),
120
                          (254,000,255,255,000,255,254,255),
121
                          (254,000,255,255,000,255,254,000),
122
                          (254,000,255,255,000,255,254,255),
123
                          (254,000,255,255,000,255,254,000)
124
                          );
125
 
126
    constant input_data2   : I_MATRIX_TYPE :=
127
                          (
128
                          (000,000,000,000,000,000,000,000),
129
                          (000,000,000,000,000,000,000,000),
130
                          (000,000,000,000,000,000,000,000),
131
                          (000,000,000,000,000,000,000,000),
132
                          (000,000,000,000,000,000,000,000),
133
                          (000,000,000,000,000,000,000,000),
134
                          (000,000,000,000,000,000,000,000),
135
                          (000,000,000,000,000,000,000,000)
136
                          );
137
    constant input_data3   : I_MATRIX_TYPE :=
138
                          (
139
                          (55,89,0,2,35,34,100,255),
140
                          (144,151,153,151,159,156,156,156),
141
                          (150,155,165,163,158,126,156,156),
142
                          (254,000,255,255,000,245,254,255),
143
                          (159,199,161,162,162,133,155,165),
144
                          (231,000,255,235,000,255,254,253),
145
                          (162,162,161,163,162,157,157,157),
146
                          (11,12,167,165,166,167,101,108)
147
                          );
148
 
149
   constant input_data4   : I_MATRIX_TYPE :=
150
                          (
151
                          (135,14,145,15,155,15,155,15),
152
                          (140,15,151,15,152,15,153,15),
153
                          (154,15,165,16,156,15,157,15),
154
                          (158,16,168,16,169,15,150,15),
155
                          (15,161,16,162,16,153,15,154),
156
                          (165,16,166,16,167,15,158,15),
157
                          (16,169,16,160,16,152,15,153),
158
                          (164,16,165,16,165,15,156,15)
159
                          );
160
 
161
    -- from JPEG standard (but not in standard itself!)                      
162
    constant Q_JPEG_STD : I_MATRIX_TYPE :=
163
                          (
164
                          (16,11,10,16,24,40,51,61),
165
                          (12,12,14,19,26,58,60,55),
166
                          (14,13,16,24,40,57,69,56),
167
                          (14,17,22,29,51,87,80,62),
168
                          (18,22,37,56,68,109,103,77),
169
                          (24,35,55,64,81,104,113,92),
170
                          (49,64,78,87,103,121,120,101),
171
                          (72,92,95,98,112,100,103,99)
172
                          );
173
 
174
    -- CANON EOS10D super fine quality                      
175
    constant Q_CANON10D : I_MATRIX_TYPE :=
176
                          (
177
                          (1,  1,  1,  1,  1,  1,  2,  2),
178
                          (1,  1,       1,      1,      1,      2,      4,      4),
179
                          (1,  1,       1,      1,      1,      3,      3,      5),
180
                          (1,  1,       1,      2,      3,      3,      5,      5),
181
                          (1,  1,       3,      3,      4,      4,      5,      5),
182
                          (1,  3,       3,      3,      4,      5,      6,      6),
183
                          (2,  3,       3,      5,      3,      6,      5,      5),
184
                          (3,  3,       4,      3,      6,      4,      5,      5)
185
                          );
186
 
187
    -- quantization matrix used in testbench                      
188
    constant Q_MATRIX_USED : I_MATRIX_TYPE := Q_CANON10D;
189
 
190
    constant Ce : COEM_TYPE :=
191
                            (
192
                            (CONV_SIGNED(AP,ROMDATA_W),CONV_SIGNED(AP,ROMDATA_W),CONV_SIGNED(AP,ROMDATA_W),CONV_SIGNED(AP,ROMDATA_W)),
193
                            (CONV_SIGNED(BP,ROMDATA_W),CONV_SIGNED(CP,ROMDATA_W),CONV_SIGNED(CM,ROMDATA_W),CONV_SIGNED(BM,ROMDATA_W)),
194
                            (CONV_SIGNED(AP,ROMDATA_W),CONV_SIGNED(AM,ROMDATA_W),CONV_SIGNED(AM,ROMDATA_W),CONV_SIGNED(AP,ROMDATA_W)),
195
                            (CONV_SIGNED(CP,ROMDATA_W),CONV_SIGNED(BM,ROMDATA_W),CONV_SIGNED(BP,ROMDATA_W),CONV_SIGNED(CM,ROMDATA_W))
196
                            );
197
 
198
    constant Co : COEM_TYPE :=
199
                            (
200
                            (CONV_SIGNED(DP,ROMDATA_W),CONV_SIGNED(EP,ROMDATA_W),CONV_SIGNED(FP,ROMDATA_W),CONV_SIGNED(GP,ROMDATA_W)),
201
                            (CONV_SIGNED(EP,ROMDATA_W),CONV_SIGNED(GM,ROMDATA_W),CONV_SIGNED(DM,ROMDATA_W),CONV_SIGNED(FM,ROMDATA_W)),
202
                            (CONV_SIGNED(FP,ROMDATA_W),CONV_SIGNED(DM,ROMDATA_W),CONV_SIGNED(GP,ROMDATA_W),CONV_SIGNED(EP,ROMDATA_W)),
203
                            (CONV_SIGNED(GP,ROMDATA_W),CONV_SIGNED(FM,ROMDATA_W),CONV_SIGNED(EP,ROMDATA_W),CONV_SIGNED(DM,ROMDATA_W))
204
                            );
205
end MDCTTB_PKG;
206
 
207
--------------------------------------------------
208
-- PACKAGE BODY
209
--------------------------------------------------                        
210
package body MDCTTB_PKG is
211
  --------------------------------------------------------------------------
212
  -- converts an INTEGER into a CHARACTER
213
  -- for 0 to 9 the obvious mapping is used, higher
214
  -- values are mapped to the CHARACTERs A-Z
215
  -- (this is usefull for systems with base > 10)
216
  -- (adapted from Steve Vogwell's posting in comp.lang.vhdl) 
217
  --------------------------------------------------------------------------
218
  function CHR(int: INTEGER) return CHARACTER is
219
   variable c: CHARACTER;
220
  begin
221
    case int is
222
      when  0 => c := '0';
223
      when  1 => c := '1';
224
      when  2 => c := '2';
225
      when  3 => c := '3';
226
      when  4 => c := '4';
227
      when  5 => c := '5';
228
      when  6 => c := '6';
229
      when  7 => c := '7';
230
      when  8 => c := '8';
231
      when  9 => c := '9';
232
      when 10 => c := 'A';
233
      when 11 => c := 'B';
234
      when 12 => c := 'C';
235
      when 13 => c := 'D';
236
      when 14 => c := 'E';
237
      when 15 => c := 'F';
238
      when 16 => c := 'G';
239
      when 17 => c := 'H';
240
      when 18 => c := 'I';
241
      when 19 => c := 'J';
242
      when 20 => c := 'K';
243
      when 21 => c := 'L';
244
      when 22 => c := 'M';
245
      when 23 => c := 'N';
246
      when 24 => c := 'O';
247
      when 25 => c := 'P';
248
      when 26 => c := 'Q';
249
      when 27 => c := 'R';
250
      when 28 => c := 'S';
251
      when 29 => c := 'T';
252
      when 30 => c := 'U';
253
      when 31 => c := 'V';
254
      when 32 => c := 'W';
255
      when 33 => c := 'X';
256
      when 34 => c := 'Y';
257
      when 35 => c := 'Z';
258
      when others => c := '?';
259
    end case;
260
    return c;
261
  end CHR;
262
 
263
 
264
 
265
  --------------------------------------------------------------------------
266
  -- convert INTEGER to STRING using specified base 
267
  --------------------------------------------------------------------------
268
  function STR(int: INTEGER; base: INTEGER) return STRING is
269
   variable temp:      STRING(1 to 10);
270
   variable num:       INTEGER;
271
   variable abs_int:   INTEGER;
272
   variable len:       INTEGER := 1;
273
   variable power:     INTEGER := 1;
274
  begin
275
   -- bug fix for negative numbers
276
   abs_int := abs(int);
277
   num     := abs_int;
278
   while num >= base loop
279
     len := len + 1;
280
     num := num / base;
281
   end loop ;
282
   for i in len downto 1 loop
283
     temp(i) := chr(abs_int/power mod base);
284
     power := power * base;
285
   end loop ;
286
   -- return result and add sign if required
287
   if int < 0 then
288
      return '-'& temp(1 to len);
289
    else
290
      return temp(1 to len);
291
   end if;
292
  end STR;
293
 
294
  ------------------------------------------------
295
  -- computes DCT1D
296
  ------------------------------------------------
297
  function COMPUTE_REF_DCT1D(input_matrix : I_MATRIX_TYPE; shift : BOOLEAN)
298
  return I_MATRIX_TYPE is
299
   variable fXm : VECTOR4 := (0.0,0.0,0.0,0.0);
300
   variable fXs : VECTOR4 := (0.0,0.0,0.0,0.0);
301
   variable fYe : VECTOR4 := (0.0,0.0,0.0,0.0);
302
   variable fYo : VECTOR4 := (0.0,0.0,0.0,0.0);
303
   variable ref_dct_matrix : I_MATRIX_TYPE;
304
   variable norma_input : MATRIX_TYPE;
305
  begin
306
     -- compute reference coefficients
307
     for x in 0 to N-1 loop
308
 
309
       for s in 0 to 7 loop
310
         if shift = TRUE then
311
           norma_input(x,s) := (REAL(input_matrix(x,s))- REAL(LEVEL_SHIFT))/2.0;
312
         else
313
           norma_input(x,s) := REAL(input_matrix(x,s))/2.0;
314
         end if;
315
       end loop;
316
       fXs(0) := norma_input(x,0)+norma_input(x,7);
317
       fXs(1) := norma_input(x,1)+norma_input(x,6);
318
       fXs(2) := norma_input(x,2)+norma_input(x,5);
319
       fXs(3) := norma_input(x,3)+norma_input(x,4);
320
 
321
       fXm(0) := norma_input(x,0)-norma_input(x,7);
322
       fXm(1) := norma_input(x,1)-norma_input(x,6);
323
       fXm(2) := norma_input(x,2)-norma_input(x,5);
324
       fXm(3) := norma_input(x,3)-norma_input(x,4);
325
 
326
       for k in 0 to N/2-1 loop
327
         fYe(k) := REAL(CONV_INTEGER(Ce(k,0)))*fXs(0) +
328
                   REAL(CONV_INTEGER(Ce(k,1)))*fXs(1) +
329
                   REAL(CONV_INTEGER(Ce(k,2)))*fXs(2) +
330
                   REAL(CONV_INTEGER(Ce(k,3)))*fXs(3);
331
         fYo(k) := REAL(CONV_INTEGER(Co(k,0)))*fXm(0) +
332
                   REAL(CONV_INTEGER(Co(k,1)))*fXm(1) +
333
                   REAL(CONV_INTEGER(Co(k,2)))*fXm(2) +
334
                   REAL(CONV_INTEGER(Co(k,3)))*fXm(3);
335
       end loop;
336
 
337
       -- transpose matrix by writing in row order
338
       ref_dct_matrix(0,x) := INTEGER(fYe(0)/REAL((2**(COE_W-1))));
339
       ref_dct_matrix(1,x) := INTEGER(fYo(0)/REAL((2**(COE_W-1))));
340
       ref_dct_matrix(2,x) := INTEGER(fYe(1)/REAL((2**(COE_W-1))));
341
       ref_dct_matrix(3,x) := INTEGER(fYo(1)/REAL((2**(COE_W-1))));
342
       ref_dct_matrix(4,x) := INTEGER(fYe(2)/REAL((2**(COE_W-1))));
343
       ref_dct_matrix(5,x) := INTEGER(fYo(2)/REAL((2**(COE_W-1))));
344
       ref_dct_matrix(6,x) := INTEGER(fYe(3)/REAL((2**(COE_W-1))));
345
       ref_dct_matrix(7,x) := INTEGER(fYo(3)/REAL((2**(COE_W-1))));
346
 
347
     end loop;
348
 
349
     return ref_dct_matrix;
350
   end COMPUTE_REF_DCT1D;
351
 
352
   -----------------------------------------------
353
   -- compares NxN matrices, logs failure if difference
354
   -- greater than maximum error specified
355
   -----------------------------------------------
356
   procedure CMP_MATRIX(ref_matrix    : in I_MATRIX_TYPE;
357
                       dcto_matrix    : in I_MATRIX_TYPE;
358
                       max_error      : in INTEGER;
359
                       error_matrix   : out I_MATRIX_TYPE;
360
                       error_cnt      : inout INTEGER
361
                       ) is
362
     variable error_matrix_v : I_MATRIX_TYPE;
363
   begin
364
     for a in 0 to N - 1 loop
365
       for b in 0 to N - 1 loop
366
         error_matrix_v(a,b) := ref_matrix(a,b) - dcto_matrix(a,b);
367
         if abs(error_matrix_v(a,b)) > max_error then
368
           error_cnt := error_cnt + 1;
369
           assert false
370
             report "E01: DCT max error violated!"
371
             severity Error;
372
         end if;
373
       end loop;
374
     end loop;
375
     error_matrix := error_matrix_v;
376
  end CMP_MATRIX;
377
 
378
  ------------------------------------------------
379
  -- computes IDCT on NxN matrix
380
  ------------------------------------------------
381
  function COMPUTE_REF_IDCT(X : I_MATRIX_TYPE)
382
  return I_MATRIX_TYPE is
383
    variable i  : INTEGER := 0;
384
    variable j  : INTEGER := 0;
385
    variable u  : INTEGER := 0;
386
    variable v  : INTEGER := 0;
387
    variable Cu : REAL;
388
    variable Cv : REAL;
389
    variable xi : MATRIX_TYPE := null_data_r;
390
    variable xr : I_MATRIX_TYPE;
391
  begin
392
    -- idct
393
    for i in 0 to N-1 loop
394
      for j in 0 to N-1 loop
395
        for u in 0 to N-1 loop
396
          if u = 0 then
397
            Cu := 1.0/sqrt(2.0);
398
          else
399
            Cu := 1.0;
400
          end if;
401
          for v in 0 to N-1 loop
402
            if v = 0 then
403
              Cv := 1.0/sqrt(2.0);
404
            else
405
              Cv := 1.0;
406
            end if;
407
            xi(i,j) := xi(i,j) +
408
                     2.0/REAL(N)*Cu*Cv*REAL(X(u,v))*
409
                     cos( ( (2.0*REAL(i)+1.0)*REAL(u)*MATH_PI ) / (2.0*REAL(N)) )*
410
                     cos( ( (2.0*REAL(j)+1.0)*REAL(v)*MATH_PI ) / (2.0*REAL(N)) );
411
            xr(i,j) := INTEGER(ROUND(xi(i,j)))+LEVEL_SHIFT;
412
          end loop;
413
        end loop;
414
      end loop;
415
    end loop;
416
    return xr;
417
  end COMPUTE_REF_IDCT;
418
 
419
  ------------------------------------------------
420
  -- computes peak signal to noise ratio
421
  -- for reconstruced and input image data
422
  ------------------------------------------------
423
  function COMPUTE_PSNR(ref_input : I_MATRIX_TYPE;
424
                       reconstr_input : I_MATRIX_TYPE) return REAL is
425
    variable psnr_tmp : REAL := 0.0;
426
  begin
427
    for i in 0 to N-1 loop
428
      for j in 0 to N-1 loop
429
        psnr_tmp := psnr_tmp + (REAL(ref_input(i,j))-REAL(reconstr_input(i,j)))**2;
430
      end loop;
431
    end loop;
432
    psnr_tmp := psnr_tmp / (REAL(N)*REAL(N));
433
    psnr_tmp := 10.0*LOG10( (REAL(MAX_PIX_VAL)**2) / psnr_tmp );
434
    return psnr_tmp;
435
 
436
  end COMPUTE_PSNR;
437
 
438
  ------------------------------------------------
439
  -- computes peak signal to noise ratio
440
  -- for reconstruced and input image data
441
  ------------------------------------------------
442
  function COMPUTE_PSNR(ref_input : IMAGE_TYPE;
443
                       reconstr_input : IMAGE_TYPE;
444
                       ysize : INTEGER;
445
                       xsize : INTEGER
446
                       ) return REAL is
447
    variable psnr_tmp : REAL := 0.0;
448
    variable lineb    : LINE;
449
  begin
450
    for i in 0 to ysize-1 loop
451
      for j in 0 to xsize-1 loop
452
        psnr_tmp := psnr_tmp +
453
                    (REAL(ref_input(i,j))-REAL(reconstr_input(i,j)))**2;
454
      end loop;
455
    end loop;
456
    psnr_tmp := psnr_tmp / (REAL(ysize)*REAL(xsize));
457
    --WRITE(lineb,STRING'("MSE Mean Squared Error is "));
458
    --WRITE(lineb,psnr_tmp); 
459
    --assert false
460
    --  report lineb.all
461
    --  severity Note;
462
    psnr_tmp := 10.0*LOG10( (REAL(MAX_PIX_VAL)**2) / psnr_tmp );
463
    return psnr_tmp;
464
 
465
  end COMPUTE_PSNR;
466
 
467
 
468
end MDCTTB_PKG;

powered by: WebSVN 2.1.0

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