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

Subversion Repositories dirac

[/] [dirac/] [trunk/] [src/] [testbench/] [ArithmeticCoderTestbench.vhd] - Blame information for rev 14

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

Line No. Rev Author Line
1 5 petebleack
-- ***** BEGIN LICENSE BLOCK *****
2
-- 
3 9 petebleack
-- $Id: ArithmeticCoderTestbench.vhd,v 1.5 2006-09-06 18:41:06 petebleackley Exp $ $Name: not supported by cvs2svn $
4
-- *
5
-- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
-- *
7
-- * The contents of this file are subject to the Mozilla Public License
8
-- * Version 1.1 (the "License"); you may not use this file except in compliance
9
-- * with the License. You may obtain a copy of the License at
10
-- * http://www.mozilla.org/MPL/
11
-- *
12
-- * Software distributed under the License is distributed on an "AS IS" basis,
13
-- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
14
-- * the specific language governing rights and limitations under the License.
15
-- *
16
-- * The Original Code is BBC Research and Development code.
17
-- *
18
-- * The Initial Developer of the Original Code is the British Broadcasting
19
-- * Corporation.
20
-- * Portions created by the Initial Developer are Copyright (C) 2004.
21
-- * All Rights Reserved.
22
-- *
23
-- * Contributor(s): Peter Bleackley (Original author)
24
-- *
25
-- * Alternatively, the contents of this file may be used under the terms of
26
-- * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
27
-- * Public License Version 2.1 (the "LGPL"), in which case the provisions of
28
-- * the GPL or the LGPL are applicable instead of those above. If you wish to
29
-- * allow use of your version of this file only under the terms of the either
30
-- * the GPL or LGPL and not to allow others to use your version of this file
31
-- * under the MPL, indicate your decision by deleting the provisions above
32
-- * and replace them with the notice and other provisions required by the GPL
33
-- * or LGPL. If you do not delete the provisions above, a recipient may use
34
-- * your version of this file under the terms of any one of the MPL, the GPL
35
-- * or the LGPL.
36 5 petebleack
-- * ***** END LICENSE BLOCK ***** */
37 2 petebleack
 
38
LIBRARY ieee;
39
USE ieee.std_logic_1164.ALL;
40
USE ieee.numeric_std.ALL;
41
use IEEE.std_logic_textio.all;
42
use ieee.std_logic_arith.all;
43
use ieee.std_logic_unsigned.all;
44
use STD.textio.all;
45
 
46
ENTITY arithmeticcoder_ArithmeticCoderTestbench_vhd_tb IS
47
END arithmeticcoder_ArithmeticCoderTestbench_vhd_tb;
48
 
49
ARCHITECTURE behavior OF arithmeticcoder_ArithmeticCoderTestbench_vhd_tb IS
50
 
51
        COMPONENT arithmeticcoder
52
        PORT(
53
                ENABLE : IN std_logic;
54
                DATA_IN : IN std_logic;
55 5 petebleack
                CONTEXT_ENABLE : in std_logic;
56
                CONTEXT_IN : in std_logic_vector (5 downto 0);
57 8 petebleack
                HALVECOUNTS_IN : in std_logic;
58
                FLUSH : in std_logic;
59 2 petebleack
                RESET : IN std_logic;
60
                CLOCK : IN std_logic;
61
                SENDING : OUT std_logic;
62 8 petebleack
                DATA_OUT : OUT std_logic;
63
                FLUSH_COMPLETE : out std_logic
64 2 petebleack
                );
65
        END COMPONENT;
66 8 petebleack
        component EXP_GOLOMB_COUNTER
67
        port( DATA_IN : in std_logic_vector (31 downto 0);
68
                TEST : in std_logic;
69
                RESET : in std_logic;
70
                CLOCK : in std_logic;
71
                COUNTING : out std_logic;
72
                DATA_OUT : out std_logic);
73
        end component EXP_GOLOMB_COUNTER;
74
 
75 2 petebleack
        SIGNAL ENABLE :  std_logic;
76
        SIGNAL DATA_IN :  std_logic := '0';
77 8 petebleack
        SIGNAL RESET :  std_logic := '1';
78 2 petebleack
        SIGNAL CLOCK :  std_logic := '0';
79 8 petebleack
        signal FLUSH : std_logic := '0';
80
        signal HALVECOUNTS : std_logic := '0';
81 2 petebleack
        SIGNAL SENDING :  std_logic;
82
        SIGNAL DATA_OUT :  std_logic;
