cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
rx_engine.cpp
Go to the documentation of this file.
1 
17 
42 
55 #include "rx_engine.hpp"
56 
57 using namespace hls;
58 
59 
60 
64 #ifndef __SYNTHESIS__
65  extern bool gTraceEvent;
66 #endif
67 
68 #define THIS_NAME "TOE/RXe"
69 
70 #define TRACE_OFF 0x0000
71 #define TRACE_TLE 1 << 1
72 #define TRACE_IPH 1 << 2
73 #define TRACE_CSA 1 << 3
74 #define TRACE_MDH 1 << 4
75 #define TRACE_TID 1 << 5
76 #define TRACE_TSD 1 << 6
77 #define TRACE_EVM 1 << 7
78 #define TRACE_FSM 1 << 8
79 #define TRACE_MWR 1 << 9
80 #define TRACE_RAN 1 << 10
81 #define TRACE_ALL 0xFFFF
82 
83 #define DEBUG_LEVEL (TRACE_OFF)
84 
85 
86 
146  stream<AxisIp4> &siIPRX_Data,
147  stream<AxisRaw> &soIph_Data,
148  stream<TcpSegLen> &soIph_TcpSegLen)
149 {
150  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
151  #pragma HLS PIPELINE II=1 enable_flush
152  #pragma HLS INLINE off
153 
154  const char *myName = concat3(THIS_NAME, "/", "Tle");
155 
156  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
157  static ap_uint<4> tle_chunkCount=0;
158  #pragma HLS RESET variable=tle_chunkCount
159  static bool tle_residue=false;
160  #pragma HLS RESET variable=tle_residue
161 
162  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
163  static bool tle_shift; // Keeps track of the chunk alignment
164  static Ip4HdrLen tle_ip4HdrLen;
165  static Ip4TotalLen tle_ip4TotLen;
166  static Ip4DatLen tle_ipDataLen;
167  static AxisIp4 tle_prevChunk;
168 
169  //-- DYNAMIC VARIABLES -----------------------------------------------------
170  AxisRaw sendChunk;
171 
172  //-- MAIN PROCESS
173  if (!siIPRX_Data.empty() and !soIph_Data.full() and !tle_residue) {
174  AxisIp4 currChunk = siIPRX_Data.read();
175  switch (tle_chunkCount) {
176  case CHUNK_0:
177  tle_ip4HdrLen = currChunk.getIp4HdrLen();
178  tle_ip4TotLen = currChunk.getIp4TotalLen();
179  // Compute length of IPv4 data (.i.e. the TCP segment length)
180  tle_ipDataLen = tle_ip4TotLen - (tle_ip4HdrLen * 4);
181  tle_ip4HdrLen -= 2; // We just processed 8 bytes
182  tle_chunkCount++;
183  break;
184  case CHUNK_1:
185  // Forward length of IPv4 data (.i.e. the TCP segment length)
186  soIph_TcpSegLen.write(tle_ipDataLen);
187  tle_ip4HdrLen -= 2; // We just processed 8 bytes
188  tle_chunkCount++;
189  break;
190  case CHUNK_2:
191  // Forward destination IP address
192  // Warning, half of this address is now in 'prevChunk'
193  sendChunk.setLE_TData(tle_prevChunk.getLE_TData(63, 32), 31, 0);
194  sendChunk.setLE_TKeep(tle_prevChunk.getLE_TKeep( 7, 4), 3, 0);
195  sendChunk.setLE_TData( currChunk.getLE_TData(31, 0), 63, 32);
196  sendChunk.setLE_TKeep( currChunk.getLE_TKeep( 3, 0), 7, 4);
197  sendChunk.setLE_TLast( currChunk.getLE_TKeep()[4] == 0);
198  soIph_Data.write(sendChunk);
199  tle_ip4HdrLen -= 1; // We just processed the last 4 bytes of a standard IP4 header
200  tle_chunkCount++;
201  if (DEBUG_LEVEL & TRACE_TLE) { printAxisRaw(myName, "soIph_Data =", sendChunk); }
202  break;
203  case CHUNK_3:
204  switch (tle_ip4HdrLen) {
205  case 0: // No or end of IP option(s) - Forward half of 'prevChunk' and half of 'currChunk'.
206  sendChunk.setLE_TData(tle_prevChunk.getLE_TData(63, 32), 31, 0);
207  sendChunk.setLE_TKeep(tle_prevChunk.getLE_TKeep( 7, 4), 3, 0);
208  sendChunk.setLE_TData( currChunk.getLE_TData(31, 0), 63, 32);
209  sendChunk.setLE_TKeep( currChunk.getLE_TKeep( 3, 0), 7, 4);
210  sendChunk.setLE_TLast( currChunk.getLE_TKeep()[4] == 0);
211  soIph_Data.write(sendChunk);
212  tle_shift = true;
213  tle_chunkCount++;
214  if (DEBUG_LEVEL & TRACE_TLE) { printAxisRaw(myName, "soIph_Data =", sendChunk); }
215  break;
216  case 1: // Drop IP option located in 'prevChunk' and forward entire 'currChunk'
217  sendChunk = AxisRaw(currChunk.getLE_TData(), currChunk.getLE_TKeep(), currChunk.getLE_TLast());
218  soIph_Data.write(sendChunk);
219  tle_shift = false;
220  tle_ip4HdrLen = 0;
221  tle_chunkCount++;
222  if (DEBUG_LEVEL & TRACE_TLE) { printAxisRaw(myName, "soIph_Data =", sendChunk); }
223  break;
224  default: // Drop two option chunks located in half of 'prevChunk' and half of 'currChunk'.
225  tle_ip4HdrLen -= 2;
226  break;
227  }
228  break;
229  default:
230  if (tle_shift) {
231  // The 'currChunk' is not aligned with the outgoing 'sendChunk'
232  sendChunk.setLE_TData(tle_prevChunk.getLE_TData(63, 32), 31, 0);
233  sendChunk.setLE_TKeep(tle_prevChunk.getLE_TKeep( 7, 4), 3, 0);
234  sendChunk.setLE_TData( currChunk.getLE_TData(31, 0), 63, 32);
235  sendChunk.setLE_TKeep( currChunk.getLE_TKeep( 3, 0), 7, 4);
236  sendChunk.setLE_TLast( currChunk.getLE_TKeep()[4] == 0);
237  soIph_Data.write(sendChunk);
238  if (DEBUG_LEVEL & TRACE_TLE) { printAxisRaw(myName, "soIph_Data =", sendChunk); }
239  if (currChunk.getTLast()) {
240  tle_chunkCount = 0;
241  tle_residue = (currChunk.getLE_TKeep()[4] != 0);
242  }
243  }
244  else {
245  // The 'currChunk' is aligned with the outgoing 'sendChunk'
246  sendChunk = AxisIp4(currChunk.getLE_TData(), currChunk.getLE_TKeep(), currChunk.getLE_TLast());
247  soIph_Data.write(sendChunk);
248  if (DEBUG_LEVEL & TRACE_TLE) { printAxisRaw(myName, "soIph_Data =", sendChunk); }
249  if (currChunk.getTLast()) {
250  tle_chunkCount = 0;
251  }
252  }
253  break;
254  } // End of: switch (tle_chunkCount)
255  // Always copy 'currChunk' into 'prevChunk'
256  tle_prevChunk = currChunk;
257  }
258  else if (tle_residue) {
259  // Send remaining data
260  AxisRaw sendChunk = AxisRaw(0, 0, TLAST);
261  sendChunk.setLE_TData(tle_prevChunk.getLE_TData(63, 32), 31, 0);
262  sendChunk.setLE_TKeep(tle_prevChunk.getLE_TKeep( 7, 4), 3, 0);
263  soIph_Data.write(sendChunk);
264  tle_residue = false;
265  if (DEBUG_LEVEL & TRACE_TLE) { printAxisRaw(myName, "soIph_Data =", sendChunk); }
266  }
267 }
268 
269 
321  stream<AxisRaw> &siTle_Data,
322  stream<TcpSegLen> &siTle_TcpSegLen,
323  stream<AxisPsd4> &soCsa_PseudoPkt)
324 {
325  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
326  #pragma HLS PIPELINE II=1 enable_flush
327  #pragma HLS INLINE off
328 
329  const char *myName = concat3(THIS_NAME, "/", "Iph");
330 
331  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
332  static bool iph_residue=false;
333  #pragma HLS RESET variable=iph_residue
334  static ap_uint<2> iph_chunkCount=0;
335  #pragma HLS RESET variable=iph_chunkCount
336 
337  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
338  static AxisRaw iph_prevChunk;
339 
340  //-- DYNAMIC VARIABLES -----------------------------------------------------
341  ValBit valid;
343  AxisRaw currChunk;
344  AxisPsd4 sendChunk;
345 
346  if (iph_residue) {
347  sendChunk.setLE_TData(iph_prevChunk.getLE_TData(63, 32), 31, 0);
348  sendChunk.setLE_TKeep(iph_prevChunk.getLE_TKeep( 7, 4), 3, 0);
349  sendChunk.setLE_TData( 0x00000000, 63, 32);
350  sendChunk.setLE_TKeep( 0x0, 7, 4);
351  sendChunk.setLE_TLast(TLAST);
352  soCsa_PseudoPkt.write(sendChunk);
353  iph_residue = false;
354  if (DEBUG_LEVEL & TRACE_IPH) { printAxisRaw(myName, "soCsa_PseudoPkt =", sendChunk); }
355  }
356  else if(!siTle_Data.empty() and !soCsa_PseudoPkt.full()) {
357  switch (iph_chunkCount) {
358  case CHUNK_0:
359  // Forward [IP_DA|IP_SA]
360  siTle_Data.read(currChunk);
361  soCsa_PseudoPkt.write(currChunk);
362  iph_chunkCount++;
363  if (DEBUG_LEVEL & TRACE_IPH) { printAxisRaw(myName, "soCsa_PseudoPkt =", currChunk); }
364  break;
365  case CHUNK_1:
366  // Forward [TCP_DP|TCP_SP|TCP_LEN|PROT|0x00]
367  if (!siTle_TcpSegLen.empty()) {
368  siTle_TcpSegLen.read(tcpSegLen);
369  siTle_Data.read(currChunk);
370  // Assemble outgoing chunk
371  sendChunk.setPsd4ResBits(0x00);
372  sendChunk.setPsd4Prot(IP4_PROT_TCP);
373  sendChunk.setPsd4Len(tcpSegLen);
374  sendChunk.setTcpSrcPort(byteSwap16(currChunk.getLE_TData(15, 0)));
375  sendChunk.setTcpDstPort(byteSwap16(currChunk.getLE_TData(31, 16)));
376  sendChunk.setLE_TKeep(0xFF);
377  sendChunk.setLE_TLast(0);
378  soCsa_PseudoPkt.write(sendChunk);
379  iph_chunkCount++;
380  if (DEBUG_LEVEL & TRACE_IPH) printAxisRaw(myName, "soCsa_PseudoPkt =", sendChunk);
381  }
382  break;
383  default:
384  siTle_Data.read(currChunk);
385  // Forward [ ACK_NUM | SEQ_NUM ] or
386  // [URG_PTR|CHEKSUM|WINSIZE| FLAGS ] or
387  // [ DATA ]
388  sendChunk.setLE_TData(iph_prevChunk.getLE_TData(63, 32), 31, 0);
389  sendChunk.setLE_TKeep(iph_prevChunk.getLE_TKeep( 7, 4), 3, 0);
390  sendChunk.setLE_TData( currChunk.getLE_TData(31, 0), 63, 32);
391  sendChunk.setLE_TKeep( currChunk.getLE_TKeep( 3, 0), 7, 4);
392  sendChunk.setLE_TLast(currChunk.getLE_TKeep()[4] == 0);
393  soCsa_PseudoPkt.write(sendChunk);
394  if (DEBUG_LEVEL & TRACE_IPH) printAxisRaw(myName, "soCsa_PseudoPkt =", sendChunk);
395  break;
396  }
397  // Always copy 'currChunk' into 'prevChunk'
398  iph_prevChunk = currChunk;
399  if (currChunk.getTLast()) {
400  iph_chunkCount = 0;
401  iph_residue = currChunk.getLE_TKeep()[4] != 0;
402  }
403  }
404 }
405 
406 
445  stream<AxisPsd4> &siIph_PseudoPkt,
446  stream<AxisApp> &soTid_Data,
447  stream<ValBit> &soTid_DataVal,
448  stream<RXeMeta> &soMdh_Meta,
449  stream<SocketPair> &soMdh_SockPair,
450  stream<TcpPort> &soPRt_GetState)
451 {
452  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
453  #pragma HLS PIPELINE II=1 enable_flush
454  #pragma HLS INLINE off
455 
456  const char *myName = concat3(THIS_NAME, "/", "Csa");
457 
458  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
459  static ap_uint<3> csa_chunkCount=0;
460  #pragma HLS RESET variable=csa_chunkCount
461  static bool csa_doCSumVerif=false;
462  #pragma HLS RESET variable=csa_doCSumVerif
463  static bool csa_residue=false;
464  #pragma HLS RESET variable=csa_residue
465  static ap_uint<3> csa_cc_state=0;
466  #pragma HLS RESET variable=csa_cc_state
467  static ap_uint<17> csa_tcp_sums[4]={0, 0, 0, 0};
468  #pragma HLS RESET variable=csa_tcp_sums
469  #pragma HLS ARRAY_PARTITION \
470  variable=csa_tcp_sums complete dim=1
471 
472  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
473  static TcpDataOff csa_dataOffset;
474  static bool csa_doShift;
475  static SocketPair csa_socketPair;
476  static RXeMeta csa_meta;
477  static TcpDstPort csa_tcpDstPort;
478  static TcpChecksum csa_tcpCSum;
479  static ap_uint<32> csa_half_tdata;
480  static ap_uint<4> csa_half_tkeep;
481 
482  //-- DYNAMIC VARIABLES -----------------------------------------------------
483  AxisPsd4 currChunk(0,0,0);
484  AxisApp sendChunk(0,0,0);
485 
486  if (!siIph_PseudoPkt.empty() and !soTid_Data.full() and !csa_doCSumVerif) {
487  currChunk = siIph_PseudoPkt.read();
488 
489  switch (csa_chunkCount) {
490  case CHUNK_0:
491  csa_doShift = false;
492  // Get IP-SA & IP-DA
493  csa_socketPair.src.addr = currChunk.getPsd4SrcAddr();
494  csa_socketPair.dst.addr = currChunk.getPsd4DstAddr();
495  sendChunk.setTLast(currChunk.getTLast());
496  csa_chunkCount++;
497  break;
498  case CHUNK_1:
499  // Get Segment length
500  csa_meta.length = currChunk.getPsd4Len();
501  // Get TCP-SP & TCP-DP
502  csa_socketPair.src.port = currChunk.getTcpSrcPort();
503  csa_socketPair.dst.port = currChunk.getTcpDstPort();
504  csa_tcpDstPort = currChunk.getTcpDstPort();
505  sendChunk.setTLast(currChunk.getTLast());
506  csa_chunkCount++;
507  break;
508  case CHUNK_2:
509  // Get Sequence and Acknowledgment Numbers
510  csa_meta.seqNumb = currChunk.getTcpSeqNum();
511  csa_meta.ackNumb = currChunk.getTcpAckNum();
512  sendChunk.setTLast(currChunk.getTLast());
513  csa_chunkCount++;
514  break;
515  case CHUNK_3:
516  // Get Data Offset
517  csa_dataOffset = currChunk.getTcpDataOff();
518  csa_meta.length -= (csa_dataOffset * 4);
519  // Get Control Bits
520  // [ 8] == FIN | [ 9] == SYN | [10] == RST
521  // [11] == PSH | [12] == ACK | [13] == URG
522  csa_meta.ack = currChunk.getTcpCtrlAck();
523  csa_meta.rst = currChunk.getTcpCtrlRst();
524  csa_meta.syn = currChunk.getTcpCtrlSyn();
525  csa_meta.fin = currChunk.getTcpCtrlFin();
526  // Get Window Size
527  csa_meta.winSize = currChunk.getTcpWindow();
528  // Get the checksum of the pseudo-header (only for debug purposes)
529  csa_tcpCSum = currChunk.getTcpChecksum();
530  sendChunk.setTLast(currChunk.getTLast());
531  csa_chunkCount++;
532  break;
533  default:
534  if (csa_dataOffset >= 6) {
535  // Handle TCP options.
536  // Warning: At this point, we only support one TCP option and
537  // we further assume that this option is always 32-bit aligned.
538  // [TODO] Must add support for Window Scaling and unaligned options.
539  TcpOptKind optionKind = currChunk.getTcpOptKind();
540  if (optionKind == TCP_OPT_KIND_MSS) {
541  // Extract the MSS value
542  TcpOptMss theirMSS = currChunk.getTcpOptMss();
543  if (DEBUG_LEVEL & TRACE_CSA) {
544  printInfo(myName, "TCP segment includes 4 option bytes (OptKind=2, OptLen=4, MSS=%d)\n",
545  theirMSS.to_uint());
546  }
547  }
548  else {
549  printWarn(myName, "The TCP option %d is not yet supported and will be dropped.\n", optionKind.to_uchar());
550  }
551  if (csa_dataOffset == 6) {
552  csa_dataOffset -= 1;
553  csa_doShift = true;
554  csa_half_tdata = currChunk.getLE_TData(63, 32);
555  csa_half_tkeep = currChunk.getLE_TKeep( 7, 4);
556  }
557  else {
558  csa_dataOffset -= 2;
559  }
560  }
561  else {
562  // The DataOffset == 5 (or less)
563  if (!csa_doShift) {
564  sendChunk = currChunk;
565  soTid_Data.write(sendChunk);
566  }
567  else {
568  sendChunk.setLE_TData( csa_half_tdata, 31, 0);
569  sendChunk.setLE_TKeep( csa_half_tkeep, 3, 0);
570  sendChunk.setLE_TData(currChunk.getLE_TData(31, 0), 63, 32);
571  sendChunk.setLE_TKeep(currChunk.getLE_TKeep( 3, 0), 7, 4);
572  sendChunk.setTLast( currChunk.getLE_TKeep()[4] == 0);
573  soTid_Data.write(sendChunk);
574  if (DEBUG_LEVEL & TRACE_CSA) { printAxisRaw(myName, "soTid_Data() =", sendChunk); }
575  csa_half_tdata = currChunk.getLE_TData(63, 32);
576  csa_half_tkeep = currChunk.getLE_TKeep( 7, 4);
577  }
578  }
579  break;
580  } // End of: switch
581 
582  // Accumulate TCP checksum
583  for (int i = 0; i < 4; i++) {
584  #pragma HLS UNROLL
585  TcpCsum temp;
586  if (currChunk.getLE_TKeep(i*2+1, i*2) == 0x3) {
587  temp( 7, 0) = currChunk.getLE_TData(i*16+15, i*16+8);
588  temp(15, 8) = currChunk.getLE_TData(i*16+ 7, i*16);
589  csa_tcp_sums[i] += temp;
590  csa_tcp_sums[i] = (csa_tcp_sums[i] + (csa_tcp_sums[i] >> 16)) & 0xFFFF;
591  }
592  else if (currChunk.getLE_TKeep()[i*2] == 0x1) {
593  temp( 7, 0) = 0;
594  temp(15, 8) = currChunk.getLE_TData(i*16+7, i*16);
595  csa_tcp_sums[i] += temp;
596  csa_tcp_sums[i] = (csa_tcp_sums[i] + (csa_tcp_sums[i] >> 16)) & 0xFFFF;
597  }
598  }
599 
600  // Handle last chunk
601  if(currChunk.getTLast()) {
602  csa_chunkCount = 0;
603  csa_residue = !sendChunk.getTLast();
604  csa_doCSumVerif = true;
605  }
606  } // End of: if (!siIph_Data.empty() && !csa_doCSumVerif)
607  else if(csa_residue and !soTid_Data.full()) {
608  if (csa_meta.length != 0) {
609  sendChunk.setLE_TData(csa_half_tdata, 31, 0);
610  sendChunk.setLE_TData( 0x00000000, 63, 32);
611  sendChunk.setLE_TKeep(csa_half_tkeep, 3, 0);
612  sendChunk.setLE_TKeep( 0x0, 7, 4);
613  sendChunk.setLE_TLast(TLAST);
614  soTid_Data.write(sendChunk);
615  if (DEBUG_LEVEL & TRACE_CSA) { printAxisRaw(myName, "soTid_Data() =", currChunk); }
616  }
617  csa_residue = false;
618  }
619  else if (csa_doCSumVerif) {
620  switch (csa_cc_state) {
621  case 0:
622  csa_tcp_sums[0] = (csa_tcp_sums[0] + (csa_tcp_sums[0] >> 16)) & 0xFFFF;
623  csa_tcp_sums[1] = (csa_tcp_sums[1] + (csa_tcp_sums[1] >> 16)) & 0xFFFF;
624  csa_tcp_sums[2] = (csa_tcp_sums[2] + (csa_tcp_sums[2] >> 16)) & 0xFFFF;
625  csa_tcp_sums[3] = (csa_tcp_sums[3] + (csa_tcp_sums[3] >> 16)) & 0xFFFF;
626  csa_cc_state++;
627  break;
628  case 1:
629  csa_tcp_sums[0] += csa_tcp_sums[2];
630  csa_tcp_sums[1] += csa_tcp_sums[3];
631  csa_tcp_sums[0] = (csa_tcp_sums[0] + (csa_tcp_sums[0] >> 16)) & 0xFFFF;
632  csa_tcp_sums[1] = (csa_tcp_sums[1] + (csa_tcp_sums[1] >> 16)) & 0xFFFF;
633  csa_cc_state++;
634  break;
635  case 2:
636  csa_tcp_sums[0] += csa_tcp_sums[1];
637  csa_tcp_sums[0] = (csa_tcp_sums[0] + (csa_tcp_sums[0] >> 16)) & 0xFFFF;
638  csa_cc_state++;
639  break;
640  case 3:
641  csa_tcp_sums[0] = ~csa_tcp_sums[0];
642  csa_cc_state++;
643  break;
644  case 4:
645  if (csa_tcp_sums[0](15, 0) == 0) {
646  // The checksum is correct. TCP segment is valid.
647  // Forward to metadata to MetaDataHandler
648  soMdh_Meta.write(csa_meta);
649  soMdh_SockPair.write(csa_socketPair);
650  if (csa_meta.length != 0) {
651  // Forward valid checksum info to TcpInvalidDropper
652  soTid_DataVal.write(OK);
653  if (DEBUG_LEVEL & TRACE_CSA) {
654  printInfo(myName, "Received end-of-packet. Checksum is correct.\n");
655  }
656  }
657  // Request state of TCP_DP
658  soPRt_GetState.write(csa_tcpDstPort);
659  }
660  else {
661  printWarn(myName, "RECEIVED BAD CHECKSUM (0x%4.4X - Delta= 0x%4.4X).\n",
662  csa_tcpCSum.to_uint(), (~csa_tcp_sums[0](15, 0).to_uint() & 0xFFFF));
663  if(csa_meta.length != 0) {
664  // Packet has some TCP payload
665  soTid_DataVal.write(KO);
666  }
667  if (DEBUG_LEVEL & TRACE_CSA) {
668  printSockPair(myName, csa_socketPair);
669  }
670  }
671  csa_doCSumVerif = false;
672  csa_tcp_sums[0] = 0;
673  csa_tcp_sums[1] = 0;
674  csa_tcp_sums[2] = 0;
675  csa_tcp_sums[3] = 0;
676  csa_cc_state = 0;
677  break;
678  } // End of: switch
679  }
680 } // End of: pCheckSumAccumulator
681 
682 
696  stream<AxisApp> &siCsa_Data,
697  stream<ValBit> &siCsa_DataVal,
698  stream<AxisApp> &soTsd_Data,
699  stream<ap_uint<8> > &soMMIO_CrcDropCnt)
700 {
701  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
702  #pragma HLS PIPELINE II=1 enable_flush
703  #pragma HLS INLINE off
704 
705  const char *myName = concat3(THIS_NAME, "/", "Tid");
706 
707  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
708  static enum FsmStates { TSD_IDLE=0, TSD_FWD, TSD_DROP } \
709  tid_fsmState=TSD_IDLE;
710  #pragma HLS RESET variable=tid_fsmState
711  static ap_uint<8 > tid_crcDropCounter=0;
712  #pragma HLS reset variable=tid_crcDropCounter
713 
714 
715  //-- DYNAMIC VARIABLES -----------------------------------------------------
716  AxisApp currChunk;
717  ValBit validBit;
718 
719  switch (tid_fsmState) {
720  case TSD_IDLE:
721  if (!siCsa_DataVal.empty()) {
722  siCsa_DataVal.read(validBit);
723  if (validBit == OK) {
724  tid_fsmState = TSD_FWD;
725  }
726  else {
727  tid_fsmState = TSD_DROP;
728  tid_crcDropCounter++;
729  printWarn(myName, "Bad checksum: Dropping payload for this packet!\n");
730  }
731  }
732  break;
733  case TSD_FWD:
734  if(!siCsa_Data.empty() && !soTsd_Data.full()) {
735  siCsa_Data.read(currChunk);
736  soTsd_Data.write(currChunk);
737  if (currChunk.getTLast()) {
738  tid_fsmState = TSD_IDLE;
739  }
740  if (DEBUG_LEVEL & TRACE_TID) { printAxisRaw(myName, "soTsd_Data =", currChunk); }
741  }
742  break;
743  case TSD_DROP:
744  if(!siCsa_Data.empty()) {
745  siCsa_Data.read(currChunk);
746  if (currChunk.getTLast()) {
747  tid_fsmState = TSD_IDLE;
748  }
749  }
750  break;
751  } // End of: switch
752 
753  //-- ALWAYS
754  if (!soMMIO_CrcDropCnt.full()) {
755  soMMIO_CrcDropCnt.write(tid_crcDropCounter);
756  }
757  else {
758  printFatal(myName, "Cannot write soMMIO_CrcDropCnt stream...");
759  }
760 
761 } // End of: pTcpInvalidDropper
762 
763 
776  stream<AxisApp> &siTid_Data,
777  stream<CmdBit> &siMdh_DropCmd,
778  stream<CmdBit> &siFsm_DropCmd,
779  stream<AxisApp> &soMwr_Data)
780 {
781  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
782  #pragma HLS PIPELINE II=1 enable_flush
783  #pragma HLS INLINE off
784 
785  const char *myName = concat3(THIS_NAME, "/", "Tsd");
786 
787  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
788  static enum FsmStates { TSD_RD_DROP_CMD1=0, TSD_RD_DROP_CMD2, TSD_FWD, TSD_DROP } \
789  tsd_fsmState=TSD_RD_DROP_CMD1;
790  #pragma HLS RESET variable=tsd_fsmState
791 
792  switch (tsd_fsmState) {
793  case TSD_RD_DROP_CMD1:
794  if (!siMdh_DropCmd.empty()) {
795  CmdBit dropCmd = siMdh_DropCmd.read();
796  if (dropCmd) {
797  tsd_fsmState = TSD_DROP;
798  printWarn(myName, "[Mdh] is requesting to drop this packet.\n");
799  }
800  else {
801  tsd_fsmState = TSD_RD_DROP_CMD2;
802  }
803  }
804  break;
805  case TSD_RD_DROP_CMD2:
806  if (!siFsm_DropCmd.empty()) {
807  CmdBit dropCmd = siFsm_DropCmd.read();
808  if (dropCmd) {
809  tsd_fsmState = TSD_DROP;
810  printWarn(myName, "[Fsm] is requesting to drop this packet.\n");
811  }
812  else {
813  tsd_fsmState = TSD_FWD;
814  }
815  }
816  break;
817  case TSD_FWD:
818  if(!siTid_Data.empty() && !soMwr_Data.full()) {
819  AxisApp currChunk = siTid_Data.read();
820  if (currChunk.getTLast()) {
821  tsd_fsmState = TSD_RD_DROP_CMD1;
822  }
823  soMwr_Data.write(currChunk);
824  if (DEBUG_LEVEL & TRACE_TID) { printAxisRaw(myName, "soMwr_Data =", currChunk); }
825  }
826  break;
827  case TSD_DROP:
828  if(!siTid_Data.empty()) {
829  AxisApp currChunk = siTid_Data.read();
830  if (currChunk.getTLast()) {
831  tsd_fsmState = TSD_RD_DROP_CMD1;
832  }
833  }
834  break;
835  } // End of: switch
836 }
837 
838 
860  stream<AxisApp> &siTsd_Data,
861  stream<DmCmd> &siFsm_MemWrCmd,
862  stream<DmCmd> &soMEM_WrCmd,
863  stream<AxisApp> &soMEM_WrData,
864  stream<FlagBool> &soRan_SplitSeg)
865 {
866  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
867  #pragma HLS PIPELINE II=1 enable_flush
868  #pragma HLS INLINE off
869 
870  const char *myName = concat3(THIS_NAME, "/", "Mwr");
871 
872  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
873  static enum FsmStates { MWR_IDLE=0,
874  MWR_FWD_ALIGNED, MWR_SPLIT_1ST_CMD,
875  MWR_FWD_1ST_BUF, MWR_FWD_2ND_BUF, MWR_RESIDUE } \
876  mwr_fsmState=MWR_IDLE;
877  #pragma HLS RESET variable=mwr_fsmState
878  static ap_uint<3> mwr_residueLen=0;
879  #pragma HLS RESET variable=mwr_residueLen
880  static bool mwr_accessBreakdown=false;
881  #pragma HLS RESET variable=mwr_accessBreakdown
882 
883  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
884  static DmCmd mwr_memWrCmd;
885  static AxisApp mwr_currChunk;
886  static RxBufPtr mwr_firstAccLen;
887  static TcpSegLen mwr_nrBytesToWr;
888  static ap_uint<4> mwr_splitOffset;
889  static uint16_t mwr_debugCounter=3; // To align with # in the DAT file
890 
891  switch (mwr_fsmState) {
892  case MWR_IDLE:
893  if (!siFsm_MemWrCmd.empty() and !soRan_SplitSeg.full() and !soMEM_WrCmd.full()) {
894  siFsm_MemWrCmd.read(mwr_memWrCmd);
895  if ((mwr_memWrCmd.saddr.range(TOE_WINDOW_BITS-1, 0) + mwr_memWrCmd.btt) > TOE_RX_BUFFER_SIZE) {
896  //-- Break this segment in two memory accesses because TCP Rx memory buffer wraps around
897  soRan_SplitSeg.write(true);
898 
899  if (DEBUG_LEVEL & TRACE_MWR) {
900  printInfo(myName, "TCP Rx memory buffer wraps around: This segment will be broken in two memory buffers.\n");
901  }
902  mwr_fsmState = MWR_SPLIT_1ST_CMD;
903  }
904  else {
905  //-- Don't split and issue the write command
906  soRan_SplitSeg.write(false);
907  soMEM_WrCmd.write(mwr_memWrCmd);
908 
909  if (DEBUG_LEVEL & TRACE_MWR) {
910  printInfo(myName, "Issuing memory write command #%d - SADDR=0x%9.9x - BTT=%d\n",
911  mwr_debugCounter, mwr_memWrCmd.saddr.to_uint(), mwr_memWrCmd.btt.to_uint());
912  mwr_debugCounter++;
913  }
914  mwr_fsmState = MWR_FWD_ALIGNED;
915  }
916  }
917  break;
918  case MWR_SPLIT_1ST_CMD:
919  if (!soMEM_WrCmd.full()) {
920  mwr_firstAccLen = TOE_RX_BUFFER_SIZE - mwr_memWrCmd.saddr;
921  mwr_nrBytesToWr = mwr_firstAccLen;
922  soMEM_WrCmd.write(DmCmd(mwr_memWrCmd.saddr, mwr_firstAccLen));
923 
924  if (DEBUG_LEVEL & TRACE_MWR) {
925  printInfo(myName, "Issuing 1st memory write command #%d - SADDR=0x%9.9x - BTT=%d\n",
926  mwr_debugCounter, mwr_memWrCmd.saddr.to_uint(), mwr_firstAccLen.to_uint());
927  }
928  mwr_fsmState = MWR_FWD_1ST_BUF;
929  }
930  break;
931  case MWR_FWD_ALIGNED:
932  if (!siTsd_Data.empty() and !soMEM_WrData.full()) {
933  //-- Default streaming state used to forward segments or splitted buffers
934  //-- that are aligned with the Axis raw width
935  AxisApp memChunk = siTsd_Data.read();
936  soMEM_WrData.write(memChunk);
937  if (memChunk.getTLast()) {
938  mwr_fsmState = MWR_IDLE;
939  }
940 
941  if (DEBUG_LEVEL & TRACE_MWR) { printAxisRaw(myName, "FWD_ALIGNED: soMEM_WrData =", memChunk); }
942  }
943  break;
944  case MWR_FWD_1ST_BUF:
945  if (!siTsd_Data.empty() and !soMEM_WrData.full()) {
946  //-- Create 1st splitted data buffer and stream it to memory
947  siTsd_Data.read(mwr_currChunk);
948  AxisApp memChunk = mwr_currChunk;
949  if (mwr_nrBytesToWr > (ARW/8)) {
950  mwr_nrBytesToWr -= (ARW/8);
951  }
952  else if (!soMEM_WrCmd.full()) {
953  if (mwr_nrBytesToWr == (ARW/8)) {
954  //-- End of 1st segment and begin of 2nd segment are aligned
955  memChunk.setLE_TLast(TLAST);
956 
957  //-- Prepare and issue 2nd command
958  mwr_memWrCmd.saddr(TOE_WINDOW_BITS-1, 0) = 0;
959  mwr_memWrCmd.btt -= mwr_firstAccLen;
960  soMEM_WrCmd.write(mwr_memWrCmd);
961 
962  if (DEBUG_LEVEL & TRACE_MWR) {
963  printInfo(myName, "Issuing 2nd memory write command #%d - SADDR=0x%9.9x - BTT=%d\n",
964  mwr_debugCounter, mwr_memWrCmd.saddr.to_uint(), mwr_memWrCmd.btt.to_uint());
965  mwr_debugCounter++;
966  }
967  mwr_fsmState = MWR_FWD_ALIGNED;
968  }
969  else {
970  //-- End of 1st segment and begin of 2nd segment not aligned
971  memChunk.setLE_TLast(TLAST);
972  memChunk.setLE_TKeep(lenToLE_tKeep(mwr_nrBytesToWr));
973  #ifndef __SYNTHESIS__
974  memChunk.setLE_TData(0, (ARW-1), ((int)mwr_nrBytesToWr*8));
975  #endif
976 
977  //-- Prepare and issue 2nd command
978  mwr_memWrCmd.saddr(TOE_WINDOW_BITS-1, 0) = 0;
979  mwr_memWrCmd.btt -= mwr_firstAccLen;
980  soMEM_WrCmd.write(mwr_memWrCmd);
981 
982  if (DEBUG_LEVEL & TRACE_MWR) {
983  printInfo(myName, "Issuing 2nd memory write command #%d - SADDR=0x%9.9x - BTT=%d\n",
984  mwr_debugCounter, mwr_memWrCmd.saddr.to_uint(), mwr_memWrCmd.btt.to_uint());
985  mwr_debugCounter++;
986  }
987  mwr_splitOffset = (ARW/8) - mwr_nrBytesToWr;
988  if (mwr_currChunk.getLE_TLast()) {
989  mwr_fsmState = MWR_RESIDUE;
990  }
991  else {
992  mwr_fsmState = MWR_FWD_2ND_BUF;
993  }
994  }
995  }
996 
997  soMEM_WrData.write(memChunk);
998  if (DEBUG_LEVEL & TRACE_MWR) { printAxisRaw(myName, "FWD_1ST_BUF: soMEM_WrData =", memChunk); }
999  }
1000  break;
1001  case MWR_FWD_2ND_BUF:
1002  if (!siTsd_Data.empty() && !soMEM_WrData.full()) {
1003  //-- Alternate streaming state used to re-align a splitted second buffer
1004  AxisApp prevChunk = mwr_currChunk;
1005  mwr_currChunk = siTsd_Data.read();
1006 
1007  AxisApp joinedChunk(0,0,0); // [FIXME-Create a join method in AxisRaw]
1008  // Set lower-part of the joined chunk with the last bytes of the previous chunk
1009  joinedChunk.setLE_TData(prevChunk.getLE_TData((ARW )-1, ((ARW )-((int)mwr_splitOffset*8))),
1010  ((int)mwr_splitOffset*8)-1, 0);
1011  joinedChunk.setLE_TKeep(prevChunk.getLE_TKeep((ARW/8)-1, ((ARW/8)-((int)mwr_splitOffset ))),
1012  ((int)mwr_splitOffset )-1, 0);
1013  // Set higher part of the joined chunk with the first bytes of the current chunk
1014  joinedChunk.setLE_TData(mwr_currChunk.getLE_TData((ARW )-((int)mwr_splitOffset*8)-1, 0),
1015  (ARW ) -1, ((int)mwr_splitOffset*8));
1016  joinedChunk.setLE_TKeep(mwr_currChunk.getLE_TKeep((ARW/8)-((int)mwr_splitOffset )-1, 0),
1017  (ARW/8) -1, ((int)mwr_splitOffset ));
1018  if (mwr_currChunk.getLE_TLast()) {
1019  if (mwr_currChunk.getLen() > mwr_nrBytesToWr) {
1020  // This cannot be the last chunk because the current one plus
1021  // the remainder of the previous one do not fit into a single chunk.
1022  // Goto the 'MWR_RESIDUE' and handle the remainder of that chunk.
1023  mwr_fsmState = MWR_RESIDUE;
1024  }
1025  else {
1026  // The entire current chunk and the remainder of the previous chunk
1027  // fit into a single chunk. We are done with this 2nd memory buffer.
1028  joinedChunk.setLE_TLast(TLAST);
1029  mwr_fsmState = MWR_IDLE;
1030  }
1031  }
1032  soMEM_WrData.write(joinedChunk);
1033  if (DEBUG_LEVEL & TRACE_MWR) { printAxisRaw(myName, "FWD_2ND_BUF: soMEM_WrData =", joinedChunk); }
1034  }
1035  break;
1036  case MWR_RESIDUE:
1037  if (!soMEM_WrData.full()) {
1038  //-- Output the very last unaligned chunk
1039  AxisApp prevChunk = mwr_currChunk;
1040  AxisApp lastChunk(0,0,0);
1041 
1042  // Set lower-part of the last chunk with the last bytes of the previous chunk
1043  lastChunk.setLE_TData(prevChunk.getLE_TData((ARW )-1, ((ARW )-((int)mwr_splitOffset*8))),
1044  ((int)mwr_splitOffset*8)-1, 0);
1045  lastChunk.setLE_TKeep(prevChunk.getLE_TKeep((ARW/8)-1, ((ARW/8)-((int)mwr_splitOffset ))),
1046  ((int)mwr_splitOffset )-1, 0);
1047  lastChunk.setLE_TLast(TLAST);
1048  soMEM_WrData.write(lastChunk);
1049 
1050  if (DEBUG_LEVEL & TRACE_MWR) { printAxisRaw(myName, "RESIDUE : soMEM_WrData =", lastChunk); }
1051  mwr_fsmState = MWR_IDLE;
1052  }
1053  break;
1054  }
1055 }
1056 
1057 
1076  stream<DmSts> &siMEM_WrSts,
1077  stream<TcpAppNotif> &siFsm_Notif,
1078  stream<TcpAppNotif> &soRAi_RxNotif,
1079  stream<FlagBool> &siMwr_SplitSeg,
1080  stream<StsBit> &soMMIO_MemWrErr)
1081 {
1082  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1083  #pragma HLS PIPELINE II=1 enable_flush
1084  #pragma HLS INLINE off
1085 
1086  const char *myName = concat3(THIS_NAME, "/", "Ran");
1087 
1088  //-- LOCAL STREAMS ---------------------------------------------------------
1089  static stream<TcpAppNotif> ssRxNotifFifo("ssRxNotifFifo");
1090  #pragma HLS STREAM variable=ssRxNotifFifo depth=32 // WARNING: [FIXME] Depends on the memory delay !!!
1091  #pragma HLS DATA_PACK variable=ssRxNotifFifo
1092 
1093  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1094  static FlagBool ran_doubleAccessFlag=FLAG_OFF;
1095  #pragma HLS RESET variable=ran_doubleAccessFlag
1096  static StsBit ran_dataMoverError=STS_NO_ERR;
1097  #pragma HLS RESET variable=ran_dataMoverError
1098 
1099  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
1100  static DmSts ran_dmStatus1;
1101  static DmSts ran_dmStatus2;
1102  static TcpAppNotif ran_appNotification;
1103 
1104  if (ran_doubleAccessFlag == FLAG_ON) {
1105  // The segment was splitted and notification will only go out now
1106  if(!siMEM_WrSts.empty()) {
1107  siMEM_WrSts.read(ran_dmStatus2);
1108  if (ran_dmStatus1.okay and ran_dmStatus2.okay) {
1109  soRAi_RxNotif.write(ran_appNotification);
1110  if (DEBUG_LEVEL & TRACE_RAN) {
1111  printInfo(myName, "Sending APP notification to [RAi]. This was a double access.\n");
1112  }
1113  }
1114  else {
1115  ran_dataMoverError = ran_dmStatus1.slverr | ran_dmStatus1.decerr | ran_dmStatus1.interr | \
1116  ran_dmStatus2.slverr | ran_dmStatus2.decerr | ran_dmStatus2.interr;;
1117  if (DEBUG_LEVEL & TRACE_RAN) {
1118  printError(myName, "The previous splitted mem-write command failed (OKAY=0).\n");
1119  }
1120  }
1121  ran_doubleAccessFlag = FLAG_OFF;
1122  }
1123  }
1124  else {
1125  //-- We don't know yet about a possible double memory access
1126  if (!siMEM_WrSts.empty() and !siMwr_SplitSeg.empty() and !ssRxNotifFifo.empty()) {
1127  siMEM_WrSts.read(ran_dmStatus1);
1128  siMwr_SplitSeg.read(ran_doubleAccessFlag);
1129  ssRxNotifFifo.read(ran_appNotification);
1130  if (ran_doubleAccessFlag == FLAG_OFF) {
1131  // This segment consists of a single memory access
1132  if (ran_dmStatus1.okay) {
1133  // Output the notification now
1134  soRAi_RxNotif.write(ran_appNotification);
1135  if (DEBUG_LEVEL & TRACE_RAN) {
1136  printInfo(myName, "Sending APP notification to [RAi].\n");
1137  }
1138  }
1139  else {
1140  ran_dataMoverError = ran_dmStatus1.slverr | ran_dmStatus1.decerr | ran_dmStatus1.interr;
1141  if (DEBUG_LEVEL & TRACE_RAN) {
1142  printError(myName, "The previous memory write command failed (OKAY=0).\n");
1143  }
1144  }
1145  }
1146  else {
1147  if (DEBUG_LEVEL & TRACE_RAN) {
1148  printInfo(myName, "The memory access was broken down in two parts.\n");
1149  }
1150  }
1151  }
1152  else if (!siFsm_Notif.empty() and !ssRxNotifFifo.full()) {
1153  siFsm_Notif.read(ran_appNotification);
1154  if (ran_appNotification.tcpDatLen != 0) {
1155  ssRxNotifFifo.write(ran_appNotification);
1156  }
1157  else {
1158  // Do not send forward the notification to [APP]
1159  printInfo(myName, "Received an RxNotif with LENGTH=0.\n");
1160  }
1161  }
1162  }
1163 
1164  //-- ALWAYS
1165  if (!soMMIO_MemWrErr.full()) {
1166  soMMIO_MemWrErr.write(ran_dataMoverError);
1167  }
1168  else {
1169  printFatal(myName, "Cannot write soMMIO_MemWrerr stream...");
1170  }
1171 }
1172 
1173 
1198  stream<RXeMeta> &siCsa_Meta,
1199  stream<SocketPair> &siCsa_SockPair,
1200  stream<SessionLookupQuery> &soSLc_SessLkpReq,
1201  stream<SessionLookupReply> &siSLc_SessLkpRep,
1202  stream<StsBit> &siPRt_PortSts,
1203  stream<ExtendedEvent> &soEVe_Event,
1204  stream<CmdBit> &soTsd_DropCmd,
1205  stream<RXeFsmMeta> &soFsm_Meta,
1206  stream<ap_uint<8> > &soMMIO_SessDropCnt)
1207 {
1208  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1209  #pragma HLS PIPELINE II=1 enable_flush
1210  #pragma HLS INLINE off
1211 
1212  const char *myName = concat3(THIS_NAME, "/", "Mdh");
1213 
1214  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1215  static enum FsmStates { MDH_META=0, \
1216  MDH_LOOKUP } mdh_fsmState;
1217  #pragma HLS RESET variable=mdh_fsmState
1218  static ap_uint<8 > mdh_SessDropCounter=0;
1219  #pragma HLS reset variable=mdh_SessDropCounter
1220 
1221  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
1222  static RXeMeta mdh_meta;
1223  static SessionLookupReply mdh_sessLookupReply;
1224  static Ip4Address mdh_ip4SrcAddr;
1225  static TcpPort mdh_tcpSrcPort;
1226  static TcpPort mdh_tcpDstPort;
1227 
1228  //-- DYNAMIC VARIABLES -----------------------------------------------------
1229  SocketPair socketPair;
1230  StsBit dstPortStatus;
1231 
1232  switch (mdh_fsmState) {
1233  case MDH_META:
1234  // Wait until we get a reply from the PortTable (PRt)
1235  if (!siPRt_PortSts.empty()) {
1236  // Read metadata and socket pair
1237  if (!siCsa_Meta.empty() && !siCsa_SockPair.empty()) {
1238  siPRt_PortSts.read(dstPortStatus);
1239  siCsa_Meta.read(mdh_meta);
1240  siCsa_SockPair.read(socketPair);
1241  mdh_ip4SrcAddr = socketPair.src.addr;
1242  mdh_tcpSrcPort = socketPair.src.port;
1243  mdh_tcpDstPort = socketPair.dst.port;
1244  if (dstPortStatus == STS_CLOSED) {
1245  // The destination port is closed
1246  if (DEBUG_LEVEL & TRACE_MDH) {
1247  printWarn(myName, "Port 0x%4.4X (%d) is not open.\n",
1248  mdh_tcpDstPort.to_uint(), mdh_tcpDstPort.to_uint());
1249  }
1250  if (!mdh_meta.rst) {
1251  // Reply with 'RST+ACK' and send necessary socket-pair through event
1252  LE_SocketPair switchedTuple; // [FIXME]
1253  switchedTuple.src.addr = byteSwap32(socketPair.dst.addr);
1254  switchedTuple.dst.addr = byteSwap32(socketPair.src.addr);
1255  switchedTuple.src.port = byteSwap16(socketPair.dst.port);
1256  switchedTuple.dst.port = byteSwap16(socketPair.src.port);
1257  if (mdh_meta.syn || mdh_meta.fin) {
1258  soEVe_Event.write(ExtendedEvent(rstEvent(mdh_meta.seqNumb+mdh_meta.length+1),
1259  switchedTuple)); //always 0
1260  }
1261  else {
1262  soEVe_Event.write(ExtendedEvent(rstEvent(mdh_meta.seqNumb+mdh_meta.length),
1263  switchedTuple));
1264  }
1265  }
1266  else {
1267  // The RST bit is set. Ignore => do nothing
1268  }
1269  if (mdh_meta.length != 0) {
1270  soTsd_DropCmd.write(CMD_DROP);
1271  mdh_SessDropCounter++;
1272  }
1273  }
1274  else {
1275  // Destination Port is opened
1276  if (DEBUG_LEVEL & TRACE_MDH) {
1277  printInfo(myName, "Destination port 0x%4.4X (%d) is open.\n",
1278  mdh_tcpDstPort.to_uint(), mdh_tcpDstPort.to_uint());
1279  }
1280  // Query a session lookup. Only allow creation of a new entry when SYN or SYN_ACK
1281  LE_SocketPair leSocketPair(LE_SockAddr(byteSwap32(socketPair.src.addr),byteSwap16(socketPair.src.port)),
1282  LE_SockAddr(byteSwap32(socketPair.dst.addr),byteSwap16(socketPair.dst.port)));
1283  soSLc_SessLkpReq.write(SessionLookupQuery(leSocketPair,
1284  (mdh_meta.syn && !mdh_meta.rst && !mdh_meta.fin))); // [FIXME - Endianess
1285  if (DEBUG_LEVEL & TRACE_MDH) {
1286  printInfo(myName, "Request the SLc to lookup the following session:\n");
1287  printSockPair(myName, socketPair);
1288  }
1289  mdh_fsmState = MDH_LOOKUP;
1290  }
1291  }
1292  }
1293  break;
1294  case MDH_LOOKUP:
1295  // Wait until we get a reply from the SessionLookupController (SLc)
1296  // Warning: There may be a large delay for the lookup to complete
1297  if (!siSLc_SessLkpRep.empty()) {
1298  siSLc_SessLkpRep.read(mdh_sessLookupReply);
1299  if (mdh_sessLookupReply.hit) {
1300  // Forward metadata to the TCP FiniteStateMachine (Fsm)
1301  soFsm_Meta.write(RXeFsmMeta(mdh_sessLookupReply.sessionID,
1302  mdh_ip4SrcAddr, mdh_tcpSrcPort,
1303  mdh_tcpDstPort, mdh_meta));
1304  if (DEBUG_LEVEL & TRACE_MDH)
1305  printInfo(myName, "Successful session lookup. \n");
1306  }
1307  else {
1308  // [TODO - Port is Open, but we have no sessionID for it]
1309  if (DEBUG_LEVEL & TRACE_MDH)
1310  printWarn(myName, "Session lookup failed! \n");
1311  }
1312  if (mdh_meta.length != 0) {
1313  soTsd_DropCmd.write(!mdh_sessLookupReply.hit);
1314  if (!mdh_sessLookupReply.hit) {
1315  mdh_SessDropCounter++;
1316  }
1317  }
1318  mdh_fsmState = MDH_META;
1319  }
1320  break;
1321  } // End of: switch
1322 
1323  //-- ALWAYS
1324  if (!soMMIO_SessDropCnt.full()) {
1325  soMMIO_SessDropCnt.write(mdh_SessDropCounter);
1326  }
1327  else {
1328  printFatal(myName, "Cannot write soMMIO_SessDropCnt stream...");
1329  }
1330 } // End of: pMetaDataHandler
1331 
1332 
1359  stream<RXeFsmMeta> &siMdh_FsmMeta,
1360  stream<StateQuery> &soSTt_StateQry,
1361  stream<TcpState> &siSTt_StateRep,
1362  stream<RXeRxSarQuery> &soRSt_RxSarQry,
1363  stream<RxSarReply> &siRSt_RxSarRep,
1364  stream<RXeTxSarQuery> &soTSt_TxSarQry,
1365  stream<RXeTxSarReply> &siTSt_TxSarRep,
1366  stream<RXeReTransTimerCmd> &soTIm_ReTxTimerCmd,
1367  stream<SessionId> &soTIm_ClearProbeTimer,
1368  stream<SessionId> &soTIm_CloseTimer,
1369  stream<SessState> &soTAi_SessOpnSts, // [TODO -Merge with eventEngine]
1370  stream<Event> &soEVe_Event,
1371  stream<CmdBit> &soTsd_DropCmd,
1372  stream<DmCmd> &soMwr_WrCmd,
1373  stream<TcpAppNotif> &soRan_RxNotif,
1374  stream<ap_uint<8> > &soMMIO_OooDropCnt,
1375  stream<RxBufPtr> &soDBG_RxFreeSpace,
1376  stream<ap_uint<32> > &soDBG_TcpIpRxByteCnt,
1377  stream<ap_uint<8> > &soDBG_OooDebug)
1378 {
1379  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1380  #pragma HLS PIPELINE II=1 enable_flush
1381  #pragma HLS INLINE off
1382 
1383  const char *myName = concat3(THIS_NAME, "/", "Fsm");
1384 
1385  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1386  static enum FsmStates { FSM_LOAD=0, FSM_TRANSITION } \
1387  fsm_fsmState=FSM_LOAD;
1388  #pragma HLS RESET variable=fsm_fsmState
1389  static bool fsm_txSarRequest=false;
1390  #pragma HLS RESET variable=fsm_txSarRequest
1391  static ap_uint<8 > fsm_oooDropCounter=0;
1392  #pragma HLS RESET variable=fsm_oooDropCounter
1393  static RxBufPtr fsm_freeSpace=0;
1394  #pragma HLS RESET variable=fsm_freeSpace
1395  static ap_uint<32> fsm_rxByteCounter;
1396  #pragma HLS RESET variable=fsm_rxByteCounter
1397  static ap_uint<8 > fsm_oooDebugState=0;
1398  #pragma HLS RESET variable=fsm_oooDebugState
1399 
1400  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
1401  static RXeFsmMeta fsm_Meta;
1402 
1403  //-- DYNAMIC VARIABLES -----------------------------------------------------
1404  ap_uint<4> control_bits;
1405  TcpState tcpState;
1406  RxSarReply rxSar;
1407  RXeTxSarReply txSar;
1408 
1409  fsm_oooDebugState = 0;
1410 
1411  switch(fsm_fsmState) {
1412  case FSM_LOAD:
1413  if (!siMdh_FsmMeta.empty()) {
1414  siMdh_FsmMeta.read(fsm_Meta);
1415  // Request the current state of this session
1416  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, QUERY_RD));
1417  // Always request the RxSarTable, even though not required for SYN-ACK
1418  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, QUERY_RD));
1419  if (fsm_Meta.meta.ack) {
1420  // Only request the txSar when (ACK+ANYTHING); not for SYN
1421  soTSt_TxSarQry.write(RXeTxSarQuery(fsm_Meta.sessionId, QUERY_RD));
1422  fsm_txSarRequest = true;
1423  }
1424  fsm_fsmState = FSM_TRANSITION;
1425  fsm_oooDebugState = 1;
1426  }
1427  break;
1428  case FSM_TRANSITION:
1429  // Check if transition to FSM_LOAD occurs
1430  if (!siSTt_StateRep.empty() and !siRSt_RxSarRep.empty() and
1431  !(fsm_txSarRequest and siTSt_TxSarRep.empty())) {
1432  fsm_fsmState = FSM_LOAD;
1433  fsm_txSarRequest = false;
1434  }
1435  control_bits[0] = fsm_Meta.meta.ack;
1436  control_bits[1] = fsm_Meta.meta.syn;
1437  control_bits[2] = fsm_Meta.meta.fin;
1438  control_bits[3] = fsm_Meta.meta.rst;
1439  switch (control_bits) {
1440  case 1:
1441  //--------------------------------------
1442  //-- ACK
1443  //--------------------------------------
1444  if (fsm_fsmState == FSM_LOAD) {
1445  siSTt_StateRep.read(tcpState);
1446  siRSt_RxSarRep.read(rxSar);
1447  siTSt_TxSarRep.read(txSar);
1448 
1449  //-- ALWAYS - Compute free space to ensure that 'appd' pointer is not overtaken
1450  fsm_freeSpace = ((rxSar.appd - rxSar.oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
1451  soDBG_RxFreeSpace.write(fsm_freeSpace);
1452 
1453  if (DEBUG_LEVEL & TRACE_FSM) {
1454  printInfo(myName, "Entering 'ACK' processing.\n \
1455  \t\t Meta.seqNum =0x%8.8x \n \
1456  \t\t RxSar.appd =0x%8.8x \n \
1457  \t\t RxSar.oooHead=0x%8.8x \n \
1458  \t\t RxSar.oooTail=0x%8.8x \n \
1459  \t\t FreeSpace = %8d\n",
1460  fsm_Meta.meta.seqNumb.to_uint(),
1461  rxSar.oooHead.to_uint(),
1462  rxSar.oooTail.to_uint(),
1463  fsm_freeSpace.to_uint());
1464  }
1465 
1466  TimerCmd timerCmd;
1467  if (fsm_Meta.meta.ackNumb == txSar.prevUnak) {
1468  timerCmd = STOP_TIMER;
1469  }
1470  else {
1471  timerCmd = LOAD_TIMER;
1472  }
1473  soTIm_ReTxTimerCmd.write(RXeReTransTimerCmd(fsm_Meta.sessionId, timerCmd));
1474  if ( (tcpState == ESTABLISHED) || (tcpState == SYN_RECEIVED) ||
1475  (tcpState == FIN_WAIT_1) || (tcpState == CLOSING) ||
1476  (tcpState == LAST_ACK) ) {
1477  // Check if new ACK arrived
1478  if ( (fsm_Meta.meta.ackNumb == txSar.prevAckd) and
1479  (txSar.prevAckd != txSar.prevUnak) ) {
1480  // Not new ACK; increase counter but only if it does not contain data
1481  if (fsm_Meta.meta.length == 0) {
1482  txSar.count++;
1483  }
1484  }
1485  else {
1486  // Notify probeTimer about new ACK
1487  soTIm_ClearProbeTimer.write(fsm_Meta.sessionId);
1488  // Check for SlowStart & Increase Congestion Window
1489  if (txSar.cong_window <= (txSar.slowstart_threshold-ZYC2_MSS)) {
1490  txSar.cong_window += ZYC2_MSS;
1491  }
1492  else if (txSar.cong_window <= TOE_MAX_CONGESTION_WINDOW) { // 0xF7FF
1493  txSar.cong_window += 365; //TODO replace by approx. of (MSS x MSS) / cong_window
1494  }
1495  txSar.count = 0;
1496  txSar.fastRetransmitted = false;
1497  }
1498  // Update TxSarTable (only if count or retransmit)
1499  if ( ( (fsm_Meta.meta.ackNumb >= txSar.prevAckd) and (fsm_Meta.meta.ackNumb <= txSar.prevUnak)) or
1500  (((fsm_Meta.meta.ackNumb >= txSar.prevAckd) or (fsm_Meta.meta.ackNumb <= txSar.prevUnak)) and (txSar.prevUnak < txSar.prevAckd))) {
1501  soTSt_TxSarQry.write((RXeTxSarQuery(fsm_Meta.sessionId,
1502  fsm_Meta.meta.ackNumb,
1503  fsm_Meta.meta.winSize,
1504  txSar.cong_window,
1505  txSar.count,
1506  ((txSar.count == 3) || txSar.fastRetransmitted))));
1507  }
1508 
1509  // If packet contains payload
1510  // We must handle Out-Of-Order delivered segments
1511  if (fsm_Meta.meta.length != 0) {
1512 
1513  // Build a DDR memory address for this segment
1514  // FYI - The TCP Rx buffers use up to 1GB (16Kx64KB).
1515  RxMemPtr memSegAddr = TOE_RX_MEMORY_BASE;
1516  memSegAddr(29, TOE_WINDOW_BITS) = fsm_Meta.sessionId(13, 0);
1517  memSegAddr(TOE_WINDOW_BITS-1, 0) = fsm_Meta.meta.seqNumb.range(TOE_WINDOW_BITS-1, 0);
1518 
1519  // Increment the Rx byte counter
1520  fsm_rxByteCounter += fsm_Meta.meta.length;
1521 
1522  RxSeqNum newRcvd = 0;
1523  RxSeqNum newOooHead = 0;
1524  RxSeqNum newOooTail = 0;
1525 
1526  //-- DEFAULT : No OOO and Rx segment is in expected sequence order
1527  if (!rxSar.ooo and (fsm_Meta.meta.seqNumb == rxSar.rcvd) and
1528  (fsm_freeSpace > fsm_Meta.meta.length)) {
1529  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "OOO-DEFAULT : Rx segment is in-order.\n"); }
1530  // Generate new received pointer
1531  newRcvd = fsm_Meta.meta.seqNumb + fsm_Meta.meta.length;
1532  // Update RxSar pointers
1533  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, newRcvd, QUERY_WR));
1534  // Send memory write command
1535  assessSize(myName, soMwr_WrCmd, "soMwr_WrCmd", cDepth_FsmToMwr_WrCmd);
1536  soMwr_WrCmd.write(DmCmd(memSegAddr, fsm_Meta.meta.length));
1537  // Send Rx data notify to [APP]
1538  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, fsm_Meta.meta.length,
1539  fsm_Meta.ip4SrcAddr, fsm_Meta.tcpSrcPort,
1540  fsm_Meta.tcpDstPort));
1541  // Send keep command
1542  soTsd_DropCmd.write(CMD_KEEP);
1543  fsm_oooDebugState = 2;
1544  }
1545  //-- START : No OOO but Rx segment arrived out-of-order
1546  else if (!rxSar.ooo and (fsm_Meta.meta.seqNumb > rxSar.rcvd) and
1547  (fsm_freeSpace > (fsm_Meta.meta.seqNumb+fsm_Meta.meta.length-rxSar.oooHead)(TOE_WINDOW_BITS-1, 0))) {
1548  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "OOO-START : Rx segment is out-of-order.\n"); }
1549  // Generate new oooHead and oooTail pointers
1550  newOooHead = fsm_Meta.meta.seqNumb + fsm_Meta.meta.length;
1551  newOooTail = fsm_Meta.meta.seqNumb;
1552  // Update RxSar pointers
1553  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, rxSar.rcvd, FLAG_OOO, newOooHead, newOooTail, QUERY_WR));
1554  // Send memory write command
1555  soMwr_WrCmd.write(DmCmd(memSegAddr, fsm_Meta.meta.length));
1556  // Prevent [Ran] to send Rx data notify to [APP] by setting LENGTH=0 !!!
1557  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, 0,
1558  fsm_Meta.ip4SrcAddr, fsm_Meta.tcpSrcPort,
1559  fsm_Meta.tcpDstPort));
1560  // Send keep command
1561  soTsd_DropCmd.write(CMD_KEEP);
1562  fsm_oooDebugState = 3;
1563  }
1564  //-- CONTINUE: OOO exists and Rx segment is in-order with respect to 'oooHead' pointer
1565  else if (rxSar.ooo and (fsm_Meta.meta.seqNumb == rxSar.oooHead) and
1566  (fsm_freeSpace > fsm_Meta.meta.length)) {
1567  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "OOO-CONTINUE: Rx segment is in-order with respect to 'oooHead'.\n"); }
1568  // Generate new oooHead pointer
1569  newOooHead = fsm_Meta.meta.seqNumb + fsm_Meta.meta.length;
1570  // Update RxSar pointers
1571  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, rxSar.rcvd, FLAG_OOO, newOooHead, rxSar.oooTail, QUERY_WR));
1572  // Send memory write command
1573  soMwr_WrCmd.write(DmCmd(memSegAddr, fsm_Meta.meta.length));
1574  // Prevent [Ran] to send Rx data notify to [APP] by setting LENGTH=0 !!!
1575  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, 0,
1576  fsm_Meta.ip4SrcAddr, fsm_Meta.tcpSrcPort,
1577  fsm_Meta.tcpDstPort));
1578  // Send keep command
1579  soTsd_DropCmd.write(CMD_KEEP);
1580  fsm_oooDebugState = 4;
1581  }
1582  //-- CONTINUE: OOO exists, Rx segment is in-order with respect to 'rcvd' pointer but it does not fill the gap
1583  else if (rxSar.ooo and (fsm_Meta.meta.seqNumb == rxSar.rcvd) and
1584  ((fsm_Meta.meta.seqNumb + fsm_Meta.meta.length) < rxSar.oooTail)) {
1585  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "OOO-CONTINUE: Rx segment is in-order with respect to 'rcvd' but it does not fill the gap.\n"); }
1586  // Generate new received pointer
1587  newRcvd = fsm_Meta.meta.seqNumb + fsm_Meta.meta.length;
1588  // Update RxSar pointers
1589  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, newRcvd, FLAG_OOO, rxSar.oooHead, rxSar.oooTail, QUERY_WR));
1590  // Send memory write command
1591  soMwr_WrCmd.write(DmCmd(memSegAddr, fsm_Meta.meta.length));
1592  // Send Rx data notify to [APP]
1593  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, fsm_Meta.meta.length,
1594  fsm_Meta.ip4SrcAddr, fsm_Meta.tcpSrcPort,
1595  fsm_Meta.tcpDstPort));
1596  // Send keep command
1597  soTsd_DropCmd.write(CMD_KEEP);
1598  fsm_oooDebugState = 5;
1599  }
1600  //-- END : OOO exists, Rx segment is in-order with respect to 'rcvd' pointer and it fills the gap
1601  else if (rxSar.ooo and (fsm_Meta.meta.seqNumb == rxSar.rcvd) and
1602  ((fsm_Meta.meta.seqNumb + fsm_Meta.meta.length) == rxSar.oooTail)) {
1603  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "OOO-END : Rx segment is in-order with respect to 'rcvd' and it fills the gap.\n"); }
1604  // Generate new received pointer
1605  newRcvd = rxSar.oooHead;
1606  // Update RxSar pointers
1607  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, newRcvd, FLAG_INO, rxSar.oooHead, rxSar.oooTail, QUERY_WR));
1608  // Send memory write command
1609  soMwr_WrCmd.write(DmCmd(memSegAddr, fsm_Meta.meta.length));
1610  // Send Rx data notify to [APP]
1611  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, (rxSar.oooHead - rxSar.rcvd),
1612  fsm_Meta.ip4SrcAddr, fsm_Meta.tcpSrcPort,
1613  fsm_Meta.tcpDstPort));
1614  // Send keep command
1615  soTsd_DropCmd.write(CMD_KEEP);
1616  fsm_oooDebugState = 6;
1617  }
1618  //-- OOO-DROP : Always drop segment in all other cases
1619  else {
1620  soTsd_DropCmd.write(CMD_DROP);
1621  fsm_oooDropCounter++;
1622  fsm_oooDebugState = 10;
1623  if ( (fsm_Meta.meta.seqNumb < rxSar.rcvd)) {
1624  printInfo(myName, "OOO-Dropping Rx segment (Frame is a retransmission because of a lost or delayed ACK). \n");
1625  fsm_oooDebugState = 11;
1626  }
1627  else if ( (!rxSar.ooo and (fsm_Meta.meta.seqNumb == rxSar.rcvd) and (fsm_freeSpace < fsm_Meta.meta.length)) or
1628  (!rxSar.ooo and (fsm_Meta.meta.seqNumb > rxSar.rcvd) and (fsm_freeSpace > (fsm_Meta.meta.seqNumb+fsm_Meta.meta.length-rxSar.rcvd)(TOE_WINDOW_BITS-1, 0))) ) {
1629  printInfo(myName, "OOO-Dropping Rx segment (Not enough space left in the Rx ring buffer).\n");
1630  fsm_oooDebugState = 12;
1631  }
1632  else if (fsm_Meta.meta.seqNumb+fsm_Meta.meta.length == rxSar.rcvd) {
1633  printInfo(myName, "OOO-Dropping Rx segment (Segment is a duplicate).\n");
1634  fsm_oooDebugState = 13;
1635  }
1636  else {
1637  printFatal(myName, "OOO-Dropping Rx segment (Reason is unknown).\n");
1638  fsm_oooDebugState = 14;
1639  }
1640  }
1641  }
1642 
1643  //-- Generate ACK Event -------------------------------------
1644 # if FAST_RETRANSMIT
1645  if (txSar.count == 3 && !txSar.fastRetransmitted) { // [FIXME - Use a constant here]
1646  soEVe_Event.write(event(RT, fsm_Meta.sessionId));
1647  }
1648  else if (fsm_meta.meta.length != 0) {
1649 #else
1650  if (fsm_Meta.meta.length != 0) {
1651 #endif
1652  if (!rxSar.ooo and (fsm_Meta.meta.seqNumb == rxSar.rcvd) and
1653  (fsm_freeSpace > fsm_Meta.meta.length)) {
1654  // No OOO and Rx segment is in expected sequence order
1655  soEVe_Event.write(Event(ACK_EVENT, fsm_Meta.sessionId));
1656  }
1657  else {
1658  // TCP retransmission frame
1659  soEVe_Event.write(Event(ACK_NODELAY_EVENT, fsm_Meta.sessionId));
1660  fsm_oooDebugState += 100;
1661  }
1662  }
1663 
1664  //-- Reset Retransmit Timer --------------------------------
1665  if (fsm_Meta.meta.ackNumb == txSar.prevUnak) {
1666  switch (tcpState) {
1667  case SYN_RECEIVED:
1668  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, ESTABLISHED, QUERY_WR));
1669  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "Session[%d] - TCP State = ESTABISHED.\n", fsm_Meta.sessionId.to_uint()); }
1670  break;
1671  case CLOSING:
1672  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, TIME_WAIT, QUERY_WR));
1673  soTIm_CloseTimer.write(fsm_Meta.sessionId); // [TDOD - rename]
1674  break;
1675  case LAST_ACK:
1676  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, CLOSED, QUERY_WR));
1677  break;
1678  default:
1679  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1680  break;
1681  }
1682  }
1683  else { // we have to release the lock
1684  // Reset rtTimer
1685  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR)); // or ESTABLISHED
1686  }
1687  } // End of : if ( (tcpState == ...
1688  // TODO if timewait just send ACK, can it be time wait??
1689  else { // state == (CLOSED || SYN_SENT || CLOSE_WAIT || FIN_WAIT_2 || TIME_WAIT)
1690  // SENT RST, RFC 793: fig.11
1691  soEVe_Event.write(rstEvent(fsm_Meta.sessionId, fsm_Meta.meta.seqNumb+fsm_Meta.meta.length)); // noACK ?
1692  // if data is in the pipe it needs to be droppped
1693  if (fsm_Meta.meta.length != 0) {
1694  soTsd_DropCmd.write(CMD_DROP);
1695  }
1696  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1697  }
1698  } // End of: ACK processing
1699  break;
1700  case 2:
1701  //--------------------------------------
1702  //-- SYN
1703  //--------------------------------------
1704  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "Entering 'SYN' processing.\n"); }
1705  if (fsm_fsmState == FSM_LOAD) {
1706  siSTt_StateRep.read(tcpState);
1707  siRSt_RxSarRep.read(rxSar);
1708  if (tcpState == CLOSED or tcpState == SYN_SENT) {
1709  // Initialize RxSar with received SeqNum
1710  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, fsm_Meta.meta.seqNumb+1,
1711  QUERY_WR, QUERY_INIT));
1712  // Initialize TxSar with received WindowSize
1713  // All other parameters are zero or false; they will be initialized by [TXe]
1714  soTSt_TxSarQry.write((RXeTxSarQuery(fsm_Meta.sessionId, 0, fsm_Meta.meta.winSize,
1715  0, 0, false)));
1716  // Post a SYN_ACK event request
1717  soEVe_Event.write(Event(SYN_ACK_EVENT, fsm_Meta.sessionId));
1718  if (DEBUG_LEVEL & TRACE_FSM) printInfo(myName, "Requesting [TXe] to send a [SYN,ACK] for SessId %d.\n", fsm_Meta.sessionId.to_uint());
1719  // Change TcpState to SYN_RECEIVED
1720  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, SYN_RECEIVED, QUERY_WR));
1721  }
1722  else if (tcpState == SYN_RECEIVED) { // && mdh_meta.seqNumb+1 == rxSar.recvd) // Maybe Check for seq
1723  // If it is the same SYN, we resent SYN-ACK, almost like quick RT, we could also wait for RT timer
1724  if (fsm_Meta.meta.seqNumb+1 == rxSar.rcvd) {
1725  // Retransmit SYN_ACK
1726  ap_uint<3> rtCount = 1;
1727  soEVe_Event.write(Event(SYN_ACK_EVENT, fsm_Meta.sessionId, rtCount));
1728  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1729  }
1730  else { // Sent RST, RFC 793: fig.9 (old) duplicate SYN(+ACK)
1731  soEVe_Event.write(rstEvent(fsm_Meta.sessionId, fsm_Meta.meta.seqNumb+1)); //length == 0
1732  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, CLOSED, QUERY_WR));
1733  }
1734  }
1735  else { // Any synchronized state
1736  // Unexpected SYN arrived, reply with normal ACK, RFC 793: fig.10
1737  soEVe_Event.write(Event(ACK_NODELAY_EVENT, fsm_Meta.sessionId));
1738  // TODo send RST, has no ACK??
1739  // Respond with RST, no ACK, seq ==
1740  //eventEngine.write(rstEvent(mdh_meta.seqNumb, mh_meta.length, true));
1741  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1742  }
1743  }
1744  break;
1745  case 3:
1746  //--------------------------------------
1747  //-- SYN_ACK
1748  //--------------------------------------
1749  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "Entering 'SYN_ACK' processing.\n"); }
1750  if (fsm_fsmState == FSM_LOAD) {
1751  siSTt_StateRep.read(tcpState);
1752  siRSt_RxSarRep.read(rxSar);
1753  siTSt_TxSarRep.read(txSar);
1754  TimerCmd timerCmd = (fsm_Meta.meta.ackNumb == txSar.prevUnak) ? STOP_TIMER : LOAD_TIMER;
1755  soTIm_ReTxTimerCmd.write(RXeReTransTimerCmd(fsm_Meta.sessionId, timerCmd));
1756  if ( (tcpState == SYN_SENT) and (fsm_Meta.meta.ackNumb == txSar.prevUnak) ) { // && !mh_lup.created)
1757  // Initialize RxSar with received SeqNum
1758  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, fsm_Meta.meta.seqNumb+1,
1759  QUERY_WR, QUERY_INIT));
1760  // Update TxSar with received AckNum and WindowSize
1761  soTSt_TxSarQry.write(RXeTxSarQuery(fsm_Meta.sessionId,
1762  fsm_Meta.meta.ackNumb,
1763  fsm_Meta.meta.winSize,
1764  txSar.cong_window, 0, false)); // [TODO - maybe include count check]
1765  // Set ACK event
1766  soEVe_Event.write(Event(ACK_NODELAY_EVENT, fsm_Meta.sessionId));
1767  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, ESTABLISHED, QUERY_WR));
1768  // Signal [TAi] that the active connection was successfully established
1769  soTAi_SessOpnSts.write(SessState(fsm_Meta.sessionId, ESTABLISHED));
1770  }
1771  else if (tcpState == SYN_SENT) { //TODO correct answer?
1772  // Sent RST, RFC 793: fig.9 (old) duplicate SYN(+ACK)
1773  soEVe_Event.write(rstEvent(fsm_Meta.sessionId,
1774  fsm_Meta.meta.seqNumb+fsm_Meta.meta.length+1));
1775  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, CLOSED, QUERY_WR));
1776  }
1777  else {
1778  // Unexpected SYN arrived, reply with normal ACK, RFC 793: fig.10
1779  soEVe_Event.write(Event(ACK_NODELAY_EVENT, fsm_Meta.sessionId));
1780  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1781  }
1782  }
1783  break;
1784  case 5:
1785  //--------------------------------------
1786  //-- FIN (_ACK)
1787  //--------------------------------------
1788  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "Entering 'FIN_ACK' processing.\n"); }
1789  if (fsm_fsmState == FSM_LOAD) {
1790  siSTt_StateRep.read(tcpState);
1791  siRSt_RxSarRep.read(rxSar);
1792  siTSt_TxSarRep.read(txSar);
1793  TimerCmd timerCmd = (fsm_Meta.meta.ackNumb == txSar.prevUnak) ? STOP_TIMER : LOAD_TIMER;
1794  soTIm_ReTxTimerCmd.write(RXeReTransTimerCmd(fsm_Meta.sessionId, timerCmd));
1795  // Check state and if FIN in order, Current out of order FINs are not accepted
1796  if ( (tcpState == ESTABLISHED or tcpState == FIN_WAIT_1 or tcpState == FIN_WAIT_2) and (rxSar.rcvd == fsm_Meta.meta.seqNumb) ) {
1797  soTSt_TxSarQry.write((RXeTxSarQuery(fsm_Meta.sessionId,
1798  fsm_Meta.meta.ackNumb, fsm_Meta.meta.winSize,
1799  txSar.cong_window, txSar.count,
1800  ~QUERY_FAST_RETRANSMIT))); //TODO include count check
1801  // +1 for phantom byte, there might be data too
1802  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, fsm_Meta.meta.seqNumb+fsm_Meta.meta.length+1,
1803  QUERY_WR)); // diff to ACK
1804  // Clear the probe timer
1805  soTIm_ClearProbeTimer.write(fsm_Meta.sessionId);
1806  // Check if there is payload
1807  if (fsm_Meta.meta.length != 0) {
1808  // Build a DDR memory address for this segment
1809  RxMemPtr memSegAddr = TOE_RX_MEMORY_BASE;
1810  memSegAddr(29, 16) = fsm_Meta.sessionId(13, 0);
1811  memSegAddr(15, 0) = fsm_Meta.meta.seqNumb(15, 0);
1812 #if !(RX_DDR_BYPASS)
1813  soMwr_WrCmd.write(DmCmd(memSegAddr, fsm_Meta.meta.length));
1814 #endif
1815  // Tell Application new data is available and connection got closed
1816  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, fsm_Meta.meta.length, fsm_Meta.ip4SrcAddr,
1817  fsm_Meta.tcpSrcPort, fsm_Meta.tcpDstPort, CLOSED));
1818  soTsd_DropCmd.write(CMD_KEEP);
1819  }
1820  else if (tcpState == ESTABLISHED) {
1821  // Tell Application connection got closed
1822  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, 0, fsm_Meta.ip4SrcAddr,
1823  fsm_Meta.tcpSrcPort, fsm_Meta.tcpDstPort, CLOSED));
1824  }
1825  // Update state
1826  if (tcpState == ESTABLISHED) {
1827  soEVe_Event.write(Event(FIN_EVENT, fsm_Meta.sessionId));
1828  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, LAST_ACK, QUERY_WR));
1829  }
1830  else { //FIN_WAIT_1 || FIN_WAIT_2
1831  if (fsm_Meta.meta.ackNumb == txSar.prevUnak) {
1832  // Check if final FIN is ACK'd -> LAST_ACK
1833  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, TIME_WAIT, QUERY_WR));
1834  soTIm_CloseTimer.write(fsm_Meta.sessionId);
1835  }
1836  else {
1837  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, CLOSING, QUERY_WR));
1838  }
1839  soEVe_Event.write(Event(ACK_EVENT, fsm_Meta.sessionId));
1840  }
1841  }
1842  else { // NOT (ESTABLISHED || FIN_WAIT_1 || FIN_WAIT_2)
1843  soEVe_Event.write(Event(ACK_EVENT, fsm_Meta.sessionId));
1844  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1845  // If there is payload we need to drop it
1846  if (fsm_Meta.meta.length != 0) {
1847  soTsd_DropCmd.write(CMD_DROP);
1848  }
1849  }
1850  }
1851  break;
1852  default: //TODO MAYBE load everything all the time
1853  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "Received segment. CtrlBits=0x%X\n", control_bits.to_uchar()); }
1854  // stateTable is locked, make sure it is released in at the end
1855  // If there is an ACK we read txSar
1856  // We always read rxSar
1857  if (fsm_fsmState == FSM_LOAD) {
1858  siSTt_StateRep.read(tcpState);
1859  siRSt_RxSarRep.read(rxSar); //TODO not sure nb works
1860  siTSt_TxSarRep.read_nb(txSar);
1861  }
1862  if (fsm_fsmState == FSM_LOAD) {
1863  // Handle if RST
1864  if (fsm_Meta.meta.rst) {
1865  if (tcpState == SYN_SENT) {
1866  // [TODO this would be a RST,ACK i think]
1867  // Check if matching SYN
1868  if (fsm_Meta.meta.ackNumb == txSar.prevUnak) {
1869  // The connection culd not be established
1870  soTAi_SessOpnSts.write(SessState(fsm_Meta.sessionId, CLOSED));
1871  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, CLOSED, QUERY_WR));
1872  soTIm_ReTxTimerCmd.write(RXeReTransTimerCmd(fsm_Meta.sessionId, STOP_TIMER));
1873  }
1874  else {
1875  // Ignore since not matching
1876  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1877  }
1878  }
1879  else {
1880  // Check if in window
1881  if (fsm_Meta.meta.seqNumb == rxSar.rcvd) {
1882  // Tell application, RST occurred, abort
1883  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, 0, fsm_Meta.ip4SrcAddr,
1884  fsm_Meta.tcpSrcPort, fsm_Meta.tcpDstPort, CLOSED)); // RESET-CLOSED
1885  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, CLOSED, QUERY_WR)); //TODO maybe some TIME_WAIT state
1886  soTIm_ReTxTimerCmd.write(RXeReTransTimerCmd(fsm_Meta.sessionId, STOP_TIMER));
1887  }
1888  else {
1889  // Ignore since not matching window
1890  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1891  }
1892  }
1893  }
1894  else { // Handle non RST bogus packages
1895  //TODO maybe sent RST ourselves, or simply ignore
1896  // For now ignore, sent ACK??
1897  //eventsOut.write(rstEvent(mh_meta.seqNumb, 0, true));
1898  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1899  } // End of: if (fsm_meta.meta.rst)
1900  } // if fsm_stat
1901  break;
1902  } // End of: switch control_bits
1903  if (DEBUG_LEVEL & TRACE_FSM) {
1904  printInfo(myName, "Flags - [0x%X] \n", control_bits.to_uint());
1905  }
1906  break;
1907  } // End of: switch state
1908 
1909  //-- ALWAYS -------------------------------------------
1910  if (!soMMIO_OooDropCnt.full()) {
1911  soMMIO_OooDropCnt.write(fsm_oooDropCounter);
1912  }
1913  else {
1914  printFatal(myName, "Cannot write soMMIO_OooDropCnt stream...");
1915  }
1916  if (!soDBG_TcpIpRxByteCnt.full()) {
1917  soDBG_TcpIpRxByteCnt.write(fsm_rxByteCounter);
1918  }
1919  else {
1920  printFatal(myName, "Cannot write soDBG_TcpIpRxByteCnt stream...");
1921  }
1922  if (!soDBG_OooDebug.full()) {
1923  soDBG_OooDebug.write(fsm_oooDebugState);
1924  }
1925  else {
1926  printFatal(myName, "Cannot write soDBG_OooDebug stream...");
1927  }
1928 
1929 } // End of: pFiniteStateMachine(
1930 
1931 
1944  stream<ExtendedEvent> &siMdh_Event,
1945  stream<Event> &siFsm_Event,
1946  stream<ExtendedEvent> &soEVe_Event)
1947 {
1948  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1949  #pragma HLS PIPELINE II=1 enable_flush
1950  #pragma HLS INLINE
1951 
1952  const char *myName = concat3(THIS_NAME, "/", "Evm");
1953 
1954  if (!siMdh_Event.empty()) {
1955  soEVe_Event.write(siMdh_Event.read());
1956  }
1957  else if (!siFsm_Event.empty()) {
1958  soEVe_Event.write(siFsm_Event.read());
1959  }
1960 }
1961 
1962 
1963 
2001  // IP Rx Interface
2002  stream<AxisIp4> &siIPRX_Data,
2003  //-- Session Lookup Controller Interface
2004  stream<SessionLookupQuery> &soSLc_SessLkReq,
2005  stream<SessionLookupReply> &siSLc_SessLkRep,
2006  //-- State Table Interface
2007  stream<StateQuery> &soSTt_StateQry,
2008  stream<TcpState> &siSTt_StateRep,
2009  //-- Port Table Interface
2010  stream<TcpPort> &soPRt_PortStateReq,
2011  stream<RepBit> &siPRt_PortStateRep,
2012  //-- Rx SAR Table Interface
2013  stream<RXeRxSarQuery> &soRSt_RxSarQry,
2014  stream<RxSarReply> &siRSt_RxSarRep,
2015  //-- Tx SAR Table Interface
2016  stream<RXeTxSarQuery> &soTSt_TxSarQry,
2017  stream<RXeTxSarReply> &siTSt_TxSarRep,
2018  //-- Timers Interface
2019  stream<RXeReTransTimerCmd> &soTIm_ReTxTimerCmd,
2020  stream<SessionId> &soTIm_ClearProbeTimer,
2021  stream<SessionId> &soTIm_CloseTimer,
2022  //-- Event Engine Interface
2023  stream<ExtendedEvent> &soEVe_SetEvent,
2024  //-- Tx Application Interface
2025  stream<SessState> &soTAi_SessOpnSts,
2026  //-- Rx Application Interface
2027  stream<TcpAppNotif> &soRAi_RxNotif,
2028  //-- MEM / Rx Write Path Interface
2029  stream<DmCmd> &soMEM_WrCmd,
2030  stream<AxisApp> &soMEM_WrData,
2031  stream<DmSts> &siMEM_WrSts,
2032  //--MMIO Interfaces
2033  stream<StsBit> &soMMIO_RxMemWrErr,
2034  stream<ap_uint<8> > &soMMIO_CrcDropCnt,
2035  stream<ap_uint<8> > &soMMIO_SessDropCnt,
2036  stream<ap_uint<8> > &soMMIO_OooDropCnt,
2037  //-- DEBUG Interfaces
2038  stream<RxBufPtr> &soDBG_RxFreeSpace,
2039  stream<ap_uint<32> > &soDBG_TcpIpRxByteCnt,
2040  stream<ap_uint<8> > &soDBG_OooDebug)
2041 {
2042  //-- DIRECTIVES FOR THE INTERFACES ----------------------------------------
2043  #pragma HLS DATAFLOW
2044  #pragma HLS INTERFACE ap_ctrl_none port=return
2045 
2046  //-------------------------------------------------------------------------
2047  //-- LOCAL STREAMS (Sorted by the name of the modules which generate them)
2048  //-------------------------------------------------------------------------
2049 
2050  //-- Tcp Length Extract (Tle) ---------------------------------------------
2051  static stream<AxisRaw> ssTleToIph_Data ("ssTleToIph_Data");
2052  #pragma HLS stream variable=ssTleToIph_Data depth=8
2053  #pragma HLS DATA_PACK variable=ssTleToIph_Data
2054 
2055  static stream<TcpSegLen> ssTleToIph_TcpSegLen ("ssTleToIph_TcpSegLen");
2056  #pragma HLS stream variable=ssTleToIph_TcpSegLen depth=2
2057 
2058  //-- Insert Pseudo Header (Iph) -------------------------------------------
2059  static stream<AxisPsd4> ssIphToCsa_PseudoPkt ("ssIphToCsa_PseudoPkt");
2060  #pragma HLS stream variable=ssIphToCsa_PseudoPkt depth=8
2061  #pragma HLS DATA_PACK variable=ssIphToCsa_PseudoPkt
2062 
2063  //-- CheckSum Accumulator (Csa) -------------------------------------------
2064  static stream<AxisApp> ssCsaToTid_Data ("ssCsaToTid_Data");
2065  #pragma HLS stream variable=ssCsaToTid_Data depth=256 //critical, tcp checksum computation
2066  #pragma HLS DATA_PACK variable=ssCsaToTid_Data
2067 
2068  static stream<ValBit> ssCsaToTid_DataValid ("ssCsaToTid_DataValid");
2069  #pragma HLS stream variable=ssCsaToTid_DataValid depth=2
2070 
2071  static stream<RXeMeta> ssCsaToMdh_Meta ("ssCsaToMdh_Meta");
2072  #pragma HLS stream variable=ssCsaToMdh_Meta depth=2
2073  #pragma HLS DATA_PACK variable=ssCsaToMdh_Meta
2074 
2075  static stream<SocketPair> ssCsaToMdh_SockPair ("ssCsaToMdh_SockPair");
2076  #pragma HLS stream variable=ssCsaToMdh_SockPair depth=2
2077  #pragma HLS DATA_PACK variable=ssCsaToMdh_SockPair
2078 
2079  //-- Tcp Invalid dropper (Tid) --------------------------------------------
2080  static stream<AxisApp> ssTidToTsd_Data ("ssTidToTsd_Data");
2081  #pragma HLS stream variable=ssTidToTsd_Data depth=8
2082  #pragma HLS DATA_PACK variable=ssTidToTsd_Data
2083 
2084  //-- Tcp Tcp Segment Dropper (Tsd) -----------------------------------------
2085  static stream<AxisApp> ssTsdToMwr_Data ("ssTsdToMwr_Data");
2086  #pragma HLS stream variable=ssTsdToMwr_Data depth=16
2087  #pragma HLS DATA_PACK variable=ssTsdToMwr_Data
2088 
2089  //-- MetaData Handler (Mdh) -----------------------------------------------
2090  static stream<ExtendedEvent> ssMdhToEvm_Event ("ssMdhToEvm_Event");
2091  #pragma HLS stream variable=ssMdhToEvm_Event depth=cDepth_MdhToEvm_Event
2092  #pragma HLS DATA_PACK variable=ssMdhToEvm_Event
2093 
2094  static stream<CmdBit> ssMdhToTsd_DropCmd ("ssMdhToTsd_DropCmd");
2095  #pragma HLS stream variable=ssMdhToTsd_DropCmd depth=cDepth_MdhToTsd_DropCmd
2096 
2097  static stream<RXeFsmMeta> ssMdhToFsm_Meta ("ssMdhToFsm_Meta");
2098  #pragma HLS stream variable=ssMdhToFsm_Meta depth=2
2099  #pragma HLS DATA_PACK variable=ssMdhToFsm_Meta
2100 
2101  //-- Finite State Machine (Fsm) -------------------------------------------
2102  static stream<CmdBit> ssFsmToTsd_DropCmd ("ssFsmToTsd_DropCmd");
2103  #pragma HLS stream variable=ssFsmToTsd_DropCmd depth=cDepth_FsmToTsd_DropCmd
2104 
2105  static stream<TcpAppNotif> ssFsmToRan_Notif ("ssFsmToRan_Notif");
2106  #pragma HLS stream variable=ssFsmToRan_Notif depth=cDepth_FsmToRan_Notif
2107  #pragma HLS DATA_PACK variable=ssFsmToRan_Notif
2108 
2109  static stream<Event> ssFsmToEvm_Event ("ssFsmToEvm_Event");
2110  #pragma HLS stream variable=ssFsmToEvm_Event depth=cDepth_FsmToEve_Event
2111  #pragma HLS DATA_PACK variable=ssFsmToEvm_Event
2112 
2113  static stream<DmCmd> ssFsmToMwr_WrCmd ("ssFsmToMwr_WrCmd");
2114  #pragma HLS stream variable=ssFsmToMwr_WrCmd depth=cDepth_FsmToMwr_WrCmd
2115  #pragma HLS DATA_PACK variable=ssFsmToMwr_WrCmd
2116 
2117  //-- Memory Writer (Mwr) --------------------------------------------------
2118  static stream<FlagBool> ssMwrToRan_SplitSeg ("ssMwrToRan_SplitSeg");
2119  #pragma HLS stream variable=ssMwrToRan_SplitSeg depth=cDepth_MwrToRan_SplitSeg
2120 
2121  //-------------------------------------------------------------------------
2122  //-- PROCESS FUNCTIONS
2123  //-------------------------------------------------------------------------
2124 
2126  siIPRX_Data,
2127  ssTleToIph_Data,
2128  ssTleToIph_TcpSegLen);
2129 
2130 
2132  ssTleToIph_Data,
2133  ssTleToIph_TcpSegLen,
2134  ssIphToCsa_PseudoPkt);
2135 
2137  ssIphToCsa_PseudoPkt,
2138  ssCsaToTid_Data,
2139  ssCsaToTid_DataValid,
2140  ssCsaToMdh_Meta,
2141  ssCsaToMdh_SockPair,
2142  soPRt_PortStateReq);
2143 
2145  ssCsaToTid_Data,
2146  ssCsaToTid_DataValid,
2147  ssTidToTsd_Data,
2148  soMMIO_CrcDropCnt);
2149 
2151  ssCsaToMdh_Meta,
2152  ssCsaToMdh_SockPair,
2153  soSLc_SessLkReq,
2154  siSLc_SessLkRep,
2155  siPRt_PortStateRep,
2156  ssMdhToEvm_Event,
2157  ssMdhToTsd_DropCmd,
2158  ssMdhToFsm_Meta,
2159  soMMIO_SessDropCnt);
2160 
2162  ssMdhToFsm_Meta,
2163  soSTt_StateQry,
2164  siSTt_StateRep,
2165  soRSt_RxSarQry,
2166  siRSt_RxSarRep,
2167  soTSt_TxSarQry,
2168  siTSt_TxSarRep,
2169  soTIm_ReTxTimerCmd,
2170  soTIm_ClearProbeTimer,
2171  soTIm_CloseTimer,
2172  soTAi_SessOpnSts,
2173  ssFsmToEvm_Event,
2174  ssFsmToTsd_DropCmd,
2175  ssFsmToMwr_WrCmd,
2176  ssFsmToRan_Notif,
2177  soMMIO_OooDropCnt,
2178  soDBG_RxFreeSpace,
2179  soDBG_TcpIpRxByteCnt,
2180  soDBG_OooDebug);
2181 
2183  ssTidToTsd_Data,
2184  ssMdhToTsd_DropCmd,
2185  ssFsmToTsd_DropCmd,
2186  ssTsdToMwr_Data);
2187 
2189  ssTsdToMwr_Data,
2190  ssFsmToMwr_WrCmd,
2191  soMEM_WrCmd,
2192  soMEM_WrData,
2193  ssMwrToRan_SplitSeg);
2194 
2196  siMEM_WrSts,
2197  ssFsmToRan_Notif,
2198  soRAi_RxNotif,
2199  ssMwrToRan_SplitSeg,
2200  soMMIO_RxMemWrErr);
2201 
2203  ssMdhToEvm_Event,
2204  ssFsmToEvm_Event,
2205  soEVe_SetEvent);
2206 
2207 }
2208 
Ip4TotalLen getIp4TotalLen()
Definition: AxisIp4.hpp:205
Ip4HdrLen getIp4HdrLen()
Definition: AxisIp4.hpp:199
TcpPort getTcpDstPort()
Definition: AxisPsd4.hpp:149
TcpSeqNum getTcpSeqNum()
Definition: AxisPsd4.hpp:152
void setTcpDstPort(TcpPort port)
Definition: AxisPsd4.hpp:148
void setPsd4Len(Ly4Len len)
Definition: AxisPsd4.hpp:138
void setTcpSrcPort(TcpPort port)
Definition: AxisPsd4.hpp:145
Ip4Addr getPsd4SrcAddr()
Definition: AxisPsd4.hpp:127
TcpCtrlBit getTcpCtrlAck()
Definition: AxisPsd4.hpp:175
TcpPort getTcpSrcPort()
Definition: AxisPsd4.hpp:146
TcpCtrlBit getTcpCtrlFin()
Definition: AxisPsd4.hpp:167
TcpDataOff getTcpDataOff()
Definition: AxisPsd4.hpp:164
void setPsd4ResBits(Psd4Res res)
Definition: AxisPsd4.hpp:132
TcpOptKind getTcpOptKind()
Definition: AxisPsd4.hpp:193
TcpAckNum getTcpAckNum()
Definition: AxisPsd4.hpp:155
TcpWindow getTcpWindow()
Definition: AxisPsd4.hpp:184
TcpOptMss getTcpOptMss()
Definition: AxisPsd4.hpp:198
void setPsd4Prot(Ip4Prot prot)
Definition: AxisPsd4.hpp:135
TcpCtrlBit getTcpCtrlRst()
Definition: AxisPsd4.hpp:171
Ly4Len getPsd4Len()
Definition: AxisPsd4.hpp:139
Ip4Addr getPsd4DstAddr()
Definition: AxisPsd4.hpp:130
TcpChecksum getTcpChecksum()
Definition: AxisPsd4.hpp:187
TcpCtrlBit getTcpCtrlSyn()
Definition: AxisPsd4.hpp:169
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< 1 > okay
ap_uint< 1 > decerr
ap_uint< 1 > slverr
ap_uint< 1 > interr
Definition: toe.hpp:661
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
RXeMeta meta
Definition: rx_engine.hpp:94
Ip4SrcAddr ip4SrcAddr
Definition: rx_engine.hpp:91
TcpDstPort tcpDstPort
Definition: rx_engine.hpp:93
TcpSrcPort tcpSrcPort
Definition: rx_engine.hpp:92
SessionId sessionId
Definition: rx_engine.hpp:90
TcpSegLen length
Definition: rx_engine.hpp:77
TcpCtrlBit ack
Definition: rx_engine.hpp:78
TcpCtrlBit fin
Definition: rx_engine.hpp:81
TcpCtrlBit rst
Definition: rx_engine.hpp:79
TcpSeqNum seqNumb
Definition: rx_engine.hpp:74
TcpWindow winSize
Definition: rx_engine.hpp:76
TcpCtrlBit syn
Definition: rx_engine.hpp:80
TcpAckNum ackNumb
Definition: rx_engine.hpp:75
TxAckNum prevUnak
Definition: toe.hpp:471
ap_uint< 2 > count
Definition: toe.hpp:474
CmdBool fastRetransmitted
Definition: toe.hpp:475
TcpWindow slowstart_threshold
Definition: toe.hpp:473
TcpWindow cong_window
Definition: toe.hpp:472
TxAckNum prevAckd
Definition: toe.hpp:470
FlagBool ooo
Definition: toe.hpp:374
RxSeqNum oooTail
Definition: toe.hpp:373
RxBufPtr appd
Definition: toe.hpp:370
RxSeqNum oooHead
Definition: toe.hpp:372
RxSeqNum rcvd
Definition: toe.hpp:371
SessionId sessionID
Definition: toe.hpp:334
HitState hit
Definition: toe.hpp:335
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
TcpDatLen tcpDatLen
Definition: nts.hpp:90
TcpSegLen tcpSegLen
Definition: tb_nal.cpp:833
TcpAppOpnRep SessState
Definition: toe.hpp:279
const int cDepth_FsmToMwr_WrCmd
Definition: rx_engine.hpp:104
void rx_engine(stream< AxisIp4 > &siIPRX_Data, stream< SessionLookupQuery > &soSLc_SessLkReq, stream< SessionLookupReply > &siSLc_SessLkRep, stream< StateQuery > &soSTt_StateQry, stream< TcpState > &siSTt_StateRep, stream< TcpPort > &soPRt_PortStateReq, stream< RepBit > &siPRt_PortStateRep, stream< RXeRxSarQuery > &soRSt_RxSarQry, stream< RxSarReply > &siRSt_RxSarRep, stream< RXeTxSarQuery > &soTSt_TxSarQry, stream< RXeTxSarReply > &siTSt_TxSarRep, stream< RXeReTransTimerCmd > &soTIm_ReTxTimerCmd, stream< SessionId > &soTIm_ClearProbeTimer, stream< SessionId > &soTIm_CloseTimer, stream< ExtendedEvent > &soEVe_SetEvent, stream< SessState > &soTAi_SessOpnSts, stream< TcpAppNotif > &soRAi_RxNotif, stream< DmCmd > &soMEM_WrCmd, stream< AxisApp > &soMEM_WrData, stream< DmSts > &siMEM_WrSts, stream< StsBit > &soMMIO_RxMemWrErr, stream< ap_uint< 8 > > &soMMIO_CrcDropCnt, stream< ap_uint< 8 > > &soMMIO_SessDropCnt, stream< ap_uint< 8 > > &soMMIO_OooDropCnt, stream< RxBufPtr > &soDBG_RxFreeSpace, stream< ap_uint< 32 > > &soDBG_TcpIpRxByteCnt, stream< ap_uint< 8 > > &soDBG_OooDebug)
Receive Engine (RXe)
Definition: rx_engine.cpp:2000
#define TRACE_CSA
Definition: rx_engine.cpp:73
void pRxAppNotifier(stream< DmSts > &siMEM_WrSts, stream< TcpAppNotif > &siFsm_Notif, stream< TcpAppNotif > &soRAi_RxNotif, stream< FlagBool > &siMwr_SplitSeg, stream< StsBit > &soMMIO_MemWrErr)
Rx Application Notifier (Ran)
Definition: rx_engine.cpp:1075
void pRxMemoryWriter(stream< AxisApp > &siTsd_Data, stream< DmCmd > &siFsm_MemWrCmd, stream< DmCmd > &soMEM_WrCmd, stream< AxisApp > &soMEM_WrData, stream< FlagBool > &soRan_SplitSeg)
Rx Memory Writer (Mwr)
Definition: rx_engine.cpp:859
TcpSeqNum RxSeqNum
Definition: toe.hpp:290
TimerCmd
Definition: toe.hpp:622
void pTcpSegmentDropper(stream< AxisApp > &siTid_Data, stream< CmdBit > &siMdh_DropCmd, stream< CmdBit > &siFsm_DropCmd, stream< AxisApp > &soMwr_Data)
TCP Segment Dropper (Tsd)
Definition: rx_engine.cpp:775
#define TRACE_FSM
Definition: rx_engine.cpp:78
#define TRACE_TID
Definition: rx_engine.cpp:75
#define TRACE_TLE
Definition: rx_engine.cpp:71
void pTcpLengthExtractor(stream< AxisIp4 > &siIPRX_Data, stream< AxisRaw > &soIph_Data, stream< TcpSegLen > &soIph_TcpSegLen)
TCP Length Extraction (Tle)
Definition: rx_engine.cpp:145
void pTcpInvalidDropper(stream< AxisApp > &siCsa_Data, stream< ValBit > &siCsa_DataVal, stream< AxisApp > &soTsd_Data, stream< ap_uint< 8 > > &soMMIO_CrcDropCnt)
TCP Invalid checksum Dropper (Tid)
Definition: rx_engine.cpp:695
void pMetaDataHandler(stream< RXeMeta > &siCsa_Meta, stream< SocketPair > &siCsa_SockPair, stream< SessionLookupQuery > &soSLc_SessLkpReq, stream< SessionLookupReply > &siSLc_SessLkpRep, stream< StsBit > &siPRt_PortSts, stream< ExtendedEvent > &soEVe_Event, stream< CmdBit > &soTsd_DropCmd, stream< RXeFsmMeta > &soFsm_Meta, stream< ap_uint< 8 > > &soMMIO_SessDropCnt)
MetaData Handler (Mdh)
Definition: rx_engine.cpp:1197
bool gTraceEvent
Definition: tb_nal.cpp:151
#define THIS_NAME
Definition: rx_engine.cpp:68
void pFiniteStateMachine(stream< RXeFsmMeta > &siMdh_FsmMeta, stream< StateQuery > &soSTt_StateQry, stream< TcpState > &siSTt_StateRep, stream< RXeRxSarQuery > &soRSt_RxSarQry, stream< RxSarReply > &siRSt_RxSarRep, stream< RXeTxSarQuery > &soTSt_TxSarQry, stream< RXeTxSarReply > &siTSt_TxSarRep, stream< RXeReTransTimerCmd > &soTIm_ReTxTimerCmd, stream< SessionId > &soTIm_ClearProbeTimer, stream< SessionId > &soTIm_CloseTimer, stream< SessState > &soTAi_SessOpnSts, stream< Event > &soEVe_Event, stream< CmdBit > &soTsd_DropCmd, stream< DmCmd > &soMwr_WrCmd, stream< TcpAppNotif > &soRan_RxNotif, stream< ap_uint< 8 > > &soMMIO_OooDropCnt, stream< RxBufPtr > &soDBG_RxFreeSpace, stream< ap_uint< 32 > > &soDBG_TcpIpRxByteCnt, stream< ap_uint< 8 > > &soDBG_OooDebug)
Finite State machine (Fsm)
Definition: rx_engine.cpp:1358
void pInsertPseudoHeader(stream< AxisRaw > &siTle_Data, stream< TcpSegLen > &siTle_TcpSegLen, stream< AxisPsd4 > &soCsa_PseudoPkt)
Insert pseudo header (Iph)
Definition: rx_engine.cpp:320
TcpBufAdr RxBufPtr
Definition: toe.hpp:298
#define TRACE_IPH
Definition: rx_engine.cpp:72
#define DEBUG_LEVEL
Definition: rx_engine.cpp:83
void pCheckSumAccumulator(stream< AxisPsd4 > &siIph_PseudoPkt, stream< AxisApp > &soTid_Data, stream< ValBit > &soTid_DataVal, stream< RXeMeta > &soMdh_Meta, stream< SocketPair > &soMdh_SockPair, stream< TcpPort > &soPRt_GetState)
TCP checksum accumulator (Csa)
Definition: rx_engine.cpp:444
void pEventMultiplexer(stream< ExtendedEvent > &siMdh_Event, stream< Event > &siFsm_Event, stream< ExtendedEvent > &soEVe_Event)
Event Multiplexer (Evm)
Definition: rx_engine.cpp:1943
#define TRACE_RAN
Definition: rx_engine.cpp:80
#define TRACE_MDH
Definition: rx_engine.cpp:74
ap_uint< 32 > RxMemPtr
Definition: toe.hpp:295
#define TRACE_MWR
Definition: rx_engine.cpp:79
@ ACK_EVENT
Definition: toe.hpp:273
@ FIN_EVENT
Definition: toe.hpp:274
@ SYN_ACK_EVENT
Definition: toe.hpp:274
@ ACK_NODELAY_EVENT
Definition: toe.hpp:274
@ LOAD_TIMER
Definition: toe.hpp:622
@ STOP_TIMER
Definition: toe.hpp:623
@ CHUNK_2
Definition: toe.hpp:244
@ CHUNK_1
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
ap_uint< 8 > TcpOptKind
Definition: AxisTcp.hpp:117
#define printError(callerName, format,...)
A macro to print an error message.
Definition: nts_utils.hpp:195
LE_tKeep lenToLE_tKeep(ap_uint< 4 > noValidBytes)
A function to set a number of '1' in an 8-bit field. It is used here to set the number of valid bytes...
Definition: nts_utils.cpp:307
#define QUERY_FAST_RETRANSMIT
Definition: nts_types.hpp:68
TcpState
Definition: nts_types.hpp:296
ap_uint< 1 > StsBit
Definition: nts_types.hpp:116
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
ap_uint< 16 > Ip4DatLen
Definition: AxisIp4.hpp:173
#define QUERY_RD
Definition: nts_types.hpp:65
ap_uint< 1 > ValBit
Definition: nts_types.hpp:117
ap_uint< 16 > TcpDstPort
Definition: AxisTcp.hpp:104
ap_uint< 4 > Ip4HdrLen
Definition: AxisIp4.hpp:157
#define STS_CLOSED
Definition: nts_types.hpp:82
bool FlagBool
Definition: nts_types.hpp:124
#define CMD_DROP
Definition: nts_types.hpp:61
#define QUERY_WR
Definition: nts_types.hpp:66
#define IP4_PROT_TCP
Definition: nts_types.hpp:184
ap_uint< 16 > TcpPort
Definition: AxisTcp.hpp:105
#define FLAG_OOO
Definition: nts_types.hpp:73
#define QUERY_INIT
Definition: nts_types.hpp:67
#define CMD_KEEP
Definition: nts_types.hpp:62
#define printInfo(callerName, format,...)
A macro to print an information message.
Definition: nts_utils.hpp:169
#define OK
Definition: nts_types.hpp:57
ap_uint< 16 > Ip4TotalLen
Definition: AxisIp4.hpp:159
ap_uint< 1 > CmdBit
Definition: nts_types.hpp:108
#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
#define KO
Definition: nts_types.hpp:58
ap_uint< 4 > TcpDataOff
Definition: AxisTcp.hpp:109
ap_uint< 16 > TcpOptMss
Definition: AxisTcp.hpp:119
ap_uint< 32 > Ip4Address
Definition: AxisIp4.hpp:168
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 STS_NO_ERR
Definition: nts_types.hpp:84
#define TLAST
Definition: AxisRaw.hpp:116
#define FLAG_INO
Definition: nts_types.hpp:74
ap_uint< 16 > TcpChecksum
Definition: AxisTcp.hpp:113
#define FLAG_OFF
Definition: nts_types.hpp:70
#define FLAG_ON
Definition: nts_types.hpp:71
#define TCP_OPT_KIND_MSS
Definition: AxisTcp.hpp:129
@ LAST_ACK
Definition: nts_types.hpp:298
@ FIN_WAIT_2
Definition: nts_types.hpp:297
@ FIN_WAIT_1
Definition: nts_types.hpp:297
@ SYN_SENT
Definition: nts_types.hpp:296
@ TIME_WAIT
Definition: nts_types.hpp:297
@ ESTABLISHED
Definition: nts_types.hpp:296
@ CLOSING
Definition: nts_types.hpp:297
@ CLOSED
Definition: nts_types.hpp:296
@ SYN_RECEIVED
Definition: nts_types.hpp:296
: Rx Engine (RXe) 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