SURF  1.0
GtpRxCommaAligner.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : GtpPgpWordAligner.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2012-11-06
5 -- Last update: 2013-07-15
6 -------------------------------------------------------------------------------
7 -- Description: Pgp2 Gtp Word aligner
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 --! @see entity
23  --! @ingroup xilinx_Virtex5_gtp
25 
26  generic (
27  TPD_G : time := 1 ns);
28 
29  port (
30  gtpRxUsrClk2 : in std_logic;
31  gtpRxUsrClk2Rst : in std_logic;
32  gtpRxData : in std_logic_vector(19 downto 0);
33  codeErr : in std_logic_vector(1 downto 0);
34  dispErr : in std_logic_vector(1 downto 0);
35  gtpRxUsrClk2Sel : out std_logic; -- Select phase of usrclk2
36  gtpRxSlide : out std_logic;
37  gtpRxCdrReset : out std_logic;
38  aligned : out std_logic);
39 
40 end entity GtpRxCommaAligner;
41 
42 architecture rtl of GtpRxCommaAligner is
43 
44  constant RAW_COMMA_C : std_logic_vector(9 downto 0) := "0101111100";
45 
46  type StateType is (SEARCH_S, RESET_S, SLIDE_S, SLIDE_WAIT_0_S, SLIDE_WAIT_1_S, WAIT_SETTLE_S, ALIGNED_S);
47 
48  type RegType is record
49  state : StateType;
50  last : std_logic_vector(9 downto 0);
51  slideCount : unsigned(2 downto 0);
52  waitCounter : unsigned(4 downto 0);
53 
54  -- Outputs
55  gtpRxUsrClk2Sel : std_logic; -- Select phase of usrclk2
56  gtpRxSlide : std_logic;
57  gtpRxCdrReset : std_logic;
58  aligned : std_logic;
59  end record RegType;
60 
61  signal r, rin : RegType;
62 
63 begin
64 
65  seq : process (gtpRxUsrClk2, gtpRxUsrClk2Rst) is
66  begin
67  if (gtpRxUsrClk2Rst = '1') then
68  r.state <= SEARCH_S after TPD_G;
69  r.last <= (others => '0') after TPD_G;
70  r.slideCount <= (others => '0') after TPD_G;
71  r.waitCounter <= (others => '0') after TPD_G;
72 
73  r.gtpRxUsrClk2Sel <= '0' after TPD_G;
74  r.gtpRxSlide <= '0' after TPD_G;
75  r.gtpRxCdrReset <= '0' after TPD_G;
76  r.aligned <= '0' after TPD_G;
77  elsif (rising_edge(gtpRxUsrClk2)) then
78  r <= rin after TPD_G;
79  end if;
80  end process;
81 
82  comb : process (r, gtpRxData, codeErr, dispErr) is
83  variable v : RegType;
84  variable searchVar : std_logic_vector(29 downto 0);
85  begin
86  v := r;
87 
88  v.gtpRxCdrReset := '0';
89  v.gtpRxSlide := '0';
90  v.aligned := '0';
91 
92  v.last := gtpRxData(19 downto 10); -- Save high byte
93  searchVar := gtpRxData & r.last;
94 
95  case r.state is
96  when SEARCH_S =>
97  for i in 0 to 20 loop
98  -- Look for pos or neg comma
99  if (searchVar((i+9) downto i) = RAW_COMMA_C or searchVar(i+9 downto i) = not RAW_COMMA_C) then
100  if (i = 2 or i = 4 or i = 6 or i = 8 or i = 0) then
101 -- v.slideCount := to_unsigned(9-i, 3);
102 -- v.state := SLIDE_S;
103  v.gtpRxUsrClk2Sel := not r.gtpRxUsrClk2Sel; -- Invert clock
104  elsif (i = 12 or i = 14 or i = 16 or i = 18) then
105  v.slideCount := to_unsigned(i-11, 3);
106  v.state := SLIDE_S;
107  -- Not sure if this can be done here.
108  -- Might want some wait time before starting slides
109 
110  elsif (i = 10) then
111  v.state := ALIGNED_S;
112  else
113  -- else reset the rx and hope for a new lock requiring an even number of slides
114  v.gtpRxCdrReset := '1';
115  v.state := RESET_S;
116  end if;
117  end if;
118  end loop;
119 
120  when RESET_S =>
121  v.gtpRxCdrReset := '1';
122  -- Async reset will eventually get everything back to SEARCH_S state
123 
124  when SLIDE_S =>
125  v.gtpRxSlide := '1';
126  v.state := SLIDE_WAIT_0_S;
127 
128  when SLIDE_WAIT_0_S =>
129  v.slideCount := r.slideCount - 1;
130  if (r.slideCount = 0) then
131  v.slideCount := (others => '0');
132  v.state := WAIT_SETTLE_S;
133  else
134  v.state := SLIDE_WAIT_1_S;
135  end if;
136 
137  when SLIDE_WAIT_1_S =>
138  v.state := SLIDE_S;
139 
140  when WAIT_SETTLE_S =>
141  -- All the rxslide assertions take some time
142  v.waitCounter := r.waitCounter + 1;
143  if (r.waitCounter = "11111") then
144  v.state := SEARCH_S; -- Double check that the slides worked
145  end if;
146 
147  when ALIGNED_S =>
148  v.aligned := '1';
149  -- Reuse wait counter to count 8b10b errors
150  -- After several errors, reset
151  if (codeErr /= "00" or dispErr /= "00") then
152  v.waitCounter := r.waitCounter + 1;
153  end if;
154  if (r.waitCounter = "11111") then
155  v.state := RESET_S;
156  end if;
157 
158  end case;
159 
160  rin <= v;
161 
163  gtpRxSlide <= r.gtpRxSlide;
165  aligned <= r.aligned;
166 
167  end process comb;
168 
169 end architecture rtl;
out gtpRxSlidestd_logic
in gtpRxDatastd_logic_vector( 19 downto 0)
out alignedstd_logic
out gtpRxUsrClk2Selstd_logic
in dispErrstd_logic_vector( 1 downto 0)
out gtpRxCdrResetstd_logic
in gtpRxUsrClk2Rststd_logic
in codeErrstd_logic_vector( 1 downto 0)
in gtpRxUsrClk2std_logic