83
        signal TRANSMIT :       std_logic;
84
        signal DATA_TRANSFER :  std_logic;
85 8 petebleack
        signal FLUSH_COMPLETE : std_logic;
86 5 petebleack
        signal DATA_IN2 :       std_logic_vector (0 downto 0);
87
        signal BUFFERED2 : std_logic_vector (0 downto 0);
88
        signal FIFO_EMPTY : std_logic;
89
        signal BUFFERED : std_logic;
90 8 petebleack
        constant PERIOD : time := 16 ns;
91 5 petebleack
        signal CONTEXT_ENABLE : std_logic;
92
        signal DECODER_CONTEXT_ENABLE : std_logic;
93 8 petebleack
        signal NUMBITS : std_logic_vector (31 downto 0) := "00000000000000000000000000000000";
94
        signal NEXTNUMBITS : std_logic_vector (31 downto 0);
95
        signal NUMBYTES : std_logic_vector (28 downto 0);
96
        signal CONTEXT_IN : std_logic_vector (5 downto 0) := "000000";
97 5 petebleack
        signal DECODER_CONTEXT : std_logic_vector (5 downto 0) := "000000";
98 8 petebleack
        signal BYTECOUNT : std_logic_vector (31 downto 0);
99
        signal EXP_GOLOMB_READY : std_logic;
100
        signal EXP_GOLOMB_DATA : std_logic;
101
        signal BYTE_INSERT : std_logic := '0';
102
        signal COMPVAL : character;
103
        signal SUPPRESS_READ : std_logic := '0';
104
        type ENCODER_STATUS is (INIT, INIT2, HEADERS, CODING, FLUSHING, EXP_GOLOMB, WRITE_DATA, FINISHED);
105
        signal STATE : ENCODER_STATUS := INIT;
106
        type RAM is array (65535 downto 0) of integer;
107
        signal STORAGE : RAM;
108
        type CHARFILE is file of character;
109
        file raw_data : CHARFILE open read_mode is "test1.dr0";
110
        file contexts : CHARFILE open read_mode is "test1.ctx";
111
        file coded_stream : CHARFILE open write_mode is "test1.drc";
112
        file comparison_data : CHARFILE open read_mode is "test1.dr1";
113
        type INTARRAY is array (7 downto 0) of integer;
114
        function CONTEXT_INTERPRET(CONTEXT : integer) return std_logic_vector is
115
        variable VALUE : std_logic_vector(5 downto 0);
116
        begin
117
                if CONTEXT >= 128 then
118
                        VALUE(5) := '1';
119
                else
120
                        VALUE(5) := '0';
121
                end if;
122
                if (CONTEXT mod 128) >= 64 then
123
                        VALUE(4) := '1';
124
                else
125
                        VALUE(4) := '0';
126
                end if;
127
                if (CONTEXT mod 64) >= 32 then
128
                        VALUE(3) := '1';
129
                else
130
                        VALUE(3) := '0';
131
                end if;
132
                if (CONTEXT mod 32) >= 16 then
133
                        VALUE(2) := '1';
134
                else
135
                        VALUE(2) := '0';
136
                end if;
137
                if (CONTEXT mod 16) >= 8 then
138
                        VALUE(1) := '1';
139
                else
140
                        VALUE(1) := '0';
141
                end if;
142
                if (CONTEXT mod 8) >= 4 then
143
                        VALUE(0) := '1';
144
                else
145
                        VALUE(0) := '0';
146
                end if;
147
                return VALUE;
148
        end function CONTEXT_INTERPRET;
149 2 petebleack
BEGIN
150
 
151
        uut: arithmeticcoder
152
        PORT MAP(
153
                ENABLE => ENABLE,
154
                DATA_IN => DATA_IN,
155 5 petebleack
                CONTEXT_ENABLE => CONTEXT_ENABLE,
156 8 petebleack
                CONTEXT_IN => CONTEXT_IN,
157
                HALVECOUNTS_IN => HALVECOUNTS,
158
                FLUSH => FLUSH,
159 2 petebleack
                RESET => RESET,
160
                CLOCK => CLOCK,
161
                SENDING => TRANSMIT,
162 8 petebleack
                DATA_OUT => DATA_TRANSFER,
163
                FLUSH_COMPLETE => FLUSH_COMPLETE
164 2 petebleack
        );
165 8 petebleack
 
166
        EGC: EXP_GOLOMB_COUNTER
