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

Subversion Repositories dirac

[/] [dirac/] [trunk/] [src/] [encoder/] [ARITHMETICCODER.vhd] - Blame information for rev 8

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

Line No. Rev Author Line
1 2 petebleack
-- ***** BEGIN LICENSE BLOCK *****
2
-- 
3 8 petebleack
-- 
4
--  Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
-- 
6
--  The contents of this file are subject to the Mozilla Public License
7
--  Version 1.1 (the "License"); you may not use this file except in compliance
8
--  with the License. You may obtain a copy of the License at
9
--  http://www.mozilla.org/MPL/
10
-- 
11
--  Software distributed under the License is distributed on an "AS IS" basis,
12
--  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
13
--  the specific language governing rights and limitations under the License.
14
-- 
15
--  The Original Code is BBC Research and Development code.
16
-- 
17
--  The Initial Developer of the Original Code is the British Broadcasting
18
--  Corporation.
19
--  Portions created by the Initial Developer are Copyright (C) 2006.
20
--  All Rights Reserved.
21
-- 
22
--  Contributor(s): Peter Bleackley (Original author)
23
-- 
24
--  Alternatively, the contents of this file may be used under the terms of
25
--  the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
26
--  Public License Version 2.1 (the "LGPL"), in which case the provisions of
27
--  the GPL or the LGPL are applicable instead of those above. If you wish to
28
--  allow use of your version of this file only under the terms of the either
29
--  the GPL or LGPL and not to allow others to use your version of this file
30
--  under the MPL, indicate your decision by deleting the provisions above
31
--  and replace them with the notice and other provisions required by the GPL
32
--  or LGPL. If you do not delete the provisions above, a recipient may use
33
--  your version of this file under the terms of any one of the MPL, the GPL
34
--  or the LGPL.
35 2 petebleack
-- * ***** END LICENSE BLOCK ***** */
36
 
37
library IEEE;
38
use IEEE.STD_LOGIC_1164.ALL;
39
use IEEE.STD_LOGIC_ARITH.ALL;
40
use IEEE.STD_LOGIC_UNSIGNED.ALL;
41
 
42
--  Uncomment the following lines to use the declarations that are
43
--  provided for instantiating Xilinx primitive components.
44
--library UNISIM;
45
--use UNISIM.VComponents.all;
46
 
47
entity ARITHMETICCODER is
48
    Port ( ENABLE : in std_logic;
49
           DATA_IN : in std_logic;
50 5 petebleack
                          CONTEXT_ENABLE : in std_logic;
51
                          CONTEXT_IN : in std_logic_vector (5 downto 0);
52 8 petebleack
                          HALVECOUNTS_IN : in std_logic;
53
                          FLUSH : in std_logic;
54 2 petebleack
                          RESET : in std_logic;
55
           CLOCK : in std_logic;
56
           SENDING : out std_logic;
57 8 petebleack
           DATA_OUT : out std_logic;
58
                          FLUSH_COMPLETE : out std_logic);
59 2 petebleack
end ARITHMETICCODER;
60
 
61
architecture RTL of ARITHMETICCODER is
62 5 petebleack
 
63 2 petebleack
        component LIMIT_REGISTER
64
        generic(CONST: std_logic);
65
        port(     LOAD : in std_logic_vector(15 downto 0);
66
           SET_VALUE : in std_logic;
67
           SHIFT_ALL : in std_logic;
68
           SHIFT_MOST : in std_logic;
69
                          RESET : in std_logic;
70
           CLOCK : in std_logic;
71
           OUTPUT : out std_logic_vector(15 downto 0));
72
        end component LIMIT_REGISTER;
73
        component FOLLOW_COUNTER
74
        port    ( INCREMENT : in std_logic;
75
           TEST : in std_logic;
76
                          RESET : in std_logic;
77
           CLOCK : in std_logic;
78
           OUTPUT : out std_logic);
79
        end component FOLLOW_COUNTER;
80
        component CONVERGENCE_CHECK
