cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
tx_engine.cpp
Go to the documentation of this file.
1 
17 
42 
55 #include "tx_engine.hpp"
56 
57 using namespace hls;
58 
59 
63 #ifndef __SYNTHESIS__
64  extern bool gTraceEvent;
65 #endif
66 
67 #define THIS_NAME "TOE/TXe"
68 
69 #define FIXME 1
70 
71 #define TRACE_OFF 0x0000
72 #define TRACE_MDL 1 << 1
73 #define TRACE_IHC 1 << 2
74 #define TRACE_SPS 1 << 3
75 #define TRACE_PHC 1 << 4
76 #define TRACE_MRD 1 << 5
77 #define TRACE_TSS 1 << 6
78 #define TRACE_SCA 1 << 7
79 #define TRACE_TCA 1 << 8
80 #define TRACE_IPS 1 << 9
81 #define TRACE_ALL 0xFFFF
82 
83 #define DEBUG_LEVEL (TRACE_OFF)
84 
85 
86 
118  stream<ExtendedEvent> &siAKd_Event,
119  stream<SessionId> &soRSt_RxSarReq,
120  stream<RxSarReply> &siRSt_RxSarRep,
121  stream<TXeTxSarQuery> &soTSt_TxSarQry,
122  stream<TXeTxSarReply> &siTSt_TxSarRep,
123  stream<TXeReTransTimerCmd> &soTIm_ReTxTimerCmd,
124  stream<SessionId> &soTIm_SetProbeTimer,
125  stream<TcpDatLen> &soIhc_TcpDatLen,
126  stream<TXeMeta> &soPhc_TxeMeta,
127  stream<DmCmd> &soMrd_BufferRdCmd,
128  stream<SessionId> &soSLc_ReverseLkpReq,
129  stream<StsBool> &soSps_IsLookup,
130 #if (TCP_NODELAY)
131  stream<bool> &soTODO_IsDdrBypass,
132 #endif
133  stream<LE_SocketPair> &soSps_RstSockPair,
134  stream<SigBit> &soEVe_RxEventSig)
135 {
136  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
137  #pragma HLS INLINE off
138  #pragma HLS PIPELINE II=1 enable_flush
139 
140  const char *myName = concat3(THIS_NAME, "/", "Mdl");
141 
142  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
143  static enum FsmStates { MDL_WAIT_EVENT=0, MDL_PROCESS_EVENT } \
144  mdl_fsmState=MDL_WAIT_EVENT;
145  #pragma HLS RESET variable=mdl_fsmState
146  static FlagBool mdl_sarLoaded=false;
147  #pragma HLS RESET variable=mdl_sarLoaded
148  static ap_uint<2> mdl_segmentCount=0; // [FIXME - Too small for re-transmit?]
149  #pragma HLS RESET variable=mdl_segmentCount
150 
151  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
152  static ExtendedEvent mdl_curEvent;
153  static RxSarReply mdl_rxSar;
154  static TXeTxSarReply mdl_txSar;
155  static ap_uint<32> mdl_randomValue = 100000; // [FIXME - Add a random Initial Sequence Number in EMIF]
156  static TXeMeta mdl_txeMeta;
157 
158  //-- DYNAMIC VARIABLES -----------------------------------------------------
159  TcpWindow winSize;
160  TcpWindow usableWindow;
161  TcpDatLen currDatLen;
162  ap_uint<16> slowstart_threshold;
163  rstEvent resetEvent;
164 
165  switch (mdl_fsmState) {
166  case MDL_WAIT_EVENT:
167  if (!siAKd_Event.empty()) {
168  siAKd_Event.read(mdl_curEvent);
169  if (DEBUG_LEVEL & TRACE_MDL) {
170  printInfo(myName, "Received event '%s' for session #%d from [AKd].\n",
171  getEventName(mdl_curEvent.type), mdl_curEvent.sessionID.to_uint());
172  }
173  mdl_sarLoaded = false;
174  assessSize(myName, soEVe_RxEventSig, "soEVe_RxEventSig", 2); // [FIXME-Use constant for the length]
175  soEVe_RxEventSig.write(1);
176 
177  // NOT necessary for SYN/SYN_ACK only needs one
178  switch(mdl_curEvent.type) {
179  case RT_EVENT:
180  case TX_EVENT:
181  case SYN_ACK_EVENT:
182  case FIN_EVENT:
183  case ACK_EVENT:
184  case ACK_NODELAY_EVENT:
185  assessSize(myName, soRSt_RxSarReq, "soRSt_RxSarReq", cDepth_TXeToRSt_Req);
186  soRSt_RxSarReq.write(mdl_curEvent.sessionID);
187  assessSize(myName, soTSt_TxSarQry, "soTSt_TxSarQry", cDepth_TXeToTSt_Qry);
188  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID, QUERY_RD));
189  break;
190  case RST_EVENT:
191  // Get txSar for SEQ numb
192  resetEvent = mdl_curEvent;
193  if (resetEvent.hasSessionID()) {
194  assessSize(myName, soTSt_TxSarQry, "soTSt_TxSarQry", cDepth_TXeToTSt_Qry);
195  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID, QUERY_RD));
196  }
197  break;
198  case SYN_EVENT:
199  if (mdl_curEvent.rt_count != 0) {
200  assessSize(myName, soTSt_TxSarQry, "soTSt_TxSarQry", cDepth_TXeToTSt_Qry);
201  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID, QUERY_RD));
202  }
203  break;
204  default:
205  break;
206  }
207  mdl_fsmState = MDL_PROCESS_EVENT;
208  // [FIXME - Add a random Initial Sequence Number in EMIF and move this out of here]
209  mdl_randomValue++;
210  }
211  mdl_segmentCount = 0;
212  break;
213  case MDL_PROCESS_EVENT:
214  switch(mdl_curEvent.type) {
215  // When Nagle's algorithm disabled; Can bypass DDR
216 #if (TCP_NODELAY)
217  case TX:
218  if (DEBUG_LEVEL & TRACE_MDL)
219  printInfo(myName, "Got TX event.\n");
220  if ((!rxSar2txEng_rsp.empty() && !txSar2txEng_upd_rsp.empty()) || ml_sarLoaded) {
221  if (!ml_sarLoaded) {
222  rxSar2txEng_rsp.read(rxSar);
223  txSar2txEng_upd_rsp.read(mdl_txSar);
224  }
225 
226  // Compute our space, Advertise at least a quarter/half, otherwise 0
227  winSize = (rxSar.appd - ((ap_uint<16>)rxSar.recvd)) - 1; // This works even for wrap around
228  meta.ackNumb = rxSar.recvd;
229  meta.seqNumb = mdl_txSar.not_ackd;
230  meta.window_size = winSize;
231  meta.ack = 1; // ACK is always set when established
232  meta.rst = 0;
233  meta.syn = 0;
234  meta.fin = 0;
235 
236  //TODO this is hack, makes sure that probeTimer is never set.
237  if (0x7FFF < ml_curEvent.length) {
238  txEng2timer_setProbeTimer.write(ml_curEvent.sessionID);
239  }
240 
241  meta.length = ml_curEvent.length;
242 
243  // TODO some checking
244  mdl_txSar.not_ackd += ml_curEvent.length;
245 
246  txEng2txSar_upd_req.write(txTxSarQuery(ml_curEvent.sessionID, mdl_txSar.not_ackd, 1));
247  ml_FsmState = 0;
248 
249  // Send a packet only if there is data or we want to send an empty probing message
250  if (meta.length != 0) { // || ml_curEvent.retransmit) //TODO retransmit boolean currently not set, should be removed
251  txEng_ipMetaFifoOut.write(meta.length);
252  txEng_tcpMetaFifoOut.write(meta);
253  txEng_isLookUpFifoOut.write(true);
254  txEng_isDDRbypass.write(true);
255  txEng2sLookup_rev_req.write(ml_curEvent.sessionID);
256 
257  // Only set RT timer if we actually send sth, TODO only set if we change state and sent sth
258  txEng2timer_setRetransmitTimer.write(txRetransmitTimerSet(ml_curEvent.sessionID));
259  } //TODO if probe send msg length 1
260  ml_sarLoaded = true;
261  }
262  break;
263 #else
264  case TX_EVENT:
265  if (DEBUG_LEVEL & TRACE_MDL) {
266  printInfo(myName, "Entering the 'TX' processing.\n");
267  }
268  // Send everything between txSar.not_ackd and txSar.app
269  if ((!siRSt_RxSarRep.empty() and !siTSt_TxSarRep.empty()) or mdl_sarLoaded) {
270  if (!mdl_sarLoaded) {
271  siRSt_RxSarRep.read(mdl_rxSar);
272  siTSt_TxSarRep.read(mdl_txSar);
273  }
274  // Compute our space, Advertise at least a quarter/half, otherwise 0
275  //[FIXME-TODO: It is better to compute and maintain the window_size in the [Rst] module]
276  winSize = ((mdl_rxSar.appd - (RxBufPtr)mdl_rxSar.oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
277  mdl_txeMeta.ackNumb = mdl_rxSar.rcvd;
278  mdl_txeMeta.seqNumb = mdl_txSar.not_ackd;
279  mdl_txeMeta.winSize = winSize;
280  mdl_txeMeta.ack = 1; // ACK is always set when ESTABISHED
281  mdl_txeMeta.rst = 0;
282  mdl_txeMeta.syn = 0;
283  mdl_txeMeta.fin = 0;
284  mdl_txeMeta.length = 0;
285  currDatLen = (mdl_txSar.app - ((TxBufPtr)mdl_txSar.not_ackd));
286 
287  TxBufPtr usedLength = ((TxBufPtr)mdl_txSar.not_ackd - mdl_txSar.ackd);
288  if (mdl_txSar.min_window > usedLength) {
289  // FYI: min_window = Min(txSar.recv_window, mdl_txSar.cong_window)
290  usableWindow = mdl_txSar.min_window - usedLength;
291  }
292  else {
293  usableWindow = 0;
294  }
295 
296  // Construct address before modifying mdl_txSar.not_ackd
297  // FYI - The TCP Tx buffers use up to 1GB (16Kx64KB). They are located at base@+1GB
298  TxMemPtr memSegAddr = TOE_TX_MEMORY_BASE;
299  memSegAddr(29, 16) = mdl_curEvent.sessionID(13, 0);
300  memSegAddr(15, 0) = mdl_txSar.not_ackd(15, 0);
301 
302  // Check if length is bigger than Usable Window or MSS
303  if (currDatLen <= usableWindow) {
304  if (currDatLen+TCP_HEADER_LEN > ZYC2_MSS) {
305  //-- Start IP Fragmentation ----------------------------
306  //-- We stay in this state
307  mdl_txSar.not_ackd += ZYC2_MSS-TCP_HEADER_LEN;
308  mdl_txeMeta.length = ZYC2_MSS-TCP_HEADER_LEN;
309  }
310  else {
311  //-- No IP Fragmentation or End of Fragmentation -------
312  //-- If we sent all data, we might also need to send a FIN
313  if (mdl_txSar.finReady and (mdl_txSar.ackd == mdl_txSar.not_ackd or currDatLen == 0)) {
314  mdl_curEvent.type = FIN_EVENT;
315  }
316  else {
317  mdl_txSar.not_ackd += currDatLen;
318  mdl_txeMeta.length = currDatLen;
319  mdl_fsmState = MDL_WAIT_EVENT;
320  }
321  // Write back 'txSar.not_ackd' pointer
322  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID,
323  mdl_txSar.not_ackd, QUERY_WR));
324  }
325  }
326  else {
327  // Code duplication, but better timing.
328  if (usableWindow+TCP_HEADER_LEN >= ZYC2_MSS) {
329  //-- Start IP Fragmentation ----------------------------
330  //-- We stay in this state
331  mdl_txSar.not_ackd += ZYC2_MSS-TCP_HEADER_LEN;
332  mdl_txeMeta.length = ZYC2_MSS-TCP_HEADER_LEN;
333  }
334  else {
335  // Check if we sent >= MSS data
336  //OBSO if (mdl_txSar.ackd == mdl_txSar.not_ackd) {
337  mdl_txSar.not_ackd += usableWindow;
338  mdl_txeMeta.length = usableWindow;
339  //OBSO }
340  //OBSO // Set probe Timer to try again later
341  //OBSO soTIm_SetProbeTimer.write(mdl_curEvent.sessionID);
342  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID,
343  mdl_txSar.not_ackd, QUERY_WR));
344  mdl_fsmState = MDL_WAIT_EVENT;
345  }
346  }
347 
348  if (mdl_txeMeta.length != 0) {
349  soMrd_BufferRdCmd.write(DmCmd(memSegAddr, mdl_txeMeta.length));
350  }
351  // Send a packet only if there is data or we want to send an empty probing message
352  if (mdl_txeMeta.length != 0) { // || mdl_curEvent.retransmit) //TODO retransmit boolean currently not set, should be removed
353  soIhc_TcpDatLen.write(mdl_txeMeta.length);
354  soPhc_TxeMeta.write(mdl_txeMeta);
355  soSps_IsLookup.write(true);
356  soSLc_ReverseLkpReq.write(mdl_curEvent.sessionID);
357  // Only set RT timer if we actually send sth,
358  // [TODO - Only set if we change state and sent sth]
359  soTIm_ReTxTimerCmd.write(TXeReTransTimerCmd(mdl_curEvent.sessionID));
360  } // [TODO - if probe send msg length 1]
361  mdl_sarLoaded = true;
362  }
363  break;
364 #endif
365  case RT_EVENT:
366  if (DEBUG_LEVEL & TRACE_MDL) { printInfo(myName, "Entering the 'RT' processing.\n"); }
367  if ((!siRSt_RxSarRep.empty() && !siTSt_TxSarRep.empty()) || mdl_sarLoaded) {
368  if (!mdl_sarLoaded) {
369  siRSt_RxSarRep.read(mdl_rxSar);
370  siTSt_TxSarRep.read(mdl_txSar);
371  }
372  // Compute our window size
373  //[FIXME-TODO: It is better to compute and maintain the window_size in the [Rst] module]
374  winSize = ((mdl_rxSar.appd - (RxBufPtr)mdl_rxSar.oooHead(TOE_WINDOW_BITS-1, 0)) - 1); // This works even for wrap around
375  if (!mdl_txSar.finSent) // No FIN sent
376  currDatLen = ((TxBufPtr) mdl_txSar.not_ackd - mdl_txSar.ackd);
377  else // FIN already sent
378  currDatLen = ((TxBufPtr) mdl_txSar.not_ackd - mdl_txSar.ackd)-1;
379  mdl_txeMeta.ackNumb = mdl_rxSar.rcvd;
380  mdl_txeMeta.seqNumb = mdl_txSar.ackd;
381  mdl_txeMeta.winSize = winSize;
382  mdl_txeMeta.ack = 1; // ACK is always set when session is established
383  mdl_txeMeta.rst = 0;
384  mdl_txeMeta.syn = 0;
385  mdl_txeMeta.fin = 0;
386  // Construct address before modifying 'mdl_txSar.ackd'
387  TxMemPtr memSegAddr; // 0x40000000
388  memSegAddr(31, 30) = 0x01;
389  memSegAddr(29, 16) = mdl_curEvent.sessionID(13, 0);
390  memSegAddr(15, 0) = mdl_txSar.ackd(15, 0); // mdl_curEvent.address;
391  // Decrease Slow Start Threshold, only on first RT from retransmitTimer
392  if (!mdl_sarLoaded and (mdl_curEvent.rt_count == 1)) {
393  if (currDatLen > (4*ZYC2_MSS)) { // max(FlightSize/2, 2*MSS) RFC:5681
394  slowstart_threshold = currDatLen/2;
395  }
396  else {
397  slowstart_threshold = (2 * ZYC2_MSS);
398  }
399  soTSt_TxSarQry.write(TXeTxSarRtQuery(mdl_curEvent.sessionID, slowstart_threshold));
400  }
401  // Since we are retransmitting from 'txSar.ackd' to 'txSar.not_ackd',
402  // this data is already inside the usableWindow => No check is required
403  // Only check if length is bigger than MSS
404  if (currDatLen+TCP_HEADER_LEN > ZYC2_MSS) {
405  // We stay in this state and sent immediately another packet
406  mdl_txeMeta.length = ZYC2_MSS-TCP_HEADER_LEN;
407  mdl_txSar.ackd += ZYC2_MSS-TCP_HEADER_LEN;
408  // [TODO - replace with dynamic count, remove this]
409  if (mdl_segmentCount == 3) {
410  // Should set a probe or sth??
411  //txEng2txSar_upd_req.write(txTxSarQuery(ml_curEvent.sessionID, mdl_txSar.not_ackd, 1));
412  mdl_fsmState = MDL_WAIT_EVENT;
413  }
414  mdl_segmentCount++;
415  }
416  else {
417  mdl_txeMeta.length = currDatLen;
418  if (mdl_txSar.finSent) {
419  mdl_curEvent.type = FIN_EVENT;
420  }
421  else {
422  mdl_fsmState = MDL_WAIT_EVENT;
423  }
424  }
425 
426  // Only send a packet if there is data
427  if (mdl_txeMeta.length != 0) {
428  soMrd_BufferRdCmd.write(DmCmd(memSegAddr, mdl_txeMeta.length));
429  soIhc_TcpDatLen.write(mdl_txeMeta.length);
430  soPhc_TxeMeta.write(mdl_txeMeta);
431  soSps_IsLookup.write(true);
432 #if (TCP_NODELAY)
433  soTODO_isDDRbypass.write(false);
434 #endif
435  soSLc_ReverseLkpReq.write(mdl_curEvent.sessionID);
436  // Only set RT timer if we actually send sth
437  soTIm_ReTxTimerCmd.write(TXeReTransTimerCmd(mdl_curEvent.sessionID));
438  }
439  mdl_sarLoaded = true;
440  }
441  break;
442  case ACK_EVENT:
443  case ACK_NODELAY_EVENT:
444  if (DEBUG_LEVEL & TRACE_MDL) { printInfo(myName, "Entering the 'ACK' processing.\n"); }
445  if (!siRSt_RxSarRep.empty() and !siTSt_TxSarRep.empty()) {
446  siRSt_RxSarRep.read(mdl_rxSar);
447  siTSt_TxSarRep.read(mdl_txSar);
448 
449  //[FIXME-TODO: It is better to compute and maintain the window_size in the [Rst] module]
450  winSize = ((mdl_rxSar.appd - (RxBufPtr)mdl_rxSar.oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
451  mdl_txeMeta.ackNumb = mdl_rxSar.rcvd;
452  mdl_txeMeta.seqNumb = mdl_txSar.not_ackd; //Always send SEQ
453  mdl_txeMeta.winSize = winSize;
454  mdl_txeMeta.length = 0;
455  mdl_txeMeta.ack = 1;
456  mdl_txeMeta.rst = 0;
457  mdl_txeMeta.syn = 0;
458  mdl_txeMeta.fin = 0;
459  soIhc_TcpDatLen.write(mdl_txeMeta.length);
460  soPhc_TxeMeta.write(mdl_txeMeta);
461  soSps_IsLookup.write(true);
462  soSLc_ReverseLkpReq.write(mdl_curEvent.sessionID);
463  mdl_fsmState = MDL_WAIT_EVENT;
464  }
465  break;
466  case SYN_EVENT:
467  if (DEBUG_LEVEL & TRACE_MDL) { printInfo(myName, "Entering the 'SYN' processing.\n"); }
468  if (((mdl_curEvent.rt_count != 0) and !siTSt_TxSarRep.empty()) or (mdl_curEvent.rt_count == 0)) {
469  if (mdl_curEvent.rt_count != 0) {
470  siTSt_TxSarRep.read(mdl_txSar);
471  mdl_txeMeta.seqNumb = mdl_txSar.ackd;
472  }
473  else {
474  mdl_txSar.not_ackd = mdl_randomValue; // [FIXME - Use a register from EMIF]
475  mdl_randomValue = (mdl_randomValue* 8) xor mdl_randomValue;
476  // Initialize TxSar with the UnAcked byte pointer
477  mdl_txeMeta.seqNumb = mdl_txSar.not_ackd;
478  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID, mdl_txSar.not_ackd+1, QUERY_WR, QUERY_INIT));
479  }
480  mdl_txeMeta.ackNumb = 0;
481  //mdl_txeMeta.seqNumb = mdl_txSar.not_ackd;
482  mdl_txeMeta.winSize = 0xFFFF;
483  mdl_txeMeta.length = 4; // FYI - MSS adds 4 option bytes
484  mdl_txeMeta.ack = 0;
485  mdl_txeMeta.rst = 0;
486  mdl_txeMeta.syn = 1;
487  mdl_txeMeta.fin = 0;
488  soIhc_TcpDatLen.write(mdl_txeMeta.length);
489  soPhc_TxeMeta.write(mdl_txeMeta);
490  soSps_IsLookup.write(true);
491  soSLc_ReverseLkpReq.write(mdl_curEvent.sessionID);
492  // Set retransmission timer
493  soTIm_ReTxTimerCmd.write(TXeReTransTimerCmd(mdl_curEvent.sessionID, SYN_EVENT));
494  mdl_fsmState = MDL_WAIT_EVENT;
495  }
496  break;
497  case SYN_ACK_EVENT:
498  if (DEBUG_LEVEL & TRACE_MDL) { printInfo(myName, "Entering the 'SYN_ACK' processing.\n"); }
499  if (!siRSt_RxSarRep.empty() and !siTSt_TxSarRep.empty()) {
500  siRSt_RxSarRep.read(mdl_rxSar);
501  siTSt_TxSarRep.read(mdl_txSar);
502 
503  // Construct SYN_ACK message
504  mdl_txeMeta.ackNumb = mdl_rxSar.rcvd;
505  mdl_txeMeta.winSize = MY_MSS * 12;
506  mdl_txeMeta.length = 4; // FYI - MSS adds 4 option bytes
507  mdl_txeMeta.ack = 1;
508  mdl_txeMeta.rst = 0;
509  mdl_txeMeta.syn = 1;
510  mdl_txeMeta.fin = 0;
511  if (mdl_curEvent.rt_count != 0) {
512  mdl_txeMeta.seqNumb = mdl_txSar.ackd;
513  }
514  else {
515  mdl_txSar.not_ackd = mdl_randomValue; // FIXME better rand();
516  mdl_randomValue = (mdl_randomValue* 8) xor mdl_randomValue;
517  // Initialize TxSar with the UnAcked byte pointer
518  mdl_txeMeta.seqNumb = mdl_txSar.not_ackd;
519  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID,
520  mdl_txSar.not_ackd+1, QUERY_WR, QUERY_INIT));
521  }
522  soIhc_TcpDatLen.write(mdl_txeMeta.length);
523  soPhc_TxeMeta.write(mdl_txeMeta);
524  soSps_IsLookup.write(true);
525  soSLc_ReverseLkpReq.write(mdl_curEvent.sessionID);
526  // Set retransmission timer
527  soTIm_ReTxTimerCmd.write(TXeReTransTimerCmd(mdl_curEvent.sessionID, SYN_ACK_EVENT));
528  mdl_fsmState = MDL_WAIT_EVENT;
529  }
530  break;
531  case FIN_EVENT:
532  if (DEBUG_LEVEL & TRACE_MDL) { printInfo(myName, "Entering the 'FIN' processing.\n"); }
533  if ((!siRSt_RxSarRep.empty() && !siTSt_TxSarRep.empty()) || mdl_sarLoaded) {
534  if (!mdl_sarLoaded) {
535  siRSt_RxSarRep.read(mdl_rxSar);
536  siTSt_TxSarRep.read(mdl_txSar);
537  }
538  // Construct FIN message
539  //[FIXME-TODO: It is better to compute and maintain the window_size in the [Rst] module]
540  winSize = ((mdl_rxSar.appd - (RxBufPtr)mdl_rxSar.oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
541  mdl_txeMeta.ackNumb = mdl_rxSar.rcvd;
542  //meta.seqNumb = mdl_txSar.not_ackd;
543  mdl_txeMeta.winSize = winSize;
544  mdl_txeMeta.length = 0;
545  mdl_txeMeta.ack = 1; // has to be set for FIN message as well
546  mdl_txeMeta.rst = 0;
547  mdl_txeMeta.syn = 0;
548  mdl_txeMeta.fin = 1;
549 
550  // Check if retransmission, in case of RT, we have to reuse 'not_ackd' number
551  if (mdl_curEvent.rt_count != 0)
552  mdl_txeMeta.seqNumb = mdl_txSar.not_ackd-1; // Special case, or use ackd?
553  else {
554  mdl_txeMeta.seqNumb = mdl_txSar.not_ackd;
555  // Check if all data is sent, otherwise we have to delay FIN message
556  // Set FIN flag, such that probeTimer is informed
557  if (mdl_txSar.app == mdl_txSar.not_ackd(15, 0))
558  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID, mdl_txSar.not_ackd+1,
559  QUERY_WR, ~QUERY_INIT, true, true));
560  else
561  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID, mdl_txSar.not_ackd,
562  QUERY_WR, ~QUERY_INIT, true, false));
563  }
564 
565  // Check if there is a FIN to be sent // [TODO - maybe restrict this]
566  if (mdl_txeMeta.seqNumb(15, 0) == mdl_txSar.app) {
567  soIhc_TcpDatLen.write(mdl_txeMeta.length);
568  soPhc_TxeMeta.write(mdl_txeMeta);
569  soSps_IsLookup.write(true);
570  soSLc_ReverseLkpReq.write(mdl_curEvent.sessionID);
571  // Set retransmission timer
572  soTIm_ReTxTimerCmd.write(TXeReTransTimerCmd(mdl_curEvent.sessionID));
573  }
574  mdl_fsmState = MDL_WAIT_EVENT;
575  }
576  break;
577  case RST_EVENT:
578  if (DEBUG_LEVEL & TRACE_MDL) { printInfo(myName, "Entering the 'RST' processing.\n"); }
579  // Assumption RST length == 0
580  resetEvent = mdl_curEvent;
581  if (!resetEvent.hasSessionID()) {
582  soIhc_TcpDatLen.write(0);
583  soPhc_TxeMeta.write(TXeMeta(0, resetEvent.getAckNumb(), 1, 1, 0, 0));
584  soSps_IsLookup.write(false);
585  soSps_RstSockPair.write(mdl_curEvent.tuple);
586  mdl_fsmState = MDL_WAIT_EVENT;
587  }
588  else if (!siTSt_TxSarRep.empty()) {
589  siTSt_TxSarRep.read(mdl_txSar);
590  soIhc_TcpDatLen.write(0);
591  soSps_IsLookup.write(true);
592  soSLc_ReverseLkpReq.write(resetEvent.sessionID); //there is no sessionID??
593  soPhc_TxeMeta.write(TXeMeta(mdl_txSar.not_ackd, resetEvent.getAckNumb(), 1, 1, 0, 0));
594 
595  mdl_fsmState = MDL_WAIT_EVENT;
596  }
597  break;
598  } // End of: switch(mdl_curEvent.type)
599  if (DEBUG_LEVEL & TRACE_MDL) {
600  printInfo(myName, "Event : [%s]\n", getEventName(mdl_curEvent.type));
601  printInfo(myName, "\t ackNumb = %lu\n", mdl_txeMeta.ackNumb.to_ulong());
602  printInfo(myName, "\t seqNumb = %lu\n", mdl_txeMeta.seqNumb.to_ulong());
603  printInfo(myName, "\t winSize = %d \n", mdl_txeMeta.winSize.to_uint());
604  printInfo(myName, "\t length = %d \n", mdl_txeMeta.length.to_uint());
605  }
606  break;
607  } // End of: switch
608 
609 } // End of: pMetaDataLoader
610 
611 
625  stream<fourTuple> &siSLc_ReverseLkpRsp,
626  stream<LE_SocketPair> &siMdl_RstSockPair, // [FIXME]
627  stream<StsBool> &siMdl_IsLookup,
628  stream<IpAddrPair> &soIhc_IpAddrPair,
629  stream<SocketPair> &soPhc_SocketPair)
630 {
631  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
632  #pragma HLS PIPELINE II=1 enable_flush
633  #pragma HLS INLINE off
634 
635  const char *myName = concat3(THIS_NAME, "/", "Sps");
636 
637  //-- STATIC CONTROL VARIABLES (with RESET) --------------------------------
638  static bool sps_getMeta=false;
639  #pragma HLS RESET variable=sps_getMeta
640 
641  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
642  static StsBool sps_isLookUp;
643 
644  //-- DYNAMIC VARIABLES ----------------------------------------------------
645  fourTuple tuple;
646 
647  if (not sps_getMeta) {
648  if (!siMdl_IsLookup.empty()) {
649  siMdl_IsLookup.read(sps_isLookUp);
650  sps_getMeta = true;
651  }
652  }
653  else {
654  if (!siSLc_ReverseLkpRsp.empty() && sps_isLookUp) {
655  siSLc_ReverseLkpRsp.read(tuple);
656  SocketPair socketPair(SockAddr(byteSwap32(tuple.srcIp),
657  byteSwap16(tuple.srcPort)),
658  SockAddr(byteSwap32(tuple.dstIp),
659  byteSwap16(tuple.dstPort)));
660  if (DEBUG_LEVEL & TRACE_SPS) {
661  printInfo(myName, "Received the following socket-pair from [SLc]: \n");
662  printSockPair(myName, socketPair);
663  }
664  soIhc_IpAddrPair.write(IpAddrPair(socketPair.src.addr, socketPair.dst.addr));
665  soPhc_SocketPair.write(socketPair);
666  sps_getMeta = false;
667  }
668  else if(!siMdl_RstSockPair.empty() && !sps_isLookUp) {
669  LE_SocketPair leSocketPair;
670  siMdl_RstSockPair.read(leSocketPair);
671  SocketPair socketPair = SocketPair(SockAddr(byteSwap32(leSocketPair.src.addr),
672  byteSwap16(leSocketPair.src.port)),
673  SockAddr(byteSwap32(leSocketPair.dst.addr),
674  byteSwap16(leSocketPair.dst.port)));
675  if (DEBUG_LEVEL & TRACE_SPS) {
676  printInfo(myName, "Received the following socket-pair from [Mdl]: \n");
677  printSockPair(myName, socketPair);
678  }
679  soIhc_IpAddrPair.write(IpAddrPair(socketPair.src.addr, socketPair.dst.addr));
680  soPhc_SocketPair.write(socketPair);
681  sps_getMeta = false;
682  }
683  }
684 }
685 
686 
711  stream<TcpDatLen> &siMdl_TcpDatLen,
712  stream<IpAddrPair> &siSps_IpAddrPair,
713  stream<AxisIp4> &soIPs_IpHeader)
714 {
715  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
716  #pragma HLS INLINE off
717  #pragma HLS PIPELINE II=1 enable_flush
718 
719  const char *myName = concat3(THIS_NAME, "/", "Ihc");
720 
721  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
722  static ap_uint<2> ihc_chunkCounter=0;
723  #pragma HLS RESET variable=ihc_chunkCounter
724 
725  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
726  static IpAddrPair ihc_ipAddrPair;
727 
728  //-- DYNAMIC VARIABLES -----------------------------------------------------
729  AxisIp4 currIpHdrChunk;
730  Ip4TotalLen ip4TotLen = 0;
731  TcpDatLen tcpDatLen;
732 
733  switch(ihc_chunkCounter) {
734  case CHUNK_0:
735  if (!siMdl_TcpDatLen.empty()) {
736  siMdl_TcpDatLen.read(tcpDatLen);
737  currIpHdrChunk.setIp4Version(4);
738  currIpHdrChunk.setIp4HdrLen(5);
739  currIpHdrChunk.setIp4ToS(0);
740  ip4TotLen = IP4_HEADER_LEN + TCP_HEADER_LEN + tcpDatLen;
741  currIpHdrChunk.setIp4TotalLen(ip4TotLen);
742  currIpHdrChunk.setIp4Ident(0);
743  currIpHdrChunk.setIp4Flags(0);
744  currIpHdrChunk.setIp4FragOff(0);
745  currIpHdrChunk.setLE_TKeep(0xFF);
746  currIpHdrChunk.setLE_TLast(0);
747  if (DEBUG_LEVEL & TRACE_IHC) {
748  printAxisRaw(myName, currIpHdrChunk);
749  }
750  soIPs_IpHeader.write(currIpHdrChunk);
751  ihc_chunkCounter++;
752  }
753  break;
754  case CHUNK_1:
755  if (!siSps_IpAddrPair.empty()) {
756  siSps_IpAddrPair.read(ihc_ipAddrPair);
757  currIpHdrChunk.setIp4TtL(0x40);
758  currIpHdrChunk.setIp4Prot((ap_uint<8>)IP4_PROT_TCP);
759  currIpHdrChunk.setIp4HdrCsum(0);
760  currIpHdrChunk.setIp4SrcAddr(ihc_ipAddrPair.src);
761  currIpHdrChunk.setLE_TKeep(0xFF);
762  currIpHdrChunk.setLE_TLast(0);
763  if (DEBUG_LEVEL & TRACE_IHC) {
764  printAxisRaw(myName, currIpHdrChunk);
765  }
766  soIPs_IpHeader.write(currIpHdrChunk);
767  ihc_chunkCounter++;
768  }
769  break;
770  case CHUNK_2:
771  currIpHdrChunk.setIp4DstAddr(ihc_ipAddrPair.dst);
772  currIpHdrChunk.setLE_TKeep(0x0F);
773  currIpHdrChunk.setLE_TLast(TLAST);
774  if (DEBUG_LEVEL & TRACE_IHC) {
775  printAxisRaw(myName, currIpHdrChunk);
776  }
777  soIPs_IpHeader.write(currIpHdrChunk);
778  ihc_chunkCounter = 0;
779  break;
780  }
781 
782 } // End of: pIpHeaderConstructor
783 
784 
819  stream<TXeMeta> &siMdl_TxeMeta,
820  stream<SocketPair> &siSps_SockPair,
821  stream<AxisPsd4> &soTss_PseudoHdr)
822 {
823  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
824  #pragma HLS INLINE off
825  #pragma HLS PIPELINE II=1 enable_flush
826 
827  const char *myName = concat3(THIS_NAME, "/", "Phc");
828 
829  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
830  static ap_uint<3> phc_chunkCount=0;
831  #pragma HLS RESET variable=phc_chunkCount
832 
833  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
834  static TXeMeta phc_meta;
835  static SocketPair phc_socketPair;
836 
837  //-- DYNAMIC VARIABLES -----------------------------------------------------
838  AxisPsd4 currChunk(0, 0xFF, 0);
839  TcpSegLen pseudoHdrLen = 0;
840 
841  switch(phc_chunkCount) {
842  case CHUNK_0:
843  // Build and forward [ IP_DA | IP_SA ]
844  if (!siSps_SockPair.empty() && !siMdl_TxeMeta.empty()) {
845  siSps_SockPair.read(phc_socketPair);
846  siMdl_TxeMeta.read(phc_meta);
847  currChunk.setPsd4SrcAddr(phc_socketPair.src.addr);
848  currChunk.setPsd4DstAddr(phc_socketPair.dst.addr);
849  assessSize(myName, soTss_PseudoHdr, "soTss_PseudoHdr", 32); // [FIXME-Use constant for the length]
850  soTss_PseudoHdr.write(currChunk);
851  if (DEBUG_LEVEL & TRACE_PHC) { printAxisRaw(myName, "soTss_PseudoHdr =", currChunk); }
852  phc_chunkCount++;
853  }
854  break;
855  case CHUNK_1:
856  // Build and forward [ TCP_DP | TCP_SP | SegLen | 0x06 | 0x00 ]
857  currChunk.setPsd4ResBits(0x00);
858  currChunk.setPsd4Prot(IP4_PROT_TCP);
859  // Compute the length of the TCP segment. This includes both the header and the payload.
860  pseudoHdrLen = phc_meta.length + TCP_HEADER_LEN; // [FIXME]
861  currChunk.setPsd4Len(pseudoHdrLen);
862  currChunk.setTcpSrcPort(phc_socketPair.src.port);
863  currChunk.setTcpDstPort(phc_socketPair.dst.port);
864  assessSize(myName, soTss_PseudoHdr, "soTss_PseudoHdr", 32); // [FIXME-Use constant for the length]
865  soTss_PseudoHdr.write(currChunk);
866  if (DEBUG_LEVEL & TRACE_PHC) { printAxisRaw(myName, "soTss_PseudoHdr =", currChunk); }
867  phc_chunkCount++;
868  break;
869  case CHUNK_2:
870  // Build and forward [ AckNum | SeqNum ]
871  currChunk.setTcpSeqNum(phc_meta.seqNumb);
872  currChunk.setTcpAckNum(phc_meta.ackNumb);
873  assessSize(myName, soTss_PseudoHdr, "soTss_PseudoHdr", 32); // [FIXME-Use constant for the length]
874  soTss_PseudoHdr.write(currChunk);
875  if (DEBUG_LEVEL & TRACE_PHC) { printAxisRaw(myName, "soTss_PseudoHdr =", currChunk); }
876  phc_chunkCount++;
877  break;
878  case CHUNK_3:
879  // Build and forward [ UrgPtr | CSum | Win | Flags | DataOffset & Res & NS ]
880  currChunk.setTcpCtrlNs(0);
881  currChunk.setTcpResBits(0);
882  currChunk.setTcpDataOff(5 + (int)phc_meta.syn); // 5x32bits (+ 1x32bits for MSS)
883  currChunk.setTcpCtrlFin(phc_meta.fin);
884  currChunk.setTcpCtrlSyn(phc_meta.syn);
885  currChunk.setTcpCtrlRst(phc_meta.rst);
886  currChunk.setTcpCtrlPsh(0);
887  currChunk.setTcpCtrlAck(phc_meta.ack);
888  currChunk.setTcpCtrlUrg(0);
889  currChunk.setTcpCtrlEce(0);
890  currChunk.setTcpCtrlCwr(0);
891  currChunk.setTcpWindow(phc_meta.winSize);
892  currChunk.setTcpChecksum(0);
893  currChunk.setTcpUrgPtr(0);
894  currChunk.setTLast((phc_meta.length == 0) and (phc_meta.syn == 0));
895  assessSize(myName, soTss_PseudoHdr, "soTss_PseudoHdr", 32); // [FIXME-Use constant for the length]
896  soTss_PseudoHdr.write(currChunk);
897  if (DEBUG_LEVEL & TRACE_PHC) { printAxisRaw(myName, "soTss_PseudoHdr =", currChunk); }
898  if (!phc_meta.syn) {
899  phc_chunkCount = 0;
900  }
901  else {
902  phc_chunkCount++;
903  }
904  break;
905  case CHUNK_4:
906  // Only used for SYN and MSS negotiation
907  // Build and forward [ Data 3:0 | Opt-Data | Opt-Length | Opt-Kind ]
908  currChunk.setTcpOptKind(0x02); // Option Kind = Maximum Segment Size
909  currChunk.setTcpOptLen(0x04); // Option length = 4 bytes
910  currChunk.setTcpOptMss(MY_MSS); // Our Maximum Segment Size (1456)
911  currChunk.setLE_TKeep(0x0F);
912  currChunk.setLE_TLast(TLAST);
913  assessSize(myName, soTss_PseudoHdr, "soTss_PseudoHdr", 32); // [FIXME-Use constant for the length]
914  soTss_PseudoHdr.write(currChunk);
915  if (DEBUG_LEVEL & TRACE_PHC) { printAxisRaw(myName, "soTss_PseudoHdr =", currChunk); }
916  phc_chunkCount = 0;
917  break;
918  } // End of: switch
919 
920 } // End of: pPseudoHeaderConstructor (Phc)
921 
922 
938  stream<AxisPsd4> &siPhc_PseudoHdr,
939  stream<AxisApp> &siMEM_TxP_Data,
940  #if (TCP_NODELAY)
941  stream<bool> &txEng_isDDRbypass,
942  stream<axiWord> &txApp2txEng_data_stream,
943  #endif
944  stream<AxisPsd4> &soSca_PseudoPkt,
945  stream<FlagBool> &siMrd_SplitSegFlag)
946 {
947  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
948  #pragma HLS INLINE off
949  #pragma HLS PIPELINE II=1 enable_flush
950 
951  const char *myName = concat3(THIS_NAME, "/", "Tss");
952 
953  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
954  static enum FsmState { TSS_PSD_HDR=0, TSS_PSD_OPT, TSS_DATA,
955  TSS_FWD_1ST_BUF, TSS_FWD_2ND_BUF,
956  TSS_JOIN_2ND_BUF, TSS_RESIDUE } \
957  tss_fsmState=TSS_PSD_HDR;
958  #pragma HLS RESET variable=tss_fsmState
959  static ap_uint<3> tss_psdHdrChunkCount = 0;
960  #pragma HLS RESET variable=tss_psdHdrChunkCount
961 
962  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
963  static AxisApp tss_prevChunk;
964  static ap_uint<4> tss_memRdOffset;
965  static FlagBool tss_mustJoin;
966 
967  //-- DYNAMIC VARIABLES -----------------------------------------------------
968  bool isShortCutData = false;
969 
970  switch (tss_fsmState) {
971  case TSS_PSD_HDR:
972  //-- Read and forward the first 4 chunks from [Phc]
973  if (!siPhc_PseudoHdr.empty() and !soSca_PseudoPkt.full()) {
974  AxisPsd4 currHdrChunk = siPhc_PseudoHdr.read();
975  soSca_PseudoPkt.write(currHdrChunk);
976 
977  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currHdrChunk); }
978  if (tss_psdHdrChunkCount == 3) {
979  if (currHdrChunk.getTcpCtrlSyn()) {
980  tss_fsmState = TSS_PSD_OPT; // Segment is a SYN, handle MSS
981  }
982  else {
983  tss_fsmState = TSS_DATA;
984  }
985  tss_psdHdrChunkCount = 0;
986  }
987  else {
988  tss_psdHdrChunkCount++;
989  }
990  if (currHdrChunk.getTLast()) {
991  tss_fsmState = TSS_PSD_HDR;
992  tss_psdHdrChunkCount = 0;
993  }
994  }
995  break;
996  case TSS_PSD_OPT:
997  //-- Read fifth chunk from [Phc] because segment includes a TCP option (.i.e, MSS)
998  if (!siPhc_PseudoHdr.empty() and !soSca_PseudoPkt.full()) {
999  AxisPsd4 currHdrChunk = siPhc_PseudoHdr.read();
1000  soSca_PseudoPkt.write(currHdrChunk);
1001 
1002  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currHdrChunk); }
1003  if (not currHdrChunk.getTLast()) {
1004  printFatal(myName, "Pseudo Header is malformed...\n");
1005  }
1006  tss_fsmState = TSS_PSD_HDR;
1007  }
1008  break;
1009  case TSS_DATA:
1010  //-- Handle the very 1st data chunk from the 1st memory buffer
1011  if (!siMEM_TxP_Data.empty() and !siMrd_SplitSegFlag.empty() and !soSca_PseudoPkt.full()) {
1012  siMrd_SplitSegFlag.read(tss_mustJoin);
1013  AxisApp currAppChunk = siMEM_TxP_Data.read();
1014  if (currAppChunk.getTLast()) {
1015  // We are done with the 1st memory buffer
1016  if (tss_mustJoin == false) {
1017  // The TCP segment was not splitted.
1018  // We are done with this segment. Go back to 'TSS_PSD_HDR'.
1019  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1020  tss_fsmState = TSS_PSD_HDR;
1021  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1022  }
1023  else {
1024  // The TCP segment was splitted in two parts
1025  tss_memRdOffset = currAppChunk.getLen();
1026  if (tss_memRdOffset != 8) {
1027  // The last chunk of the 1st memory buffer is not fully populated.
1028  // Don't output anything here. Save the current chunk and goto 'TSS_JOIN_2ND'.
1029  // There, we will fetch more data to fill in the current chunk.
1030  tss_prevChunk = currAppChunk;
1031  tss_fsmState = TSS_JOIN_2ND_BUF;
1032  }
1033  else {
1034  // The last chunk of the 1st memory buffer is populated with
1035  // 8 valid bytes and is therefore also aligned.
1036  // Forward this chunk and goto 'TSS_FWD_2ND_BUF'.
1037  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1038  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1039  tss_fsmState = TSS_FWD_2ND_BUF;
1040  }
1041  }
1042  }
1043  else {
1044  // The 1st memory buffer contains more than one chunk
1045  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1046  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1047  tss_fsmState = TSS_FWD_1ST_BUF;
1048  }
1049  }
1050  break;
1051  case TSS_FWD_1ST_BUF:
1052  //-- Forward all the data chunks of the 1st memory buffer
1053  if (!siMEM_TxP_Data.empty() and !soSca_PseudoPkt.full()) {
1054  AxisApp currAppChunk = siMEM_TxP_Data.read();
1055  if (currAppChunk.getTLast()) {
1056  // We are done with the 1st memory buffer
1057  if (tss_mustJoin == false) {
1058  // The TCP segment was not splitted.
1059  // We are done with this segment. Go back to 'TSS_PSD_HDR'.
1060  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1061  tss_fsmState = TSS_PSD_HDR;
1062  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1063  }
1064  else {
1065  // The TCP segment was splitted in two parts
1066  tss_memRdOffset = currAppChunk.getLen();
1067  // Always clear the last bit of the last chunk of 1st part
1068  currAppChunk.setTLast(0);
1069  if (tss_memRdOffset != 8) {
1070  // The last chunk of the 1st memory buffer is not fully populated.
1071  // Don't output anything here. Save the current chunk and goto 'TSS_JOIN_2ND'.
1072  // There, we will fetch more data to fill in the current chunk.
1073  tss_prevChunk = currAppChunk;
1074  tss_fsmState = TSS_JOIN_2ND_BUF;
1075  }
1076  else {
1077  // The last chunk of the 1st memory buffer is populated with
1078  // 8 valid bytes and is therefore also aligned.
1079  // Forward this chunk and goto 'TSS_FWD_2ND_BUF'.
1080  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1081  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1082  tss_fsmState = TSS_FWD_2ND_BUF;
1083  }
1084  }
1085  }
1086  else {
1087  // Remain in this state and continue streaming the 1st memory buffer
1088  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1089  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1090  }
1091  }
1092  break;
1093  case TSS_FWD_2ND_BUF:
1094  //-- Forward all the data chunks of the 2nd memory buffer
1095  if (!siMEM_TxP_Data.empty() and !soSca_PseudoPkt.full()) {
1096  AxisApp currAppChunk = siMEM_TxP_Data.read();
1097 
1098  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1099  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1100  if (currAppChunk.getTLast()) {
1101  // We are done with the 2nd memory buffer
1102  tss_fsmState = TSS_PSD_HDR;
1103  }
1104  }
1105  break;
1106  case TSS_JOIN_2ND_BUF:
1107  //-- Join the bytes from the 2nd memory buffer to the stream of bytes of
1108  //-- the 1st memory buffer when the 1st buffer was not fully populated.
1109  //-- The re-alignment occurs between the previously read chunk stored
1110  //-- in 'tss_prevChunk' and the latest chunk stored in 'currAppChunk',
1111  //-- and 'tss_memRdOffset' specifies the number of valid bytes in 'tss_prevChunk'.
1112  if (!siMEM_TxP_Data.empty() and !soSca_PseudoPkt.full()) {
1113  AxisApp currAppChunk = siMEM_TxP_Data.read();
1114 
1115  AxisApp joinedChunk(0,0,0); // [FIXME-Create a join method in AxisRaw]
1116  // Set lower-part of the joined chunk with the last bytes of the previous chunk
1117  joinedChunk.setLE_TData(tss_prevChunk.getLE_TData(((int)tss_memRdOffset*8)-1, 0),
1118  ((int)tss_memRdOffset*8)-1, 0);
1119  joinedChunk.setLE_TKeep(tss_prevChunk.getLE_TKeep( (int)tss_memRdOffset -1, 0),
1120  (int)tss_memRdOffset -1, 0);
1121  // Set higher part of the joined chunk with the first bytes of the current chunk
1122  joinedChunk.setLE_TData(currAppChunk.getLE_TData( ARW -1-((int)tss_memRdOffset*8), 0),
1123  ARW -1,((int)tss_memRdOffset*8));
1124  joinedChunk.setLE_TKeep(currAppChunk.getLE_TKeep((ARW/8)-1- (int)tss_memRdOffset, 0),
1125  (ARW/8)-1, (int)tss_memRdOffset);
1126  if (currAppChunk.getLE_TKeep()[8-(int)tss_memRdOffset] == 0) {
1127  // The entire current chunk fits into the remainder of the previous chunk.
1128  // We are done with this 2nd memory buffer.
1129  joinedChunk.setLE_TLast(TLAST);
1130  tss_fsmState = TSS_PSD_HDR;
1131  }
1132  else if (currAppChunk.getLE_TLast()) {
1133  // This cannot be the last chunk because it doesn't fit into the
1134  // available space of the previous chunk. Goto the 'TSS_RESIDUE'
1135  // and handle the remainder of this data chunk
1136  tss_fsmState = TSS_RESIDUE;
1137  }
1138 
1139  soSca_PseudoPkt.write(joinedChunk);
1140  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", joinedChunk); }
1141 
1142  // Move remainder of current chunk to previous chunk
1143  tss_prevChunk.setLE_TData(currAppChunk.getLE_TData(64-1, 64-(int)tss_memRdOffset*8),
1144  ((int)tss_memRdOffset*8)-1, 0);
1145  tss_prevChunk.setLE_TKeep(currAppChunk.getLE_TKeep(8-1, 8-(int)tss_memRdOffset),
1146  (int)tss_memRdOffset-1, 0);
1147  }
1148  break;
1149  case TSS_RESIDUE:
1150  //-- Output the very last unaligned chunk
1151  if (!soSca_PseudoPkt.full()) {
1152  AxisPsd4 lastChunk = AxisPsd4(0, 0, TLAST);
1153  lastChunk.setLE_TData(tss_prevChunk.getLE_TData(((int)tss_memRdOffset*8)-1, 0),
1154  ((int)tss_memRdOffset*8)-1, 0);
1155  lastChunk.setLE_TKeep(tss_prevChunk.getLE_TKeep((int)tss_memRdOffset-1, 0),
1156  (int)tss_memRdOffset-1, 0);
1157 
1158  soSca_PseudoPkt.write(lastChunk);
1159  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", lastChunk); }
1160  tss_fsmState = TSS_PSD_HDR;
1161  }
1162  break;
1163 
1164  #if (TCP_NODELAY)
1165  case 6:
1166  if (!txApp2txEng_data_stream.empty() && !soSca_PseudoPkt.full()) {
1167  txApp2txEng_data_stream.read(currWord);
1168  soSca_PseudoPkt.write(currWord);
1169  if (currWord.last) {
1170  tps_state = 0;
1171  }
1172  }
1173  break;
1174  #endif
1175  #if (TCP_NODELAY)
1176  case 7:
1177  if (!txEng_isDDRbypass.empty()) {
1178  txEng_isDDRbypass.read(isShortCutData);
1179  if (isShortCutData) {
1180  tss_fsmState = 6;
1181  }
1182  else {
1183  TSS_1ST_BUF;
1184  }
1185  }
1186  break;
1187  #endif
1188  } // End of: switch
1189 
1190 } // End of: pTcpSegStitcher
1191 
1192 
1207  stream<AxisPsd4> &siTss_PseudoPkt,
1208  stream<AxisPsd4> &soIps_PseudoPkt,
1209  stream<SubCSums> &soTca_4SubCsums)
1210 {
1211  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1212  #pragma HLS INLINE off
1213  #pragma HLS PIPELINE II=1 enable_flush
1214 
1215  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1216  static bool sca_doForwardChunk=false;
1217  #pragma HLS RESET variable=sca_doForwardChunk
1218  static ap_uint<17> sca_4CSums[4]={0, 0, 0, 0};
1219  #pragma HLS RESET variable=sca_4CSums
1220  #pragma HLS ARRAY_PARTITION \
1221  variable=sca_4CSums complete dim=1
1222 
1223  //-- DYNAMIC VARIABLES -----------------------------------------------------
1224  AxisPsd4 currPktChunk;
1225 
1226  if (!siTss_PseudoPkt.empty()) {
1227  siTss_PseudoPkt.read(currPktChunk);
1228  if (sca_doForwardChunk) {
1229  // We do not forward the first chunk of the pseudo-header
1230  // [FIXME] Consider forwarding all chunks and drop the 1st in the next process.
1231  soIps_PseudoPkt.write(currPktChunk);
1232  }
1233  for (int i = 0; i < 4; i++) {
1234  #pragma HLS UNROLL
1235  TcpCsum temp;
1236  if (currPktChunk.getLE_TKeep(i*2+1, i*2) == 0x3) {
1237  temp( 7, 0) = currPktChunk.getLE_TData(i*16+15, i*16+8);
1238  temp(15, 8) = currPktChunk.getLE_TData(i*16+ 7, i*16);
1239  sca_4CSums[i] += temp;
1240  sca_4CSums[i] = (sca_4CSums[i] + (sca_4CSums[i] >> 16)) & 0xFFFF;
1241  }
1242  else if (currPktChunk.getLE_TKeep()[i*2] == 0x1) {
1243  temp( 7, 0) = 0;
1244  temp(15, 8) = currPktChunk.getLE_TData(i*16+7, i*16);
1245  sca_4CSums[i] += temp;
1246  sca_4CSums[i] = (sca_4CSums[i] + (sca_4CSums[i] >> 16)) & 0xFFFF;
1247  }
1248  }
1249 
1250  sca_doForwardChunk = true;
1251 
1252  if(currPktChunk.getTLast()) {
1253  soTca_4SubCsums.write(sca_4CSums);
1254  sca_doForwardChunk = false;
1255  sca_4CSums[0] = 0;
1256  sca_4CSums[1] = 0;
1257  sca_4CSums[2] = 0;
1258  sca_4CSums[3] = 0;
1259  }
1260  }
1261 } // End-of: Sca
1262 
1263 
1275  stream<SubCSums> &siSca_FourSubCsums,
1276  stream<TcpChecksum> &soIps_TcpCsum)
1277 {
1278  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1279  #pragma HLS INLINE off
1280  #pragma HLS PIPELINE II=1 enable_flush
1281 
1282  const char *myName = concat3(THIS_NAME, "/", "Tca");
1283 
1284  if (!siSca_FourSubCsums.empty()) {
1285  SubCSums tca_4CSums = siSca_FourSubCsums.read();
1286 
1287  tca_4CSums.sum0 += tca_4CSums.sum2;
1288  tca_4CSums.sum1 += tca_4CSums.sum3;
1289  tca_4CSums.sum0 = (tca_4CSums.sum0 + (tca_4CSums.sum0 >> 16)) & 0xFFFF;
1290  tca_4CSums.sum1 = (tca_4CSums.sum1 + (tca_4CSums.sum1 >> 16)) & 0xFFFF;
1291  tca_4CSums.sum0 += tca_4CSums.sum1;
1292  tca_4CSums.sum0 = (tca_4CSums.sum0 + (tca_4CSums.sum0 >> 16)) & 0xFFFF;
1293  tca_4CSums.sum0 = ~tca_4CSums.sum0;
1294 
1295  if (DEBUG_LEVEL & TRACE_TCA) {
1296  printInfo(myName, "Checksum =0x%4.4X\n", tca_4CSums.sum0.to_uint());
1297  }
1298  soIps_TcpCsum.write(tca_4CSums.sum0);
1299  }
1300 }
1301 
1302 
1317  stream<AxisIp4> &siIhc_IpHeader,
1318  stream<AxisPsd4> &siSca_PseudoPkt,
1319  stream<TcpChecksum> &siTca_TcpCsum,
1320  stream<AxisIp4> &soIPTX_Data)
1321 {
1322  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1323  #pragma HLS INLINE off
1324  #pragma HLS PIPELINE II=1 enable_flush
1325 
1326  const char *myName = concat3(THIS_NAME, "/", "Ips");
1327 
1328  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1329  static ap_uint<3> ips_chunkCount=0;
1330  #pragma HLS RESET variable=ips_chunkCount
1331 
1332  //-- DYNAMIC VARIABLES -----------------------------------------------------
1333  AxisIp4 ip4HdrChunk;
1334  AxisPsd4 tcpPsdChunk;
1335  AxisIp4 currChunk(0, 0xFF, 0);
1336  TcpCsum tcpCsum;
1337 
1338  switch (ips_chunkCount) {
1339  case CHUNK_0:
1340  case CHUNK_1:
1341  if (!siIhc_IpHeader.empty() and !soIPTX_Data.full()) {
1342  siIhc_IpHeader.read(ip4HdrChunk);
1343  currChunk = ip4HdrChunk;
1344  soIPTX_Data.write(currChunk);
1345  ips_chunkCount++;
1346  if (DEBUG_LEVEL & TRACE_IPS) { printAxisRaw(myName, "soIPTX_Data =", currChunk); }
1347  }
1348  break;
1349  case CHUNK_2:
1350  // Start concatenating IPv4 header and TCP segment
1351  if (!siIhc_IpHeader.empty() && !siSca_PseudoPkt.empty() and !soIPTX_Data.full()) {
1352  siIhc_IpHeader.read(ip4HdrChunk);
1353  siSca_PseudoPkt.read(tcpPsdChunk);
1354  currChunk.setIp4DstAddr(ip4HdrChunk.getIp4DstAddr());
1355  currChunk.setTcpSrcPort(tcpPsdChunk.getTcpSrcPort());
1356  currChunk.setTcpDstPort(tcpPsdChunk.getTcpDstPort());
1357  soIPTX_Data.write(currChunk);
1358  ips_chunkCount++;
1359  if (DEBUG_LEVEL & TRACE_IPS) { printAxisRaw(myName, "soIPTX_Data =", currChunk); }
1360  }
1361  break;
1362  case CHUNK_3:
1363  if (!siSca_PseudoPkt.empty() and !soIPTX_Data.full()) {
1364  siSca_PseudoPkt.read(tcpPsdChunk);
1365  currChunk.setTcpSeqNum(tcpPsdChunk.getTcpSeqNum());
1366  currChunk.setTcpAckNum(tcpPsdChunk.getTcpAckNum());
1367  soIPTX_Data.write(currChunk);
1368  ips_chunkCount++;
1369  if (DEBUG_LEVEL & TRACE_IPS) { printAxisRaw(myName, "soIPTX_Data =", currChunk); }
1370  }
1371  break;
1372  case CHUNK_4:
1373  if (!siSca_PseudoPkt.empty() and !siTca_TcpCsum.empty() and !soIPTX_Data.full()) {
1374  siSca_PseudoPkt.read(tcpPsdChunk);
1375  siTca_TcpCsum.read(tcpCsum);
1376  // Get CtrlBits & Window & TCP UrgPtr & Checksum
1377  currChunk = tcpPsdChunk;
1378  // Now overwrite TCP checksum
1379  currChunk.setTcpChecksum(tcpCsum);
1380  soIPTX_Data.write(currChunk);
1381  if (DEBUG_LEVEL & TRACE_IPS) { printAxisRaw(myName, "soIPTX_Data =", currChunk); }
1382  ips_chunkCount++;
1383  if (tcpPsdChunk.getTLast()) {
1384  // This is the last chunk if/when there is no data payload
1385  ips_chunkCount = 0;
1386  }
1387  }
1388  break;
1389  default:
1390  if (!siSca_PseudoPkt.empty() and !soIPTX_Data.full()) {
1391  siSca_PseudoPkt.read(tcpPsdChunk); // TCP Data
1392  currChunk = tcpPsdChunk;
1393  soIPTX_Data.write(currChunk);
1394  if (DEBUG_LEVEL & TRACE_IPS) { printAxisRaw(myName, "soIPTX_Data =", currChunk); }
1395  if (tcpPsdChunk.getTLast()) {
1396  ips_chunkCount = 0;
1397  }
1398  }
1399  break;
1400  }
1401 }
1402 
1403 
1420  stream<DmCmd> &siMdl_BufferRdCmd,
1421  stream<DmCmd> &soMEM_TxpRdCmd,
1422  stream<FlagBool> &soTss_SplitMemAcc)
1423 {
1424  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1425  #pragma HLS INLINE off
1426  #pragma HLS PIPELINE II=1 enable_flush
1427 
1428  const char *myName = concat3(THIS_NAME, "/", "Mrd");
1429 
1430  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1431  static enum FsmState { MRD_1ST_ACCESS=0, MRD_2ND_ACCESS } \
1432  mrd_fsmState=MRD_1ST_ACCESS;
1433  #pragma HLS RESET variable=mrd_fsmState
1434 
1435  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
1436  static DmCmd mrd_memRdCmd;
1437  static TxBufPtr mrd_firstAccLen;
1438  static uint16_t mrd_debugCounter=1;
1439 
1440  switch (mrd_fsmState) {
1441  case MRD_1ST_ACCESS:
1442  if (!siMdl_BufferRdCmd.empty() and !soTss_SplitMemAcc.full() and !soMEM_TxpRdCmd.full()) {
1443  siMdl_BufferRdCmd.read(mrd_memRdCmd);
1444 
1445  if ((mrd_memRdCmd.saddr(TOE_WINDOW_BITS-1, 0) + mrd_memRdCmd.btt) > TOE_TX_BUFFER_SIZE) {
1446  // This segment was broken in two memory accesses because TCP Tx memory buffer wrapped around
1447  mrd_firstAccLen = TOE_TX_BUFFER_SIZE - mrd_memRdCmd.saddr;
1448  mrd_fsmState = MRD_2ND_ACCESS;
1449 
1450  soMEM_TxpRdCmd.write(DmCmd(mrd_memRdCmd.saddr, mrd_firstAccLen));
1451  soTss_SplitMemAcc.write(true);
1452  mrd_fsmState = MRD_2ND_ACCESS;
1453 
1454  if (DEBUG_LEVEL & TRACE_MRD) {
1455  printInfo(myName, "TCP Tx memory buffer wraps around: This segment is broken in two memory accesses.\n");
1456  printInfo(myName, "Issuing 1st memory read command #%d - SADDR=0x%9.9x - BTT=%d\n",
1457  mrd_debugCounter, mrd_memRdCmd.saddr.to_uint(), mrd_firstAccLen.to_uint());
1458  }
1459  }
1460  else {
1461  soMEM_TxpRdCmd.write(mrd_memRdCmd);
1462  soTss_SplitMemAcc.write(false);
1463 
1464  if (DEBUG_LEVEL & TRACE_MRD) {
1465  printInfo(myName, "Issuing memory read command #%d - SADDR=0x%9.9x - BTT=%d\n",
1466  mrd_debugCounter, mrd_memRdCmd.saddr.to_uint(), mrd_memRdCmd.btt.to_uint());
1467  mrd_debugCounter++;
1468  }
1469  }
1470  }
1471  break;
1472  case MRD_2ND_ACCESS:
1473  if (!soMEM_TxpRdCmd.full()) {
1474  // Update the command to account for the Tx buffer wrap around
1475  mrd_memRdCmd.saddr(TOE_WINDOW_BITS-1, 0) = 0;
1476  soMEM_TxpRdCmd.write(DmCmd(mrd_memRdCmd.saddr, mrd_memRdCmd.btt - mrd_firstAccLen));
1477  mrd_fsmState = MRD_1ST_ACCESS;
1478 
1479  if (DEBUG_LEVEL & TRACE_MRD) {
1480  printInfo(myName, "Issuing 2nd memory read command #%d - SADDR=0x%9.9x - BTT=%d\n",
1481  mrd_debugCounter, mrd_memRdCmd.saddr.to_uint(),
1482  (mrd_memRdCmd.btt - mrd_firstAccLen).to_uint());
1483  mrd_debugCounter++;
1484  }
1485  }
1486  break;
1487  }
1488 }
1489 
1490 
1518  //-- Ack Delayer & Event Engine Interfaces
1519  stream<ExtendedEvent> &siAKd_Event,
1520  stream<SigBit> &soEVe_RxEventSig,
1521  //-- Rx SAR Table Interface
1522  stream<SessionId> &soRSt_RxSarReq,
1523  stream<RxSarReply> &siRSt_RxSarRep,
1524  //-- Tx SAR Table Interface
1525  stream<TXeTxSarQuery> &soTSt_TxSarQry,
1526  stream<TXeTxSarReply> &siTSt_TxSarRep,
1527  //-- MEM / Tx Read Path Interface
1528  stream<DmCmd> &soMEM_Txp_RdCmd,
1529  stream<AxisApp> &siMEM_TxP_Data,
1530  //-- Timers Interface
1531  stream<TXeReTransTimerCmd> &soTIm_ReTxTimerCmd,
1532  stream<SessionId> &soTIm_SetProbeTimer,
1533  //-- Session Lookup Controller Interface
1534  stream<SessionId> &soSLc_ReverseLkpReq,
1535  stream<fourTuple> &siSLc_ReverseLkpRep,
1536  //-- IP Tx Interface
1537  stream<AxisIp4> &soIPTX_Data)
1538 {
1539  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1540  #pragma HLS DATAFLOW
1541  #pragma HLS INTERFACE ap_ctrl_none port=return
1542 
1543  //==========================================================================
1544  //== LOCAL STREAMS (Sorted by the name of the modules which generate them)
1545  //==========================================================================
1546 
1547  //--------------------------------------------------------------------------
1548  //-- Meta Data Loader (Mdl)
1549  //--------------------------------------------------------------------------
1550  static stream<TcpDatLen> ssMdlToIhc_TcpDatLen ("ssMdlToIhc_TcpDatLen");
1551  #pragma HLS stream variable=ssMdlToIhc_TcpDatLen depth=16
1552 
1553  static stream<TXeMeta> ssMdlToPhc_TxeMeta ("ssMdlToPhc_TxeMeta");
1554  #pragma HLS stream variable=ssMdlToPhc_TxeMeta depth=16
1555  #pragma HLS DATA_PACK variable=ssMdlToPhc_TxeMeta
1556 
1557  static stream<bool> ssMdlToSpS_IsLookup ("ssMdlToSpS_IsLookup");
1558  #pragma HLS stream variable=ssMdlToSpS_IsLookup depth=4
1559 
1560  static stream<DmCmd> ssMdlToMrd_BufferRdCmd ("ssMdlToMrd_BufferRdCmd");
1561  #pragma HLS stream variable=ssMdlToMrd_BufferRdCmd depth=32
1562  #pragma HLS DATA_PACK variable=ssMdlToMrd_BufferRdCmd
1563 
1564  static stream<LE_SocketPair> ssMdlToSps_RstSockPair ("ssMdlToSps_RstSockPair");
1565  #pragma HLS stream variable=ssMdlToSps_RstSockPair depth=2
1566  #pragma HLS DATA_PACK variable=ssMdlToSps_RstSockPair
1567 
1568  //--------------------------------------------------------------------------
1569  //-- Ip Header Construction (Ihc)
1570  //--------------------------------------------------------------------------
1571  static stream<AxisIp4> ssIhcToIps_IpHeader ("ssIhcToIps_IpHeader");
1572  #pragma HLS stream variable=ssIhcToIps_IpHeader depth=32
1573  #pragma HLS DATA_PACK variable=ssIhcToIps_IpHeader
1574 
1575  //-------------------------------------------------------------------------
1576  //-- Pseudo Header Construction (Phc)
1577  //-------------------------------------------------------------------------
1578  static stream<AxisPsd4> ssPhcToTss_PseudoHdr ("ssPhcToTss_PseudoHdr");
1579  #pragma HLS stream variable=ssPhcToTss_PseudoHdr depth=32
1580  #pragma HLS DATA_PACK variable=ssPhcToTss_PseudoHdr
1581 
1582  //-------------------------------------------------------------------------
1583  //-- Socket Pair Splitter (Sps)
1584  //-------------------------------------------------------------------------
1585  static stream<IpAddrPair> ssSpsToIhc_IpAddrPair ("ssSpsToIhc_IpAddrPair");
1586  #pragma HLS stream variable=ssSpsToIhc_IpAddrPair depth=4
1587  #pragma HLS DATA_PACK variable=ssSpsToIhc_IpAddrPair
1588 
1589  static stream<SocketPair> ssSpsToPhc_SockPair ("ssSpsToPhc_SockPair");
1590  #pragma HLS stream variable=ssSpsToPhc_SockPair depth=4
1591  #pragma HLS DATA_PACK variable=ssSpsToPhc_SockPair
1592 
1593  //-------------------------------------------------------------------------
1594  //-- TCP Segment Stitcher (Tss)
1595  //-------------------------------------------------------------------------
1596  static stream<AxisPsd4> ssTssToSca_PseudoPkt ("ssTssToSca_PseudoPkt");
1597  #pragma HLS stream variable=ssTssToSca_PseudoPkt depth=16
1598  #pragma HLS DATA_PACK variable=ssTssToSca_PseudoPkt
1599 
1600  //-------------------------------------------------------------------------
1601  //-- TCP Checksum Accumulator (Tca)
1602  //-------------------------------------------------------------------------
1603  static stream<TcpChecksum> ssTcaToIps_TcpCsum ("ssTcaToIps_TcpCsum");
1604  #pragma HLS stream variable=ssTcaToIps_TcpCsum depth=4
1605 
1606  //-------------------------------------------------------------------------
1607  //-- Sub-Checksum Accumulator (Sca)
1608  //-------------------------------------------------------------------------
1609  static stream<AxisPsd4> ssScaToIps_PseudoPkt ("ssScaToIps_PseudoPkt");
1610  #pragma HLS stream variable=ssScaToIps_PseudoPkt depth=256 // WARNING: Critical; has to keep complete packet for checksum computation
1611  #pragma HLS DATA_PACK variable=ssScaToIps_PseudoPkt
1612 
1613  static stream<SubCSums> ssScaToTca_FourSubCsums ("ssScaToTca_FourSubCsums");
1614  #pragma HLS stream variable=ssScaToTca_FourSubCsums depth=2
1615  #pragma HLS DATA_PACK variable=ssScaToTca_FourSubCsums
1616 
1617  //------------------------------------------------------------------------
1618  //-- Memory Reader (Mrd)
1619  //------------------------------------------------------------------------
1620  static stream<FlagBool> ssMrdToTss_SplitMemAcc ("ssMrdToTss_SplitMemAcc");
1621  #pragma HLS stream variable=ssMrdToTss_SplitMemAcc depth=32
1622 
1623  //-------------------------------------------------------------------------
1624  //-- PROCESS FUNCTIONS
1625  //-------------------------------------------------------------------------
1626 
1628  siAKd_Event,
1629  soRSt_RxSarReq,
1630  siRSt_RxSarRep,
1631  soTSt_TxSarQry,
1632  siTSt_TxSarRep,
1633  soTIm_ReTxTimerCmd,
1634  soTIm_SetProbeTimer,
1635  ssMdlToIhc_TcpDatLen,
1636  ssMdlToPhc_TxeMeta,
1637  ssMdlToMrd_BufferRdCmd,
1638  soSLc_ReverseLkpReq,
1639  ssMdlToSpS_IsLookup,
1640  ssMdlToSps_RstSockPair,
1641  soEVe_RxEventSig);
1642 
1644  ssMdlToMrd_BufferRdCmd,
1645  soMEM_Txp_RdCmd,
1646  ssMrdToTss_SplitMemAcc);
1647 
1649  siSLc_ReverseLkpRep,
1650  ssMdlToSps_RstSockPair,
1651  ssMdlToSpS_IsLookup,
1652  ssSpsToIhc_IpAddrPair,
1653  ssSpsToPhc_SockPair);
1654 
1656  ssMdlToIhc_TcpDatLen,
1657  ssSpsToIhc_IpAddrPair,
1658  ssIhcToIps_IpHeader);
1659 
1661  ssIhcToIps_IpHeader,
1662  ssScaToIps_PseudoPkt,
1663  ssTcaToIps_TcpCsum,
1664  soIPTX_Data);
1665 
1667  ssMdlToPhc_TxeMeta,
1668  ssSpsToPhc_SockPair,
1669  ssPhcToTss_PseudoHdr);
1670 
1672  ssPhcToTss_PseudoHdr,
1673  siMEM_TxP_Data,
1674  ssTssToSca_PseudoPkt,
1675  ssMrdToTss_SplitMemAcc);
1676 
1678  ssTssToSca_PseudoPkt,
1679  ssScaToIps_PseudoPkt,
1680  ssScaToTca_FourSubCsums);
1681 
1683  ssScaToTca_FourSubCsums,
1684  ssTcaToIps_TcpCsum);
1685 
1686 }
1687 
void setTcpAckNum(TcpAckNum num)
Definition: AxisIp4.hpp:250
void setIp4FragOff(Ip4FragOff offset)
Definition: AxisIp4.hpp:210
void setTcpSeqNum(TcpSeqNum num)
Definition: AxisIp4.hpp:247
void setIp4Prot(Ip4Prot prot)
Definition: AxisIp4.hpp:220
Ip4Addr getIp4DstAddr()
Definition: AxisIp4.hpp:230
void setIp4HdrLen(Ip4HdrLen ihl)
Definition: AxisIp4.hpp:198
void setTcpDstPort(TcpPort port)
Definition: AxisIp4.hpp:244
void setIp4HdrCsum(Ip4HdrCsum csum)
Definition: AxisIp4.hpp:223
void setTcpChecksum(TcpChecksum csum)
Definition: AxisIp4.hpp:272
void setIp4DstAddr(Ip4Addr addr)
Definition: AxisIp4.hpp:229
void setIp4TotalLen(Ip4TotalLen len)
Definition: AxisIp4.hpp:204
void setIp4Flags(Ip4Flags flags)
Definition: AxisIp4.hpp:215
void setIp4Version(Ip4Version ver)
Definition: AxisIp4.hpp:195
void setTcpSrcPort(TcpPort port)
Definition: AxisIp4.hpp:241
void setIp4Ident(Ip4Ident id)
Definition: AxisIp4.hpp:207
void setIp4ToS(Ip4ToS tos)
Definition: AxisIp4.hpp:201
void setIp4SrcAddr(Ip4Addr addr)
Definition: AxisIp4.hpp:226
void setIp4TtL(Ip4TtL ttl)
Definition: AxisIp4.hpp:217
TcpPort getTcpDstPort()
Definition: AxisPsd4.hpp:149
void setTcpWindow(TcpWindow win)
Definition: AxisPsd4.hpp:183
TcpSeqNum getTcpSeqNum()
Definition: AxisPsd4.hpp:152
void setTcpResBits(TcpResBits res)
Definition: AxisPsd4.hpp:160
void setTcpCtrlPsh(TcpCtrlBit bit)
Definition: AxisPsd4.hpp:172
void setTcpUrgPtr(TcpUrgPtr ptr)
Definition: AxisPsd4.hpp:189
void setTcpChecksum(TcpChecksum csum)
Definition: AxisPsd4.hpp:186
void setTcpDstPort(TcpPort port)
Definition: AxisPsd4.hpp:148
void setPsd4Len(Ly4Len len)
Definition: AxisPsd4.hpp:138
void setPsd4DstAddr(Ip4Addr addr)
Definition: AxisPsd4.hpp:129
void setTcpCtrlAck(TcpCtrlBit bit)
Definition: AxisPsd4.hpp:174
void setTcpCtrlEce(TcpCtrlBit bit)
Definition: AxisPsd4.hpp:178
void setTcpSrcPort(TcpPort port)
Definition: AxisPsd4.hpp:145
TcpPort getTcpSrcPort()
Definition: AxisPsd4.hpp:146
void setTcpOptKind(TcpOptKind val)
Definition: AxisPsd4.hpp:192
void setTcpCtrlUrg(TcpCtrlBit bit)
Definition: AxisPsd4.hpp:176
void setTcpCtrlSyn(TcpCtrlBit bit)
Definition: AxisPsd4.hpp:168
void setTcpAckNum(TcpAckNum num)
Definition: AxisPsd4.hpp:154
void setTcpOptMss(TcpOptMss val)
Definition: AxisPsd4.hpp:197
void setPsd4ResBits(Psd4Res res)
Definition: AxisPsd4.hpp:132
void setTcpDataOff(TcpDataOff offset)
Definition: AxisPsd4.hpp:163
void setTcpCtrlFin(TcpCtrlBit bit)
Definition: AxisPsd4.hpp:166
void setTcpCtrlRst(TcpCtrlBit bit)
Definition: AxisPsd4.hpp:170
TcpAckNum getTcpAckNum()
Definition: AxisPsd4.hpp:155
void setPsd4Prot(Ip4Prot prot)
Definition: AxisPsd4.hpp:135
void setTcpSeqNum(TcpSeqNum num)
Definition: AxisPsd4.hpp:151
void setTcpCtrlNs(TcpCtrlBit bit)
Definition: AxisPsd4.hpp:157
void setTcpCtrlCwr(TcpCtrlBit bit)
Definition: AxisPsd4.hpp:180
TcpCtrlBit getTcpCtrlSyn()
Definition: AxisPsd4.hpp:169
void setTcpOptLen(TcpOptLen len)
Definition: AxisPsd4.hpp:195
void setPsd4SrcAddr(Ip4Addr addr)
Definition: AxisPsd4.hpp:126
void setTLast(tLast last)
Definition: AxisRaw.hpp:246
tLast getTLast() const
Definition: AxisRaw.hpp:219
LE_tKeep getLE_TKeep(int leHi=64/8-1, int leLo=0) const
Definition: AxisRaw.hpp:264
LE_tData getLE_TData(int leHi=64 -1, int leLo=0) const
Definition: AxisRaw.hpp:260
void setLE_TLast(LE_tLast last)
Definition: AxisRaw.hpp:280
void setLE_TData(LE_tData data, int leHi=64 -1, int leLo=0)
Definition: AxisRaw.hpp:272
int getLen() const
Definition: AxisRaw.hpp:411
void setLE_TKeep(LE_tKeep keep, int leHi=64/8-1, int leLo=0)
Definition: AxisRaw.hpp:276
LE_tLast getLE_TLast() const
Definition: AxisRaw.hpp:268
ap_uint< 40 > saddr
ap_uint< 23 > btt
Definition: mem.hpp:85
ap_uint< 3 > rt_count
Definition: toe.hpp:667
SessionId sessionID
Definition: toe.hpp:664
EventType type
Definition: toe.hpp:663
LE_SocketPair tuple
Definition: toe.hpp:685
Ip4Addr src
Definition: tx_engine.hpp:115
Ip4Addr dst
Definition: tx_engine.hpp:116
LE_Ip4Address addr
Definition: nts_types.hpp:222
LE_Ly4Port port
Definition: nts_types.hpp:223
LE_SockAddr dst
Definition: nts_types.hpp:263
LE_SockAddr src
Definition: nts_types.hpp:262
RxBufPtr appd
Definition: toe.hpp:370
RxSeqNum oooHead
Definition: toe.hpp:372
RxSeqNum rcvd
Definition: toe.hpp:371
Ip4Addr addr
Definition: nts_types.hpp:209
Ly4Port port
Definition: nts_types.hpp:210
SockAddr dst
Definition: nts_types.hpp:249
SockAddr src
Definition: nts_types.hpp:248
ap_uint< 1 > ack
Definition: tx_engine.hpp:79
ap_uint< 1 > rst
Definition: tx_engine.hpp:80
TcpSegLen length
Definition: tx_engine.hpp:78
TcpWindow winSize
Definition: tx_engine.hpp:77
TcpSeqNum seqNumb
Definition: tx_engine.hpp:75
ap_uint< 1 > syn
Definition: tx_engine.hpp:81
TcpAckNum ackNumb
Definition: tx_engine.hpp:76
ap_uint< 1 > fin
Definition: tx_engine.hpp:82
TcpWindow min_window
Definition: toe.hpp:517
bool finReady
Definition: toe.hpp:519
TxAckNum not_ackd
Definition: toe.hpp:516
TxAckNum ackd
Definition: toe.hpp:515
bool finSent
Definition: toe.hpp:520
TxBufPtr app
Definition: toe.hpp:518
bool StsBool
Definition: nal.hpp:246
#define TRACE_TCA
Definition: tx_engine.cpp:79
ap_uint< 32 > TxMemPtr
Definition: toe.hpp:296
void pTcpSegStitcher(stream< AxisPsd4 > &siPhc_PseudoHdr, stream< AxisApp > &siMEM_TxP_Data, stream< AxisPsd4 > &soSca_PseudoPkt, stream< FlagBool > &siMrd_SplitSegFlag)
Definition: tx_engine.cpp:937
void pTcpChecksumAccumulator(stream< SubCSums > &siSca_FourSubCsums, stream< TcpChecksum > &soIps_TcpCsum)
TCP Checksum Accumulator (Tca)
Definition: tx_engine.cpp:1274
#define TRACE_IHC
Definition: tx_engine.cpp:73
#define TRACE_IPS
Definition: tx_engine.cpp:80
#define TRACE_TSS
Definition: tx_engine.cpp:77
const int cDepth_TXeToRSt_Req
Definition: toe.hpp:230
const char * getEventName(EventType evType)
Returns the name of an enum-based event as a user friendly string.
Definition: toe_utils.cpp:43
#define TRACE_MRD
Definition: tx_engine.cpp:76
void pSubChecksumAccumulators(stream< AxisPsd4 > &siTss_PseudoPkt, stream< AxisPsd4 > &soIps_PseudoPkt, stream< SubCSums > &soTca_4SubCsums)
Sub-Checksum Accumulator (Sca)
Definition: tx_engine.cpp:1206
void pMetaDataLoader(stream< ExtendedEvent > &siAKd_Event, stream< SessionId > &soRSt_RxSarReq, stream< RxSarReply > &siRSt_RxSarRep, stream< TXeTxSarQuery > &soTSt_TxSarQry, stream< TXeTxSarReply > &siTSt_TxSarRep, stream< TXeReTransTimerCmd > &soTIm_ReTxTimerCmd, stream< SessionId > &soTIm_SetProbeTimer, stream< TcpDatLen > &soIhc_TcpDatLen, stream< TXeMeta > &soPhc_TxeMeta, stream< DmCmd > &soMrd_BufferRdCmd, stream< SessionId > &soSLc_ReverseLkpReq, stream< StsBool > &soSps_IsLookup, stream< LE_SocketPair > &soSps_RstSockPair, stream< SigBit > &soEVe_RxEventSig)
Meta Data Loader (Mdl)
Definition: tx_engine.cpp:117
bool gTraceEvent
Definition: tb_nal.cpp:151
#define THIS_NAME
Definition: tx_engine.cpp:67
TcpBufAdr TxBufPtr
Definition: toe.hpp:299
void pIpHeaderConstructor(stream< TcpDatLen > &siMdl_TcpDatLen, stream< IpAddrPair > &siSps_IpAddrPair, stream< AxisIp4 > &soIPs_IpHeader)
IPv4 Header Constructor (Ihc)
Definition: tx_engine.cpp:710
TcpBufAdr RxBufPtr
Definition: toe.hpp:298
void tx_engine(stream< ExtendedEvent > &siAKd_Event, stream< SigBit > &soEVe_RxEventSig, stream< SessionId > &soRSt_RxSarReq, stream< RxSarReply > &siRSt_RxSarRep, stream< TXeTxSarQuery > &soTSt_TxSarQry, stream< TXeTxSarReply > &siTSt_TxSarRep, stream< DmCmd > &soMEM_Txp_RdCmd, stream< AxisApp > &siMEM_TxP_Data, stream< TXeReTransTimerCmd > &soTIm_ReTxTimerCmd, stream< SessionId > &soTIm_SetProbeTimer, stream< SessionId > &soSLc_ReverseLkpReq, stream< fourTuple > &siSLc_ReverseLkpRep, stream< AxisIp4 > &soIPTX_Data)
Transmit Engine (TXe)
Definition: tx_engine.cpp:1517
void pIpPktStitcher(stream< AxisIp4 > &siIhc_IpHeader, stream< AxisPsd4 > &siSca_PseudoPkt, stream< TcpChecksum > &siTca_TcpCsum, stream< AxisIp4 > &soIPTX_Data)
IPv4 Packet Stitcher (Ips)
Definition: tx_engine.cpp:1316
#define DEBUG_LEVEL
Definition: tx_engine.cpp:83
#define TRACE_PHC
Definition: tx_engine.cpp:75
void pPseudoHeaderConstructor(stream< TXeMeta > &siMdl_TxeMeta, stream< SocketPair > &siSps_SockPair, stream< AxisPsd4 > &soTss_PseudoHdr)
Pseudo Header Constructor (Phc)
Definition: tx_engine.cpp:818
void pTxMemoryReader(stream< DmCmd > &siMdl_BufferRdCmd, stream< DmCmd > &soMEM_TxpRdCmd, stream< FlagBool > &soTss_SplitMemAcc)
Tx Memory Reader (Mrd)
Definition: tx_engine.cpp:1419
#define TRACE_MDL
Definition: tx_engine.cpp:72
#define TRACE_SPS
Definition: tx_engine.cpp:74
void pSocketPairSplitter(stream< fourTuple > &siSLc_ReverseLkpRsp, stream< LE_SocketPair > &siMdl_RstSockPair, stream< StsBool > &siMdl_IsLookup, stream< IpAddrPair > &soIhc_IpAddrPair, stream< SocketPair > &soPhc_SocketPair)
Definition: tx_engine.cpp:624
const int cDepth_TXeToTSt_Qry
Definition: toe.hpp:231
@ RST_EVENT
Definition: toe.hpp:274
@ SYN_EVENT
Definition: toe.hpp:273
@ ACK_EVENT
Definition: toe.hpp:273
@ FIN_EVENT
Definition: toe.hpp:274
@ SYN_ACK_EVENT
Definition: toe.hpp:274
@ TX_EVENT
Definition: toe.hpp:273
@ RT_EVENT
Definition: toe.hpp:273
@ ACK_NODELAY_EVENT
Definition: toe.hpp:274
@ CHUNK_2
Definition: toe.hpp:244
@ CHUNK_1
Definition: toe.hpp:244
@ CHUNK_4
Definition: toe.hpp:244
@ CHUNK_3
Definition: toe.hpp:244
@ CHUNK_0
Definition: toe.hpp:244
ap_uint< 16 > TcpSegLen
Definition: AxisTcp.hpp:121
#define assessSize(callerName, stream, streamName, depth)
A macro that checks if a stream is full.
Definition: nts_utils.hpp:223
void printAxisRaw(const char *callerName, AxisRaw chunk)
Prints an Axis raw data chunk (used for debugging).
Definition: nts_utils.cpp:46
ap_uint< 16 > TcpCsum
Definition: AxisTcp.hpp:114
#define ARW
Definition: AxisRaw.hpp:114
#define QUERY_RD
Definition: nts_types.hpp:65
#define TCP_HEADER_LEN
Definition: AxisTcp.hpp:81
bool FlagBool
Definition: nts_types.hpp:124
#define QUERY_WR
Definition: nts_types.hpp:66
#define IP4_PROT_TCP
Definition: nts_types.hpp:184
ap_uint< 16 > TcpDatLen
Definition: AxisTcp.hpp:123
#define QUERY_INIT
Definition: nts_types.hpp:67
#define IP4_HEADER_LEN
Definition: AxisIp4.hpp:133
#define printInfo(callerName, format,...)
A macro to print an information message.
Definition: nts_utils.hpp:169
ap_uint< 16 > Ip4TotalLen
Definition: AxisIp4.hpp:159
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
Definition: nts_utils.hpp:161
ap_uint< 16 > TcpWindow
Definition: AxisTcp.hpp:112
void printSockPair(const char *callerName, SocketPair sockPair)
Print a socket pair association.
Definition: nts_utils.cpp:114
#define printFatal(callerName, format,...)
A macro to print a fatal error message and exit.
Definition: nts_utils.hpp:208
#define TLAST
Definition: AxisRaw.hpp:116
ap_uint< 17 > sum3
Definition: tx_engine.hpp:101
ap_uint< 17 > sum0
Definition: tx_engine.hpp:98
ap_uint< 17 > sum1
Definition: tx_engine.hpp:99
ap_uint< 17 > sum2
Definition: tx_engine.hpp:100
ap_uint< 32 > dstIp
Definition: nts_types.hpp:231
ap_uint< 32 > srcIp
Definition: nts_types.hpp:230
ap_uint< 16 > dstPort
Definition: nts_types.hpp:233
ap_uint< 16 > srcPort
Definition: nts_types.hpp:232
TxAckNum getAckNumb()
Definition: toe.hpp:707
bool hasSessionID()
Definition: toe.hpp:713
: Tx Engine (TXe) of the TCP Offload Engine (TOE)
ap_uint< 32 > byteSwap32(ap_uint< 32 > inputVector)
Definition: udp.cpp:78
ap_uint< 16 > byteSwap16(ap_uint< 16 > inputVector)
Definition: udp.cpp:82