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

Subversion Repositories mdct

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

powered by: WebSVN 2.1.0

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