SURF  1.0
GLinkEncoder.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : GLinkEncoder.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2012-04-19
5 -- Last update: 2017-05-05
6 -------------------------------------------------------------------------------
7 -- Description: Encodes 16 bit data raw words into 20 bit GLink words.
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 
22 use work.StdRtlPkg.all;
23 use work.GLinkPkg.all;
24 
25 --! @see entity
26  --! @ingroup protocols_glink_core
27 entity GLinkEncoder is
28  generic (
29  TPD_G : time := 1 ns;
30  RST_ASYNC_G : boolean := false;
31  RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset
32  FLAGSEL_G : boolean := false);
33  port (
34  en : in sl := '1';
35  clk : in sl;
36  rst : in sl;
38  encodedData : out slv(19 downto 0));
39 end GLinkEncoder;
40 
41 architecture rtl of GLinkEncoder is
42 
43  function disparity (vec : slv(19 downto 0)) return signed is
44  variable onesCountVar : unsigned(4 downto 0);
45  variable disparityVar : signed(5 downto 0);
46  begin
47  onesCountVar := onesCountU(vec);
48  disparityVar := (signed('0' & onesCountVar) - 10);
49  return disparityVar(4 downto 0);
50  end function;
51 
52  type RegType is record
53  toggle : sl;
54  encodedData : slv(19 downto 0);
55  runningDisparity : signed(4 downto 0);
56  end record;
57 
58  constant REG_INIT_C : RegType := (
59  '0',
61  (others => '0'));
62 
63  signal r : RegType := REG_INIT_C;
64  signal rin : RegType;
65 
66 begin
67 
68  comb : process (gLinkTx, r, rst)
69  variable v : RegType;
70  variable glinkWordVar : GLinkWordType;
71  variable rawBufferflyVar : slv(0 to 15);
72  variable rawDisparityVar : signed(4 downto 0);
73  begin
74  -- Latch the current value
75  v := r;
76 
77  -- Reverse the bit order
78  rawBufferflyVar := bitReverse(gLinkTx.data);
79 
80  -- Check for idle or control
81  if (gLinkTx.idle = '1') or (gLinkTx.control = '1') then
82  glinkWordVar.c := GLINK_CONTROL_WORD_C;
83  else
84  -- Check for flag select enabled
85  if (FLAGSEL_G = true) then
86  if (gLinkTx.flag = '1') then
87  glinkWordVar.c := GLINK_DATA_WORD_FLAG_HIGH_C;
88  else
89  glinkWordVar.c := GLINK_DATA_WORD_FLAG_LOW_C;
90  end if;
91  else
92  -- Check the toggle bit
93  if r.toggle = '1' then
94  glinkWordVar.c := GLINK_DATA_WORD_FLAG_HIGH_C;
95  -- Toggle the bit
96  v.toggle := '0';
97  else
98  glinkWordVar.c := GLINK_DATA_WORD_FLAG_LOW_C;
99  -- Toggle the bit
100  v.toggle := '1';
101  end if;
102  end if;
103  end if;
104 
105  -- Latch the reversed word
106  glinkWordVar.w := rawBufferflyVar;
107 
108  -- Control overrides data assignments
109  if (gLinkTx.control = '1') then
110  glinkWordVar.w := rawBufferflyVar(0 to 6) & "01" & rawBufferflyVar(7 to 13);
111  end if;
112 
113  -- Idle overrides control
114  if (gLinkTx.idle = '1') then
115  glinkWordVar.w := GLINK_IDLE_WORD_FF1L_C;
116  end if;
117 
118  -- Encode the G-Link word into an SLV
119  v.encodedData := toSlv(glinkWordVar);
120 
121  -- Calculate the disparity of the encoded word so far
122  rawDisparityVar := disparity(v.encodedData);
123 
124  -- Invert if necessary to reduce disparity
125  if (rawDisparityVar(4) = r.runningDisparity(4)) then
126  if (gLinkTx.idle = '1') then
128  else
129  -- Normal data or control, invert everything
130  v.encodedData := not v.encodedData;
131  end if;
132  -- Calculated raw disparity must be (2's complement) inverted too
133  rawDisparityVar := (not rawDisparityVar) + 1;
134  end if;
135 
136  -- Data now fully encoded. Calculate its disparity and add it to the running total
137  v.runningDisparity := r.runningDisparity + rawDisparityVar;
138 
139  -- Synchronous Reset
140  if (RST_ASYNC_G = false and rst = RST_POLARITY_G) then
141  v := REG_INIT_C;
142  end if;
143 
144  -- Register the variable for next clock cycle
145  rin <= v;
146 
147  -- Outputs
149 
150  end process comb;
151 
152  seq : process (clk, rst) is
153  begin
154  if rising_edge(clk) then
155  if en = '1' then
156  r <= rin after TPD_G;
157  end if;
158  end if;
159  -- Asynchronous Reset
160  if (RST_ASYNC_G and rst = RST_POLARITY_G) then
161  r <= REG_INIT_C after TPD_G;
162  end if;
163  end process seq;
164 
165 end rtl;
out encodedDataslv( 19 downto 0)
slv( 0 to 15) := X"FF00" GLINK_IDLE_WORD_FF0_C
Definition: GLinkPkg.vhd:101
std_logic sl
Definition: StdRtlPkg.vhd:28
RST_ASYNC_Gboolean := false
slv( 0 to 15) := X"FF80" GLINK_IDLE_WORD_FF1H_C
Definition: GLinkPkg.vhd:103
slv( 3 downto 0) := "1011" GLINK_DATA_WORD_FLAG_HIGH_C
Definition: GLinkPkg.vhd:86
slv( 3 downto 0) := "1101" GLINK_DATA_WORD_FLAG_LOW_C
Definition: GLinkPkg.vhd:84
RST_POLARITY_Gsl := '1'
in gLinkTxGLinkTxType
_library_ ieeeieee
TPD_Gtime := 1 ns
slv( 15 downto 0) data
Definition: GLinkPkg.vhd:33
slv( 0 to 15) := X"FE00" GLINK_IDLE_WORD_FF1L_C
Definition: GLinkPkg.vhd:102
slv( 3 downto 0) := "0011" GLINK_CONTROL_WORD_C
Definition: GLinkPkg.vhd:82
FLAGSEL_Gboolean := false
in ensl := '1'
sl idle
Definition: GLinkPkg.vhd:30
slv( 0 to 15) w
Definition: GLinkPkg.vhd:117
slv( 3 downto 0) c
Definition: GLinkPkg.vhd:118
sl flag
Definition: GLinkPkg.vhd:32
sl control
Definition: GLinkPkg.vhd:31
std_logic_vector slv
Definition: StdRtlPkg.vhd:29