cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
timers.cpp
Go to the documentation of this file.
1 
17 
43 
56 #include "timers.hpp"
57 
58 using namespace hls;
59 
60 
64 #ifndef __SYNTHESIS__
65  extern bool gTraceEvent;
66 #endif
67 
68 #define THIS_NAME "TOE/TIm"
69 
70 #define TRACE_OFF 0x0000
71 #define TRACE_CLT 1 << 1
72 #define TRACE_PBT 1 << 2
73 #define TRACE_RTT 1 << 3
74 #define TRACE_ALL 0xFFFF
75 
76 #define DEBUG_LEVEL (TRACE_OFF)
77 
78 
90 template<typename T> void pStreamMux(
91  stream<T> &si1,
92  stream<T> &si2,
93  stream<T> &so)
94 {
95  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
96  #pragma HLS PIPELINE II=1 enable_flush
97  #pragma HLS INLINE off
98 
99  if (!si1.empty())
100  so.write(si1.read());
101  else if (!si2.empty())
102  so.write(si2.read());
103 }
104 
105 
136  stream<RXeReTransTimerCmd> &siRXe_ReTxTimerCmd,
137  stream<TXeReTransTimerCmd> &siTXe_ReTxTimerCmd,
138  stream<Event> &soEmx_Event,
139  stream<SessionId> &soSmx_SessCloseCmd,
140  stream<SessState> &soTAi_Notif,
141  stream<TcpAppNotif> &soRAi_Notif)
142 {
143  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
144  #pragma HLS PIPELINE II=1 enable_flush
145  #pragma HLS INLINE off
146 
147  const char *myName = concat3(THIS_NAME, "/", "Rtt");
148 
149  //-- STATIC ARRAYs ---------------------------------------------------------
150  static ReTxTimerEntry RETRANSMIT_TIMER_TABLE[TOE_MAX_SESSIONS];
151  #pragma HLS RESOURCE variable=RETRANSMIT_TIMER_TABLE core=RAM_T2P_BRAM
152  #pragma HLS DEPENDENCE variable=RETRANSMIT_TIMER_TABLE inter false
153  #pragma HLS RESET variable=RETRANSMIT_TIMER_TABLE
154 
155  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
156  static bool rtt_waitForWrite=false;
157  #pragma HLS RESET variable=rtt_waitForWrite
158  static SessionId rtt_prevPosition=0;
159  #pragma HLS RESET variable=rtt_prevPosition
160  static SessionId rtt_position=0;
161  #pragma HLS RESET variable=rtt_position
162 
163  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
164  static RXeReTransTimerCmd rtt_rxeCmd;
165 
166  //-- DYNAMIC VARIABLES ----------------------------------------------------
167  ReTxTimerEntry currEntry;
168  TXeReTransTimerCmd txeCmd;
169  ValBool txeCmdVal;
170  SessionId currID;
171 
172  if (rtt_waitForWrite and (rtt_rxeCmd.sessionID != rtt_prevPosition)) {
173  //-------------------------------------------------------------
174  // Handle previously read command from [RXe] (i.e. RELOAD|STOP)
175  //-------------------------------------------------------------
176  if (rtt_rxeCmd.command == LOAD_TIMER) {
177  RETRANSMIT_TIMER_TABLE[rtt_rxeCmd.sessionID].time = TIME_1s;
178  if (DEBUG_LEVEL & TRACE_RTT) {
179  printInfo(myName, "Session #%d - Reloading RTO timer (value=%d i.e. %d clock cycles).\n",
180  rtt_rxeCmd.sessionID.to_int(), RETRANSMIT_TIMER_TABLE[rtt_rxeCmd.sessionID].time.to_uint(),
181  TOE_MAX_SESSIONS * RETRANSMIT_TIMER_TABLE[rtt_rxeCmd.sessionID].time.to_uint());
182  }
183  }
184  else { //-- STOP the timer
185  RETRANSMIT_TIMER_TABLE[rtt_rxeCmd.sessionID].time = 0;
186  RETRANSMIT_TIMER_TABLE[rtt_rxeCmd.sessionID].active = false;
187  if (DEBUG_LEVEL & TRACE_RTT) {
188  printInfo(myName, "Session #%d - Stopping RTO timer.\n",
189  rtt_rxeCmd.sessionID.to_int());
190  }
191  }
192  RETRANSMIT_TIMER_TABLE[rtt_rxeCmd.sessionID].retries = 0;
193  rtt_waitForWrite = false;
194  }
195  else if (!siRXe_ReTxTimerCmd.empty() and !rtt_waitForWrite) {
196  //------------------------------------------------
197  // Read input command from [RXe]
198  // INFO: Rx path has priority over Tx path
199  //------------------------------------------------
200  siRXe_ReTxTimerCmd.read(rtt_rxeCmd);
201  rtt_waitForWrite = true;
202  }
203  else {
204  if (!siTXe_ReTxTimerCmd.empty()) {
205  //------------------------------------------------
206  // Read input command from [TXe]
207  //------------------------------------------------
208  txeCmd = siTXe_ReTxTimerCmd.read();
209  txeCmdVal = true;
210  currID = txeCmd.sessionID;
211  if ( (txeCmd.sessionID-3 < rtt_position) and
212  (rtt_position <= txeCmd.sessionID) ) {
213  rtt_position += 5; // [FIXME - Why is this?]
214  }
215  }
216  else {
217  txeCmdVal = false;
218  currID = rtt_position;
219  // Increment position to be used in next loop
220  rtt_position++;
221  if (rtt_position >= TOE_MAX_SESSIONS) {
222  rtt_position = 0;
223  }
224  }
225 
226  // Get current entry from table
227  currEntry = RETRANSMIT_TIMER_TABLE[currID];
228 
229  if (txeCmdVal) {
230  // There is a pending set command from [TXe]. Go and process it.
231  currEntry.type = txeCmd.type;
232  if (not currEntry.active) {
233  switch(currEntry.retries) {
234  case 0:
235  currEntry.time = TIME_3s;
236  break;
237  case 1:
238  currEntry.time = TIME_6s;
239  break;
240  case 2:
241  currEntry.time = TIME_12s;
242  break;
243  default:
244  currEntry.time = TIME_30s;
245  break;
246  }
247  currEntry.active = true;
248  if (DEBUG_LEVEL & TRACE_RTT) {
249  printInfo(myName, "Session #%d - Starting RTO timer (value=%d i.e. %d clock cycles).\n",
250  currID.to_int(), currEntry.time.to_uint(),
251  currEntry.time.to_uint()*TOE_MAX_SESSIONS);
252  }
253  }
254  else {
255  if (DEBUG_LEVEL & TRACE_RTT) {
256  printInfo(myName, "Session #%d - Current RTO timer (value=%d i.e. %d clock cycles).\n",
257  currID.to_int(), currEntry.time.to_uint(),
258  currEntry.time.to_uint()*TOE_MAX_SESSIONS);
259  }
260  }
261  }
262  else {
263  // No [TXe] command. Manage RETRANSMIT_TIMER_TABLE entries
264  if (currEntry.active) {
265  if (currEntry.time > 0) {
266  currEntry.time--;
267  }
268  // We need to check if we can generate another event, otherwise we might
269  // end up in a Deadlock since the [TXe] will not be able to set new
270  // retransmit timers.
271  else if (!soEmx_Event.full()) {
272  currEntry.time = 0;
273  currEntry.active = false;
274  if (currEntry.retries < 4) {
275  currEntry.retries++;
276  //-- Send timeout event to [TXe]
277  soEmx_Event.write(Event((EventType)currEntry.type,
278  currID,
279  currEntry.retries));
280  printWarn(myName, "Session #%d - RTO Timeout (retries=%d).\n",
281  currID.to_int(), currEntry.retries.to_uint());
282  }
283  else {
284  currEntry.retries = 0;
285  soSmx_SessCloseCmd.write(currID);
286  if (currEntry.type == SYN_EVENT) {
287  soTAi_Notif.write(SessState(currID, CLOSED));
288  if (DEBUG_LEVEL & TRACE_RTT) {
289  printWarn(myName, "Notifying [TAi] - Failed to open session %d (event=\'%s\').\n",
290  currID.to_int(), getEventName(currEntry.type));
291  }
292  }
293  else {
294  soRAi_Notif.write(TcpAppNotif(currID, CLOSED));
295  if (DEBUG_LEVEL & TRACE_RTT) {
296  printWarn(myName, "Notifying [RAi] - Session %d timeout (event=\'%s\').\n",
297  currID.to_int(), getEventName(currEntry.type));
298  }
299  }
300  }
301  }
302  }
303  } // End of: txeCmdVal
304 
305  // Write the entry back into the table
306  RETRANSMIT_TIMER_TABLE[currID] = currEntry;
307  rtt_prevPosition = currID;
308  }
309 }
310 
311 
328  stream<SessionId> &siRXe_ClrProbeTimer,
329  stream<SessionId> &siTXe_SetProbeTimer,
330  stream<Event> &soEmx_Event)
331 {
332  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
333  #pragma HLS INLINE off
334  #pragma HLS PIPELINE II=1 enable_flush
335 
336  const char *myName = concat3(THIS_NAME, "/", "Pbt");
337 
338  //-- STATIC ARRAYS ---------------------------------------------------------
339  static ProbeTimerEntry PROBE_TIMER_TABLE[TOE_MAX_SESSIONS];
340  #pragma HLS RESOURCE variable=PROBE_TIMER_TABLE core=RAM_T2P_BRAM
341  #pragma HLS DATA_PACK variable=PROBE_TIMER_TABLE
342  #pragma HLS DEPENDENCE variable=PROBE_TIMER_TABLE inter false
343  #pragma HLS RESET variable=PROBE_TIMER_TABLE
344 
345  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
346  static bool pbt_WaitForWrite=false;
347  #pragma HLS RESET variable=pbt_WaitForWrite
348  static SessionId pbt_currSessId=0;
349  #pragma HLS RESET variable=pbt_currSessId
350  static SessionId pbt_updtSessId=0;
351  #pragma HLS RESET variable=pbt_updtSessId
352  static SessionId pbt_prevSessId=0;
353  #pragma HLS RESET variable=pbt_prevSessId
354 
355  //-- DYNAMIC VARIABLES -----------------------------------------------------
356  bool fastResume = false;
357 
358  if (pbt_WaitForWrite) {
359  //-- Update the table
360  if (pbt_updtSessId != pbt_prevSessId) {
361  PROBE_TIMER_TABLE[pbt_updtSessId].time = TIME_10s;
362  //****************************************************************
363  //** [FIXME - Disabling the KeepAlive process for the time being]
364  //****************************************************************
365  PROBE_TIMER_TABLE[pbt_updtSessId].active = false;
366  pbt_WaitForWrite = false;
367  }
368  pbt_prevSessId--;
369  }
370  else if (!siTXe_SetProbeTimer.empty()) {
371  //-- Read the Session-Id to set
372  siTXe_SetProbeTimer.read(pbt_updtSessId);
373  pbt_WaitForWrite = true;
374  }
375  else { // if (!soEmx_Event.full()) this leads to II=2
376  SessionId sessIdToProcess;
377 
378  if (!siRXe_ClrProbeTimer.empty()) {
379  //-- Read the Session-Id to clear
380  sessIdToProcess = siRXe_ClrProbeTimer.read();
381  fastResume = true;
382  }
383  else {
384  sessIdToProcess = pbt_currSessId;
385  pbt_currSessId++;
386  if (pbt_currSessId == TOE_MAX_SESSIONS) {
387  pbt_currSessId = 0;
388  }
389  }
390 
391  if (PROBE_TIMER_TABLE[sessIdToProcess].active) {
392  if (fastResume) {
393  //-- Clear (de-activate) the keepalive process for the current session-ID
394  PROBE_TIMER_TABLE[sessIdToProcess].time = 0;
395  PROBE_TIMER_TABLE[sessIdToProcess].active = false;
396  fastResume = false;
397  }
398  else if (PROBE_TIMER_TABLE[sessIdToProcess].time == 0 and !soEmx_Event.full()) {
399  //-- Request to send a keepalive probe
400  PROBE_TIMER_TABLE[sessIdToProcess].time = 0;
401  PROBE_TIMER_TABLE[sessIdToProcess].active = false;
402  #if !(TCP_NODELAY)
403  soEmx_Event.write(Event(TX_EVENT, sessIdToProcess));
404  #else
405  soEmx_Event.write(Event(RT_EVENT, sessIdToProcess));
406  #endif
407  }
408  else {
409  PROBE_TIMER_TABLE[sessIdToProcess].time -= 1;
410  }
411  }
412  pbt_prevSessId = sessIdToProcess;
413  }
414 }
415 
416 
427  stream<SessionId> &siRXe_CloseTimer,
428  stream<SessionId> &soSmx_SessCloseCmd)
429 {
430  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
431  #pragma HLS PIPELINE II=1 enable_flush
432  #pragma HLS INLINE off
433 
434  //-- STATIC ARRAYS ---------------------------------------------------------
435  static CloseTimerEntry CLOSE_TIMER_TABLE[TOE_MAX_SESSIONS];
436  #pragma HLS RESOURCE variable=CLOSE_TIMER_TABLE core=RAM_T2P_BRAM
437  #pragma HLS DATA_PACK variable=CLOSE_TIMER_TABLE
438  #pragma HLS DEPENDENCE variable=CLOSE_TIMER_TABLE inter false
439  #pragma HLS RESET variable=CLOSE_TIMER_TABLE
440 
441  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
442  static bool clt_waitForWrite=false;
443  #pragma HLS RESET variable=clt_waitForWrite
444  static SessionId clt_currSessId=0;
445  #pragma HLS RESET variable=clt_currSessId
446  static SessionId clt_prevSessId=0;
447  #pragma HLS RESET variable=clt_prevSessId
448 
449  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
450  static SessionId clt_sessIdToSet;
451 
452  if (clt_waitForWrite) {
453  //-- Update the table
454  if (clt_sessIdToSet != clt_prevSessId) {
455  CLOSE_TIMER_TABLE[clt_sessIdToSet].time = TIME_60s;
456  CLOSE_TIMER_TABLE[clt_sessIdToSet].active = true;
457  clt_waitForWrite = false;
458  }
459  clt_prevSessId--;
460  }
461  else if (!siRXe_CloseTimer.empty()) {
462  //-- Read the Session-Id to set
463  siRXe_CloseTimer.read(clt_sessIdToSet);
464  clt_waitForWrite = true;
465  }
466  else {
467  clt_prevSessId = clt_currSessId;
468  // Check if timer is 0, otherwise decrement
469  if (CLOSE_TIMER_TABLE[clt_currSessId].active) {
470  if (CLOSE_TIMER_TABLE[clt_currSessId].time > 0) {
471  CLOSE_TIMER_TABLE[clt_currSessId].time -= 1;
472  }
473  else {
474  CLOSE_TIMER_TABLE[clt_currSessId].time = 0;
475  CLOSE_TIMER_TABLE[clt_currSessId].active = false;
476  soSmx_SessCloseCmd.write(clt_currSessId);
477  }
478  }
479 
480  if (clt_currSessId == TOE_MAX_SESSIONS) {
481  clt_currSessId = 0;
482  }
483  else {
484  clt_currSessId++;
485  }
486  }
487 }
488 
489 
505 void timers(
506  stream<RXeReTransTimerCmd> &siRXe_ReTxTimerCmd,
507  stream<SessionId> &siRXe_ClrProbeTimer,
508  stream<SessionId> &siRXe_CloseTimer,
509  stream<TXeReTransTimerCmd> &siTXe_ReTxTimerCmd,
510  stream<SessionId> &siTXe_SetProbeTimer,
511  stream<SessionId> &soSTt_SessCloseCmd,
512  stream<Event> &soEVe_Event,
513  stream<SessState> &soTAi_Notif,
514  stream<TcpAppNotif> &soRAi_Notif)
515 {
516  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
517  #pragma HLS INLINE
518 
519  //==========================================================================
520  //== LOCAL STREAMS (Sorted by the name of the modules which generate them)
521  //==========================================================================
522  static stream<SessionId> ssClsToSmx_SessCloseCmd ("ssClsToSmx_SessCloseCmd");
523  #pragma HLS stream variable=ssClsToSmx_SessCloseCmd depth=2
524 
525  static stream<SessionId> ssRttToSmx_SessCloseCmd ("ssRttToSmx_SessCloseCmd");
526  #pragma HLS stream variable=ssRttToSmx_SessCloseCmd depth=2
527 
528  static stream<Event> ssRttToEmx_Event ("ssRttToEmx_Event");
529  #pragma HLS stream variable=ssRttToEmx_Event depth=2
530  #pragma HLS DATA_PACK variable=ssRttToEmx_Event
531 
532  static stream<Event> ssPbtToEmx_Event ("ssPbtToEmx_Event");
533  #pragma HLS stream variable=ssPbtToEmx_Event depth=2
534  #pragma HLS DATA_PACK variable=ssPbtToEmx_Event
535 
536  // Event Mux (Emx) based on template stream Mux
537  // Notice order --> RetransmitTimer comes before ProbeTimer
538  pStreamMux(
539  ssRttToEmx_Event,
540  ssPbtToEmx_Event,
541  soEVe_Event);
542 
543  // ReTransmit Timer (Rtt)
545  siRXe_ReTxTimerCmd,
546  siTXe_ReTxTimerCmd,
547  ssRttToEmx_Event,
548  ssRttToSmx_SessCloseCmd,
549  soTAi_Notif,
550  soRAi_Notif);
551 
552  // Probe Timer (Pbt)
553  pProbeTimer(
554  siRXe_ClrProbeTimer,
555  siTXe_SetProbeTimer,
556  ssPbtToEmx_Event);
557 
558  pCloseTimer(
559  siRXe_CloseTimer,
560  ssClsToSmx_SessCloseCmd);
561 
562  // State table release Mux (Smx) based on template stream Mux
563  pStreamMux(
564  ssClsToSmx_SessCloseCmd,
565  ssRttToSmx_SessCloseCmd,
566  soSTt_SessCloseCmd);
567 
568 }
569 
ap_uint< 32 > time
Definition: timers.hpp:75
Definition: toe.hpp:661
ap_uint< 32 > time
Definition: timers.hpp:86
TimerCmd command
Definition: toe.hpp:631
SessionId sessionID
Definition: toe.hpp:630
ap_uint< 32 > time
Definition: timers.hpp:97
ap_uint< 3 > retries
Definition: timers.hpp:98
EventType type
Definition: timers.hpp:100
EventType type
Definition: toe.hpp:645
SessionId sessionID
Definition: toe.hpp:644
TcpAppOpnRep SessState
Definition: toe.hpp:279
void pStreamMux(stream< T > &si1, stream< T > &si2, stream< T > &so)
A 2-to-1 generic Stream Multiplexer.
Definition: timers.cpp:90
#define TRACE_RTT
Definition: timers.cpp:73
EventType
Definition: toe.hpp:273
void timers(stream< RXeReTransTimerCmd > &siRXe_ReTxTimerCmd, stream< SessionId > &siRXe_ClrProbeTimer, stream< SessionId > &siRXe_CloseTimer, stream< TXeReTransTimerCmd > &siTXe_ReTxTimerCmd, stream< SessionId > &siTXe_SetProbeTimer, stream< SessionId > &soSTt_SessCloseCmd, stream< Event > &soEVe_Event, stream< SessState > &soTAi_Notif, stream< TcpAppNotif > &soRAi_Notif)
The Timers (TIm)
Definition: timers.cpp:505
const char * getEventName(EventType evType)
Returns the name of an enum-based event as a user friendly string.
Definition: toe_utils.cpp:43
bool gTraceEvent
Definition: tb_nal.cpp:151
#define THIS_NAME
Definition: timers.cpp:68
void pRetransmitTimer(stream< RXeReTransTimerCmd > &siRXe_ReTxTimerCmd, stream< TXeReTransTimerCmd > &siTXe_ReTxTimerCmd, stream< Event > &soEmx_Event, stream< SessionId > &soSmx_SessCloseCmd, stream< SessState > &soTAi_Notif, stream< TcpAppNotif > &soRAi_Notif)
ReTransmit Timer (Rtt) process.
Definition: timers.cpp:135
#define DEBUG_LEVEL
Definition: timers.cpp:76
void pCloseTimer(stream< SessionId > &siRXe_CloseTimer, stream< SessionId > &soSmx_SessCloseCmd)
Close Timer (Clt) process.
Definition: timers.cpp:426
void pProbeTimer(stream< SessionId > &siRXe_ClrProbeTimer, stream< SessionId > &siTXe_SetProbeTimer, stream< Event > &soEmx_Event)
Probe Timer (Prb) process.
Definition: timers.cpp:327
@ SYN_EVENT
Definition: toe.hpp:273
@ TX_EVENT
Definition: toe.hpp:273
@ RT_EVENT
Definition: toe.hpp:273
@ LOAD_TIMER
Definition: toe.hpp:622
ap_uint< 16 > SessionId
Definition: nts_types.hpp:136
bool ValBool
Definition: nts_types.hpp:131
#define printInfo(callerName, format,...)
A macro to print an information message.
Definition: nts_utils.hpp:169
#define printWarn(callerName, format,...)
A macro to print a warning message.
Definition: nts_utils.hpp:182
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
Definition: nts_utils.hpp:161
@ CLOSED
Definition: nts_types.hpp:296
: Timers (TIm) for the TCP Offload Engine (TOE)