SURF  1.0
Pgp2bTxPhy.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : Pgp2bTxPhy.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2009-05-27
5 -- Last update: 2017-03-28
6 -------------------------------------------------------------------------------
7 -- Description:
8 -- Physical interface receive module for the Pretty Good Protocol version 2 core.
9 -------------------------------------------------------------------------------
10 -- This file is part of 'SLAC Firmware Standard Library'.
11 -- It is subject to the license terms in the LICENSE.txt file found in the
12 -- top-level directory of this distribution and at:
13 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
14 -- No part of 'SLAC Firmware Standard Library', including this file,
15 -- may be copied, modified, propagated, or distributed except according to
16 -- the terms contained in the LICENSE.txt file.
17 -------------------------------------------------------------------------------
18 
19 LIBRARY ieee;
20 use ieee.std_logic_1164.all;
21 use ieee.std_logic_arith.all;
22 use ieee.std_logic_unsigned.all;
23 use work.StdRtlPkg.all;
24 use work.Pgp2bPkg.all;
25 
26 --! @see entity
27  --! @ingroup protocols_pgp_pgp2b_core
28 entity Pgp2bTxPhy is
29  generic (
30  TPD_G : time := 1 ns;
31  TX_LANE_CNT_G : integer range 1 to 2 := 1 -- Number of receive lanes, 1-2
32  );
33  port (
34 
35  -- System clock, reset & control
36  pgpTxClkEn : in sl := '1'; -- Master clock Enable
37  pgpTxClk : in sl; -- Master clock
38  pgpTxClkRst : in sl; -- Synchronous reset input
39 
40  -- Link is ready
41  pgpTxLinkReady : out sl; -- Local side has link
42 
43  -- Opcode Transmit Interface
44  pgpTxOpCodeEn : in sl; -- Opcode receive enable
45  pgpTxOpCode : in slv(7 downto 0); -- Opcode receive value
46 
47  -- Sideband data
48  pgpLocLinkReady : in sl; -- Far end side has link
49  pgpLocData : in slv(7 downto 0); -- Far end side User Data
50 
51  -- Cell Transmit Interface
52  cellTxSOC : in sl; -- Cell data start of cell
53  cellTxSOF : in sl; -- Cell data start of frame
54  cellTxEOC : in sl; -- Cell data end of cell
55  cellTxEOF : in sl; -- Cell data end of frame
56  cellTxEOFE : in sl; -- Cell data end of frame error
57  cellTxData : in slv(TX_LANE_CNT_G*16-1 downto 0); -- Cell data data
58 
59  -- Physical Interface Signals
60  phyTxData : out slv(TX_LANE_CNT_G*16-1 downto 0); -- PHY receive data
61  phyTxDataK : out slv(TX_LANE_CNT_G*2-1 downto 0); -- PHY receive data is K character
62  phyTxReady : in sl -- PHY receive interface is ready
63  );
64 
65 end Pgp2bTxPhy;
66 
67 
68 -- Define architecture
69 architecture Pgp2bTxPhy of Pgp2bTxPhy is
70 
71  -- Local Signals
72  signal algnCnt : slv(6 downto 0);
73  signal algnCntRst : sl;
74  signal intTxLinkReady : sl;
75  signal nxtTxLinkReady : sl;
76  signal nxtTxData : slv(TX_LANE_CNT_G*16-1 downto 0);
77  signal nxtTxDataK : slv(TX_LANE_CNT_G*2-1 downto 0);
78  signal dlyTxData : slv(TX_LANE_CNT_G*16-1 downto 0);
79  signal dlyTxDataK : slv(TX_LANE_CNT_G*2-1 downto 0);
80  signal dlySelect : sl;
81  signal intTxData : slv(TX_LANE_CNT_G*16-1 downto 0);
82  signal intTxDataK : slv(TX_LANE_CNT_G*2-1 downto 0);
83  signal intTxOpCode : slv(7 downto 0);
84  signal intTxOpCodeEn : sl;
85  signal skpAData : slv(TX_LANE_CNT_G*16-1 downto 0);
86  signal skpADataK : slv(TX_LANE_CNT_G*2-1 downto 0);
87  signal skpBData : slv(TX_LANE_CNT_G*16-1 downto 0);
88  signal skpBDataK : slv(TX_LANE_CNT_G*2-1 downto 0);
89  signal alnAData : slv(TX_LANE_CNT_G*16-1 downto 0);
90  signal alnADataK : slv(TX_LANE_CNT_G*2-1 downto 0);
91  signal alnBData : slv(TX_LANE_CNT_G*16-1 downto 0);
92  signal alnBDataK : slv(TX_LANE_CNT_G*2-1 downto 0);
93  signal ltsAData : slv(TX_LANE_CNT_G*16-1 downto 0);
94  signal ltsADataK : slv(TX_LANE_CNT_G*2-1 downto 0);
95  signal ltsBData : slv(TX_LANE_CNT_G*16-1 downto 0);
96  signal ltsBDataK : slv(TX_LANE_CNT_G*2-1 downto 0);
97  signal cellData : slv(TX_LANE_CNT_G*16-1 downto 0);
98  signal cellDataK : slv(TX_LANE_CNT_G*2-1 downto 0);
99  signal dlyTxEOC : sl;
100 
101  -- Physical Link State
102  constant ST_LOCK_C : slv(3 downto 0) := "0000";
103  constant ST_SKP_A_C : slv(3 downto 0) := "0001";
104  constant ST_SKP_B_C : slv(3 downto 0) := "0010";
105  constant ST_LTS_A_C : slv(3 downto 0) := "0011";
106  constant ST_LTS_B_C : slv(3 downto 0) := "0100";
107  constant ST_ALN_A_C : slv(3 downto 0) := "0101";
108  constant ST_ALN_B_C : slv(3 downto 0) := "0110";
109  constant ST_CELL_C : slv(3 downto 0) := "0111";
110  constant ST_EMPTY_C : slv(3 downto 0) := "1000";
111  signal curState : slv(3 downto 0);
112  signal nxtState : slv(3 downto 0);
113 
114 begin
115 
116  -- Link status
118 
119  -- State transition sync logic.
120  process ( pgpTxClk ) begin
121  if rising_edge(pgpTxClk) then
122  if pgpTxClkRst = '1' then
123  curState <= ST_LOCK_C after TPD_G;
124  algnCnt <= (others=>'0') after TPD_G;
125  intTxLinkReady <= '0' after TPD_G;
126  intTxOpCode <= (others=>'0') after TPD_G;
127  intTxOpCodeEn <= '0' after TPD_G;
128  elsif pgpTxClkEn = '1' then
129  -- Opcode Transmit
130  if pgpTxOpCodeEn = '1' then
131  intTxOpCode <= pgpTxOpCode after TPD_G;
132  end if;
134 
135  -- Status signal
137 
138  -- PLL Lock is lost
139  if phyTxReady = '0' then
140  curState <= ST_LOCK_C after TPD_G;
141  else
142  curState <= nxtState after TPD_G;
143  end if;
144 
145  -- Cell Counter
146  if algnCntRst = '1' then
147  algnCnt <= (others=>'1') after TPD_G;
148  elsif algnCnt /= 0 and cellTxEOC = '1' then
149  algnCnt <= algnCnt - 1 after TPD_G;
150  end if;
151  end if;
152  end if;
153  end process;
154 
155 
156  -- Link control state machine
160  case curState is
161 
162  -- Wait for lock state
163  when ST_LOCK_C =>
164  algnCntRst <= '1';
165  nxtTxLinkReady <= '0';
166  nxtTxData <= (others=>'0');
167  nxtTxDataK <= (others=>'0');
168  nxtState <= ST_SKP_A_C;
169 
170  -- Transmit SKIP word A
171  when ST_SKP_A_C =>
172  nxtTxData <= skpAData;
174  algnCntRst <= '0';
176  nxtState <= ST_SKP_B_C;
177 
178  -- Transmit SKIP word B
179  when ST_SKP_B_C =>
180  nxtTxData <= skpBData;
182  algnCntRst <= '0';
184  nxtState <= ST_LTS_A_C;
185 
186  -- Transmit Align word A
187  when ST_ALN_A_C =>
188  nxtTxData <= alnAData;
190  algnCntRst <= '0';
192  nxtState <= ST_ALN_B_C;
193 
194  -- Transmit Align word B
195  when ST_ALN_B_C =>
196  nxtTxData <= alnBData;
198  algnCntRst <= '0';
200  nxtState <= ST_LTS_A_C;
201 
202  -- Transmit Link Training word A
203  when ST_LTS_A_C =>
204  nxtTxData <= ltsAData;
206  algnCntRst <= '0';
208  nxtState <= ST_LTS_B_C;
209 
210  -- Transmit Link Training word B
211  when ST_LTS_B_C =>
212  nxtTxData <= ltsBData;
214  algnCntRst <= '0';
215  nxtTxLinkReady <= '1';
216  nxtState <= ST_CELL_C;
217 
218  -- Transmit Cell Data
219  when ST_CELL_C =>
220  nxtTxLinkReady <= '1';
221  nxtTxData <= cellData;
223  algnCntRst <= '0';
224 
225  -- State transition
226  if cellTxEOC = '1' then
227  nxtState <= ST_EMPTY_C;
228  else
229  nxtState <= curState;
230  end if;
231 
232  -- Empty location, used to re-adjust delay pipeline
233  when ST_EMPTY_C =>
234  nxtTxLinkReady <= '1';
235  nxtTxData <= (others=>'0');
236  nxtTxDataK <= (others=>'0');
237 
238  -- After enough cells send alignment word
239  if algnCnt = 0 then
240  algnCntRst <= '1';
241  nxtState <= ST_ALN_A_C;
242  else
243  algnCntRst <= '0';
244  nxtState <= ST_SKP_A_C;
245  end if;
246 
247  -- Default state
248  when others =>
249  algnCntRst <= '0';
250  nxtTxLinkReady <= '0';
251  nxtTxData <= (others=>'0');
252  nxtTxDataK <= (others=>'0');
253  nxtState <= ST_LOCK_C;
254  end case;
255  end process;
256 
257 
258  -- Generate Data
259  GEN_DATA: for i in 0 to (TX_LANE_CNT_G-1) generate
260 
261  -- Skip word A
262  skpAData(i*16+7 downto i*16) <= K_COM_C;
263  skpADataK(i*2) <= '1';
264  skpAData(i*16+15 downto i*16+8) <= K_SKP_C;
265  skpADataK(i*2+1) <= '1';
266 
267  -- Skip word B
268  skpBData(i*16+7 downto i*16) <= K_SKP_C;
269  skpBDataK(i*2) <= '1';
270  skpBData(i*16+15 downto i*16+8) <= K_SKP_C;
271  skpBDataK(i*2+1) <= '1';
272 
273  -- Alignment Word A
274  alnAData(i*16+7 downto i*16) <= K_COM_C;
275  alnADataK(i*2) <= '1';
276  alnAData(i*16+15 downto i*16+8) <= K_ALN_C;
277  alnADataK(i*2+1) <= '1';
278 
279  -- Alignment Word B
280  alnBData(i*16+7 downto i*16) <= K_ALN_C;
281  alnBDataK(i*2) <= '1';
282  alnBData(i*16+15 downto i*16+8) <= K_ALN_C;
283  alnBDataK(i*2+1) <= '1';
284 
285  -- Link Training Word A
286  ltsAData(i*16+7 downto i*16) <= K_LTS_C;
287  ltsADataK(i*2) <= '1';
288  ltsAData(i*16+15 downto i*16+8) <= D_102_C;
289  ltsADataK(i*2+1) <= '0';
290 
291  -- Link Training Word B
292  ltsBData(i*16+7 downto i*16) <= pgpLocData;
293  ltsBDataK(i*2) <= '0';
294  ltsBData(i*16+14) <= '0'; -- Spare
295  ltsBData(i*16+13 downto i*16+12) <= conv_std_logic_vector(TX_LANE_CNT_G-1,2);
296  ltsBData(i*16+11 downto i*16+8) <= PGP2B_ID_C;
297  ltsBData(i*16+15) <= pgpLocLinkReady;
298  ltsBDataK(i*2+1) <= '0';
299 
300  -- Cell Data, lower byte
301  cellData(i*16+7 downto i*16) <= K_SOF_C when cellTxSOF = '1' else
302  K_SOC_C when cellTxSOC = '1' else
303  K_EOFE_C when cellTxEOFE = '1' else
304  K_EOF_C when cellTxEOF = '1' else
305  K_EOC_C when cellTxEOC = '1' else
306  cellTxData(i*16+7 downto i*16);
307 
308  -- Cell Data, upper byte
309  cellData(i*16+15 downto i*16+8) <= cellTxData(i*16+15 downto i*16+8);
310 
311  -- Cell Data, lower control
312  cellDataK(i*2) <= '1' when cellTxSOF = '1' or cellTxSOC = '1' or cellTxEOFE = '1' or
313  cellTxEOF = '1' or cellTxEOC = '1' else '0';
314 
315  -- Cell Data, upper control
316  cellDataK(i*2+1) <= '0';
317  end generate;
318 
319 
320  -- Delay chain select, used when an opcode is transmitted.
321  -- opcode will overwrite current position and delay chain will
322  -- be selected until an EOC is transmitted. At that time the
323  -- non-delayed chain will be select. An empty position is inserted
324  -- after EOC so that valid opcodes are not lost.
325  process ( pgpTxClk ) begin
326  if rising_edge(pgpTxClk) then
327  if pgpTxClkRst = '1' then
328  dlySelect <= '0' after TPD_G;
329  dlyTxEOC <= '0' after TPD_G;
330  elsif pgpTxClkEn = '1' then
331  -- Choose delay chain when opcode is transmitted
332  if intTxOpCodeEn = '1' then
333  dlySelect <= '1' after TPD_G;
334 
335  -- Reset delay chain when delayed EOC is transmitted
336  elsif dlyTxEOC = '1' then
337  dlySelect <= '0' after TPD_G;
338  end if;
339 
340  -- Delayed copy of EOC
341  dlyTxEOC <= cellTxEOC after TPD_G;
342 
343  end if;
344  end if;
345  end process;
346 
347 
348  -- Outgoing data
349  GEN_OUT: for i in 0 to (TX_LANE_CNT_G-1) generate
350  process ( pgpTxClk ) begin
351  if rising_edge(pgpTxClk) then
352  if pgpTxClkRst = '1' then
353  intTxData(i*16+15 downto i*16) <= (others=>'0') after TPD_G;
354  intTxDataK(i*2+1 downto i*2) <= (others=>'0') after TPD_G;
355  dlyTxData(i*16+15 downto i*16) <= (others=>'0') after TPD_G;
356  dlyTxDataK(i*2+1 downto i*2) <= (others=>'0') after TPD_G;
357  elsif pgpTxClkEn = '1' then
358  -- Delayed copy of data
359  dlyTxData(i*16+15 downto i*16) <= nxtTxData(i*16+15 downto i*16) after TPD_G;
360  dlyTxDataK(i*2+1 downto i*2) <= nxtTxDataK(i*2+1 downto i*2) after TPD_G;
361 
362  -- PLL Lock is lost
363  if phyTxReady = '0' then
364  intTxData(i*16+15 downto i*16) <= (others=>'0') after TPD_G;
365  intTxDataK(i*2+1 downto i*2) <= (others=>'0') after TPD_G;
366  else
367 
368  -- Delayed data, opcode transmission is not allowed until delay line resets
369  if dlySelect = '1' then
370  intTxData(i*16+15 downto i*16) <= dlyTxData(i*16+15 downto i*16) after TPD_G;
371  intTxDataK(i*2+1 downto i*2) <= dlyTxDataK(i*2+1 downto i*2) after TPD_G;
372 
373  -- Transmit opcode
374  elsif intTxOpCodeEn = '1' then
375  intTxData(i*16+7 downto i*16) <= K_OTS_C after TPD_G;
376  intTxDataK(i*2) <= '1' after TPD_G;
377  intTxData(i*16+15 downto i*16+8) <= intTxOpCode after TPD_G;
378  intTxDataK(i*2+1) <= '0' after TPD_G;
379 
380  -- Nornal Data
381  else
382  intTxData(i*16+15 downto i*16) <= nxtTxData(i*16+15 downto i*16) after TPD_G;
383  intTxDataK(i*2+1 downto i*2) <= nxtTxDataK(i*2+1 downto i*2) after TPD_G;
384  end if;
385  end if;
386  end if;
387  end if;
388  end process;
389  end generate;
390 
391  -- Outgoing data
392  phyTxData <= intTxData;
394 
395 end Pgp2bTxPhy;
396 
slv( 6 downto 0) algnCnt
Definition: Pgp2bTxPhy.vhd:72
slv( TX_LANE_CNT_G* 16- 1 downto 0) ltsBData
Definition: Pgp2bTxPhy.vhd:95
slv( TX_LANE_CNT_G* 2- 1 downto 0) nxtTxDataK
Definition: Pgp2bTxPhy.vhd:77
slv( 7 downto 0) intTxOpCode
Definition: Pgp2bTxPhy.vhd:83
TPD_Gtime := 1 ns
Definition: Pgp2bTxPhy.vhd:30
std_logic sl
Definition: StdRtlPkg.vhd:28
slv( 7 downto 0) := "11111011" K_SOC_C
Definition: Pgp2bPkg.vhd:42
slv( 3 downto 0) := "1000" ST_EMPTY_C
Definition: Pgp2bTxPhy.vhd:110
in cellTxSOFsl
Definition: Pgp2bTxPhy.vhd:53
slv( TX_LANE_CNT_G* 16- 1 downto 0) dlyTxData
Definition: Pgp2bTxPhy.vhd:78
in cellTxDataslv( TX_LANE_CNT_G* 16- 1 downto 0)
Definition: Pgp2bTxPhy.vhd:57
out pgpTxLinkReadysl
Definition: Pgp2bTxPhy.vhd:41
in pgpTxClkRstsl
Definition: Pgp2bTxPhy.vhd:38
in phyTxReadysl
Definition: Pgp2bTxPhy.vhd:63
slv( 7 downto 0) := "11111101" K_EOF_C
Definition: Pgp2bPkg.vhd:44
slv( TX_LANE_CNT_G* 16- 1 downto 0) nxtTxData
Definition: Pgp2bTxPhy.vhd:76
slv( 3 downto 0) curState
Definition: Pgp2bTxPhy.vhd:111
slv( 7 downto 0) := "01011100" K_EOC_C
Definition: Pgp2bPkg.vhd:46
in pgpTxClkEnsl := '1'
Definition: Pgp2bTxPhy.vhd:36
slv( TX_LANE_CNT_G* 16- 1 downto 0) skpAData
Definition: Pgp2bTxPhy.vhd:85
in pgpTxOpCodeslv( 7 downto 0)
Definition: Pgp2bTxPhy.vhd:45
slv( TX_LANE_CNT_G* 16- 1 downto 0) intTxData
Definition: Pgp2bTxPhy.vhd:81
slv( 7 downto 0) := "00111100" K_LTS_C
Definition: Pgp2bPkg.vhd:36
slv( 7 downto 0) := "01111100" K_OTS_C
Definition: Pgp2bPkg.vhd:40
slv( 3 downto 0) := "0110" ST_ALN_B_C
Definition: Pgp2bTxPhy.vhd:108
slv( 3 downto 0) := "0011" ST_LTS_A_C
Definition: Pgp2bTxPhy.vhd:105
slv( TX_LANE_CNT_G* 16- 1 downto 0) alnAData
Definition: Pgp2bTxPhy.vhd:89
slv( TX_LANE_CNT_G* 2- 1 downto 0) dlyTxDataK
Definition: Pgp2bTxPhy.vhd:79
slv( 3 downto 0) := "0101" ST_ALN_A_C
Definition: Pgp2bTxPhy.vhd:107
slv( 7 downto 0) := "11110111" K_SOF_C
Definition: Pgp2bPkg.vhd:43
slv( TX_LANE_CNT_G* 2- 1 downto 0) skpBDataK
Definition: Pgp2bTxPhy.vhd:88
slv( TX_LANE_CNT_G* 2- 1 downto 0) skpADataK
Definition: Pgp2bTxPhy.vhd:86
slv( 7 downto 0) := "11111110" K_EOFE_C
Definition: Pgp2bPkg.vhd:45
in pgpLocLinkReadysl
Definition: Pgp2bTxPhy.vhd:48
TX_LANE_CNT_Ginteger range 1 to 2:= 1
Definition: Pgp2bTxPhy.vhd:32
slv( TX_LANE_CNT_G* 16- 1 downto 0) alnBData
Definition: Pgp2bTxPhy.vhd:91
slv( 3 downto 0) := "0001" ST_SKP_A_C
Definition: Pgp2bTxPhy.vhd:103
slv( 7 downto 0) := "10111100" K_COM_C
Definition: Pgp2bPkg.vhd:35
out phyTxDataKslv( TX_LANE_CNT_G* 2- 1 downto 0)
Definition: Pgp2bTxPhy.vhd:61
in cellTxSOCsl
Definition: Pgp2bTxPhy.vhd:52
slv( TX_LANE_CNT_G* 16- 1 downto 0) ltsAData
Definition: Pgp2bTxPhy.vhd:93
slv( 7 downto 0) := "01001010" D_102_C
Definition: Pgp2bPkg.vhd:37
slv( TX_LANE_CNT_G* 16- 1 downto 0) cellData
Definition: Pgp2bTxPhy.vhd:97
in cellTxEOCsl
Definition: Pgp2bTxPhy.vhd:54
slv( TX_LANE_CNT_G* 2- 1 downto 0) alnBDataK
Definition: Pgp2bTxPhy.vhd:92
slv( TX_LANE_CNT_G* 2- 1 downto 0) alnADataK
Definition: Pgp2bTxPhy.vhd:90
_library_ ieeeieee
Definition: Pgp2bTxCell.vhd:19
slv( 7 downto 0) := "11011100" K_ALN_C
Definition: Pgp2bPkg.vhd:41
slv( TX_LANE_CNT_G* 16- 1 downto 0) skpBData
Definition: Pgp2bTxPhy.vhd:87
in pgpLocDataslv( 7 downto 0)
Definition: Pgp2bTxPhy.vhd:49
slv( TX_LANE_CNT_G* 2- 1 downto 0) cellDataK
Definition: Pgp2bTxPhy.vhd:98
slv( 7 downto 0) := "00011100" K_SKP_C
Definition: Pgp2bPkg.vhd:39
slv( TX_LANE_CNT_G* 2- 1 downto 0) ltsBDataK
Definition: Pgp2bTxPhy.vhd:96
in pgpTxClksl
Definition: Pgp2bTxPhy.vhd:37
in cellTxEOFsl
Definition: Pgp2bTxPhy.vhd:55
slv( 3 downto 0) := "0111" ST_CELL_C
Definition: Pgp2bTxPhy.vhd:109
slv( 3 downto 0) nxtState
Definition: Pgp2bTxPhy.vhd:112
in cellTxEOFEsl
Definition: Pgp2bTxPhy.vhd:56
out phyTxDataslv( TX_LANE_CNT_G* 16- 1 downto 0)
Definition: Pgp2bTxPhy.vhd:60
slv( 3 downto 0) := "0000" ST_LOCK_C
Definition: Pgp2bTxPhy.vhd:102
slv( 3 downto 0) := "0100" ST_LTS_B_C
Definition: Pgp2bTxPhy.vhd:106
slv( 3 downto 0) := "0101" PGP2B_ID_C
Definition: Pgp2bPkg.vhd:49
slv( TX_LANE_CNT_G* 2- 1 downto 0) intTxDataK
Definition: Pgp2bTxPhy.vhd:82
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
slv( TX_LANE_CNT_G* 2- 1 downto 0) ltsADataK
Definition: Pgp2bTxPhy.vhd:94
in pgpTxOpCodeEnsl
Definition: Pgp2bTxPhy.vhd:44
slv( 3 downto 0) := "0010" ST_SKP_B_C
Definition: Pgp2bTxPhy.vhd:104