SURF  1.0
Code10b12bPkg.vhd
Go to the documentation of this file.
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 -------------------------------------------------------------------------------
17 
18 library ieee;
19 use ieee.std_logic_1164.all;
20 use ieee.std_logic_arith.all;
21 use ieee.std_logic_unsigned.all;
22 
23 use work.StdRtlPkg.all;
24 --use work.TextUtilPkg.all;
25 
26 package Code10b12bPkg is
27 --! @file
28  --! @ingroup base_general
29 
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
34 
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
37 
38  -------------------------------------------------------------------------------------------------
39  -- Disparity types and helper functions
40  -------------------------------------------------------------------------------------------------
41  function toString (code : slv(9 downto 0); k : sl) return string;
42 
43  subtype DisparityType is integer range -1 to 1;
44  function conv (d : sl) return DisparityType;
45  function conv (d : DisparityType) return sl;
46 
47  function getDisparity (vec : slv) return integer;
48 
49  -------------------------------------------------------------------------------------------------
50  -- 5B6B Code Constants
51  -------------------------------------------------------------------------------------------------
52  type Code5b6bType is record
53  out6b : slv(5 downto 0);
56  end record Code5b6bType;
57 
58  type Code5b6bArray is array (natural range <>) of Code5b6bType;
59 
60  constant D_CODE_TABLE_C : Code5b6bArray(0 to 31) := (
61  ("000110", 1, -1),
62  ("010001", 1, -1),
63  ("010010", 1, -1),
64  ("100011", 0, 0),
65  ("010100", 1, -1),
66  ("100101", 0, 0),
67  ("100110", 0, 0),
68  ("000111", -1, 0), -- D.7 Special case
69  ("011000", 1, -1),
70  ("101001", 0, 0),
71  ("101010", 0, 0),
72  ("001011", 0, 0),
73  ("101100", 0, 0),
74  ("001101", 0, 0),
75  ("001110", 0, 0),
76  ("000101", 1, -1), -- ("111010", -1, 1),
77  ("001001", 1, -1), -- ("110110", -1, 1),
78  ("110001", 0, 0),
79  ("110010", 0, 0),
80  ("010011", 0, 0),
81  ("110100", 0, 0),
82  ("010101", 0, 0),
83  ("010110", 0, 0),
84  ("101000", 1, -1), -- ("010111", -1, 1),
85  ("001100", 1, -1),
86  ("011001", 0, 0),
87  ("011010", 0, 0),
88  ("100100", 1, -1), -- ("011011", -1, 1),
89  ("011100", 0, 0),
90  ("100010", 1, -1), -- ("011101", -1, 1),
91  ("100001", 1, -1), -- ("011110", -1, 1),
92  ("001010", 1, -1)); -- ("110101", -1, 1));
93 
94  constant K_CODE_TABLE_C : Code5b6bArray(0 to 31) := (
95  ("000110", 1, -1),
96  ("010001", 1, -1),
97  ("010010", 1, -1),
98  ("100011", 1, 0),
99  ("010100", 1, -1),
100  ("100101", 1, 0),
101  ("100110", 1, 0),
102  ("000111", -1, 0), -- D.7 Special case
103  ("011000", 1, -1),
104  ("101001", 1, 0),
105  ("101010", 1, 0),
106  ("001011", 1, 0),
107  ("101100", 1, 0),
108  ("001101", 1, 0),
109  ("001110", 1, 0),
110  ("000101", 1, -1), -- ("111010", -1, 1),
111  ("001001", 1, -1), -- ("110110", -1, 1),
112  ("110001", 1, 0),
113  ("110010", 1, 0),
114  ("010011", 1, 0),
115  ("110100", 1, 0),
116  ("010101", 1, 0),
117  ("010110", 1, 0),
118  ("101000", 1, -1), -- ("010111", -1, 1),
119  ("001100", 1, -1),
120  ("011001", 1, 0),
121  ("011010", 1, 0),
122  ("100100", 1, -1), -- ("011011", -1, 1),
123  ("000011", 1, -1),
124  ("100010", 1, -1), -- ("011101", -1, 1),
125  ("100001", 1, -1), -- ("011110", -1, 1),
126  ("001010", 1, -1)); -- ("110101", -1, 1));
127 
128  procedure encode10b12b (
129  dataIn : in slv(9 downto 0);
130  dataKIn : in sl;
131  dispIn : in sl;
132  dataOut : out slv(11 downto 0);
133  dispOut : out sl);
134 
135  procedure decode10b12b (
136  dataIn : in slv(11 downto 0);
137  dispIn : in sl;
138  dataOut : out slv(9 downto 0);
139  dataKOut : inout sl;
140  dispOut : inout sl;
141  codeError : out sl;
142  dispError : inout sl);
143 
144 end package Code10b12bPkg;
145 
146 package body Code10b12bPkg is
147 
148  function toString (code : slv(9 downto 0); k : sl) return string is
149  variable s : string(1 to 8);
150  begin
151  s := resize(ite(k = '1', "K.", "D.") &
152  integer'image(conv_integer(code(4 downto 0))) &
153  "." &
154  integer'image(conv_integer(code(9 downto 5))), 8);
155  return s;
156  end function toString;
157 
158  function conv (d : sl) return DisparityType is
159  begin
160  if (d = '1') then
161  return 1;
162  else
163  return -1;
164  end if;
165  end function conv;
166 
167  function conv (d : DisparityType) return sl is
168  begin
169  if (d = -1) then
170  return '0';
171  else
172  return '1';
173  end if;
174  end function conv;
175 
176  function getDisparity (vec : slv) return integer is
177  variable ones : integer;
178  variable zeros : integer;
179  variable disparity : integer;
180  begin
181  zeros := 0;
182  ones := 0;
183  for i in vec'range loop
184  if (vec(i) = '0') then
185  zeros := zeros + 1;
186  end if;
187  end loop;
188 
189  ones := vec'length-zeros;
190  disparity := ones-zeros;
191 
192  return disparity;
193 
194  end function getDisparity;
195 
196 
197  procedure encode10b12b (
198  dataIn : in slv(9 downto 0);
199  dataKIn : in sl;
200  dispIn : in sl;
201  dataOut : out slv(11 downto 0);
202  dispOut : out sl)
203  is
204  variable tmp : Code5b6bType;
205  variable lowWordIn : slv(4 downto 0);
206  variable lowWordOut : slv(5 downto 0);
207  variable lowDispOut : DisparityType;
208  variable highWordIn : slv(4 downto 0);
209  variable highWordOut : slv(5 downto 0);
210  variable highDispOut : DisparityType;
211  begin
212 
213  -- First, split in input word in two
214  highWordIn := dataIn(9 downto 5);
215  lowWordIn := dataIn(4 downto 0);
216 
217  -- Select low output word
218  tmp := D_CODE_TABLE_C(conv_integer(lowWordIn));
219  if (dataKIn = '1') then
220  tmp := K_CODE_TABLE_C(conv_integer(lowWordIn));
221 -- tmp := K_CODE_TABLE_C(28);
222  end if;
223 
224  -- Decide whether to invert
225  if (tmp.expDisp /= 0) then
226  if (conv(dispIn) /= tmp.expDisp) then
227  lowWordOut := not tmp.out6b;
228  lowDispOut := tmp.outDisp * (-1);
229  else
230  lowWordOut := tmp.out6b;
231  lowDispOut := tmp.outDisp;
232  end if;
233  else
234  lowWordOut := tmp.out6b;
235  lowDispOut := conv(dispIn);
236  end if;
237 
238  -- If selected code has even disparity,
239  -- use dispIn to decide upper word disparity
240  if (lowDispOut = 0) then
241  lowDispOut := conv(dispIn);
242  end if;
243 
244 
245 
246  -- Select high output word
247  tmp := D_CODE_TABLE_C(conv_integer(highWordIn));
248  if (dataKIn = '1') then
249  tmp := K_CODE_TABLE_C(conv_integer(highWordIn));
250  end if;
251 
252  -- Decide whether to invert
253  if (tmp.expDisp /= 0) then
254  if (lowDispOut /= tmp.expDisp) then
255  highWordOut := not tmp.out6b;
256  highDispOut := tmp.outDisp * (-1);
257  else
258  highWordOut := tmp.out6b;
259  highDispOut := tmp.outDisp;
260  end if;
261  else
262  highWordOut := tmp.out6b;
263  highDispOut := lowDispOut;
264  end if;
265 
266  if (highDispOut = 0) then
267  highDispOut := lowDispOut;
268  end if;
269 
270  -- Handle K.28.28 case
271 -- if (dataKIn = '1') then
272 -- if (highWordIn = "11100") then
273 -- highWordOut := not "111100";
274 -- highDispOut := conv(dispIn);
275 -- end if;
276 -- end if;
277 
278  dispOut := conv(highDispOut);
279  dataOut := highWordOut & lowWordOut;
280 
281  end procedure;
282 
283  procedure decode10b12b (
284  dataIn : in slv(11 downto 0);
285  dispIn : in sl;
286  dataOut : out slv(9 downto 0);
287  dataKOut : inout sl;
288  dispOut : inout sl;
289  codeError : out sl;
290  dispError : inout sl)
291  is
292  variable tmp : Code5b6bType;
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 : integer;
300  variable runDisp : integer;
301  variable k28Disp : integer;
302  begin
303 
304 -- print("------------");
305  -- Set default values
306  codeError := '1';
307  dispError := '0';
308  dataKOut := '0';
309  lowWordOut := (others => '0');
310  highWordOut := (others => '0');
311 
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));
318  dispError := '1';
319  end if;
320 
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));
328  dispError := '1';
329  end if;
330 
331 -- print("dataIn: " & str(dataIn));
332 -- print("inputDisp: " & str(inputDisp));
333 -- print("runDisp: " & str(runDisp));
334 
335 
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
339  dispOut := '1';
340  elsif (runDisp < 0) then
341  dispOut := '0';
342  else
343  dispOut := conv(inputDisp/2);
344  end if;
345 
346 -- print("dispOut: " & str(dispOut));
347 -- print("------------");
348 
349  lowWordIn := dataIn(5 downto 0);
350  highWordIn := dataIn(11 downto 6);
351 
352  -- Check for a k-code
353  if ((lowWordIn = K_CODE_TABLE_C(28).out6b) or
354  (lowWordIn = not(K_CODE_TABLE_C(28).out6b))) then
355 
356  lowWordOut := conv_std_logic_vector(28, 5);
357  if (lowWordIn = K_CODE_TABLE_C(28).out6b) then
358  k28Disp := K_CODE_TABLE_C(28).outDisp;
359  else
360  k28Disp := (-1)*K_CODE_TABLE_C(28).outDisp;
361  end if;
362  dataKOut := '1';
363  lowWordValid := '1';
364  end if;
365 
366 
367  -- Need to check for valid k5/6 code
368  if (dataKout = '1') then
369  for i in K_CODE_TABLE_C'range loop
370  tmp := K_CODE_TABLE_C(i);
371  if (((highWordIn = tmp.out6b) and ((k28Disp = tmp.expDisp) or (tmp.expDisp = 0))) or
372  ((highWordIn = not (tmp.out6b)) and ((k28Disp = (-1)*(tmp.expDisp))))) then
373 
374  highWordOut := conv_std_logic_vector(i, 5);
375  dataKOut := '1';
376  highWordValid := '1';
377  exit;
378  end if;
379  end loop;
380  end if;
381 
382  if (dataKOut = '0') then
383 
384  -- Decode low word
385  for i in D_CODE_TABLE_C'range loop
386  tmp := D_CODE_TABLE_C(i);
387  if ((lowWordIn = tmp.out6b) or
388  ((lowWordIn = not (tmp.out6b)) and (tmp.expDisp /= 0))) then
389 
390  lowWordOut := conv_std_logic_vector(i, 5);
391  lowWordValid := '1';
392  exit;
393  end if;
394  end loop;
395 
396  -- Decode high word
397  for i in D_CODE_TABLE_C'range loop
398  tmp := D_CODE_TABLE_C(i);
399  if ((highWordIn = tmp.out6b) or
400  ((highWordIn = not (tmp.out6b)) and (tmp.expDisp /= 0))) then
401 
402  highWordOut := conv_std_logic_vector(i, 5);
403  highWordValid := '1';
404  exit;
405  end if;
406  end loop;
407 
408 
409  end if;
410 
411  if (lowWordValid = '1' and highWordValid = '1') then
412  codeError := '0';
413  end if;
414 
415  dataOut(4 downto 0) := lowWordOut;
416  dataOut(9 downto 5) := highWordOut;
417 
418  end procedure decode10b12b;
419 
420 
421 end package body Code10b12bPkg;
_library_ ieeeieee
slv( 5 downto 0) out6b
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
std_logic sl
Definition: StdRtlPkg.vhd:28
slv( 9 downto 0) := "0101111100" K_28_11_C
integer getDisparityvec,
string toStringcode,k,
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
DisparityType expDisp
array(natural range <> ) of Code5b6bType Code5b6bArray
DisparityType outDisp
DisparityType convd,
encode10b12bdataIn,dataKIn,dispIn,dataOut,dispOut,
decode10b12bdataIn,dispIn,dataOut,dataKOut,dispOut,codeError,dispError,
std_logic_vector slv
Definition: StdRtlPkg.vhd:29