81
        port    ( HIGH_MSB : in std_logic;
82
           LOW_MSB : in std_logic;
83
           HIGH_SECONDBIT : in std_logic;
84
           LOW_SECONDBIT : in std_logic;
85
           CHECK : in std_logic;
86
           TRIGGER_OUTPUT : out std_logic;
87
           TRIGGER_FOLLOW : out std_logic);
88
        end component CONVERGENCE_CHECK;
89
        component ARITHMETIC_UNIT
90
        port    ( DIFFERENCE : in std_logic_vector(15 downto 0);
91
           PROB : in std_logic_vector(9 downto 0);
92
                          LOW : in std_logic_vector(15 downto 0);
93
           ENABLE : in std_logic;
94
                          RESET :       in std_logic;
95
           CLOCK : in std_logic;
96
           DIFFERENCE_OUT0 : out std_logic_vector(15 downto 0);
97
                          DIFFERENCE_OUT1 : out std_logic_vector(15 downto 0);
98
           RESULT_OUT0 : out std_logic_vector(15 downto 0);
99
                          RESULT_OUT1 : out std_logic_vector(15 downto 0);
100
           DATA_LOAD : out std_logic);
101
        end component ARITHMETIC_UNIT;
102
        component OUTPUT_UNIT
103
        port ( ENABLE : in std_logic;
104
           DATA : in std_logic;
105
           FOLLOW : in std_logic;
106
                          RESET : in std_logic;
107
           CLOCK : in std_logic;
108
           SENDING : out std_logic;
109
                          DATA_OUT : out std_logic;
110
           FOLLOW_COUNTER_TEST : out std_logic;
111
           SHIFT : out std_logic);
112
        end component OUTPUT_UNIT;
113 5 petebleack
        component INPUT_CONTROL
114
        generic( WIDTH : integer range 1 to 16);
115
        port( ENABLE : in std_logic;
116
           DATA_IN : in std_logic_vector(WIDTH - 1 downto 0);
117
           BUFFER_CONTROL : in std_logic;
118
           DEMAND : in std_logic;
119
           RESET : in std_logic;
120
           CLOCK : in std_logic;
121
           SENDING : out std_logic;
122
           DATA_OUT : out std_logic_vector(WIDTH - 1 downto 0));
123
        end component INPUT_CONTROL;
124
        component CONTEXT_MANAGER
125
        port (  CONTEXT_NUMBER : in std_logic_vector(5 downto 0);
126 8 petebleack
                                SET : in std_logic;
127
                                UPDATE : in std_logic;
128
                                DATA_IN : in std_logic;
129
                                HALVECOUNTS : in std_logic;
130 5 petebleack
           RESET : in std_logic;
131
           CLOCK : in std_logic;
132 8 petebleack
           PROB : out std_logic_vector(9 downto 0);
133
                          READY : out std_logic);
134 5 petebleack
        end component CONTEXT_MANAGER;
135 2 petebleack
        signal HIGH_SET : std_logic;
136
        signal LOW_SET  : std_logic;
137 8 petebleack
        signal TRIGGER_SHIFT : std_logic;
138 2 petebleack
        signal SHIFT_ALL :      std_logic;
139
        signal DIFFERENCE_SHIFT_ALL :   std_logic;
140
        signal SHIFT_MOST :     std_logic;
141
        signal ZERO_INPUT :     std_logic;
142
        signal ARITHMETIC_UNIT_ENABLE : std_logic;
143
        signal ARITHMETIC_UNIT_DATA_LOAD :      std_logic;
144
        signal CONVERGENCE_TEST :       std_logic;
145
        signal TRIGGER_OUTPUT : std_logic;
146
        signal FOLLOW_COUNTER_TEST :    std_logic;
147
        signal FOLLOW:  std_logic;
148
        signal DATA_LOAD: std_logic;
149
        signal OUTPUT_ACTIVE :  std_logic;
150
        signal CHECK :  std_logic;
151
        signal DELAYED_CHECK : std_logic;
152
        signal DATA_AVAILABLE : std_logic;
153
        signal BUFFERED_DATA : std_logic;
154
        signal BUFFER_INPUT :   std_logic;
155 5 petebleack
        signal NEWCONTEXT : std_logic;
