| 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;
|