167
        port map(
168
                DATA_IN => BYTECOUNT,
169
                TEST => FLUSH_COMPLETE,
170
                RESET => RESET,
171
                CLOCK => CLOCK,
172
                COUNTING => EXP_GOLOMB_READY,
173
                DATA_OUT => EXP_GOLOMB_DATA);
174
 
175
 
176 2 petebleack
 
177
        CLOCK <= not CLOCK after PERIOD/2;
178
 
179
 --*** Test Bench - User Defined Section ***
180 8 petebleack
   tb : PROCESS (CLOCK)
181
        variable POSITION : integer;
182
        variable EGPOSITION : integer;
183
        variable PLACE : integer;
184
        variable READVAL : character;
185
        variable WRITEVAL : integer;
186
        variable CONTEXT : integer;
187
        variable DATA : integer;
188
        variable COMPDATA : integer;
189
        variable THRESHOLD : integer;
190
        variable INDEX : integer range 0 to 536870911;
191
        variable READ_DATA : INTARRAY := (0,0,0,0,0,0,0,0);
192
        variable DUMMY : character;
193
 
194 2 petebleack
   BEGIN
195 8 petebleack
                if CLOCK'event and CLOCK = '1' then
196
                        if STATE = INIT then
197
                                if READ_DATA = ( 16#4B#, 16#57#, 16#2D#, 16#44#, 16#49#, 16#52#, 16#41#, 16#43#) then
198
                                        STATE <= INIT2;
199
                                        RESET <= '0';
200
                                else
201
                                        READ_DATA(7 downto 1) := READ_DATA(6 downto 0);
202
                                        read(raw_data,READVAL);
203
                                        READ_DATA(0) := character'pos(READVAL);
204
                                end if;
205
                        elsif STATE = INIT2 then
206
                                if READ_DATA (7 downto 3) = ( 16#44#, 16#49#, 16#52#, 16#41#, 16#43#) then
207
                                        STATE <= HEADERS;
208
                                        WRITEVAL := 0;
209
                                        EGPOSITION := 128;
210
                                else
211
                                        WRITEVAL := READ_DATA(7);
212
                                        write(coded_stream,character'val(WRITEVAL));
213
                                        READ_DATA(7 downto 1) := READ_DATA (6 downto 0);
214
                                end if;
215
                        elsif STATE = HEADERS then
216
                                if READ_DATA (7 downto 3) = ( 16#42#, 16#42#, 16#43#, 16#44#, 16#AC# ) then
217
                                        STATE <= CODING;
218
                                        PLACE := 0;
219
                                        POSITION := 0;
220
                                        RESET <= '1';
221
                                        ENABLE <= '0';
222
                                        DATA_IN <= '0';
223
                                        CONTEXT_ENABLE <= '0';
224
                                        CONTEXT_IN <= "000000";
225
                                        HALVECOUNTS <= '0';
226
                                        FLUSH <= '0';
227
                                        if SUPPRESS_READ = '0' then
228
                                                read(comparison_data,DUMMY);
229
                                                COMPVAL <= DUMMY;
230 5 petebleack
                                        end if;
231 8 petebleack
                                elsif READ_DATA (7 downto 3) = (16#42#, 16#42#, 16#43#, 16#44#, 16#D0# ) then
232
                                        STATE <= FINISHED;
233
                                else
234
                                        if EGPOSITION = 128 then
235
                                                read(raw_data,READVAL);
236
                                                READ_DATA(2) := character'pos(READVAL);
237
                                        end if;
238
                                        if READ_DATA(7) > 127 then
239
                                                WRITEVAL := WRITEVAL + EGPOSITION;
240
                                        end if;
241
 
242
                                        for I in 7 downto 2 loop
243
                                                if READ_DATA(I) > 127 then
244
                                                        READ_DATA(I) := (READ_DATA(I) -128) * 2;
245
                                                else
246
                                                        READ_DATA(I) := READ_DATA(I) * 2;
247
                                                end if;
248
                                                if READ_DATA(I-1) > 127 then
249
                                                        READ_DATA(I) := READ_DATA(I) + 1;
250
                                                end if;
251
                                        end loop;
252
                                        if EGPOSITION = 1 then
253
                                                write(coded_stream,character'val(WRITEVAL));
254
                                                EGPOSITION := 128;
255
                                                WRITEVAL := 0;
256
                                        else
257
                                                EGPOSITION := EGPOSITION / 2;
258
                                        end if;
259 2 petebleack
                                end if;
260 8 petebleack
                        elsif STATE = CODING then
261
                                if PLACE = 0 then
262
                                        RESET <= '0';
263
                                end if;
264
                                if PLACE mod 5 = 0 then
265
                                        read(contexts,READVAL);
266
                                        CONTEXT := character'pos(READVAL);
267
                                        CONTEXT_ENABLE <= '1';
268
                                        if CONTEXT mod 2 = 1 then
269
                                                CONTEXT_IN <= "000000";
270
                                                HALVECOUNTS <= '0';
271
                                                STATE <= FLUSHING;
272
                                                FLUSH <= '1';
273
                                        else
274
                                                CONTEXT_IN <= CONTEXT_INTERPRET(CONTEXT);
275
                                                if (CONTEXT mod 4) > 1 then
276
                                                        HALVECOUNTS <= '1';
277
                                                else
278
                                                        HALVECOUNTS <= '0';
279
                                                end if;
280
                                                FLUSH <= '0';
281
                                        end if;
282
                                elsif PLACE mod 5 = 3 then
283
                                        if POSITION = 0 then
284
                                                POSITION := 128;
285
                                                READ(raw_data,READVAL);
286
                                                DATA := character'pos(READVAL);
287
                                        end if;
288
                                        if (DATA / POSITION) mod 2 = 1 then
289
                                                DATA_IN <= '1';
290
                                        else
291
                                                DATA_IN <= '0';
292
                                        end if;
293
                                        ENABLE <= '1';
294
                                        POSITION := POSITION / 2;
295 5 petebleack
                                else
296 8 petebleack
                                        CONTEXT_ENABLE <= '0';
297
                                        ENABLE <= '0';
298
                                end if;
299
                                PLACE := PLACE + 1;
300
                        elsif STATE = FLUSHING then
301
                                if FLUSH = '1' then
302
                                        FLUSH <= '0';
303
                                        CONTEXT_ENABLE <= '0';
304
                                end if;
305
                                if FLUSH_COMPLETE = '1' then
306
                                        STATE <= EXP_GOLOMB;
307
                                        PLACE := 7;
308
                                        POSITION := 128;
309
                                        READ_DATA(7) := 0;
310
                                end if;
311
                        elsif STATE = EXP_GOLOMB then
312
                                if EXP_GOLOMB_READY = '0' then
313
                                        STATE <= WRITE_DATA;
314
                                        INDEX := 0;
315 9 petebleack
                                        if EGPOSITION /= 128 then
316
                                                write(coded_stream,character'val(WRITEVAL));
317
                                        end if;
318 8 petebleack
                                        PLACE := 7;
319
                                else
320
                                        if EXP_GOLOMB_DATA = '1' then
321
                                                WRITEVAL := WRITEVAL + EGPOSITION;
322
                                        end if;
323
                                        if EGPOSITION = 1 then
324
                                                EGPOSITION := 128;
325
                                                write(coded_stream,character'val(WRITEVAL));
326
                                                WRITEVAL := 0;
327 5 petebleack
                                        else
328 8 petebleack
                                                EGPOSITION := EGPOSITION / 2;
329 5 petebleack
                                        end if;
330
                                end if;
331 8 petebleack
 
332
                        elsif STATE  = WRITE_DATA then
333
                                if INDEX = (conv_integer(NUMBYTES)-1) then
334
                                        STATE <= HEADERS;
335
                                        WRITEVAL := 0;
336
                                else
337
                                        if PLACE < 3 then
338
                                                WRITEVAL := READ_DATA(7);
339
                                                write(coded_stream,character'val(WRITEVAL));
340
                                                READ_DATA (7 downto 3) := READ_DATA (6 downto 2);
341
                                                READ_DATA (2) := STORAGE(INDEX);
342
                                        else
343
                                                READ_DATA (PLACE) := STORAGE(INDEX);
344
                                                PLACE := PLACE - 1;
345
                                        end if;
346
                                        INDEX := INDEX + 1;
347
                                end if;
348
                        else --STATE = FINISHED
349
                                if READ_DATA (7 downto 3) = (0, 0, 0, 0, 0) then
350
                                        report ("finished") severity failure;
351
                                else
352
                                        WRITEVAL := READ_DATA(7);
353
                                        write(coded_stream,character'val(WRITEVAL));
354
                                        READ_DATA (7 downto 3) := READ_DATA (6 downto 3) & 0;
355
                                end if;
356 2 petebleack
                        end if;
357 8 petebleack
                end if;
358
 
359
 
360
 
361 2 petebleack
   END PROCESS;
362
 
363 8 petebleack
 
364
COUNT_BITS: process (CLOCK)
365 2 petebleack
        begin
366 8 petebleack
        if (CLOCK'event and CLOCK='1') then
367
                if RESET = '1' then
368
                        NUMBITS <= "00000000000000000000000000000000";
369 2 petebleack
                else
370 8 petebleack
                        if TRANSMIT = '1' then
371
                                NUMBITS <= NUMBITS + "00000000000000000000000000000001";
372 2 petebleack
                        end if;
373 8 petebleack
                        if BYTE_INSERT = '1' then
374
                                NUMBITS <= NUMBITS + "00000000000000000000000000001000";
375
                        end if;
376 4 petebleack
                end if;
377 8 petebleack
        end if;
378 2 petebleack
        end process;
379
 
380 8 petebleack
NEXTNUMBITS <= NUMBITS + "00000000000000000000000000000111";
381
 
382
NUMBYTES <= NEXTNUMBITS (31 downto 3);
383 5 petebleack
 
384 8 petebleack
        BYTECOUNT <=  "0000000000000000" & NUMBYTES(15 downto 0);
385 2 petebleack
 
386 5 petebleack
 
387 8 petebleack
WRITE_MEMORY: process(CLOCK)
388
        variable INCREMENT: integer;
389
        variable DATA : integer;
390
        variable COMPARISON : character;
391
        variable COMPDATA : integer;
392
        variable COMPDATA2 : integer;
393
begin
394 5 petebleack
        if CLOCK'event and CLOCK = '1' then
395
                if RESET = '1' then
396 8 petebleack
                        INCREMENT := 128;
397
                        BYTE_INSERT <= '0';
398
                        if SUPPRESS_READ = '0' then
399
                                COMPDATA := character'pos(COMPVAL);
400
                        end if;
401
                        COMPDATA2 := 0;
402
                        DATA := 0;
403
                elsif TRANSMIT = '1' then
404
                        if (COMPDATA rem (INCREMENT*2)) >= INCREMENT then
405
                                COMPDATA2 := COMPDATA2 + INCREMENT;
406
                        end if;
407
                        if DATA_TRANSFER = '1' then
408
                                DATA := DATA + INCREMENT;
409
                        end if;
410
                        assert COMPDATA2 = DATA report "ENCODER HAS DIVERGED" severity failure;
411
                        if INCREMENT = 1 then
412
                                STORAGE(conv_integer(NUMBYTES)-1) <= DATA;
413
                                DATA := 0;
414
                                INCREMENT := 128;
415
                                read(comparison_data,COMPARISON);
416
                                COMPDATA := character'pos(COMPARISON);
417
                                COMPDATA2 := 0;
418
                                if NUMBYTES >= "00000000000000000000000000100" then
419
                                        if STORAGE((conv_integer(NUMBYTES) -4) downto (conv_integer(NUMBYTES) - 1)) = (16#42#, 16#42#, 16#43#, 16#44#) then
420
                                                STORAGE(conv_integer(NUMBYTES)) <= 16#FF#;
421
                                                BYTE_INSERT <= '1';
422
                                        end if;
423
                                end if;
424 5 petebleack
                        else
425 8 petebleack
                                INCREMENT := INCREMENT/2;
426 5 petebleack
                        end if;
427 8 petebleack
                elsif FLUSH_COMPLETE = '1' then
428
                        if INCREMENT /= 128 then
429
                                STORAGE(conv_integer(NUMBYTES)) <= DATA;
430
                                if NUMBYTES >= "00000000000000000000000000100" then
431
                                        if STORAGE((conv_integer(NUMBYTES) -3) downto (conv_integer(NUMBYTES))) = (16#42#, 16#42#, 16#43#, 16#44#) then
432
                                                STORAGE(conv_integer(NUMBYTES)+1) <= 16#FF#;
433
                                                BYTE_INSERT <= '1';
434
                                        end if;
435
                                end if;
436
                                SUPPRESS_READ <= '0';
437
                        else
438
                                SUPPRESS_READ <= '1';
439
                        end if;
440 5 petebleack
                end if;
441 8 petebleack
                if BYTE_INSERT = '1' then
442
                        BYTE_INSERT <= '0';
443
                end if;
444 5 petebleack
        end if;
445 8 petebleack
end process WRITE_MEMORY;
446 5 petebleack
 
447 2 petebleack
END;

powered by: WebSVN 2.1.0

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