156 2 petebleack
        signal ARITHMETIC_UNIT_DIFFERENCE_OUT0 : std_logic_vector (15 downto 0);
157
        signal ARITHMETIC_UNIT_DIFFERENCE_OUT1 :        std_logic_vector(15 downto 0);
158
        signal DIFFERENCE_IN : std_logic_vector (15 downto 0);
159
        signal ARITHMETIC_UNIT_RESULT_OUT0 :    std_logic_vector (15 downto 0);
160
        signal ARITHMETIC_UNIT_RESULT_OUT1 : std_logic_vector (15 downto 0);
161
        signal DIFFERENCE_OUT : std_logic_vector (15 downto 0);
162
        signal HIGH_OUT : std_logic_vector (15 downto 0);
163
        signal LOW_OUT : std_logic_vector (15 downto 0);
164 5 petebleack
        signal PROB : std_logic_vector (9 downto 0);
165
        signal CONTEXT_SELECT : std_logic_vector (5 downto 0);
166
        signal PROB_AVAILABLE : std_logic;
167
        signal BUFFERCONTEXT :  std_logic;
168
        signal DATA_IN2 : std_logic_vector(0 downto 0);
169
        signal BUFFERED_DATA2 : std_logic_vector(0 downto 0);
170 8 petebleack
        signal CONTEXT_BUFFER_DATA_IN : std_logic_vector(7 downto 0);
171
        signal CONTEXT_BUFFER_DATA_OUT : std_logic_vector(7 downto 0);
172
--      signal LAST_FIVE_TRIGGERS : std_logic_vector(4 downto 0);
173
        signal HALVECOUNTS : std_logic;
174
        signal BUFFERED_FLUSH : std_logic;
175
        signal FLUSH_ENCODER : std_logic;
176
        signal SWITCHED_DATA : std_logic;
177
        signal CONVERGED : std_logic;
178
        signal INCREMENT_FOLLOW : std_logic;
179
        signal ALLOWHALVING : std_logic;
180
        signal RELEASE_CONTEXT : std_logic;
181
--      signal FETCH_FLUSH : std_logic;
182
        signal DEMAND_CONTEXT : std_logic;
183
        signal LOCK : std_logic;
184
        signal DEMAND_DATA : std_logic;
185
        signal HOLDCONTEXT : std_logic;
186 2 petebleack
begin
187
-- input buffering
188
INBUFFER:       INPUT_CONTROL
189 5 petebleack
        generic map(WIDTH => 1)
190 2 petebleack
        port map(ENABLE => ENABLE,
191 5 petebleack
        DATA_IN => DATA_IN2,
192 2 petebleack
        BUFFER_CONTROL => BUFFER_INPUT,
193 8 petebleack
        DEMAND => DEMAND_DATA,
194 2 petebleack
        RESET => RESET,
195
        CLOCK => CLOCK,
196
        SENDING => DATA_AVAILABLE,
197 5 petebleack
        DATA_OUT => BUFFERED_DATA2);
198 2 petebleack
 
199 5 petebleack
        DATA_IN2(0) <= DATA_IN;
200
        BUFFERED_DATA <= BUFFERED_DATA2(0);
201 8 petebleack
        DEMAND_DATA <= ARITHMETIC_UNIT_DATA_LOAD and not LOCK;
202 5 petebleack
 
203
CONTEXT_BUFFER: INPUT_CONTROL
204 8 petebleack
        generic map(WIDTH => 8)
205 5 petebleack
        port map(ENABLE => CONTEXT_ENABLE,
206 8 petebleack
        DATA_IN => CONTEXT_BUFFER_DATA_IN,
207 5 petebleack
        BUFFER_CONTROL =>        BUFFERCONTEXT,
208 8 petebleack
        DEMAND => DEMAND_CONTEXT,
209 5 petebleack
        RESET => RESET,
210
        CLOCK => CLOCK,
211
        SENDING => NEWCONTEXT,
212 8 petebleack
        DATA_OUT => CONTEXT_BUFFER_DATA_OUT);
213
 
