SURF  1.0
Code8b10bPkg.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : Code8b10bPkg.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2016-10-12
5 -- Last update: 2016-10-12
6 -------------------------------------------------------------------------------
7 -- Description: 8B10B 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.numeric_std.all;
21 use work.StdRtlPkg.all;
22 
23 package Code8b10bPkg is
24 --! @file
25  --! @ingroup base_general
26 
27  -------------------------------------------------------------------------------------------------
28  -- Control Code Constants
29  -------------------------------------------------------------------------------------------------
30  constant K_28_0_C : slv(7 downto 0) := "00011100"; -- K28.0, 0x1C
31  constant K_28_1_C : slv(7 downto 0) := "00111100"; -- K28.1, 0x3C (Comma)
32  constant K_28_2_C : slv(7 downto 0) := "01011100"; -- K28.2, 0x5C
33  constant K_28_3_C : slv(7 downto 0) := "01111100"; -- K28.3, 0x7C
34  constant K_28_4_C : slv(7 downto 0) := "10011100"; -- K28.4, 0x9C
35  constant K_28_5_C : slv(7 downto 0) := "10111100"; -- K28.5, 0xBC (Comma)
36  constant K_28_6_C : slv(7 downto 0) := "11011100"; -- K28.6, 0xDC
37  constant K_28_7_C : slv(7 downto 0) := "11111100"; -- K28.7, 0xFC (Comma)
38  constant K_23_7_C : slv(7 downto 0) := "11110111"; -- K23.7, 0xF7
39  constant K_27_7_C : slv(7 downto 0) := "11111011"; -- K27.7, 0xFB
40  constant K_29_7_C : slv(7 downto 0) := "11111101"; -- K29.7, 0xFD
41  constant K_30_7_C : slv(7 downto 0) := "11111110"; -- K30.7, 0xFE
42 
43  constant D_10_2_C : slv(7 downto 0) := "01001010"; -- D10.2, 0x4A
44  constant D_21_5_C : slv(7 downto 0) := "10110101"; -- D21.5, 0xB5
45 
46  procedure encode8b10b (
47  dataIn : in slv(7 downto 0);
48  dataKIn : in sl;
49  dispIn : in sl;
50  dataOut : out slv(9 downto 0);
51  dispOut : out sl);
52 
53  procedure decode8b10b (
54  dataIn : in slv(9 downto 0);
55  dispIn : in sl;
56  dataOut : out slv(7 downto 0);
57  dataKOut : out sl;
58  dispOut : out sl;
59  codeErr : out sl;
60  dispErr : out sl);
61 
62 end package Code8b10bPkg;
63 
64 package body Code8b10bPkg is
65 
66  procedure encode8b10b (
67  dataIn : in slv(7 downto 0);
68  dataKIn : in sl;
69  dispIn : in sl;
70  dataOut : out slv(9 downto 0);
71  dispOut : out sl)
72  is
73  variable ai, bi, ci, di, ei, fi, gi, hi, ki : sl;
74  variable aeqb, ceqd : sl;
75  variable l22, l40, l04, l13, l31 : sl;
76  variable ao, bo, co, do, eo, io, fo, go, ho, jo : sl;
77  variable pd1s6, nd1s6, ndos6, pdos6 : sl;
78  variable alt6, alt7 : sl;
79  variable nd1s4, pd1s4, ndos4, pdos4 : sl;
80  variable illegalk : sl;
81  variable compls6, disp6, compls4 : sl;
82  begin
83 
84  ai := dataIn(0);
85  bi := dataIn(1);
86  ci := dataIn(2);
87  di := dataIn(3);
88  ei := dataIn(4);
89  fi := dataIn(5);
90  gi := dataIn(6);
91  hi := dataIn(7);
92  ki := dataKIn;
93 
94  aeqb := (ai and bi) or (not ai and not bi);
95  ceqd := (ci and di) or (not ci and not di);
96  l22 := (ai and bi and not ci and not di) or
97  (ci and di and not ai and not bi) or
98  (not aeqb and not ceqd);
99  l40 := ai and bi and ci and di;
100  l04 := not ai and not bi and not ci and not di;
101  l13 := (not aeqb and not ci and not di) or
102  (not ceqd and not ai and not bi);
103  l31 := (not aeqb and ci and di) or
104  (not ceqd and ai and bi);
105 
106  -- The 5B/6B encoding
107 
108  ao := ai;
109  bo := (bi and not l40) or l04;
110  co := l04 or ci or (ei and di and not ci and not bi and not ai);
111  do := di and not (ai and bi and ci);
112  eo := (ei or l13) and not (ei and di and not ci and not bi and not ai);
113  io := (l22 and not ei) or
114  (ei and not di and not ci and not (ai and bi)) or -- D16, D17, D18
115  (ei and l40) or
116  (ki and ei and di and ci and not bi and not ai) or -- K.28
117  (ei and not di and ci and not bi and not ai);
118 
119  -- pds16 indicates cases where d-1 is assumed + to get our encoded value
120  pd1s6 := (ei and di and not ci and not bi and not ai) or (not ei and not l22 and not l31);
121  -- nds16 indicates cases where d-1 is assumed - to get our encoded value
122  nd1s6 := ki or (ei and not l22 and not l13) or (not ei and not di and ci and bi and ai);
123 
124  -- ndos6 is pds16 cases where d-1 is + yields - disp out - all of them
125  ndos6 := pd1s6;
126  -- pdos6 is nds16 cases where d-1 is - yields + disp out - all but one
127  pdos6 := ki or (ei and not l22 and not l13);
128 
129 
130  -- some Dx.7 and all Kx.7 cases result in run length of 5 case unless
131  -- an alternate coding is used (referred to as Dx.A7, normal is Dx.P7)
132  -- specifically, D11, D13, D14, D17, D18, D19.
133  if (dispIn = '1') then
134  alt6 := (not ei and di and l31);
135  else
136  alt6 := (ei and not di and l13);
137  end if;
138  alt7 := fi and gi and hi and (ki or alt6);
139 
140  fo := fi and not alt7;
141  go := gi or (not fi and not gi and not hi);
142  ho := hi;
143  jo := (not hi and (gi xor fi)) or alt7;
144 
145  -- nd1s4 is cases where d-1 is assumed - to get our encoded value
146  nd1s4 := fi and gi;
147  -- pd1s4 is cases where d-1 is assumed + to get our encoded value
148  pd1s4 := (not fi and not gi) or (ki and ((fi and not gi) or (not fi and gi)));
149 
150  -- ndos4 is pd1s4 cases where d-1 is + yields - disp out - just some
151  ndos4 := (not fi and not gi);
152  -- pdos4 is nd1s4 cases where d-1 is - yields + disp out
153  pdos4 := fi and gi and hi;
154 
155  -- only legal K codes are K28.0- > .7, K23/27/29/30.7
156  -- K28.0- > 7 is ei = di = ci = 1, bi = ai = 0
157  -- K23 is 10111
158  -- K27 is 11011
159  -- K29 is 11101
160  -- K30 is 11110 - so K23/27/29/30 are ei and l31
161  illegalk := ki and
162  (ai or bi or not ci or not di or not ei) and -- not K28.0- > 7
163  (not fi or not gi or not hi or not ei or not l31); -- not K23/27/29/30.7
164 
165  -- now determine whether to do the complementing
166  -- complement if prev disp is - and pd1s6 is set, or + and nd1s6 is set
167  compls6 := (pd1s6 and not dispin) or (nd1s6 and dispin);
168 
169  -- disparity out of 5b6b is disp in with pdso6 and ndso6
170  -- pds16 indicates cases where d-1 is assumed + to get our encoded value
171  -- ndos6 is cases where d-1 is + yields - disp out
172  -- nds16 indicates cases where d-1 is assumed - to get our encoded value
173  -- pdos6 is cases where d-1 is - yields + disp out
174  -- disp toggles in all ndis16 cases, and all but that 1 nds16 case
175 
176  disp6 := dispin xor (ndos6 or pdos6);
177 
178  compls4 := (pd1s4 and not disp6) or (nd1s4 and disp6);
179  dispOut := disp6 xor (ndos4 or pdos4);
180 
181  dataOut := (jo xor compls4) & (ho xor compls4) &
182  (go xor compls4) & (fo xor compls4) &
183  (io xor compls6) & (eo xor compls6) &
184  (do xor compls6) & (co xor compls6) &
185  (bo xor compls6) & (ao xor compls6);
186 
187  end procedure encode8b10b;
188 
189  procedure decode8b10b (
190  dataIn : in slv(9 downto 0);
191  dispIn : in sl;
192  dataOut : out slv(7 downto 0);
193  dataKOut : out sl;
194  dispOut : out sl;
195  codeErr : out sl;
196  dispErr : out sl)
197  is
198  variable ai, bi, ci, di, ei, ii, fi, gi, hi, ji : sl;
199  variable aeqb, ceqd : sl;
200  variable p22, p13, p31, p40, p04 : sl;
201  variable disp6a, disp6a2, disp6a0, disp6b : sl;
202  variable p22bceeqi, p22bncneeqi, p13in, p31i, p13dei : sl;
203  variable p22aceeqi, p22ancneeqi : sl;
204  variable p13en, anbnenin, abei, cdei, cndnenin : sl;
205  variable p22enin, p22ei, p31dnenin, p31e : sl;
206  variable compa, compb, compc, compd, compe : sl;
207  variable ao, bo, co, do, eo, ko, fo, go, ho : sl;
208  variable feqg, heqj, fghj22, fghjp13, fghjp31 : sl;
209  variable alt7, k28, k28p : sl;
210  variable disp6p, disp6n, disp4p, disp4n : sl;
211  begin
212 
213  ai := dataIn(0);
214  bi := dataIn(1);
215  ci := dataIn(2);
216  di := dataIn(3);
217  ei := dataIn(4);
218  ii := dataIn(5);
219  fi := dataIn(6);
220  gi := dataIn(7);
221  hi := dataIn(8);
222  ji := dataIn(9);
223 
224  aeqb := (ai and bi) or (not ai and not bi);
225  ceqd := (ci and di) or (not ci and not di);
226  p22 := (ai and bi and not ci and not di) or
227  (ci and di and not ai and not bi) or
228  (not aeqb and not ceqd);
229  p13 := (not aeqb and not ci and not di) or
230  (not ceqd and not ai and not bi);
231  p31 := (not aeqb and ci and di) or
232  (not ceqd and ai and bi);
233 
234  p40 := ai and bi and ci and di;
235  p04 := not ai and not bi and not ci and not di;
236 
237  disp6a := p31 or (p22 and dispin); -- pos disp if p22 and was pos, or p31.
238  disp6a2 := p31 and dispin; -- disp is ++ after 4 bits
239  disp6a0 := p13 and not dispin; -- -- disp after 4 bits
240 
241  disp6b := (((ei and ii and not disp6a0) or (disp6a and (ei or ii)) or disp6a2 or
242  (ei and ii and di)) and (ei or ii or di)) ;
243 
244  -- The 5B/6B decoding special cases where ABCDE not = abcde
245 
246  p22bceeqi := p22 and bi and ci and (ei xnor ii);
247  p22bncneeqi := p22 and not bi and not ci and (ei xnor ii);
248  p13in := p13 and not ii;
249  p31i := p31 and ii;
250  p13dei := p13 and di and ei and ii;
251  p22aceeqi := p22 and ai and ci and (ei xnor ii);
252  p22ancneeqi := p22 and not ai and not ci and (ei xnor ii);
253  p13en := p13 and not ei;
254  anbnenin := not ai and not bi and not ei and not ii;
255  abei := ai and bi and ei and ii;
256  cdei := ci and di and ei and ii;
257  cndnenin := not ci and not di and not ei and not ii;
258 
259  -- non-zero disparity cases:
260  p22enin := p22 and not ei and not ii;
261  p22ei := p22 and ei and ii;
262  -- p13in := p12 and not ii ;
263  -- p31i := p31 and ii ;
264  p31dnenin := p31 and not di and not ei and not ii;
265  -- p13dei := p13 and di and ei and ii ;
266  p31e := p31 and ei;
267 
268  compa := p22bncneeqi or p31i or p13dei or p22ancneeqi or
269  p13en or abei or cndnenin;
270  compb := p22bceeqi or p31i or p13dei or p22aceeqi or
271  p13en or abei or cndnenin;
272  compc := p22bceeqi or p31i or p13dei or p22ancneeqi or
273  p13en or anbnenin or cndnenin;
274  compd := p22bncneeqi or p31i or p13dei or p22aceeqi or
275  p13en or abei or cndnenin;
276  compe := p22bncneeqi or p13in or p13dei or p22ancneeqi or
277  p13en or anbnenin or cndnenin;
278 
279  ao := ai xor compa;
280  bo := bi xor compb;
281  co := ci xor compc;
282  do := di xor compd;
283  eo := ei xor compe;
284 
285  feqg := (fi and gi) or (not fi and not gi);
286  heqj := (hi and ji) or (not hi and not ji);
287  fghj22 := (fi and gi and not hi and not ji) or
288  (not fi and not gi and hi and ji) or
289  (not feqg and not heqj);
290  fghjp13 := (not feqg and not hi and not ji) or
291  (not heqj and not fi and not gi);
292  fghjp31 := ((not feqg) and hi and ji) or
293  (not heqj and fi and gi);
294 
295  dispout := (fghjp31 or (disp6b and fghj22) or (hi and ji)) and (hi or ji);
296 
297  ko := ((ci and di and ei and ii) or (not ci and not di and not ei and not ii) or
298  (p13 and not ei and ii and gi and hi and ji) or
299  (p31 and ei and not ii and not gi and not hi and not ji)) ;
300 
301  alt7 := (fi and not gi and not hi and -- 1000 cases, where disp6b is 1
302  ((dispin and ci and di and not ei and not ii) or ko or
303  (dispin and not ci and di and not ei and not ii))) or
304  (not fi and gi and hi and -- 0111 cases, where disp6b is 0
305  ((not dispin and not ci and not di and ei and ii) or ko or
306  (not dispin and ci and not di and ei and ii))) ;
307 
308  k28 := (ci and di and ei and ii) or not (ci or di or ei or ii);
309  -- k28 with positive disp into fghi - .1, .2, .5, and .6 special cases
310  k28p := not (ci or di or ei or ii);
311  fo := (ji and not fi and (hi or not gi or k28p)) or
312  (fi and not ji and (not hi or gi or not k28p)) or
313  (k28p and gi and hi) or
314  (not k28p and not gi and not hi);
315  go := (ji and not fi and (hi or not gi or not k28p)) or
316  (fi and not ji and (not hi or gi or k28p)) or
317  (not k28p and gi and hi) or
318  (k28p and not gi and not hi);
319  ho := ((ji xor hi) and not ((not fi and gi and not hi and ji and not k28p) or (not fi and gi and hi and not ji and k28p) or
320  (fi and not gi and not hi and ji and not k28p) or (fi and not gi and hi and not ji and k28p))) or
321  (not fi and gi and hi and ji) or (fi and not gi and not hi and not ji);
322 
323  disp6p := (p31 and (ei or ii)) or (p22 and ei and ii);
324  disp6n := (p13 and not (ei and ii)) or (p22 and not ei and not ii);
325  disp4p := fghjp31;
326  disp4n := fghjp13;
327 
328  codeErr := p40 or p04 or (fi and gi and hi and ji) or (not fi and not gi and not hi and not ji) or
329  (p13 and not ei and not ii) or (p31 and ei and ii) or
330  (ei and ii and fi and gi and hi) or (not ei and not ii and not fi and not gi and not hi) or
331  (ei and not ii and gi and hi and ji) or (not ei and ii and not gi and not hi and not ji) or
332  (not p31 and ei and not ii and not gi and not hi and not ji) or
333  (not p13 and not ei and ii and gi and hi and ji) or
334  (((ei and ii and not gi and not hi and not ji) or
335  (not ei and not ii and gi and hi and ji)) and
336  not ((ci and di and ei) or (not ci and not di and not ei))) or
337  (disp6p and disp4p) or (disp6n and disp4n) or
338  (ai and bi and ci and not ei and not ii and ((not fi and not gi) or fghjp13)) or
339  (not ai and not bi and not ci and ei and ii and ((fi and gi) or fghjp31)) or
340  (fi and gi and not hi and not ji and disp6p) or
341  (not fi and not gi and hi and ji and disp6n) or
342  (ci and di and ei and ii and not fi and not gi and not hi) or
343  (not ci and not di and not ei and not ii and fi and gi and hi);
344 
345  dataOut := ho & go & fo & eo & do & co & bo & ao;
346  dataKOut := ko;
347 
348  --my disp err fires for any legal codes that violate disparity, may fire for illegal codes
349  dispErr := ((dispin and disp6p) or (disp6n and not dispin) or
350  (dispin and not disp6n and fi and gi) or
351  (dispin and ai and bi and ci) or
352  (dispin and not disp6n and disp4p) or
353  (not dispin and not disp6p and not fi and not gi) or
354  (not dispin and not ai and not bi and not ci) or
355  (not dispin and not disp6p and disp4n) or
356  (disp6p and disp4p) or (disp6n and disp4n)) ;
357 
358  end procedure decode8b10b;
359 
360 end package body Code8b10bPkg;
slv( 7 downto 0) := "01011100" K_28_2_C
slv( 7 downto 0) := "00011100" K_28_0_C
slv( 7 downto 0) := "11111011" K_27_7_C
slv( 7 downto 0) := "11111100" K_28_7_C
slv( 7 downto 0) := "00111100" K_28_1_C
std_logic sl
Definition: StdRtlPkg.vhd:28
_library_ ieeeieee
slv( 7 downto 0) := "10110101" D_21_5_C
slv( 7 downto 0) := "11111101" K_29_7_C
encode8b10bdataIn,dataKIn,dispIn,dataOut,dispOut,
slv( 7 downto 0) := "11111110" K_30_7_C
slv( 7 downto 0) := "10111100" K_28_5_C
slv( 7 downto 0) := "10011100" K_28_4_C
slv( 7 downto 0) := "01111100" K_28_3_C
decode8b10bdataIn,dispIn,dataOut,dataKOut,dispOut,codeErr,dispErr,
slv( 7 downto 0) := "11110111" K_23_7_C
slv( 7 downto 0) := "11011100" K_28_6_C
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
slv( 7 downto 0) := "01001010" D_10_2_C