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

Subversion Repositories mdct

[/] [mdct/] [trunk/] [source/] [testbench/] [MDCTTB_PKG.vhd] - Blame information for rev 27

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

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

powered by: WebSVN 2.1.0

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