214
        CONTEXT_BUFFER_DATA_IN <= (CONTEXT_IN & HALVECOUNTS_IN & FLUSH);
215
 
216
        CONTEXT_SELECT <= CONTEXT_BUFFER_DATA_OUT(7 downto 2);
217
        HALVECOUNTS <= CONTEXT_BUFFER_DATA_OUT(1) and ALLOWHALVING;
218
        BUFFERED_FLUSH <= CONTEXT_BUFFER_DATA_OUT(0) and CONVERGENCE_TEST and (CONVERGED nor SHIFT_MOST) and not LOCK;
219
 
220
 
221
 
222
 
223 2 petebleack
-- Specify the registers
224
HIGH: LIMIT_REGISTER
225
        generic map(CONST => '1')
226
        port map(  LOAD => ARITHMETIC_UNIT_RESULT_OUT0,
227
           SET_VALUE => HIGH_SET,
228
           SHIFT_ALL => SHIFT_ALL,
229
           SHIFT_MOST => SHIFT_MOST,
230
                          RESET => RESET,
231
           CLOCK => CLOCK,
232
           OUTPUT => HIGH_OUT);
233
 
234
DIFFERENCE: LIMIT_REGISTER
235
        generic map(CONST => '1')
236
        port map(  LOAD => DIFFERENCE_IN,
237
           SET_VALUE => DATA_LOAD,
238
           SHIFT_ALL => DIFFERENCE_SHIFT_ALL,
239
           SHIFT_MOST => '0',
240
                          RESET => RESET,
241
           CLOCK => CLOCK,
242
           OUTPUT => DIFFERENCE_OUT);
243
 
244
LOW: LIMIT_REGISTER
245
        generic map(CONST => '0')
246
        port map(  LOAD => ARITHMETIC_UNIT_RESULT_OUT1,
247
           SET_VALUE => LOW_SET,
248
           SHIFT_ALL => SHIFT_ALL,
249
           SHIFT_MOST => SHIFT_MOST,
250
                          RESET => RESET,
251
           CLOCK => CLOCK,
252
           OUTPUT => LOW_OUT);
253
 
254
-- The arithmetic
255
 
256
ARITH: ARITHMETIC_UNIT
257
        port map(DIFFERENCE => DIFFERENCE_OUT,
258
           PROB => PROB,
259
                          LOW => LOW_OUT,
260
           ENABLE => ARITHMETIC_UNIT_ENABLE,
261
                          RESET => RESET,
262
           CLOCK => CLOCK,
263
           DIFFERENCE_OUT0 => ARITHMETIC_UNIT_DIFFERENCE_OUT0,
264
                          DIFFERENCE_OUT1 => ARITHMETIC_UNIT_DIFFERENCE_OUT1,
265
           RESULT_OUT0 => ARITHMETIC_UNIT_RESULT_OUT0,
266
                          RESULT_OUT1 => ARITHMETIC_UNIT_RESULT_OUT1,
267
           DATA_LOAD => ARITHMETIC_UNIT_DATA_LOAD);
268
 
269
--The convergence checks
270
 
271
CONVERGE: CONVERGENCE_CHECK
272
        port map(HIGH_MSB => HIGH_OUT(15),
273
           LOW_MSB => LOW_OUT(15),
274
           HIGH_SECONDBIT => HIGH_OUT(14),
275
           LOW_SECONDBIT => LOW_OUT(14),
276
           CHECK => CONVERGENCE_TEST,
277 8 petebleack
           TRIGGER_OUTPUT => CONVERGED,
278 2 petebleack
           TRIGGER_FOLLOW => SHIFT_MOST);
279
 
280 8 petebleack
                                TRIGGER_OUTPUT <= CONVERGED or FLUSH_ENCODER;
281 2 petebleack
--The Follow Counter
282
 
283
FC:     FOLLOW_COUNTER
284 8 petebleack
        port map( INCREMENT => INCREMENT_FOLLOW,
285 2 petebleack
           TEST => FOLLOW_COUNTER_TEST,
286
                          RESET => RESET,
287
           CLOCK => CLOCK,
288
           OUTPUT => FOLLOW);
