SURF  1.0
Monitor.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : Monitor.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2015-08-09
5 -- Last update: 2016-01-27
6 -------------------------------------------------------------------------------
7 -- Description:
8 -- Handles RSSI counters, timeouts, and statuses:
9 -- - Re-transmission timeout and request,
10 -- - NULL segment transmission (Client),
11 -- - NULL timeout detection (Server),
12 -- - Acknowledgment timeout and request,
13 -- - Valid segment counter,
14 -- - Dropped segment counter.
15 --
16 -- Status register:
17 -- statusReg_o(0) : Connection Active
18 -- statusReg_o(1) : Maximum retransmissions exceeded r.retransMax and
19 -- statusReg_o(2) : Null timeout reached (server) r.nullTout;
20 -- statusReg_o(3) : Error in acknowledgment mechanism
21 -- statusReg_o(4) : SSI Frame length too long
22 -- statusReg_o(5) : Connection to peer timed out
23 -- statusReg_o(6) : Client rejected the connection (parameters out of range)
24 -- Server proposed new parameters (parameters out of range)
25 -------------------------------------------------------------------------------
26 -- This file is part of 'SLAC Firmware Standard Library'.
27 -- It is subject to the license terms in the LICENSE.txt file found in the
28 -- top-level directory of this distribution and at:
29 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
30 -- No part of 'SLAC Firmware Standard Library', including this file,
31 -- may be copied, modified, propagated, or distributed except according to
32 -- the terms contained in the LICENSE.txt file.
33 -------------------------------------------------------------------------------
34 
35 library ieee;
36 use ieee.std_logic_1164.all;
37 use ieee.std_logic_unsigned.all;
38 use ieee.std_logic_arith.all;
39 
40 use work.StdRtlPkg.all;
41 use work.RssiPkg.all;
42 
43 --! @see entity
44  --! @ingroup protocols_rssi
45 entity Monitor is
46  generic (
47  TPD_G : time := 1 ns;
48  TIMEOUT_UNIT_G : real := 1.0E-6; -- us
49  CLK_FREQUENCY_G : real := 100.0E6;
50  SERVER_G : boolean := true;
51  WINDOW_ADDR_SIZE_G : positive := 7;
52  STATUS_WIDTH_G : positive := 6;
53  CNT_WIDTH_G : positive := 32;
54  RETRANSMIT_ENABLE_G : boolean := true
55  --
56  );
57  port (
58  clk_i : in sl;
59  rst_i : in sl;
60 
61  -- Connection FSM indicating active connection
63 
64  -- Timeout and counter values
66 
67  -- Flags from Rx module
68  rxFlags_i : in FlagsType;
69 
70  --
71  rxLastSeqN_i : in slv(7 downto 0);
72  rxWindowSize_i : in integer range 1 to 2 ** (WINDOW_ADDR_SIZE_G);
73 
74  -- Do not request resend if tx buffer empty
76 
77  -- Valid received packet
78  rxValid_i : in sl;
79  rxDrop_i : in sl;
80 
81  --
86 
87  -- Internal Errors and Timeouts
88  lenErr_i : in sl;
89  ackErr_i : in sl;
92 
93  -- Packet transmission requests
94  sndResend_o : out sl;
95  sndNull_o : out sl;
96  sndAck_o : out sl;
97 
98  -- Connection close request
99  closeRq_o : out sl;
100 
101  -- Internal statuses
102  statusReg_o : out slv(STATUS_WIDTH_G downto 0);
103  dropCnt_o : out slv(CNT_WIDTH_G-1 downto 0);
104  validCnt_o : out slv(CNT_WIDTH_G-1 downto 0);
105  resendCnt_o : out slv(CNT_WIDTH_G-1 downto 0);
106  reconCnt_o : out slv(CNT_WIDTH_G-1 downto 0)
107  );
108 end entity Monitor;
109 
110 architecture rtl of Monitor is
111  --
112  constant SAMPLES_PER_TIME_C : integer := integer(TIMEOUT_UNIT_G * CLK_FREQUENCY_G);
113  constant SAMPLES_PER_TIME_DIV3_C : integer := integer(TIMEOUT_UNIT_G * CLK_FREQUENCY_G)/3;
114  --
115  type RegType is record
116  -- Retransmission
117  retransToutCnt : slv(rssiParam_i.retransTout'left + bitSize(SAMPLES_PER_TIME_C) downto 0);
118  sndResend : sl;
119  sndResendD1 : sl;
120  retransCnt : slv(rssiParam_i.maxRetrans'left + bitSize(SAMPLES_PER_TIME_C) downto 0);
121  retransMax : sl;
122 
123  -- Null packet send/timeout
124  nullToutCnt : slv(rssiParam_i.nullSegTout'left + bitSize(SAMPLES_PER_TIME_C) downto 0);
125  sndNull : sl;
126  nullTout : sl;
127 
128  -- Ack packet cumulative/timeout
129  ackToutCnt : slv(rssiParam_i.nullSegTout'left + bitSize(SAMPLES_PER_TIME_C) downto 0);
130  lastAckSeqN : slv(7 downto 0);
131  sndAck : sl;
132 
133  -- For detecting rising edge on connActive
134  connActiveD1 : sl;
135 
136  --
137  status : slv(STATUS_WIDTH_G - 1 downto 0);
138  validCnt : slv(CNT_WIDTH_G - 1 downto 0);
139  dropCnt : slv(CNT_WIDTH_G - 1 downto 0);
140  reconCnt : slv(CNT_WIDTH_G - 1 downto 0);
141  resendCnt : slv(CNT_WIDTH_G - 1 downto 0);
142  --
143  end record RegType;
144 
145  constant REG_INIT_C : RegType := (
146  -- Retransmission
147  retransToutCnt => (others=>'0'),
148  sndResend => '0',
149  sndResendD1 => '0',
150  retransCnt => (others=>'0'),
151  retransMax => '0',
152 
153  -- Null packet send/timeout
154  nullToutCnt => (others=>'0'),
155  sndnull => '0',
156  nullTout => '0',
157 
158  -- Ack packet cumulative/timeout
159  ackToutCnt => (others=>'0'),
160  lastAckSeqN => (others=>'0'),
161  sndAck => '0',
162 
163  -- For detecting rising edge on connActive
164  connActiveD1 => '0',
165 
166  -- Statuses
167  status => (others=>'0'),
168  validCnt => (others=>'0'),
169  dropCnt => (others=>'0'),
170  reconCnt => (others=>'0'),
171  resendCnt => (others=>'0')
172  );
173 
174  signal r : RegType := REG_INIT_C;
175  signal rin : RegType;
176  signal s_status : slv(STATUS_WIDTH_G - 1 downto 0);
177  --
178 begin
179  -- Status assignment
180  s_status(0) <= r.retransMax and r.sndResend and not r.sndResendD1;
181  s_status(1) <= r.nullTout;
182  s_status(2) <= ackErr_i;
183  s_status(3) <= lenErr_i;
184  s_status(4) <= peerConnTout_i;
185  s_status(5) <= paramReject_i;
186 
189  variable v : RegType;
190  begin
191  v := r;
192 
193  -- DFF the connActive for rising edge detection
194  v.connActiveD1 := connActive_i;
195 
196  -- /////////////////////////////////////////////////////////
197  ------------------------------------------------------------
198  -- Retransmission timeout
199  ------------------------------------------------------------
200  -- /////////////////////////////////////////////////////////
201 
202  -- Retransmission Timeout counter
203  if (connActive_i = '0' or
204  r.sndResend = '1' or
205  (rxValid_i = '1' and rxFlags_i.busy = '1') or
206  dataHeadSt_i = '1' or
207  rstHeadSt_i = '1' or
208  nullHeadSt_i = '1' or
209  txBufferEmpty_i = '1' or
210  RETRANSMIT_ENABLE_G = false -- Disable retransmissions
211  ) then
212  v.retransToutCnt := (others=>'0');
213  else
214  v.retransToutCnt := r.retransToutCnt+1;
215  end if;
216 
217  -- Resend request SRFF
218  if (connActive_i = '0' or
219  (rxValid_i = '1' and rxFlags_i.busy = '1') or
220  dataHeadSt_i = '1' or
221  rstHeadSt_i = '1' or
222  nullHeadSt_i = '1' or
223  txBufferEmpty_i = '1'
224  ) then
225  v.sndResend := '0';
226  elsif (r.retransToutCnt >= (conv_integer(rssiParam_i.retransTout)*SAMPLES_PER_TIME_C) ) then
227  v.sndResend := '1';
228 
229  end if;
230 
231  -- Pipeline sndResend for edge detection
232  v.sndResendD1 := r.sndResend;
233 
234  -- /////////////////////////////////////////////////////////
235  ------------------------------------------------------------
236  -- Retransmission counter
237  ------------------------------------------------------------
238  -- /////////////////////////////////////////////////////////
239  -- Counter of consecutive retransmissions
240  -- Reset when connection is broken or a valid ACK is received
241  if (connActive_i = '0' or
242  (rxValid_i = '1' and rxFlags_i.ack = '1')
243  ) then
244  v.retransCnt := (others=>'0');
245  elsif (r.sndResend = '1' and r.sndResendD1 = '0') then -- Rising edge
246  v.retransCnt := r.retransCnt+1;
247  end if;
248 
249  -- Retransmission exceeded close connection request SRFF
250  if (connActive_i = '0' or
251  (rxValid_i = '1' and rxFlags_i.ack = '1')
252  ) then
253  v.retransMax := '0';
254  elsif (r.retransCnt >= rssiParam_i.maxRetrans) then
255  v.retransMax := '1';
256  end if;
257 
258  -- /////////////////////////////////////////////////////////
259  ------------------------------------------------------------
260  -- Null Segment transmit/timeout
261  ------------------------------------------------------------
262  -- /////////////////////////////////////////////////////////
263 
264  -- Null Segment transmission (Client)
265  if (SERVER_G = false) then
266  -- Null transmission counter
267  if (connActive_i = '0' or
268  dataHeadSt_i = '1' or
269  rstHeadSt_i = '1' or
270  nullHeadSt_i = '1' or
271  ackHeadSt_i = '1' or
272  RETRANSMIT_ENABLE_G = false -- Disable null packet transmission
273  ) then
274  v.nullToutCnt := (others=>'0');
275  else
276  v.nullToutCnt := r.nullToutCnt+1;
277  end if;
278 
279  -- Null request SRFF
280  if (connActive_i = '0' or
281  dataHeadSt_i = '1' or
282  rstHeadSt_i = '1' or
283  nullHeadSt_i = '1') then
284  v.sndNull := '0';
285  elsif (r.nullToutCnt >= (conv_integer(rssiParam_i.nullSegTout) * SAMPLES_PER_TIME_DIV3_C) ) then -- send null segments if timeout/2 reached
286  v.sndNull := '1';
287  end if;
288 
289  -- Timeout not applicable
290  v.nullTout := '0';
291 
292  -- Null timeout (Server)
293  else
294  -- Null timeout counter
295  if (connActive_i = '0' or
296  (rxValid_i = '1' and rxFlags_i.data = '1') or
297  (rxValid_i = '1' and rxFlags_i.nul = '1') or
298  (rxValid_i = '1' and rxFlags_i.ack = '1') or
299  (rxValid_i = '1' and rxFlags_i.busy = '1') or
300  RETRANSMIT_ENABLE_G = false -- Disable null timeout
301  ) then
302  v.nullToutCnt := (others=>'0');
303  else
304  v.nullToutCnt := r.nullToutCnt+1;
305  end if;
306 
307  -- Null timeout SRFF
308  if (connActive_i = '0') then
309  v.nullTout := '0';
310  elsif (r.nullToutCnt >= (conv_integer(rssiParam_i.nullSegTout) * SAMPLES_PER_TIME_C) ) then
311  v.nullTout := '1';
312  end if;
313 
314  -- Null sending not applicable
315  v.sndNull := '0';
316  end if;
317 
318  -- /////////////////////////////////////////////////////////
319  ------------------------------------------------------------
320  -- Acknowledgment cumulative/timeout
321  ------------------------------------------------------------
322  -- /////////////////////////////////////////////////////////
323 
324  -- Ack seqN registering when it is sent
325  if (connActive_i = '0') then
326  v.lastAckSeqN := rxLastSeqN_i;
327  elsif (
328  ackHeadSt_i = '1' or
329  dataHeadSt_i = '1' or
330  rstHeadSt_i = '1' or
331  nullHeadSt_i = '1'
332  ) then
333  v.lastAckSeqN := rxLastSeqN_i;
334  else
335  v.lastAckSeqN := r.lastAckSeqN;
336  end if;
337 
338  -- Timeout counter
339  if (connActive_i = '0' or
340  ackHeadSt_i = '1' or
341  dataHeadSt_i = '1' or
342  rstHeadSt_i = '1' or
343  nullHeadSt_i = '1' or
344  (rxLastSeqN_i - r.lastAckSeqN) = 0
345  ) then
346  v.ackToutCnt := (others=>'0');
347  elsif (
348  (rxLastSeqN_i - r.lastAckSeqN) > 0 and
349  (rxLastSeqN_i - r.lastAckSeqN) <= rxWindowSize_i
350  ) then
351  v.ackToutCnt := r.ackToutCnt+1;
352  end if;
353 
354  -- Ack packet request SRFF
355  if (connActive_i = '0' or
356  ackHeadSt_i = '1' or
357  dataHeadSt_i = '1' or
358  nullHeadSt_i = '1' or
359  rstHeadSt_i = '1'
360  ) then
361  v.sndAck := '0';
362 
363  -- Timeout acknowledgment request
364  elsif (r.ackToutCnt >= (conv_integer(rssiParam_i.cumulAckTout)* SAMPLES_PER_TIME_C)) then
365  v.sndAck := '1';
366 
367  -- Cumulative acknowledgment request
368  elsif ((rxLastSeqN_i - r.lastAckSeqN) >= rssiParam_i.maxCumAck) then
369  v.sndAck := '1';
370 
371  -- Null segment ACK as soon as NUL received
372  elsif (rxValid_i = '1' and rxFlags_i.nul = '1') then
373  v.sndAck := '1';
374  end if;
375 
376  -- /////////////////////////////////////////////////////////
377  ------------------------------------------------------------
378  -- Status register and valid and drop counters
379  ------------------------------------------------------------
380  -- /////////////////////////////////////////////////////////
381 
382  -- Register statuses until new connection is established
383  if (connActive_i = '1' and r.connActiveD1 = '0') then
384  v.status := (others=>'0');
385  elsif (s_status /= (s_status'range => '0') ) then
386  v.status := r.status or s_status;
387  end if;
388 
389  -- Count valid packets
390  if (connActive_i = '1' and r.connActiveD1 = '0') then
391  v.validCnt := (others=>'0');
392  elsif (rxValid_i = '1') then
393  v.validCnt := r.validCnt+1;
394  end if;
395 
396  -- Count dropped packets
397  if (connActive_i = '1' and r.connActiveD1 = '0') then
398  v.dropCnt := (others=>'0');
399  elsif (rxDrop_i = '1') then
400  v.dropCnt := r.dropCnt+1;
401  end if;
402 
403  -- Count all retransmissions within the active connection
404  if (connActive_i = '1' and r.connActiveD1 = '0') then
405  v.resendCnt := (others=>'0');
406  elsif (r.sndResend = '1' and r.sndResendD1 = '0') then -- Rising edge
407  v.resendCnt := r.resendCnt+1;
408  end if;
409 
410  -- Count all reconnections from reset
411  if (connActive_i = '1' and r.connActiveD1 = '0') then
412  v.reconCnt := r.reconCnt+1;
413  end if;
414 
415  -- /////////////////////////////////////////////////////////
416  if (rst_i = '1') then
417  v := REG_INIT_C;
418  end if;
419 
420  rin <= v;
421  -----------------------------------------------------------
422  end process comb;
423 
424  seq : process (clk_i) is
425  begin
426  if (rising_edge(clk_i)) then
427  r <= rin after TPD_G;
428  end if;
429  end process seq;
430  ---------------------------------------------------------------------
431  sndResend_o <= r.sndResend and not r.retransMax; -- Request retransmission if max retransmissions not reached
432  sndNull_o <= r.sndNull;
433  sndAck_o <= r.sndAck;
434  closeRq_o <= (r.retransMax and r.sndResend and not r.sndResendD1) or -- Close connection when exceeded resend is requested
435  r.nullTout or -- Close connection when null timeouts
436  ackErr_i or -- Close if acknowledgment error occurs
437  lenErr_i; -- Close if SSI input frame length error occurs
438  statusReg_o <= r.status & connActive_i;
439  dropCnt_o <= r.dropCnt;
440  validCnt_o <= r.validCnt;
441  resendCnt_o <= r.resendCnt;
442  reconCnt_o <= r.reconCnt;
443  ---------------------------------------------------------------------
444 end architecture rtl;
out sndNull_osl
Definition: Monitor.vhd:95
in ackErr_isl
Definition: Monitor.vhd:89
sl nul
Definition: RssiPkg.vhd:91
in lenErr_isl
Definition: Monitor.vhd:88
in clk_isl
Definition: Monitor.vhd:58
in peerConnTout_isl
Definition: Monitor.vhd:90
in dataHeadSt_isl
Definition: Monitor.vhd:84
in rxDrop_isl
Definition: Monitor.vhd:79
in nullHeadSt_isl
Definition: Monitor.vhd:85
std_logic sl
Definition: StdRtlPkg.vhd:28
slv( 15 downto 0) nullSegTout
Definition: RssiPkg.vhd:62
out sndAck_osl
Definition: Monitor.vhd:96
out dropCnt_oslv( CNT_WIDTH_G- 1 downto 0)
Definition: Monitor.vhd:103
in connActive_isl
Definition: Monitor.vhd:62
out closeRq_osl
Definition: Monitor.vhd:99
sl data
Definition: RssiPkg.vhd:92
slv( 7 downto 0) maxRetrans
Definition: RssiPkg.vhd:64
in rxFlags_iFlagsType
Definition: Monitor.vhd:68
out reconCnt_oslv( CNT_WIDTH_G- 1 downto 0)
Definition: Monitor.vhd:107
TPD_Gtime := 1 ns
Definition: Monitor.vhd:47
_library_ ieeeieee
Definition: HeaderReg.vhd:21
slv( 15 downto 0) retransTout
Definition: RssiPkg.vhd:60
in rst_isl
Definition: Monitor.vhd:59
in ackHeadSt_isl
Definition: Monitor.vhd:82
in rxLastSeqN_islv( 7 downto 0)
Definition: Monitor.vhd:71
slv( 7 downto 0) maxCumAck
Definition: RssiPkg.vhd:65
CLK_FREQUENCY_Greal := 100.0E6
Definition: Monitor.vhd:49
RETRANSMIT_ENABLE_Gboolean := true
Definition: Monitor.vhd:56
slv( 15 downto 0) cumulAckTout
Definition: RssiPkg.vhd:61
sl ack
Definition: RssiPkg.vhd:88
in paramReject_isl
Definition: Monitor.vhd:91
in rxValid_isl
Definition: Monitor.vhd:78
WINDOW_ADDR_SIZE_Gpositive := 7
Definition: Monitor.vhd:51
out sndResend_osl
Definition: Monitor.vhd:94
in rssiParam_iRssiParamType
Definition: Monitor.vhd:65
in rxWindowSize_iinteger range 1 to 2**( WINDOW_ADDR_SIZE_G)
Definition: Monitor.vhd:72
STATUS_WIDTH_Gpositive := 6
Definition: Monitor.vhd:52
out statusReg_oslv( STATUS_WIDTH_G downto 0)
Definition: Monitor.vhd:102
RssiParamType
Definition: RssiPkg.vhd:52
in txBufferEmpty_isl
Definition: Monitor.vhd:75
CNT_WIDTH_Gpositive := 32
Definition: Monitor.vhd:53
out resendCnt_oslv( CNT_WIDTH_G- 1 downto 0)
Definition: Monitor.vhd:105
sl busy
Definition: RssiPkg.vhd:93
TIMEOUT_UNIT_Greal := 1.0E-6
Definition: Monitor.vhd:48
in rstHeadSt_isl
Definition: Monitor.vhd:83
out validCnt_oslv( CNT_WIDTH_G- 1 downto 0)
Definition: Monitor.vhd:104
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
SERVER_Gboolean := true
Definition: Monitor.vhd:50