SURF  1.0
JesdSyncFsmRx.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : JesdSyncFsmRx.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2015-04-14
5 -- Last update: 2015-04-14
6 -------------------------------------------------------------------------------
7 -- Description: Synchronizer Finite state machine
8 -- Finite state machine for sub-class 1 deterministic latency
9 -- lane synchronization.
10 -- It also supports sub-class 0 non deterministic mode.
11 -------------------------------------------------------------------------------
12 -- This file is part of 'SLAC Firmware Standard Library'.
13 -- It is subject to the license terms in the LICENSE.txt file found in the
14 -- top-level directory of this distribution and at:
15 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
16 -- No part of 'SLAC Firmware Standard Library', including this file,
17 -- may be copied, modified, propagated, or distributed except according to
18 -- the terms contained in the LICENSE.txt file.
19 -------------------------------------------------------------------------------
20 
21 library ieee;
22 use ieee.std_logic_1164.all;
23 use ieee.std_logic_arith.all;
24 use ieee.std_logic_unsigned.all;
25 
26 use work.StdRtlPkg.all;
27 use work.Jesd204bPkg.all;
28 
29 --! @see entity
30  --! @ingroup protocols_jesd204b
31 entity JesdSyncFsmRx is
32  generic (
33  TPD_G: time := 1 ns;
34 
35  -- Number of bytes in a frame
36  F_G : positive := 2;
37 
38  -- Number of frames in a multi frame
39  K_G : positive := 32;
40 
41  -- Number of multi-frames in ILA sequence (4-255)
42  NUM_ILAS_MF_G : positive := 4
43  );
44  port (
45  -- Clocks and Resets
46  clk : in sl;
47  rst : in sl;
48 
49  -- Enable the module
50  enable_i : in sl;
51  gtReady_i : in sl;
52 
53  -- JESD subclass selection: '0' or '1'(default)
54  subClass_i : in sl;
55 
56  -- SYSREF for subcalss 1 fixed latency
57  sysRef_i : in sl;
58 
59  -- Data and character inputs from GT (transceivers)
60  dataRx_i : in slv((GT_WORD_SIZE_C*8)-1 downto 0);
61  chariskRx_i : in slv(GT_WORD_SIZE_C-1 downto 0);
62 
63  -- Local multi frame clock
64  lmfc_i : in sl;
65 
66  -- One or more RX modules requested synchronization
67  nSyncAny_i : in sl;
69 
70  -- Combined link errors
71  linkErr_i : in sl;
72 
73  -- Synchronous FSM control outputs
74 
75  -- Synchronization request
76  nSync_o : out sl;
77 
78  -- Elastic buffer latency in clock cycles
79  buffLatency_o : out slv(7 downto 0);
80 
81  -- Read enable for Rx Buffer.
82  -- Holds buffers between first data and LMFC
83  readBuff_o : out sl;
84 
85  -- First non comma (K) character detected.
86  -- To indicate when to realign sample within the dataRx.
87  alignFrame_o : out sl;
88 
89  -- Ila frames are being received
90  ila_o : out sl;
91 
92  -- K detected
93  kDetected_o : out sl;
94 
95  -- sysref received
96  sysref_o : out sl;
97 
98  -- Synchronisation process is complete and data is valid
99  dataValid_o : out sl
100 
101  );
102 end JesdSyncFsmRx;
103 
104 architecture rtl of JesdSyncFsmRx is
105 
106  type stateType is (
107  IDLE_S,
108  SYSREF_S,
109  SYNC_S,
110  HOLD_S,
111  ALIGN_S,
112  ILA_S,
113  DATA_S
114  );
115 
116  type RegType is record
117  -- Synchronous FSM control outputs
118  kDetectRegD1: sl;
119  kDetectRegD2: sl;
120  kDetectRegD3: sl;
121 
122  linkErr : sl;
123  nSync : sl;
124  readBuff : sl;
125  alignFrame : sl;
126  Ila : sl;
127  dataValid : sl;
128  sysref : sl;
129  cnt : slv(7 downto 0);
130  cntLatency : slv(7 downto 0);
131 
132  -- Status Machine
133  state : StateType;
134  end record RegType;
135 
136  constant REG_INIT_C : RegType := (
137  kDetectRegD1 => '0',
138  kDetectRegD2 => '0',
139  kDetectRegD3 => '0',
140 
141  linkErr => '0',
142  nSync => '0',
143  readBuff => '0',
144  alignFrame => '0',
145  Ila => '0',
146  dataValid => '0',
147  sysref => '0',
148  cnt => (others => '0'),
149  cntLatency => (others => '0'),
150 
151  -- Status Machine
152  state => IDLE_S
153  );
154 
155  signal r : RegType := REG_INIT_C;
156  signal rin : RegType;
157 
158  signal s_kDetected : sl;
159  signal s_kStable : sl;
160 
161 begin
162 
163  s_kDetected <= detKcharFunc(dataRx_i, chariskRx_i, GT_WORD_SIZE_C);
164  -- Comma detected if detected in three consecutive clock cycles
165  s_kStable <= s_kDetected and r.kDetectRegD1 and r.kDetectRegD2 and r.kDetectRegD3;
166 
167  -- State machine
168  comb : process (rst, r, enable_i,sysRef_i, dataRx_i,subClass_i, chariskRx_i, lmfc_i, nSyncAnyD1_i, nSyncAny_i, linkErr_i, gtReady_i, s_kDetected, s_kStable) is
169  variable v : RegType;
170  begin
171  -- Latch the current value
172  v := r;
173 
174  -- Comma detected pipeline
175  v.kDetectRegD1 := detKcharFunc(dataRx_i, chariskRx_i, GT_WORD_SIZE_C);
176  v.kDetectRegD2 := r.kDetectRegD1;
177  v.kDetectRegD3 := r.kDetectRegD2;
178  --
179  v.linkErr := linkErr_i;
180 
181  -- State Machine
182  case r.state is
183  ----------------------------------------------------------------------
184  when IDLE_S =>
185 
186  -- Outputs
187  v.nSync := '0';
188  v.readBuff := '1';
189  v.alignFrame := '0';
190  v.Ila := '0';
191  v.dataValid := '0';
192  v.sysref := '0';
193  v.cntLatency := (others => '0');
194 
195  -- Next state condition (depending on subclass)
196  if subClass_i = '1' then
197  if sysRef_i = '1' and enable_i = '1' and nSyncAnyD1_i = '0' and gtReady_i = '1' and s_kStable = '1' then
198  v.state := SYSREF_S;
199  end if;
200  else
201  if enable_i = '1' and gtReady_i = '1' and s_kStable = '1' then
202  v.state := SYSREF_S;
203  end if;
204  end if;
205  ----------------------------------------------------------------------
206  when SYSREF_S =>
207 
208  -- Outputs
209  v.nSync := '0';
210  v.readBuff := '1';
211  v.alignFrame := '0';
212  v.Ila := '0';
213  v.dataValid := '0';
214  v.sysref := '1';
215  v.cntLatency := (others => '0');
216 
217  -- Next state condition
218  if s_kDetected = '1' and lmfc_i = '1' then
219  v.state := SYNC_S;
220  elsif enable_i = '0' then
221  v.state := IDLE_S;
222  end if;
223  ----------------------------------------------------------------------
224  when SYNC_S =>
225 
226  -- Outputs
227  v.nSync := '1';
228  v.readBuff := '1';
229  v.alignFrame := '0';
230  v.Ila := '0';
231  v.dataValid := '0';
232  v.sysref := '1';
233  v.cntLatency := (others => '0');
234 
235  -- Next state condition
236  if s_kDetected = '0' then
237  v.state := HOLD_S;
238  -- v.readBuff := '0'; -- TODO this signal has to be applied one c-c earlier for simulation
239  -- But in hardware that is not the case. This should be investigated.
240  elsif enable_i = '0' then
241  v.state := IDLE_S;
242  end if;
243  ----------------------------------------------------------------------
244  when HOLD_S =>
245 
246  -- Outputs
247  v.nSync := '1';
248  v.readBuff := '0';
249  v.alignFrame := '0';
250  v.Ila := '0';
251  v.dataValid := '0';
252  v.sysref := '1';
253  v.cntLatency := r.cntLatency + 1;
254 
255  -- Next state condition
256  if lmfc_i = '1' then
257  v.state := ALIGN_S;
258  elsif enable_i = '0' then
259  v.state := IDLE_S;
260  end if;
261 
262  ----------------------------------------------------------------------
263  when ALIGN_S =>
264 
265  -- Outputs
266  v.nSync := '1';
267  v.readBuff := '1';
268  v.alignFrame := '1';
269  v.Ila := '1';
270  v.dataValid := '0';
271  v.sysref := '1';
272  v.cntLatency := r.cntLatency;
273 
274  -- Put ILA Sequence counter to 0
275  v.cnt := (others => '0');
276 
277  -- Next state condition
278  v.state := ILA_S;
279 
280  ----------------------------------------------------------------------
281  when ILA_S =>
282  -- Outputs
283  v.nSync := '1';
284  v.readBuff := '1';
285  v.alignFrame := '0';
286  v.Ila := '1';
287  v.dataValid := '0';
288  v.sysref := '1';
289  v.cntLatency := r.cntLatency;
290 
291  -- Increase lmfc counter.
292  if (lmfc_i = '1') then
293  v.cnt := r.cnt + 1;
294  end if;
295 
296  -- Next state condition
297  -- After NUM_ILAS_MF_G LMFC clocks the ILA sequence ends and relevant ADC data is being received.
298  if r.cnt = NUM_ILAS_MF_G then
299  v.state := DATA_S;
300  elsif enable_i = '0' or s_kStable = '1' then
301  v.state := IDLE_S;
302  end if;
303  ----------------------------------------------------------------------
304  when DATA_S =>
305  -- Outputs
306  v.nSync := '1';
307  v.readBuff := '1';
308  v.alignFrame := '0';
309  v.Ila := '0';
310  v.dataValid := '1';
311  v.sysref := '1';
312  v.cntLatency := r.cntLatency;
313 
314  -- Next state condition
315  if nSyncAny_i = '0' or r.linkErr = '1' or enable_i = '0' or s_kStable = '1' or gtReady_i = '0' then
316  v.state := IDLE_S;
317  end if;
318  ----------------------------------------------------------------------
319  when others =>
320  -- Outputs
321  v.nSync := '0';
322  v.readBuff := '0';
323  v.alignFrame := '0';
324  v.Ila := '0';
325  v.dataValid := '0';
326  v.sysref := '0';
327  v.cntLatency := (others => '0');
328 
329  -- Next state condition
330  v.state := IDLE_S;
331  ----------------------------------------------------------------------
332  end case;
333 
334  -- Synchronous Reset
335  if rst = '1' then
336  v := REG_INIT_C;
337  end if;
338 
339  -- Register the variable for next clock cycle
340  rin <= v;
341 
342  end process comb;
343 
344  seq : process (clk) is
345  begin
346  if rising_edge(clk) then
347  r <= rin after TPD_G;
348  end if;
349  end process seq;
350 
351  -- Output assignment
352  nSync_o <= r.nSync;
353  readBuff_o <= r.readBuff;
354  alignFrame_o <= r.alignFrame;
355  Ila_o <= r.Ila;
356  dataValid_o <= r.dataValid;
357  kDetected_o <= s_kStable;
358  sysref_o <= r.sysref;
359  buffLatency_o<= r.cntLatency;
360 end rtl;
F_Gpositive := 2
std_logic sl
Definition: StdRtlPkg.vhd:28
out buffLatency_oslv( 7 downto 0)
in dataRx_islv(( GT_WORD_SIZE_C* 8)- 1 downto 0)
NUM_ILAS_MF_Gpositive := 4
K_Gpositive := 32
_library_ ieeeieee
Definition: JesdRxReg.vhd:18
positive := 4 GT_WORD_SIZE_C
Definition: Jesd204bPkg.vhd:31
out alignFrame_osl
out kDetected_osl
in chariskRx_islv( GT_WORD_SIZE_C- 1 downto 0)
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
TPD_Gtime := 1 ns