Belle II KLM Scint Firmware  1
b2tt_payload.vhd
1 -- ---------------------------------------------------------------------
2 --
3 --- b2tt_payload.vhd -- TT-link payload filler
4 --
5 -- Mikihiko Nakao, KEK IPNS
6 --
7 --- revisions
8 -- 20140806 first version, split from b2tt_encode.vhd
9 -- 20160316 SEU mitigation bits rearranged
10 -- 20160831 major payload rearrangement
11 -- 20170713 ver, id, rstmask, ebit
12 -- 20170724 semreset
13 --
14 -- ---------------------------------------------------------------------
15 
16 --- b2tt_payload: library
17 library ieee;
18 use ieee.std_logic_1164.all;
19 use ieee.std_logic_unsigned.all;
20 use ieee.numeric_std.all;
21 library work;
22 use work.b2tt_symbols.all;
23 
24 --- b2tt_payload: entity
25 entity b2tt_payload is
26  port (
27  clock : in std_logic;
28  id : in std_logic_vector (23 downto 0);
29  ver : in std_logic_vector (23 downto 0);
30  utime : in std_logic_vector (31 downto 0);
31  myaddr : in std_logic_vector (19 downto 0);
32  b2clkup : in std_logic;
33  b2ttup : in std_logic;
34  b2plllk : in std_logic;
35  b2linkup : in std_logic;
36  b2linkwe : in std_logic;
37  b2ttnext : in std_logic;
38  b2lclk : in std_logic;
39  staictrl : in std_logic_vector (1 downto 0);
40  runreset : in std_logic;
41  errreset : in std_logic;
42  semreset : in std_logic;
43  busysrc : in std_logic_vector (7 downto 0);
44  feeerr : in std_logic_vector (7 downto 0);
45  timerr : in std_logic;
46  tag : in std_logic_vector (31 downto 0);
47  tagerr : in std_logic;
48  fifoerr : in std_logic;
49  fifoful : in std_logic;
50  badver : in std_logic;
51  trgmask : in std_logic;
52  rstmask : in std_logic;
53  semscan : in std_logic;
54  semdet : in std_logic;
55  semmbe : in std_logic;
56  semcrc : in std_logic;
57  idly : in std_logic_vector (23 downto 0);
58  fillsig : in std_logic;
59  regsel : in ttreg_t;
60  usrreg : in std_logic_vector (7 downto 0);
61  usrdat : in std_logic_vector (15 downto 0);
62  cntb2lwe : out std_logic_vector (15 downto 0);
63  cntftag : out std_logic_vector (15 downto 0);
64  payload : out std_logic_vector (111 downto 0) );
65 end b2tt_payload;
66 
67 --- b2tt_payload: architecture
68 architecture implementation of b2tt_payload is
69  signal buf_btime : std_logic_vector (23 downto 0) := (others => '0');
70  signal buf_etime : std_logic_vector (23 downto 0) := (others => '0');
71  signal cnt_b2lwe : std_logic_vector (47 downto 0) := (others => '0');
72  signal cnt_ftag : std_logic_vector (23 downto 0) := (others => '0');
73  signal seq_seudet : std_logic_vector (1 downto 0) := (others => '0');
74  signal cnt_seudet : std_logic_vector (9 downto 0) := (others => '0');
75  signal seq_seuscan : std_logic_vector (1 downto 0) := (others => '0');
76  signal cnt_seuscan : std_logic_vector (7 downto 0) := (others => '0');
77  signal cnt_payload : std_logic_vector (7 downto 0) := (others => '0');
78  signal sta_feeerr : std_logic_vector (7 downto 0) := (others => '0');
79  signal sta_fifoerr : std_logic := '0';
80  --signal sta_fifoful : std_logic := '0';
81  signal sta_tagerr : std_logic := '0';
82  signal sta_timerr : std_logic := '0';
83  signal sta_clkup : std_logic := '0';
84  signal sta_ttup : std_logic := '0';
85  signal sta_b2lup : std_logic := '0';
86  signal sta_b2pll : std_logic := '0';
87  signal sig_clklost : std_logic := '0';
88  signal sig_ttlost : std_logic := '0';
89  signal sig_b2llost : std_logic := '0';
90  signal sig_plllost : std_logic := '0';
91  signal sta_clklost : std_logic := '0';
92  signal sta_ttlost : std_logic := '0';
93  signal sta_b2llost : std_logic := '0';
94  signal sta_plllost : std_logic := '0';
95  signal sig_errreset : std_logic := '0';
96  signal sta_anyerr : std_logic := '0';
97  signal seq_anyerr : std_logic := '0';
98  signal seq_ereg : std_logic := '0';
99  signal seq_b2lwe : std_logic_vector (1 downto 0) := (others => '0');
100 
101  signal sta_clost : std_logic := '0';
102  signal sta_terr : std_logic := '0';
103  signal sta_rerr : std_logic := '0';
104  signal sta_ebit : std_logic_vector (5 downto 0) := (others => '0');
105 
106  signal cnt_cklost : std_logic_vector (2 downto 0) := (others => '0');
107  signal cnt_ttlost : std_logic_vector (2 downto 0) := (others => '0');
108  signal cnt_lklost : std_logic_vector (2 downto 0) := (others => '0');
109 
110  signal sta_anybsy : std_logic := '0';
111 
112  signal buf_ereg : std_logic_vector (31 downto 0) := (others => '0');
113  signal buf_payload : std_logic_vector (111 downto 0) := (others => '0');
114  alias rega : std_logic_vector (31 downto 0) is buf_payload(63 downto 32);
115  alias regb : std_logic_vector (31 downto 0) is buf_payload(31 downto 0);
116 
117  function setsta
118  ( sta: std_logic; rst: std_logic; sig: std_logic ) return std_logic is
119  begin
120  if rst = '1' then
121  return sig;
122  else
123  return sta or sig;
124  end if;
125  end function setsta;
126 
127 --- b2tt_payload: begin
128 begin
129  --- in
130  sig_errreset <= errreset or runreset;
131 
132  sta_clost <= '1' when staictrl /= "11" else (sta_clklost or sta_plllost);
133  sta_terr <= '1' when sta_ebit /= 0 else '0';
134  sta_rerr <= '1' when sta_feeerr /= 0 else '0';
135  sta_anyerr <= sta_terr or sta_clost or (not b2ttup) or sta_ttlost or
136  sta_rerr or (not b2linkup) or sta_b2llost;
137  sta_anybsy <= '1' when busysrc /= 0 else fifoful;
138 
139  --- proc_b2l
140  proc_b2l: process (b2lclk)
141  begin
142  if rising_edge(b2lclk) then
143  if b2clkup = '0' or b2linkup = '0' or runreset = '1' then
144  cnt_b2lwe <= (others => '0');
145  cnt_ftag <= (others => '0');
146  else
147  if b2linkwe = '1' then
148  cnt_b2lwe <= cnt_b2lwe + 1;
149  end if;
150  if b2ttnext = '1' then
151  cnt_ftag <= cnt_ftag + 1;
152  end if;
153  end if;
154  end if;
155  end process;
156 
157  --- proc_main
158  proc: process (clock)
159  begin
160  if clock'event and clock = '1' then
161 
162  --- seq_seudet, cnt_seudet
163  seq_seudet <= seq_seudet(0) & semdet;
164  if semreset = '1' then
165  cnt_seudet <= (others => '0');
166  elsif seq_seudet = "01" then
167  cnt_seudet <= cnt_seudet + 1;
168  end if;
169 
170  --- seq_seuscan, cnt_seuscan
171  seq_seuscan <= seq_seuscan(0) & semscan;
172  if semreset = '1' then
173  cnt_seuscan <= (others => '0');
174  elsif seq_seuscan = "01" then
175  cnt_seuscan <= cnt_seuscan + 1;
176  end if;
177 
178  --- lost
179  sta_clkup <= b2clkup;
180  sta_ttup <= b2ttup;
181  sta_b2lup <= b2linkup;
182  sta_b2pll <= b2plllk;
183 
184  sig_clklost <= sta_clkup and (not b2clkup);
185  sig_ttlost <= sta_ttup and (not b2ttup);
186  sig_b2llost <= sta_b2lup and (not b2linkup);
187  sig_plllost <= sta_b2pll and (not b2plllk);
188 
189  sta_clklost <= setsta(sta_clklost, sig_errreset, sig_clklost);
190  sta_ttlost <= setsta(sta_ttlost, sig_errreset, sig_ttlost);
191  sta_b2llost <= setsta(sta_b2llost, sig_errreset, sig_b2llost);
192  sta_plllost <= setsta(sta_plllost, sig_errreset, sig_plllost);
193 
194  --- error
195  if sig_errreset = '1' then
196  sta_feeerr <= (others => '0');
197  else
198  sta_feeerr <= sta_feeerr or feeerr;
199  end if;
200  sta_fifoerr <= setsta(sta_fifoerr, sig_errreset, fifoerr);
201  sta_tagerr <= setsta(sta_tagerr, sig_errreset, tagerr);
202  sta_timerr <= setsta(sta_timerr, sig_errreset, timerr);
203 
204  sta_ebit <= sta_tagerr &
205  sta_timerr &
206  badver &
207  sta_fifoerr &
208  semmbe &
209  semcrc;
210 
211  --- utime
212  if buf_btime = 0 then
213  buf_btime <= utime(23 downto 0);
214  end if;
215 
216  -- etime (event time)
217  seq_anyerr <= sta_anyerr;
218  seq_b2lwe <= seq_b2lwe(0) & b2linkwe;
219  if sta_anyerr /= seq_anyerr or seq_b2lwe(1) /= seq_b2lwe(0) then
220  buf_etime <= utime(23 downto 0);
221  seq_ereg <= '1';
222  else
223  seq_ereg <= '0';
224  end if;
225  if seq_ereg = '1' then
226  buf_ereg <= rega;
227  end if;
228 
229  -- "count" lost transitions
230  if sig_errreset = '1' then
231  cnt_cklost <= "000";
232  cnt_ttlost <= "000";
233  cnt_lklost <= "000";
234  else
235  -- 2017.0708.0721 no limit to detect frequent lost
236  if sig_clklost = '1' then
237  cnt_cklost(2) <= cnt_cklost(2) or (cnt_cklost(1) and cnt_cklost(0));
238  cnt_cklost(1 downto 0) <= cnt_cklost(1 downto 0) + 1;
239  end if;
240  if sig_ttlost = '1' then
241  cnt_ttlost(2) <= cnt_ttlost(2) or (cnt_ttlost(1) and cnt_ttlost(0));
242  cnt_ttlost(1 downto 0) <= cnt_ttlost(1 downto 0) + 1;
243  end if;
244  if sig_b2llost = '1' then
245  cnt_lklost(2) <= cnt_lklost(2) or (cnt_lklost(1) and cnt_lklost(0));
246  cnt_lklost(1 downto 0) <= cnt_lklost(1 downto 0) + 1;
247  end if;
248  end if;
249 
250  --- payload sticky
251  buf_payload(91 downto 84) <= cnt_payload;
252  buf_payload(83) <= '0'; -- dsel is always 0 at FEE
253  buf_payload(82) <= not b2ttup;
254  buf_payload(81) <= sta_anybsy;
255  buf_payload(80) <= sta_anyerr;
256  buf_payload(79 downto 70) <= (others => '0'); -- 10 bit reserved
257 
258  --- payload
259  if b2clkup = '0' then
260  buf_payload(111 downto 92) <= x"feeee"; -- impossible address
261  rega <= "000" & TTREG_CLOST & "0010" & x"0dead";
262  elsif fillsig = '1' then
263  buf_payload(111 downto 92) <= myaddr;
264 
265  -- here we don't care overflow, it is watched in the upstream
266  buf_payload(69 downto 64) <= cnt_seudet(5 downto 0);
267 
268  --- payload rega
269  -- trigger will be blocked if rega /= TTREG_FTAG
270  if sta_clklost = '1' or sta_plllost = '1' or staictrl /= "11" then
271  rega <= "000" & TTREG_CLOST & "000"
272  & sta_clklost & (not b2plllk) & sta_plllost
273  & (not staictrl) & cnt_cklost & "0" & x"000"; -- 1d
274  elsif b2ttup = '0' then
275  rega <= "000" & TTREG_TDOWN & '0' & cnt_ttlost & x"00000"; -- 1c
276  elsif sta_ttlost = '1' then
277  rega <= "000" & TTREG_TLOST & '0' & cnt_ttlost & x"00000"; -- 1b
278  elsif sta_ebit /= 0 then
279  rega <= "000" & TTREG_TERR & sta_ebit & "00" & x"0000"; -- 1a
280  elsif feeerr /= 0 then
281  rega <= "000" & TTREG_FERR & feeerr & x"0000"; -- 19
282  elsif sta_feeerr /= 0 then
283  rega <= "000" & TTREG_RERR & sta_feeerr & x"0000"; -- 18
284  elsif b2linkup = '0' then
285  rega <= "000" & TTREG_LDOWN & '0' & cnt_lklost & x"00000"; -- 17
286  elsif sta_b2llost = '1' then
287  rega <= "000" & TTREG_LLOST & '0' & cnt_lklost & x"00000"; -- 16
288  else
289  -- always showing "tagdone" unless there is an error
290  -- which unrecoverable without runreset
291  rega <= "000" & TTREG_FTAG & cnt_ftag; -- 0c
292  end if;
293 
294  --- payload regb
295  -- if regb is not selected by regsel, error bit is sent, which
296  -- will be merged in upstream
297  --
298  -- registers used for rega has not much meaning for regsel at FEE
299  -- and has no effect here, but they makes sense at intemediate FTSWs
300  if regsel = TTREG_USR then -- 01
301  regb <= "000" & regsel & usrreg & usrdat;
302  elsif regsel = TTREG_VER then -- 02
303  regb <= "000" & regsel & ver;
304  elsif regsel = TTREG_ID then -- 03
305  regb <= "000" & regsel & id;
306  elsif regsel = TTREG_PREG then -- 04
307  regb <= rega;
308  elsif regsel = TTREG_EREG then -- 05
309  regb <= "000" & buf_ereg(28 downto 0);
310  elsif regsel = TTREG_BTIME then -- 06
311  regb <= "000" & regsel & buf_btime(23 downto 0);
312  elsif regsel = TTREG_ETIME then -- 07
313  regb <= "000" & regsel & buf_etime;
314  elsif regsel = TTREG_WCNTL then -- 08
315  regb <= "000" & regsel & cnt_b2lwe(23 downto 0);
316  elsif regsel = TTREG_WCNTH then -- 09
317  regb <= "000" & regsel & cnt_b2lwe(47 downto 24);
318  elsif regsel = TTREG_FTAG then -- 0a
319  regb <= "000" & regsel & cnt_ftag;
320  elsif regsel = TTREG_TTAG then -- 0b
321  regb <= "000" & regsel & tag(23 downto 0);
322  elsif regsel = TTREG_SEM then -- 0c
323  regb <= "000" & regsel &
324  semmbe & semcrc & semdet & semscan & "00" &
325  cnt_seudet & cnt_seuscan;
326  elsif regsel = TTREG_IDLY then -- 13
327  regb <= "000" & regsel & idly;
328  elsif regsel = TTREG_EBIT then -- 15
329  regb <= "000" & regsel &
330  sta_ebit & -- 6 bit
331  "00000" & -- 5 bit
332  sta_clost & (not b2ttup) & sta_ttlost & -- 3 bit
333  (not b2linkup) & sta_b2llost & -- 2 bit
334  sta_feeerr; -- 8 bit
335  elsif regsel = TTREG_FERR then -- 19
336  regb <= "000" & regsel & feeerr & x"0000";
337  elsif regsel = TTREG_TMASK or
338  (regsel /= TTREG_BUSY and trgmask = '1') then -- 0f
339  regb <= "000" & TTREG_TMASK & sta_anyerr & sta_anybsy &
340  rstmask & trgmask & (not b2ttup) & "000" & x"0000";
341  elsif regsel = TTREG_BUSY or busysrc /= 0 then -- 14
342  regb <= "000" & TTREG_BUSY & busysrc & fifoful & "000" & x"000";
343  else
344  regb <= rega;
345  end if;
346 
347  cnt_payload <= cnt_payload + 1;
348  end if;
349  end if;
350  end process;
351 
352  --- out
353  payload <= buf_payload;
354  cntftag <= cnt_ftag(cntftag'left downto 0);
355  cntb2lwe <= cnt_b2lwe(cntb2lwe'left downto 0);
356 
357 --- b2tt_payload: end
358 end implementation;