1 ------------------------------------------------------------------------------- 2 -- File : Code10b12bPkg.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2016-10-05 5 -- Last update: 2016-10-26 6 ------------------------------------------------------------------------------- 7 -- Description: 10B12B Package File 8 ------------------------------------------------------------------------------- 9 -- This file is part of 'SLAC Firmware Standard Library'. 10 -- It is subject to the license terms in the LICENSE.txt file found in the 11 -- top-level directory of this distribution and at: 12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 13 -- No part of 'SLAC Firmware Standard Library', including this file, 14 -- may be copied, modified, propagated, or distributed except according to 15 -- the terms contained in the LICENSE.txt file. 16 ------------------------------------------------------------------------------- 19 use ieee.std_logic_1164.
all;
20 use ieee.std_logic_arith.
all;
21 use ieee.std_logic_unsigned.
all;
24 --use work.TextUtilPkg.all; 28 --! @ingroup base_general 30 -- Delcare input constants for commas and other important K_CODES 31 constant K_28_3_C : slv(9 downto 0) := "0001111100";
-- 0x07C -> 0x8FC, 0x703 32 constant K_28_11_C : slv(9 downto 0) := "0101111100";
-- 0x17C -> 0x2FC, 0xD03 33 constant K_28_19_C : slv(9 downto 0) := "1001111100";
-- 0x27C -> 0x4FC, 0xB03 35 constant K_28_10_C : slv(9 downto 0) := "0101011100";
-- 0x15C -> 0xABC, 0x543 36 constant K_28_21_C : slv(9 downto 0) := "1010111100";
-- 0x2BC -> 0x57C, 0xA83 38 ------------------------------------------------------------------------------------------------- 39 -- Disparity types and helper functions 40 ------------------------------------------------------------------------------------------------- 49 ------------------------------------------------------------------------------------------------- 50 -- 5B6B Code Constants 51 ------------------------------------------------------------------------------------------------- 68 ("000111", -1, 0), -- D.7 Special case 76 ("000101", 1, -1), -- ("111010", -1, 1), 77 ("001001", 1, -1), -- ("110110", -1, 1), 84 ("101000", 1, -1), -- ("010111", -1, 1), 88 ("100100", 1, -1), -- ("011011", -1, 1), 90 ("100010", 1, -1), -- ("011101", -1, 1), 91 ("100001", 1, -1), -- ("011110", -1, 1), 92 ("001010", 1, -1));
-- ("110101", -1, 1)); 102 ("000111", -1, 0), -- D.7 Special case 110 ("000101", 1, -1), -- ("111010", -1, 1), 111 ("001001", 1, -1), -- ("110110", -1, 1), 118 ("101000", 1, -1), -- ("010111", -1, 1), 122 ("100100", 1, -1), -- ("011011", -1, 1), 124 ("100010", 1, -1), -- ("011101", -1, 1), 125 ("100001", 1, -1), -- ("011110", -1, 1), 126 ("001010", 1, -1));
-- ("110101", -1, 1)); 129 dataIn :
in slv(
9 downto 0);
132 dataOut :
out slv(
11 downto 0);
136 dataIn :
in slv(
11 downto 0);
138 dataOut :
out slv(
9 downto 0);
142 dispError :
inout sl);
144 end package Code10b12bPkg;
149 variable s :
(1 to 8);
151 s := resize
(ite
(k = '
1',
"K.",
"D.") &
152 '
image(conv_integer
(code
(4 downto 0))) &
154 '
image(conv_integer
(code
(9 downto 5))),
8);
156 end function toString;
179 variable disparity : ;
183 for i
in vec'
range loop 184 if (vec
(i
) = '
0'
) then 189 ones := vec'
length-zeros;
190 disparity := ones-zeros;
194 end function getDisparity;
198 dataIn :
in slv(
9 downto 0);
201 dataOut :
out slv(
11 downto 0);
205 variable lowWordIn :
slv(4 downto 0);
206 variable lowWordOut :
slv(5 downto 0);
208 variable highWordIn :
slv(4 downto 0);
209 variable highWordOut :
slv(5 downto 0);
213 -- First, split in input word in two 214 highWordIn := dataIn
(9 downto 5);
215 lowWordIn := dataIn
(4 downto 0);
217 -- Select low output word 219 if (dataKIn = '
1'
) then 221 -- tmp := K_CODE_TABLE_C(28); 224 -- Decide whether to invert 226 if (conv
(dispIn
) /= tmp.
expDisp) then 227 lowWordOut :=
not tmp.
out6b;
228 lowDispOut := tmp.
outDisp *
(-
1);
230 lowWordOut := tmp.
out6b;
234 lowWordOut := tmp.
out6b;
235 lowDispOut := conv
(dispIn
);
238 -- If selected code has even disparity, 239 -- use dispIn to decide upper word disparity 240 if (lowDispOut =
0) then 241 lowDispOut := conv
(dispIn
);
246 -- Select high output word 248 if (dataKIn = '
1'
) then 252 -- Decide whether to invert 254 if (lowDispOut /= tmp.
expDisp) then 255 highWordOut :=
not tmp.
out6b;
256 highDispOut := tmp.
outDisp *
(-
1);
258 highWordOut := tmp.
out6b;
262 highWordOut := tmp.
out6b;
263 highDispOut := lowDispOut;
266 if (highDispOut =
0) then 267 highDispOut := lowDispOut;
270 -- Handle K.28.28 case 271 -- if (dataKIn = '1') then 272 -- if (highWordIn = "11100") then 273 -- highWordOut := not "111100"; 274 -- highDispOut := conv(dispIn); 278 dispOut := conv
(highDispOut
);
279 dataOut := highWordOut & lowWordOut;
284 dataIn :
in slv(
11 downto 0);
286 dataOut :
out slv(
9 downto 0);
290 dispError :
inout sl)
293 variable lowWordIn :
slv(5 downto 0);
294 variable lowWordOut :
slv(4 downto 0);
295 variable lowWordValid :
sl;
296 variable highWordIn :
slv(5 downto 0);
297 variable highWordOut :
slv(4 downto 0);
298 variable highWordValid :
sl;
299 variable inputDisp : ;
304 -- print("------------"); 305 -- Set default values 309 lowWordOut :=
(others => '
0'
);
310 highWordOut :=
(others => '
0'
);
312 -- Check the disparity of the input 313 inputDisp := getDisparity
(dataIn
);
314 if (inputDisp >
2 or inputDisp < -
2) then 315 -- print(">>>>Input Disp Error"); 316 -- print("dataIn: " & str(dataIn)); 317 -- print("inputDisp: " & str(inputDisp)); 321 -- Check the running disparity 322 runDisp := inputDisp +
(conv
(dispIn
)*
2);
323 if (runDisp >
2 or runDisp < -
2) then 324 -- print(">>>>Run Disp Error"); 325 -- print("dataIn: " & str(dataIn)); 326 -- print("inputDisp: " & str(inputDisp)); 327 -- print("runDisp: " & str(runDisp)); 331 -- print("dataIn: " & str(dataIn)); 332 -- print("inputDisp: " & str(inputDisp)); 333 -- print("runDisp: " & str(runDisp)); 336 -- This probably isn't correct 337 -- Need to figure out what to do when running disparity is out of range 338 if (runDisp >
0) then 340 elsif (runDisp <
0) then 343 dispOut := conv
(inputDisp/
2);
346 -- print("dispOut: " & str(dispOut)); 347 -- print("------------"); 349 lowWordIn := dataIn
(5 downto 0);
350 highWordIn := dataIn
(11 downto 6);
352 -- Check for a k-code 356 lowWordOut := conv_std_logic_vector
(28,
5);
367 -- Need to check for valid k5/6 code 368 if (dataKout = '
1'
) then 372 ((highWordIn =
not (tmp.
out6b)) and ((k28Disp =
(-
1)*
(tmp.
expDisp))))) then 374 highWordOut := conv_std_logic_vector
(i,
5);
376 highWordValid := '
1';
382 if (dataKOut = '
0'
) then 387 if ((lowWordIn = tmp.
out6b) or 388 ((lowWordIn =
not (tmp.
out6b)) and (tmp.
expDisp /=
0))) then 390 lowWordOut := conv_std_logic_vector
(i,
5);
399 if ((highWordIn = tmp.
out6b) or 400 ((highWordIn =
not (tmp.
out6b)) and (tmp.
expDisp /=
0))) then 402 highWordOut := conv_std_logic_vector
(i,
5);
403 highWordValid := '
1';
411 if (lowWordValid = '
1'
and highWordValid = '
1'
) then 415 dataOut
(4 downto 0) := lowWordOut;
416 dataOut
(9 downto 5) := highWordOut;
418 end procedure decode10b12b;
421 end package body Code10b12bPkg;
slv( 9 downto 0) := "1010111100" K_28_21_C
integer range - 1 to 1 DisparityType
slv( 9 downto 0) := "1001111100" K_28_19_C
Code5b6bArray( 0 to 31) :=(( "000110", 1,- 1),( "010001", 1,- 1),( "010010", 1,- 1),( "100011", 0, 0),( "010100", 1,- 1),( "100101", 0, 0),( "100110", 0, 0),( "000111",- 1, 0),( "011000", 1,- 1),( "101001", 0, 0),( "101010", 0, 0),( "001011", 0, 0),( "101100", 0, 0),( "001101", 0, 0),( "001110", 0, 0),( "000101", 1,- 1),( "001001", 1,- 1),( "110001", 0, 0),( "110010", 0, 0),( "010011", 0, 0),( "110100", 0, 0),( "010101", 0, 0),( "010110", 0, 0),( "101000", 1,- 1),( "001100", 1,- 1),( "011001", 0, 0),( "011010", 0, 0),( "100100", 1,- 1),( "011100", 0, 0),( "100010", 1,- 1),( "100001", 1,- 1),( "001010", 1,- 1)) D_CODE_TABLE_C
slv( 9 downto 0) := "0101111100" K_28_11_C
slv( 9 downto 0) := "0101011100" K_28_10_C
Code5b6bArray( 0 to 31) :=(( "000110", 1,- 1),( "010001", 1,- 1),( "010010", 1,- 1),( "100011", 1, 0),( "010100", 1,- 1),( "100101", 1, 0),( "100110", 1, 0),( "000111",- 1, 0),( "011000", 1,- 1),( "101001", 1, 0),( "101010", 1, 0),( "001011", 1, 0),( "101100", 1, 0),( "001101", 1, 0),( "001110", 1, 0),( "000101", 1,- 1),( "001001", 1,- 1),( "110001", 1, 0),( "110010", 1, 0),( "010011", 1, 0),( "110100", 1, 0),( "010101", 1, 0),( "010110", 1, 0),( "101000", 1,- 1),( "001100", 1,- 1),( "011001", 1, 0),( "011010", 1, 0),( "100100", 1,- 1),( "000011", 1,- 1),( "100010", 1,- 1),( "100001", 1,- 1),( "001010", 1,- 1)) K_CODE_TABLE_C
slv( 9 downto 0) := "0001111100" K_28_3_C
array(natural range <> ) of Code5b6bType Code5b6bArray
encode10b12bdataIn,dataKIn,dispIn,dataOut,dispOut,
decode10b12bdataIn,dispIn,dataOut,dataKOut,dispOut,codeError,dispError,