289 8 petebleack
                INCREMENT_FOLLOW <= SHIFT_MOST or BUFFERED_FLUSH;
290 2 petebleack
--The output unit
291
 
292
OUTPUT: OUTPUT_UNIT
293
        port map(ENABLE => TRIGGER_OUTPUT,
294 8 petebleack
           DATA => SWITCHED_DATA,
295 2 petebleack
           FOLLOW => FOLLOW,
296
                          RESET => RESET,
297
           CLOCK => CLOCK,
298
           SENDING => OUTPUT_ACTIVE,
299
                          DATA_OUT => DATA_OUT,
300
           FOLLOW_COUNTER_TEST => FOLLOW_COUNTER_TEST,
301 8 petebleack
           SHIFT => TRIGGER_SHIFT);
302 2 petebleack
 
303
        SENDING <= OUTPUT_ACTIVE;
304
 
305 8 petebleack
        SHIFT_ALL <= TRIGGER_SHIFT and not FLUSH_ENCODER;
306
 
307 2 petebleack
-- Input logic
308
 
309
        DATA_LOAD <= DATA_AVAILABLE and ARITHMETIC_UNIT_DATA_LOAD;
310
        HIGH_SET <= ZERO_INPUT and DATA_LOAD;
311
        ZERO_INPUT <= not BUFFERED_DATA;
312
        LOW_SET <= BUFFERED_DATA and DATA_LOAD;
313
 
314 8 petebleack
FLUSH_SWITCH : process (FLUSH_ENCODER,LOW_OUT,HIGH_OUT)
315
begin
316
        if FLUSH_ENCODER = '1' then
317
                SWITCHED_DATA <= LOW_OUT(14);
318
        else
319
                SWITCHED_DATA <= HIGH_OUT(15);
320
        end if;
321
end process FLUSH_SWITCH;
322
 
323 2 petebleack
-- Control logic for DIFFERENCE register
324
 
325
        DIFFERENCE_SHIFT_ALL <= SHIFT_ALL or SHIFT_MOST;
326
 
327
-- Control logic for convergence check
328
 
329
        CHECK <= DIFFERENCE_SHIFT_ALL or DATA_LOAD;
330
 
331 5 petebleack
CONVERGENCE_TEST_DELAY: process (CLOCK)
332
        begin
333
        if CLOCK'event and CLOCK = '1' then
334
                DELAYED_CHECK <= CHECK;
335
        end if;
336
        end process CONVERGENCE_TEST_DELAY;
337 2 petebleack
 
338
        CONVERGENCE_TEST <= DELAYED_CHECK or FOLLOW_COUNTER_TEST;
339
 
340
-- Control logic for arithmetic unit
341
 
342 5 petebleack
        ARITHMETIC_UNIT_ENABLE <= PROB_AVAILABLE and not(OUTPUT_ACTIVE or DIFFERENCE_SHIFT_ALL or DATA_LOAD);
343 2 petebleack
 
344
-- Control Logic for input control
345
 
346
        BUFFER_INPUT <= OUTPUT_ACTIVE or not ARITHMETIC_UNIT_DATA_LOAD;
347
 
348
-- Select the new difference value
349
 
350
NEWDIFF : process(BUFFERED_DATA,ARITHMETIC_UNIT_DIFFERENCE_OUT0,ARITHMETIC_UNIT_DIFFERENCE_OUT1)
351
        begin
352
                if(BUFFERED_DATA = '1') then
353
                        DIFFERENCE_IN <= ARITHMETIC_UNIT_DIFFERENCE_OUT1;
354
                else
355
                        DIFFERENCE_IN <= ARITHMETIC_UNIT_DIFFERENCE_OUT0;
356
                end if;
357
        end process NEWDIFF;
358
 
359 5 petebleack
-- Select the context
360
 
361
PROBABILITY : CONTEXT_MANAGER
362
                        port map(CONTEXT_NUMBER => CONTEXT_SELECT,
363 8 petebleack
                        SET => NEWCONTEXT,
364
                        UPDATE => DATA_LOAD,
365
                        DATA_IN => BUFFERED_DATA,
366
                        HALVECOUNTS => HALVECOUNTS,
367 5 petebleack
                        RESET => RESET,
368
                        CLOCK => CLOCK,
369 8 petebleack
                        PROB => PROB,
370
                        READY => PROB_AVAILABLE);
