SURF  1.0
JesdAlignFrRepCh.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : JesdAlignFrRepCh.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2015-04-15
5 -- Last update: 2016-02-12
6 -------------------------------------------------------------------------------
7 -- Description: Align bytes and replace control characters with data
8 --
9 -- What is supported:
10 -- Frame sizes 1, 2, 4
11 -- GT Word sizes 2, 4 <--- I don't think 2 word is supported because hard coded in Jesd204bPkg.vhd
12 --
13 -- Note:
14 -- dataRx_i - is little endian and byte-swapped (directly from GTH)
15 -- First sample in time: dataRx_i(7 downto 0) & dataRx_i(15 downto 8)
16 -- Second sample in time: dataRx_i(23 downto 16)& dataRx_i(31 downto 24)
17 --
18 -- sampleData_o is big endian and not byte-swapped
19 -- First sample in time: sampleData_o(31 downto 16)
20 -- Second sample in time: sampleData_o(15 downto 0)
21 -------------------------------------------------------------------------------
22 -- This file is part of 'SLAC Firmware Standard Library'.
23 -- It is subject to the license terms in the LICENSE.txt file found in the
24 -- top-level directory of this distribution and at:
25 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
26 -- No part of 'SLAC Firmware Standard Library', including this file,
27 -- may be copied, modified, propagated, or distributed except according to
28 -- the terms contained in the LICENSE.txt file.
29 -------------------------------------------------------------------------------
30 
31 library ieee;
32 use ieee.std_logic_1164.all;
33 use ieee.std_logic_unsigned.all;
34 use ieee.std_logic_arith.all;
35 
36 use work.StdRtlPkg.all;
37 use work.Jesd204bPkg.all;
38 
39 --! @see entity
40  --! @ingroup protocols_jesd204b
42  generic (
43  TPD_G : time := 1 ns;
44 
45  -- Number of bytes in a frame
46  F_G : positive := 2);
47  port (
48  clk : in sl;
49  rst : in sl;
50 
51  -- Enable character replacement
53 
54  -- Enable scrambling/descrambling
56 
57  -- One c-c long pulse from syncFSM indicating that first non K
58  -- character has been received
60 
61  -- Data ready (replace control character with data when '1')
63 
64  -- Data and character indication
65  dataRx_i : in slv((GT_WORD_SIZE_C*8)-1 downto 0);
66  chariskRx_i : in slv(GT_WORD_SIZE_C-1 downto 0);
67 
68  -- Sample data output (after alignment, character replacement and scrambling)
69  sampleData_o : out slv((GT_WORD_SIZE_C*8)-1 downto 0);
71 
72  -- Alignment and sync position errors
73  alignErr_o : out sl; -- Invalid or misaligned character in the data
74  positionErr_o : out sl -- Invalid (comma) position received at time of alignment
75  );
76 end entity JesdAlignFrRepCh;
77 
78 architecture rtl of JesdAlignFrRepCh is
79  -- How many samples is in a GT word
80  constant SAMPLES_IN_WORD_C : positive := (GT_WORD_SIZE_C/F_G);
81 
82  type RegType is record
83  dataRxD1 : slv(dataRx_i'range);
84  chariskRxD1 : slv(chariskRx_i'range);
85  dataAlignedD1 : slv(dataRx_i'range);
86  charAlignedD1 : slv(chariskRx_i'range);
87  scrData : slv(sampleData_o'range);
88  scrDataValid : sl;
89  lfsr : slv((GT_WORD_SIZE_C*8)-1 downto 0);
90  descrData : slv((GT_WORD_SIZE_C*8)-1 downto 0);
91  descrDataValid: sl;
92  sampleData : slv(sampleData_o'range);
93  dataValid : sl;
94  position : slv(chariskRx_i'range);
95  end record RegType;
96 
97  constant REG_INIT_C : RegType := (
98  dataRxD1 => (others => '0'),
99  chariskRxD1 => (others => '0'),
100  dataAlignedD1 => (others => '0'),
101  charAlignedD1 => (others => '0'),
102  scrData => (others => '0'),
103  lfsr => (others => '0'),
104  descrData => (others => '0'),
105  scrDataValid => '0',
106  sampleData => (others => '0'),
107  descrDataValid => '0',
108  dataValid => '0',
109  position => intToSlv(1, GT_WORD_SIZE_C) -- Initialize at "0001" or "01"
110  );
111 
112  signal r : RegType := REG_INIT_C;
113  signal rin : RegType;
114 
115 
116 begin
117  -- Buffer two GT words (Sequential logic)
118  -- Register the alignment position when alignFrame_i pulse
119  -- Incorrect alignment (non valid data word received) will result in
120  -- v.position = (others => '1')
121  ---------------------------------------------------------------------
122  ---------------------------------------------------------------------
124  variable v : RegType;
125 
126  -- Alignment error. Invalid data received at time of alignment
127  variable v_positionErr : sl;
128  variable v_alignErr : sl;
129  variable v_twoWordbuff : slv((GT_WORD_SIZE_C*16)-1 downto 0);
130  variable v_twoCharBuff : slv((GT_WORD_SIZE_C*2) -1 downto 0);
131  variable v_twoWordbuffAl : slv((GT_WORD_SIZE_C*16)-1 downto 0);
132  variable v_twoCharBuffAl : slv((GT_WORD_SIZE_C*2) -1 downto 0);
133  variable v_dataaligned : slv(dataRx_i'range);
134  variable v_charAligned : slv(chariskRx_i'range);
135 
136  begin
137  v := r;
138 
139  -- Buffer data and char one clock cycle
140  v.dataRxD1 := dataRx_i;
141  v.chariskRxD1 := chariskRx_i;
142 
143  -- Buffer aligned data
144  v.dataAlignedD1 := v_dataAligned;
145  v.charAlignedD1 := v_charAligned;
146 
147  -- Register the alignment
148  if (alignFrame_i = '1') then
149  v.position := detectPosFuncSwap(dataRx_i, chariskRx_i, GT_WORD_SIZE_C);
150  end if;
151 
152  -- Align samples (Combinatorial logic)
153 
154  -- Check position error (if position vector "1111" is returned)
155  v_positionErr := ite(allBits (r.position, '1'), '1', '0');
156 
157  -- Byte swap and combine the two consecutive GT words
158  v_twoWordBuff := byteSwapSlv(r.dataRxD1, GT_WORD_SIZE_C) & byteSwapSlv(dataRx_i, GT_WORD_SIZE_C);
159  v_twoCharBuff := bitReverse(r.chariskRxD1) & bitReverse(chariskRx_i);
160 
161  -- Align the bytes within the words
162  v_dataAligned := JesdDataAlign(v_twoWordBuff, r.position, GT_WORD_SIZE_C);
163  v_charAligned := JesdCharAlign(v_twoCharBuff, r.position, GT_WORD_SIZE_C);
164 
165  -- Buffer aligned word and replace the alignment characters with the data
166  v_twoWordBuffAl := r.dataAlignedD1 & v_dataAligned;
167  v_twoCharBuffAl := r.charAlignedD1 & v_charAligned;
168  v_alignErr := '0';
169 
170  -- Replace the control characters in the data with valid data
171  if(replEnable_i = '1' and dataValid_i = '1') then
172  for I in (SAMPLES_IN_WORD_C-1) downto 0 loop
173  -- If the A_CHAR_C or F_CHAR_C characters detected in the stream
174  if (v_twoCharBuffAl(I*F_G) = '1' and
175  (v_twoWordBuffAl((I*F_G*8+7) downto I*F_G*8) = A_CHAR_C or
176  v_twoWordBuffAl((I*F_G*8+7) downto I*F_G*8) = F_CHAR_C)
177  ) then
178  -- If scrambling disabled
179  -- Replace the character in the data with the data value from previous frame
180  if (scrEnable_i = '0') then
181  v_twoWordBuffAl((I*F_G*8+7) downto I*F_G*8) := v_twoWordBuffAl((I*F_G*8+8*F_G)+7 downto (I*F_G*8+8*F_G));
182  v_twoCharBuffAl(I*F_G) := '0';
183  -- If scrambling enabled
184  -- The data value equals char value and only the char flags are cleared
185  else
186  v_twoWordBuffAl := v_twoWordBuffAl;
187  v_twoCharBuffAl(I*F_G) := '0';
188  end if;
189  end if;
190  end loop;
191  end if;
192 
193  -- Check character if there are still characters in the data and issue the alignment error
194  -- The error indicates that the characters in the data are possibly misplaced or wrong characters
195  -- have been received.
196  if(replEnable_i = '1' and dataValid_i = '1') then
197  for I in (GT_WORD_SIZE_C-1) downto 0 loop
198  if (v_twoCharBuffAl(I) = '1') then
199  v_alignErr := '1';
200  end if;
201  end loop;
202  end if;
203 
204  -- Register data before scrambling
205  v.scrData := v_twoWordBuffAl((GT_WORD_SIZE_C*8)-1 downto 0);
206  v.scrDataValid := dataValid_i;
207  v.descrDataValid := r.scrDataValid;
208 
209  -- Descramble data put data into descrambler MSB first
210  -- Start descrambling when data is enabled
211  if (scrEnable_i = '1' and r.scrDataValid = '1') then
212  for i in (GT_WORD_SIZE_C*8)-1 downto 0 loop
213  v.lfsr := v.lfsr(v.lfsr'left-1 downto v.lfsr'right) & r.scrData(i);
214  --
215  v.descrData(i) := r.scrData(i);
216  for j in JESD_PRBS_TAPS_C'range loop
217  v.descrData(i) := v.descrData(i) xor v.lfsr(JESD_PRBS_TAPS_C(j));
218  end loop;
219  --
220  end loop;
221  else
222  v.descrData := r.scrData;
223  end if;
224 
225  -- Register sample data before output (Prevent timing issues! Adds one clock cycle to latency!)
226  if (scrEnable_i = '1') then
227  -- 3 c-c latency
228  v.sampleData := r.descrData;
229  v.dataValid := r.descrDataValid;
230  else
231  -- 1 c-c latency
232  v.sampleData := v_twoWordBuffAl((GT_WORD_SIZE_C*8)-1 downto 0);
233  v.dataValid := dataValid_i;
234  end if;
235 
236  if (rst = '1') then
237  v := REG_INIT_C;
238  end if;
239 
240  --
241  rin <= v;
242 
243  -- Output assignment
244  positionErr_o <= v_positionErr;
245  alignErr_o <= v_alignErr;
246  sampleData_o <= r.sampleData;
247  sampleDataValid_o <= r.dataValid;
248  -----------------------------------------------------------
249  end process comb;
250 
251  seq : process (clk) is
252  begin
253  if (rising_edge(clk)) then
254  r <= rin after TPD_G;
255  end if;
256  end process seq;
257  ---------------------------------------------------------------------
258  ---------------------------------------------------------------------
259 
260 end architecture rtl;
in chariskRx_islv( GT_WORD_SIZE_C- 1 downto 0)
std_logic sl
Definition: StdRtlPkg.vhd:28
out sampleData_oslv(( GT_WORD_SIZE_C* 8)- 1 downto 0)
NaturalArray :=( 0=> 14, 1=> 15) JESD_PRBS_TAPS_C
Definition: Jesd204bPkg.vhd:57
_library_ ieeeieee
slv( 7 downto 0) := x"7C" A_CHAR_C
Definition: Jesd204bPkg.vhd:39
positive := 4 GT_WORD_SIZE_C
Definition: Jesd204bPkg.vhd:31
in dataRx_islv(( GT_WORD_SIZE_C* 8)- 1 downto 0)
slv( 7 downto 0) := x"FC" F_CHAR_C
Definition: Jesd204bPkg.vhd:41
std_logic_vector slv
Definition: StdRtlPkg.vhd:29