371 5 petebleack
 
372 8 petebleack
 
373
 
374
FLUSH_CONTROL : process (CLOCK)
375
begin
376
        if CLOCK'event and CLOCK = '1' then
377
                if RESET = '1' then
378
                        FLUSH_ENCODER <= '0';
379
                elsif BUFFERED_FLUSH = '1'  then
380
                        FLUSH_ENCODER <= '1';
381
                elsif TRIGGER_SHIFT = '1' then
382
                        FLUSH_ENCODER <= '0';
383
                end if;
384 5 petebleack
        end if;
385 8 petebleack
end process     FLUSH_CONTROL;
386
 
387
FLUSH_COMPLETE <= FLUSH_ENCODER and TRIGGER_SHIFT;
388
 
389
LIMITHALVING : process (CLOCK)
390
begin
391
        if CLOCK'event and CLOCK='1' then
392
                if RESET='1' then
393
                        ALLOWHALVING <= '1';
394
                else
395
                        ALLOWHALVING <= not CONTEXT_BUFFER_DATA_OUT(1);
396
                end if;
397 5 petebleack
        end if;
398 8 petebleack
end process LIMITHALVING;
399 5 petebleack
 
400 8 petebleack
RELEASE_CONTEXT <= RESET or DEMAND_CONTEXT;
401 5 petebleack
 
402 8 petebleack
CONTEXTS_SHOULD_BE_BUFFERED : process (RELEASE_CONTEXT,CLOCK)
403
begin
404
        if CLOCK'event and CLOCK = '1' then
405
                if NEWCONTEXT = '1' then
406
                        HOLDCONTEXT <= '1';
407
                elsif RELEASE_CONTEXT = '1' then
408
                        HOLDCONTEXT <= '0';
409
                end if;
410
        end if;
411
end process CONTEXTS_SHOULD_BE_BUFFERED;
412
 
413
BUFFERCONTEXT <= HOLDCONTEXT and not RELEASE_CONTEXT;
414
 
415
--STORE_TRIGGERS : process (CLOCK)
416
--begin
417
--      if CLOCK'event and CLOCK='1' then
418
--              if RESET='1' then
419
--                      LAST_FIVE_TRIGGERS <= "11111";
420
--              else
421
--                      LAST_FIVE_TRIGGERS <= LAST_FIVE_TRIGGERS(3 downto 0) & (DATA_AVAILABLE or OUTPUT_ACTIVE or DIFFERENCE_SHIFT_ALL);
422
--              end if;
423
--      end if;
424
--end process STORE_TRIGGERS;
425
 
426
--GET_FLUSH_SIGNAL : process (LAST_FIVE_TRIGGERS)
427
--begin
428
--      if LAST_FIVE_TRIGGERS = "00000" then
429
--              FETCH_FLUSH <= '1';
430
--      else
431
--              FETCH_FLUSH <= '0';
432
--      end if;
433
--end process GET_FLUSH_SIGNAL;
434
 
435
LOCK_ENCODER : process (CLOCK)
436
begin
437
        if CLOCK'event and CLOCK='1' then
438
                if RESET = '1' then
439
                        LOCK <= '0';
440
                elsif BUFFERED_FLUSH='1' then
441
                        LOCK <= '1';
442
                end if;
443
        end if;
444
end process LOCK_ENCODER;
445
 
446
DEMAND_CONTEXT <= DATA_LOAD; -- or FETCH_FLUSH;--DATA_LOAD or FETCH_FLUSH or AFTER_RESET;
447
 
448
--DELAY_RESET: process (CLOCK)
449
--begin
450
--      if CLOCK'event and CLOCK='1' then
451
--              AFTER_RESET <= RESET;
452
--      end if;
453
--end process DELAY_RESET;
454 5 petebleack
--
455
 
456 2 petebleack
end RTL;

powered by: WebSVN 2.1.0

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