cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
IPRX

IP Receiver packet handler (IPRX) of the Network Transport Stack (NTS). More...

Collaboration diagram for IPRX:

Modules

 IPRX_TEST
 Testbench for the IP Receiver packet handler (IPRX) of the Network Transport Stack (NTS).
 

Files

file  test_iprx.cpp
 : Testbench for the IP Receiver packet handler (IPRX).
 
file  test_iprx.hpp
 : Testbench for the IP Receiver packet handler (IPRX).
 

Classes

class  SubSums
 

Macros

#define THIS_NAME   "IPRX"
 
#define TRACE_OFF   0x0000
 
#define TRACE_IBUF   1 << 1
 
#define TRACE_MPD   1 << 2
 
#define TRACE_ILC   1 << 3
 
#define TRACE_ICA   1 << 4
 
#define TRACE_ICC   1 << 5
 
#define TRACE_IID   1 << 6
 
#define TRACE_ICL   1 << 7
 
#define TRACE_IPR   1 << 8
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 

Functions

void pInputBuffer (stream< AxisEth > &siETH_Data, stream< AxisEth > &soMPd_Data)
 
void pMacProtocolDetector (EthAddr piMMIO_MacAddr, stream< AxisEth > &siIBuf_Data, stream< AxisArp > &soARP_Data, stream< AxisEth > &soILc_Data)
 
void pIpLengthChecker (stream< AxisEth > &siMPd_Data, stream< AxisEth > &soICa_Data)
 
void pIpChecksumAccumulator (Ip4Addr piMMIO_Ip4Address, stream< AxisEth > &siILc_Data, stream< AxisIp4 > &soIId_Data, stream< Ip4Version > &soIId_IpVer, stream< CmdBit > &soIId_DropCmd, stream< SubSums > &soICc_SubSums)
 
void pIpInvalidDropper (stream< AxisIp4 > &siICa_Data, stream< Ip4Version > &siICa_IpVer, stream< ValBit > &siICa_DropFrag, stream< ValBit > &siICc_CsumValid, stream< AxisIp4 > &soICl_Data)
 
void pIpCutLength (stream< AxisIp4 > &siIId_Data, stream< AxisIp4 > &soIPr_Data)
 
void pIpChecksumChecker (stream< SubSums > &siICa_SubSums, stream< ValBit > &soIId_CsumValid)
 
void pIpPacketRouter (stream< AxisIp4 > &siICl_Data, stream< AxisIp4 > &soICMP_Data, stream< AxisIp4 > &soICMP_Derr, stream< AxisIp4 > &soUOE_Data, stream< AxisIp4 > &soTOE_Data)
 
void iprx (EthAddr piMMIO_MacAddress, Ip4Addr piMMIO_Ip4Address, stream< AxisEth > &siETH_Data, stream< AxisArp > &soARP_Data, stream< AxisIp4 > &soICMP_Data, stream< AxisIp4 > &soICMP_Derr, stream< AxisIp4 > &soUOE_Data, stream< AxisIp4 > &soTOE_Data)
 Main process of the IP Receive handler (IPRX). More...
 
void iprx_top (EthAddr piMMIO_MacAddress, Ip4Addr piMMIO_Ip4Address, stream< AxisRaw > &siETH_Data, stream< AxisRaw > &soARP_Data, stream< AxisRaw > &soICMP_Data, stream< AxisRaw > &soICMP_Derr, stream< AxisRaw > &soUOE_Data, stream< AxisRaw > &soTOE_Data)
 Top of IP Receive handler (IPRX) More...
 

Variables

bool gTraceEvent
 
const UdpLen MaxDatagramSize = 32768
 

Detailed Description

IP Receiver packet handler (IPRX) of the Network Transport Stack (NTS).

Macro Definition Documentation

◆ DEBUG_LEVEL

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 80 of file iprx.cpp.

◆ THIS_NAME

#define THIS_NAME   "IPRX"

Definition at line 67 of file iprx.cpp.

◆ TRACE_ALL

#define TRACE_ALL   0xFFFF

Definition at line 78 of file iprx.cpp.

◆ TRACE_IBUF

#define TRACE_IBUF   1 << 1

Definition at line 70 of file iprx.cpp.

◆ TRACE_ICA

#define TRACE_ICA   1 << 4

Definition at line 73 of file iprx.cpp.

◆ TRACE_ICC

#define TRACE_ICC   1 << 5

Definition at line 74 of file iprx.cpp.

◆ TRACE_ICL

#define TRACE_ICL   1 << 7

Definition at line 76 of file iprx.cpp.

◆ TRACE_IID

#define TRACE_IID   1 << 6

Definition at line 75 of file iprx.cpp.

◆ TRACE_ILC

#define TRACE_ILC   1 << 3

Definition at line 72 of file iprx.cpp.

◆ TRACE_IPR

#define TRACE_IPR   1 << 8

Definition at line 77 of file iprx.cpp.

◆ TRACE_MPD

#define TRACE_MPD   1 << 2

Definition at line 71 of file iprx.cpp.

◆ TRACE_OFF

#define TRACE_OFF   0x0000

Definition at line 69 of file iprx.cpp.

Function Documentation

◆ iprx()

void iprx ( EthAddr  piMMIO_MacAddress,
Ip4Addr  piMMIO_Ip4Address,
stream< AxisEth > &  siETH_Data,
stream< AxisArp > &  soARP_Data,
stream< AxisIp4 > &  soICMP_Data,
stream< AxisIp4 > &  soICMP_Derr,
stream< AxisIp4 > &  soUOE_Data,
stream< AxisIp4 > &  soTOE_Data 
)

Main process of the IP Receive handler (IPRX).

Parameters
[in]piMMIO_MacAddressThe MAC address from MMIO (in network order).
[in]piMMIO_Ip4AddressThe IPv4 address from MMIO (in network order).
[in]siETH_DataData stream from ETHernet MAC layer (ETH).
[out]soARP_DataData stream to Address Resolution Protocol (ARP) server.
[out]soICMP_DataData stream to Internet Control Message Protocol (ICMP) engine.
[out]soICMP_DerrData stream in error to [ICMP].
[out]soUOE_DataData stream to UDP Offload Engine (UOE).
[out]soTOE_DataData stream to TCP Offload Engine (TOE).

: This process connects to the Rx side of the Ethernet MAC core. It extracts the IPv4 and ARP packets from the incoming Ethernet frame and forwards them the TCP-offload-engine (TOE), the Internet Control Message Protocol (ICMP) engine, the UDP Offload Engine (UOE) or the Address Resolution Protocol (ARP) server.

Note
: ** The data-error stream is used instead of the data stream when the TTL field of the incoming IPv4 packet is found the be zero. In such a case, the erroneous packet is forwarded to the ICMP module over the data-error stream. The ICMP module uses this information to build an ICMP error datagram (of type #11 –Time Exceeded) that is sent back to the sender.

Definition at line 826 of file iprx.cpp.

853 {
854  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
855  #pragma HLS DATAFLOW
856  #pragma HLS INLINE
857  #pragma HLS INTERFACE ap_ctrl_none port=return
858 
859  //--------------------------------------------------------------------------
860  //-- LOCAL STREAMS (Sorted by the name of the modules which generate them)
861  //--------------------------------------------------------------------------
862 
863  //-- Input Buffer (IBuf)
864  static stream<AxisEth> ssIBufToMPd_Data ("ssIBufToMPd_Data");
865  #pragma HLS STREAM variable=ssIBufToMPd_Data depth=8192
866 
867  //-- MAC Protocol Detector (MPd)
868  static stream<AxisEth> ssMPdToILc_Data ("ssMPdToILc_Data");
869  #pragma HLS STREAM variable=ssMPdToILc_Data depth=32
870 
871  //-- IPv4 Length Checker (ILc)
872  static stream<AxisEth> ssILcToICa_Data ("ssILcToICa_Data");
873  #pragma HLS STREAM variable=ssILcToICa_Data depth=32
874 
875  //-- IPv4 Checksum Accumulator (ICa)
876  static stream<AxisIp4> ssICaToIId_Data ("ssICaToIId_Data");
877  #pragma HLS STREAM variable=ssICaToIId_Data depth=1024 // Must hold IP header for checksum checking
878  static stream<Ip4Version> ssICaToIId_IpVer ("ssICaToIId_IpVer");
879  #pragma HLS STREAM variable=ssICaToIId_IpVer depth=32
880  static stream<CmdBit> ssICaToIId_DropFrag ("ssICaToIId_DropFrag");
881  #pragma HLS STREAM variable=ssICaToIId_DropFrag depth=32
882  static stream<SubSums> ssICaToICc_SubSums ("ssICaToICc_SubSums");
883  #pragma HLS DATA_PACK variable=ssICaToICc_SubSums
884  #pragma HLS STREAM variable=ssICaToICc_SubSums depth=32
885 
886  //-- IPv4 Invalid Dropper (IId)
887  static stream<AxisIp4> ssIIdToICl_Data ("ssIIdToICl_Data");
888  #pragma HLS DATA_PACK variable=ssIIdToICl_Data
889  #pragma HLS STREAM variable=ssIIdToICl_Data depth=32
890 
891  //-- IPv4 Cut Length (ICl)
892  static stream<AxisIp4> ssIClToIPr_Data ("ssIClToIPr_Data");
893  #pragma HLS DATA_PACK variable=ssIClToIPr_Data
894  #pragma HLS STREAM variable=ssIClToIPr_Data depth=32
895 
896  //-- IPv4 Checksum Checker
897  static stream<ValBit> ssICcToIId_CsumVal ("ssICcToIId_CsumVal");
898  #pragma HLS STREAM variable=ssICcToIId_CsumVal depth=32
899 
900  //-- PROCESS FUNCTIONS -----------------------------------------------------
901 
902  pInputBuffer(
903  siETH_Data,
904  ssIBufToMPd_Data);
905 
907  piMMIO_MacAddress,
908  ssIBufToMPd_Data,
909  soARP_Data,
910  ssMPdToILc_Data);
911 
913  ssMPdToILc_Data,
914  ssILcToICa_Data);
915 
917  piMMIO_Ip4Address,
918  ssILcToICa_Data,
919  ssICaToIId_Data,
920  ssICaToIId_IpVer,
921  ssICaToIId_DropFrag,
922  ssICaToICc_SubSums);
923 
925  ssICaToICc_SubSums,
926  ssICcToIId_CsumVal);
927 
929  ssICaToIId_Data,
930  ssICaToIId_IpVer,
931  ssICaToIId_DropFrag,
932  ssICcToIId_CsumVal,
933  ssIIdToICl_Data);
934 
935  pIpCutLength(
936  ssIIdToICl_Data,
937  ssIClToIPr_Data);
938 
940  ssIClToIPr_Data,
941  soICMP_Data,
942  soICMP_Derr,
943  soUOE_Data,
944  soTOE_Data);
945 
946 }
void pIpCutLength(stream< AxisIp4 > &siIId_Data, stream< AxisIp4 > &soIPr_Data)
Definition: iprx.cpp:576
void pIpLengthChecker(stream< AxisEth > &siMPd_Data, stream< AxisEth > &soICa_Data)
Definition: iprx.cpp:226
void pIpInvalidDropper(stream< AxisIp4 > &siICa_Data, stream< Ip4Version > &siICa_IpVer, stream< ValBit > &siICa_DropFrag, stream< ValBit > &siICc_CsumValid, stream< AxisIp4 > &soICl_Data)
Definition: iprx.cpp:504
void pInputBuffer(stream< AxisEth > &siETH_Data, stream< AxisEth > &soMPd_Data)
Definition: iprx.cpp:94
void pMacProtocolDetector(EthAddr piMMIO_MacAddr, stream< AxisEth > &siIBuf_Data, stream< AxisArp > &soARP_Data, stream< AxisEth > &soILc_Data)
Definition: iprx.cpp:133
void pIpChecksumChecker(stream< SubSums > &siICa_SubSums, stream< ValBit > &soIId_CsumValid)
Definition: iprx.cpp:643
void pIpPacketRouter(stream< AxisIp4 > &siICl_Data, stream< AxisIp4 > &soICMP_Data, stream< AxisIp4 > &soICMP_Derr, stream< AxisIp4 > &soUOE_Data, stream< AxisIp4 > &soTOE_Data)
Definition: iprx.cpp:689
void pIpChecksumAccumulator(Ip4Addr piMMIO_Ip4Address, stream< AxisEth > &siILc_Data, stream< AxisIp4 > &soIId_Data, stream< Ip4Version > &soIId_IpVer, stream< CmdBit > &soIId_DropCmd, stream< SubSums > &soICc_SubSums)
Definition: iprx.cpp:323
Here is the call graph for this function:
Here is the caller graph for this function:

◆ iprx_top()

void iprx_top ( EthAddr  piMMIO_MacAddress,
Ip4Addr  piMMIO_Ip4Address,
stream< AxisRaw > &  siETH_Data,
stream< AxisRaw > &  soARP_Data,
stream< AxisRaw > &  soICMP_Data,
stream< AxisRaw > &  soICMP_Derr,
stream< AxisRaw > &  soUOE_Data,
stream< AxisRaw > &  soTOE_Data 
)

Top of IP Receive handler (IPRX)

Parameters
[in]piMMIO_MacAddressThe MAC address from MMIO (in network order).
[in]piMMIO_Ip4AddressThe IPv4 address from MMIO (in network order).
[in]siETH_DataData stream from ETHernet MAC layer (ETH).
[out]soARP_DataData stream to Address Resolution Protocol (ARP) server.
[out]soICMP_DataData stream to Internet Control Message Protocol (ICMP) engine.
[out]soICMP_DerrData stream in error to [ICMP].
[out]soUOE_DataData stream to UDP Offload Engine (UOE).
[out]soTOE_DataData stream to TCP Offload Engine (TOE).

ENTITY - IP RX HANDLER (IPRX)

Definition at line 1032 of file iprx.cpp.

1059 {
1060 
1061  //-- DIRECTIVES FOR THE INTERFACES -----------------------------------------
1062  #pragma HLS INTERFACE ap_ctrl_none port=return
1063 
1064  #pragma HLS INTERFACE ap_stable port=piMMIO_MacAddress name=piMMIO_MacAddress
1065  #pragma HLS INTERFACE ap_stable port=piMMIO_Ip4Address name=piMMIO_Ip4Address
1066 
1067  #pragma HLS INTERFACE axis off port=siETH_Data name=siETH_Data
1068 
1069  #pragma HLS INTERFACE axis off port=soARP_Data name=soARP_Data
1070 
1071  #pragma HLS INTERFACE axis off port=soICMP_Data name=soICMP_Data
1072  #pragma HLS INTERFACE axis off port=soICMP_Derr name=soICMP_Derr
1073 
1074  #pragma HLS INTERFACE axis off port=soUOE_Data name=soUOE_Data
1075  #pragma HLS INTERFACE axis off port=soTOE_Data name=soTOE_Data
1076 
1077  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1078  #pragma HLS DATAFLOW disable_start_propagation
1079 
1080  //-- LOCAL INPUT and OUTPUT STREAMS ----------------------------------------
1081  static stream<AxisEth> ssiETH_Data;
1082  static stream<AxisArp> ssoARP_Data;
1083  static stream<AxisIp4> ssoICMP_Data;
1084  static stream<AxisIp4> ssoICMP_Derr;
1085  static stream<AxisIp4> ssoUOE_Data;
1086  static stream<AxisIp4> ssoTOE_Data;
1087 
1088  //-- INPUT STREAM CASTING --------------------------------------------------
1089  pAxisRawCast(siETH_Data, ssiETH_Data);
1090 
1091  //-- MAIN IPRX PROCESS -----------------------------------------------------
1092  iprx(
1093  //-- MMIO Interfaces
1094  piMMIO_MacAddress,
1095  piMMIO_Ip4Address,
1096  //-- ETHernet MAC Layer Interface
1097  ssiETH_Data,
1098  //-- ARP Interface
1099  ssoARP_Data,
1100  //-- ICMP Interfaces
1101  ssoICMP_Data,
1102  ssoICMP_Derr,
1103  //-- UDP Interface
1104  ssoUOE_Data,
1105  //-- TOE Interface
1106  ssoTOE_Data);
1107 
1108  //-- OUTPUT STREAM CASTING -------------------------------------------------
1109  pAxisRawCast(ssoARP_Data, soARP_Data);
1110  pAxisRawCast(ssoICMP_Data, soICMP_Data);
1111  pAxisRawCast(ssoICMP_Derr, soICMP_Derr);
1112  pAxisRawCast(ssoUOE_Data, soUOE_Data);
1113  pAxisRawCast(ssoTOE_Data, soTOE_Data);
1114 
1115 }
void iprx(EthAddr piMMIO_MacAddress, Ip4Addr piMMIO_Ip4Address, stream< AxisEth > &siETH_Data, stream< AxisArp > &soARP_Data, stream< AxisIp4 > &soICMP_Data, stream< AxisIp4 > &soICMP_Derr, stream< AxisIp4 > &soUOE_Data, stream< AxisIp4 > &soTOE_Data)
Main process of the IP Receive handler (IPRX).
Definition: iprx.cpp:826
void pAxisRawCast(hls::stream< TypeIn > &si, hls::stream< TypeOut > &so)
AxisRaw cast - Casts an AxisRaw stream to/from an AxisRaw derived class.
Definition: AxisRaw.hpp:148
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pInputBuffer()

void pInputBuffer ( stream< AxisEth > &  siETH_Data,
stream< AxisEth > &  soMPd_Data 
)

Input Buffer (IBuf)

Parameters
[in]siETH_DataData steam from the ETHernet interface (ETH).
[out]soMPd_DataData stream to MAC Protocol Detector (MPd).

This process enqueues the incoming data traffic into a FiFo. [TOOD-FIXME - Do we really need this buffer? Can we get ride of it?].

Definition at line 94 of file iprx.cpp.

97 {
98  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
99  #pragma HLS INLINE off
100  #pragma HLS PIPELINE II=1 enable_flush
101 
102  const char *myName = concat3(THIS_NAME, "/", "IBuf");
103 
104  if (!siETH_Data.empty() && !soMPd_Data.full()) {
105  AxisEth axisEth;
106  siETH_Data.read(axisEth);
107  if (not axisEth.isValid()) {
108  if (DEBUG_LEVEL & TRACE_IBUF) {
109  printWarn(myName, "Received an AxisChunk with an unexpected \'tkeep\' or \'tlast\' value.\n");
110  printAxisRaw(myName, "Aborting the frame after: ", AxisRaw(axisEth.getLE_TData(), axisEth.getLE_TKeep(), axisEth.getLE_TLast()));
111  }
112  soMPd_Data.write(AxisEth(axisEth.getLE_TData(), 0x00, 1));
113  }
114  else {
115  soMPd_Data.write(axisEth);
116  }
117  }
118 }
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
bool isValid() const
Definition: AxisRaw.hpp:434
LE_tLast getLE_TLast() const
Definition: AxisRaw.hpp:268
#define TRACE_IBUF
Definition: iprx.cpp:70
#define THIS_NAME
Definition: iprx.cpp:67
#define DEBUG_LEVEL
Definition: iprx.cpp:80
void printAxisRaw(const char *callerName, AxisRaw chunk)
Prints an Axis raw data chunk (used for debugging).
Definition: nts_utils.cpp:46
#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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pIpChecksumAccumulator()

void pIpChecksumAccumulator ( Ip4Addr  piMMIO_Ip4Address,
stream< AxisEth > &  siILc_Data,
stream< AxisIp4 > &  soIId_Data,
stream< Ip4Version > &  soIId_IpVer,
stream< CmdBit > &  soIId_DropCmd,
stream< SubSums > &  soICc_SubSums 
)

IP Checksum Checker (ICa)

Parameters
[in]piMMIO_Ip4AddressThe IPv4 address from MMIO (in network order).
[in]siILc_DataData stream from IpLengthChecker (ILc).
[out]soIId_DataData stream to IpInvalidDropper (IId).
[out]soIId_IpVerThe IP version to [IId].
[out]soIId_DropCmdTell [IId] to drop this IP packet.
[out]soICc_SubSumsFour sub-checksums to IpChecksumChecker (ICc).

This process computes four sub-sums in parallel to later assess the checksum of the IPv4 header.

Definition at line 323 of file iprx.cpp.

330 {
331  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
332  #pragma HLS INLINE off
333  #pragma HLS PIPELINE II=1 enable_flush
334 
335  const char *myName = concat3(THIS_NAME, "/", "ICa");
336 
337  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
338  static bool ica_wasLastChunk=false;
339  #pragma HLS RESET variable=ica_wasLastChunk
340  static ap_uint<3> ica_chunkCount=0;
341  #pragma HLS RESET variable=ica_chunkCount
342 
343  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
344  static ap_uint<17> ica_ipHdrSums[4];
345  static ap_uint<8> ica_ipHdrLen;
346  static LE_Ip4Addr ica_dstIpAddress;
347  static AxisEth ica_prevChunk;
348 
349  //-- DYNAMIC VARIABLES -----------------------------------------------------
350  AxisEth currChunk;
351  AxisIp4 sendChunk;
352  ap_uint<16> ip4FlagsAndFragOff;
353  bool ipAddrMatch;
354 
355  currChunk.setLE_TLast(0);
356  if (!siILc_Data.empty() && !ica_wasLastChunk && !soIId_IpVer.full() &&
357  !soIId_DropCmd.full() && !soICc_SubSums.full() && !soIId_Data.full()) {
358  siILc_Data.read(currChunk);
359 
360  switch (ica_chunkCount) {
361  case 0:
362  // Skip because chunk contains MAC_SA[1:0] | MAC_DA[5:0]
363  for (int i=0; i<4 ;++i) {
364  ica_ipHdrSums[i] = 0;
365  }
366  ica_chunkCount++;
367  break;
368  case 1:
369  // Retrieve the IP version field
370  soIId_IpVer.write(currChunk.getIp4Version());
371  // Retrieve the Internet Header Length
372  ica_ipHdrLen = currChunk.getIp4HdrLen();
373  // Retrieve the first two bytes of the IPv4 header
374  ica_ipHdrSums[3].range(15,12) = currChunk.getIp4Version();
375  ica_ipHdrSums[3].range(11, 8) = currChunk.getIp4HdrLen();
376  ica_ipHdrSums[3].range( 7, 0) = currChunk.getIp4ToS();
377  ica_chunkCount++;
378  break;
379  case 2:
380  // Check for fragmentation in this cycle. Need to check the MF flag.
381  // If set, then drop. If not set, then check the fragment offset and
382  // if it is non-zero then drop.
383  ip4FlagsAndFragOff = byteSwap16(currChunk.getLE_TData().range(47, 32));
384  if (ip4FlagsAndFragOff.range(12, 0) != 0 || ip4FlagsAndFragOff.bit(13) != 0) {
385  soIId_DropCmd.write(CMD_DROP);
386  if (ip4FlagsAndFragOff.bit(13) != 0) {
387  printWarn(myName, "The More Fragments (MF) is set but IP fragmentation is not supported (yet).\n");
388  }
389  if (ip4FlagsAndFragOff.range(12, 0) != 0) {
390  printWarn(myName, "Fragment offset is set but not supported (yet) !!!\n");
391  }
392  }
393  else {
394  soIId_DropCmd.write(CMD_KEEP);
395  }
396  for (int i = 0; i < 4; i++) {
397  #pragma HLS unroll
398  ica_ipHdrSums[i] += byteSwap16(currChunk.getLE_TData().range(i*16+15, i*16));
399  ica_ipHdrSums[i] = (ica_ipHdrSums[i] + (ica_ipHdrSums[i] >> 16)) & 0xFFFF;
400  }
401  ica_ipHdrLen -= 2;
402  ica_chunkCount++;
403  break;
404  case 3:
405  ica_dstIpAddress.range(31, 16) = currChunk.getIp4DstAddrHi();
406  for (int i = 0; i < 4; i++) {
407  #pragma HLS unroll
408  ica_ipHdrSums[i] += byteSwap16(currChunk.getLE_TData().range(i*16+15, i*16));
409  ica_ipHdrSums[i] = (ica_ipHdrSums[i] + (ica_ipHdrSums[i] >> 16)) & 0xFFFF;
410  }
411  ica_ipHdrLen -= 2;
412  ica_chunkCount++;
413  break;
414 
415  default:
416  if (ica_chunkCount == 4) {
417  ica_dstIpAddress(15, 0) = currChunk.getIp4DstAddrLo();
418  }
419  switch (ica_ipHdrLen) {
420  case 0:
421  break;
422  case 1:
423  // Sum up part0
424  ica_ipHdrSums[0] += currChunk.getIp4DstAddrLo();
425  ica_ipHdrSums[0] = (ica_ipHdrSums[0] + (ica_ipHdrSums[0] >> 16)) & 0xFFFF;
426  ica_ipHdrLen = 0;
427  // Assess destination IP address (FYI - IP Broadcast addresses are dropped)
428  if (ica_dstIpAddress == piMMIO_Ip4Address) {
429  ipAddrMatch = true;
430  }
431  else {
432  ipAddrMatch = false;
433  }
434  soICc_SubSums.write(SubSums(ica_ipHdrSums, ipAddrMatch));
435  break;
436  case 2:
437  // Sum up parts 0-2
438  for (int i = 0; i < 4; i++) {
439  #pragma HLS unroll
440  ica_ipHdrSums[i] += byteSwap16(currChunk.getLE_TData().range(i*16+15, i*16));
441  ica_ipHdrSums[i] = (ica_ipHdrSums[i] + (ica_ipHdrSums[i] >> 16)) & 0xFFFF;
442  }
443  ica_ipHdrLen = 0;
444  // Assess destination IP address (FYI - IP Broadcast addresses are dropped)
445  if (ica_dstIpAddress == piMMIO_Ip4Address) {
446  // || ica_dstIpAddress == 0xFFFFFFFF) {
447  ipAddrMatch = true;
448  }
449  else {
450  ipAddrMatch = false;
451  }
452  soICc_SubSums.write(SubSums(ica_ipHdrSums, ipAddrMatch));
453  break;
454  default:
455  // Sum up everything
456  for (int i = 0; i < 4; i++) {
457  #pragma HLS unroll
458  ica_ipHdrSums[i] += byteSwap16(currChunk.getLE_TData().range(i*16+15, i*16));
459  ica_ipHdrSums[i] = (ica_ipHdrSums[i] + (ica_ipHdrSums[i] >> 16)) & 0xFFFF;
460  }
461  ica_ipHdrLen -= 2;
462  break;
463  }
464  break;
465  } // End of: switch(ica_chunkCount)f
466 
467  if (ica_chunkCount > 2) {
468  // Send AxisIp4 chunks while re-aligning the outgoing chunks
469  sendChunk = AxisIp4((currChunk.getLE_TData().range(47, 0), ica_prevChunk.getLE_TData().range(63, 48)),
470  (currChunk.getLE_TKeep().range( 5, 0), ica_prevChunk.getLE_TKeep().range( 7, 6)),
471  (currChunk.getLE_TKeep()[6] == 0));
472  soIId_Data.write(sendChunk);
473  }
474  ica_prevChunk = currChunk;
475  if (currChunk.getLE_TLast()) {
476  ica_chunkCount = 0;
477  ica_wasLastChunk = !sendChunk.getLE_TLast();
478  }
479  }
480  else if(ica_wasLastChunk && !soIId_Data.full()) {
481  // Send remaining Chunk;
482  sendChunk = AxisIp4(ica_prevChunk.getLE_TData().range(63, 48),
483  ica_prevChunk.getLE_TKeep().range( 7, 6),
484  TLAST);
485  soIId_Data.write(sendChunk);
486  ica_wasLastChunk = false;
487  }
488 }
Ip4HdrLen getIp4HdrLen()
Definition: AxisEth.hpp:237
Ip4DstAddrHi getIp4DstAddrHi()
Definition: AxisEth.hpp:268
Ip4Version getIp4Version()
Definition: AxisEth.hpp:234
Ip4DstAddrLo getIp4DstAddrLo()
Definition: AxisEth.hpp:270
Ip4ToS getIp4ToS()
Definition: AxisEth.hpp:240
void setLE_TLast(LE_tLast last)
Definition: AxisRaw.hpp:280
Definition: iprx.hpp:73
ap_uint< 32 > LE_Ip4Addr
Definition: AxisIp4.hpp:149
#define CMD_DROP
Definition: nts_types.hpp:61
#define CMD_KEEP
Definition: nts_types.hpp:62
#define TLAST
Definition: AxisRaw.hpp:116
ap_uint< 16 > byteSwap16(ap_uint< 16 > inputVector)
Definition: udp.cpp:82
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pIpChecksumChecker()

void pIpChecksumChecker ( stream< SubSums > &  siICa_SubSums,
stream< ValBit > &  soIId_CsumValid 
)

IPv4 Checksum Checker (ICc)

Parameters
[in]siICa_SubSumsFour sub-checksums from IpChecksumAccumulator (ICa).
[out]soIId_CsumValidChecksum valid information.

This process computes the final IP header checksum by adding the 4 subsums.

Definition at line 643 of file iprx.cpp.

646 {
647  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
648  #pragma HlS INLINE off
649  #pragma HLS PIPELINE II=1 enable_flush
650 
651  const char *myName = concat3(THIS_NAME, "/", "ICc");
652 
653  if (!siICa_SubSums.empty() && !soIId_CsumValid.full()) {
654  SubSums ipHdrSums = siICa_SubSums.read();
655 
656  ipHdrSums.sum0 += ipHdrSums.sum2;
657  ipHdrSums.sum1 += ipHdrSums.sum3;
658  ipHdrSums.sum0 = (ipHdrSums.sum0 + (ipHdrSums.sum0 >> 16)) & 0xFFFF;
659  ipHdrSums.sum1 = (ipHdrSums.sum1 + (ipHdrSums.sum1 >> 16)) & 0xFFFF;
660  ipHdrSums.sum0 += ipHdrSums.sum1;
661  ipHdrSums.sum0 = (ipHdrSums.sum0 + (ipHdrSums.sum0 >> 16)) & 0xFFFF;
662  ipHdrSums.sum0 = ~ipHdrSums.sum0;
663  if (ipHdrSums.sum0(15, 0) != 0x0000) {
664  printError(myName, "Bad IP header checksum: Expected 0x0000 - Computed 0x%4.4X\n", ipHdrSums.sum0(15, 0).to_int());
665  }
666  soIId_CsumValid.write((ipHdrSums.sum0(15, 0) == 0x0000) && ipHdrSums.ipMatch);
667  }
668 }
ap_uint< 17 > sum1
Definition: iprx.hpp:76
ap_uint< 17 > sum0
Definition: iprx.hpp:75
bool ipMatch
Definition: iprx.hpp:79
ap_uint< 17 > sum2
Definition: iprx.hpp:77
ap_uint< 17 > sum3
Definition: iprx.hpp:78
#define printError(callerName, format,...)
A macro to print an error message.
Definition: nts_utils.hpp:195
Here is the caller graph for this function:

◆ pIpCutLength()

void pIpCutLength ( stream< AxisIp4 > &  siIId_Data,
stream< AxisIp4 > &  soIPr_Data 
)

IPv4 Cut Length (ICl)

Parameters
[in]siIId_DataData stream from IpInvalidDropper (IId).
[out]soIPr_DataData stream to IpPacketRouter (IPr).

This process intercepts and drops packets which are longer than the announced 'Ip4TotalLenght' field.

Definition at line 576 of file iprx.cpp.

579 {
580  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
581  #pragma HLS INLINE off
582  #pragma HLS PIPELINE II=1 enable_flush
583 
584  const char *myName = concat3(THIS_NAME, "/", "ICl");
585 
586  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
587  static enum FsmStates {FSM_FWD=0, FSM_DROP} icl_fsmState=FSM_FWD;
588  #pragma HLS RESET variable=icl_fsmState
589  static ap_uint<13> icl_chunkCount=0; // Ip4TotalLen/8
590  #pragma HLS RESET variable=icl_chunkCount
591 
592  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
593  static Ip4TotalLen icl_ip4TotalLength;
594 
595  switch(icl_fsmState){
596  case FSM_FWD:
597  if (!siIId_Data.empty() && !soIPr_Data.full()) {
598  AxisIp4 currChunk = siIId_Data.read();
599  switch (icl_chunkCount) {
600  case 0:
601  icl_ip4TotalLength = currChunk.getIp4TotalLen();
602  break;
603  default:
604  if (((icl_chunkCount+1)*8) >= icl_ip4TotalLength) {
605  if (currChunk.getLE_TLast() == 0) {
606  icl_fsmState = FSM_DROP;
607  }
608  currChunk.setLE_TLast(TLAST);
609  ap_uint<4> leftLength = icl_ip4TotalLength - (icl_chunkCount*8);
610  currChunk.setLE_TKeep(lenToLE_tKeep(leftLength));
611  }
612  break;
613  } // End of: switch(icl_chunkCount)
614  soIPr_Data.write(currChunk);
615  icl_chunkCount++;
616  if (currChunk.getLE_TLast()) {
617  icl_chunkCount = 0;
618  }
619  }
620  break;
621  case FSM_DROP:
622  if (!siIId_Data.empty()) {
623  AxisIp4 currChunk = siIId_Data.read();
624  if (currChunk.getLE_TLast()) {
625  icl_fsmState = FSM_FWD;
626  }
627  }
628  break;
629 
630  } // End of: switch(icl_fsmState)
631 }
Ip4TotalLen getIp4TotalLen()
Definition: AxisIp4.hpp:205
void setLE_TKeep(LE_tKeep keep, int leHi=64/8-1, int leLo=0)
Definition: AxisRaw.hpp:276
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
ap_uint< 16 > Ip4TotalLen
Definition: AxisIp4.hpp:159
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pIpInvalidDropper()

void pIpInvalidDropper ( stream< AxisIp4 > &  siICa_Data,
stream< Ip4Version > &  siICa_IpVer,
stream< ValBit > &  siICa_DropFrag,
stream< ValBit > &  siICc_CsumValid,
stream< AxisIp4 > &  soICl_Data 
)

IP Invalid Dropper (IId)

Parameters
[in]siICa_DataData stream from IpChecksumAccumulator (ICa).
[in]siICa_IpVerThe IP version from [ICa].
[in]siICa_DropFragDrop this IP fragment from [ICA].
[out]siICc_CsumValidChecksum is valid from IpChecksumChecker (ICc).
[out]soICl_DataData stream to IP Cut Length (ICl).

Drops an IP packet when its version is not '4' (siICa_IpVer), when it is a fragmented packet (siICa_DropFrag) or when its IP header checksum is not valid (siICc_CsumValid). Otherwise, the IPv4 packet is passed on.

Definition at line 504 of file iprx.cpp.

510 {
511  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
512  #pragma HLS INLINE off
513  #pragma HLS PIPELINE II=1 enable_flush
514 
515  const char *myName = concat3(THIS_NAME, "/", "IId");
516 
517  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
518  static enum FsmStates {FSM_IDLE=0, FSM_FWD, FSM_DROP} iid_fsmState=FSM_IDLE;
519  #pragma HLS RESET variable=iid_fsmState
520 
521  //-- DYNAMIC VARIABLES -----------------------------------------------------
522  AxisIp4 currChunk = AxisIp4(0, 0, 0);
523 
524  switch(iid_fsmState) {
525  case FSM_IDLE:
526  if (!siICc_CsumValid.empty() && !siICa_IpVer.empty() && !siICa_DropFrag.empty() &&
527  !siICa_Data.empty() && !soICl_Data.full()) {
528  siICa_Data.read(currChunk);
529  // Assess validity of the current IPv4 packet
530  ValBit csumValid = (siICc_CsumValid.read() == 1); // CSUM is valid
531  ValBit isIpv4Pkt = (siICa_IpVer.read() == 4); // IP Version is 4
532  ValBit doKeepPkt = (siICa_DropFrag.read() == CMD_KEEP); // Do not drop
533  ap_uint<2> valid = (csumValid + isIpv4Pkt + doKeepPkt);
534  if (valid != 3) {
535  iid_fsmState = FSM_DROP;
536  printWarn(myName, "The current IP packet will be dropped because:\n");
537  printWarn(myName, " csumValid=%d | isIpv4Pkt=%d | doKeepPkt=%d\n",
538  csumValid.to_int(), isIpv4Pkt.to_int(), doKeepPkt.to_int());
539  }
540  else {
541  soICl_Data.write(currChunk);
542  iid_fsmState = FSM_FWD;
543  }
544  }
545  break;
546  case FSM_FWD:
547  if(!siICa_Data.empty() && !soICl_Data.full()) {
548  siICa_Data.read(currChunk);
549  soICl_Data.write(currChunk);
550  if (currChunk.getLE_TLast()) {
551  iid_fsmState = FSM_IDLE;
552  }
553  }
554  break;
555  case FSM_DROP:
556  if(!siICa_Data.empty()){
557  siICa_Data.read(currChunk);
558  if (currChunk.getLE_TLast()) {
559  iid_fsmState = FSM_IDLE;
560  }
561  }
562  break;
563  }
564 }
#define FSM_IDLE
Definition: harris.hpp:79
ap_uint< 1 > ValBit
Definition: nts_types.hpp:117
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pIpLengthChecker()

void pIpLengthChecker ( stream< AxisEth > &  siMPd_Data,
stream< AxisEth > &  soICa_Data 
)

IP Length Checker (ILc)

Parameters
[in]siMPd_DataData steam from the MAC Protocol Detector (MPd).
[out]soICa_DataData stream to IP Checksum Accumulator (ICa).

This process checks the length of the IPv4 packet and drops it if it is too long. [TODO:Remove this process. It makes no sense since we do not support fragmentation.]

Definition at line 226 of file iprx.cpp.

229 {
230  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
231  #pragma HLS INLINE off
232  #pragma HLS PIPELINE II=1 enable_flush
233 
234  const char *myName = concat3(THIS_NAME, "/", "ILc");
235 
236  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
237  static ap_uint<2> ilc_leftToWrite=0;
238  #pragma HLS RESET variable=ilc_leftToWrite
239  static enum FsmStates {FSM_IDLE=0, FSM_SIZECHECK, FSM_STREAM} ilc_fsmState=FSM_IDLE;
240  #pragma HLS RESET variable=ilc_fsmState
241  static ap_uint<2> ilc_chunkCount=0;
242  #pragma HLS RESET variable=ilc_chunkCount
243  static ap_uint<1> ilc_filterPacket=0;
244  #pragma HLS RESET variable=ilc_filterPacket
245 
246  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
247  static ap_shift_reg<AxisEth, 2> chunkBuffer; // A shift reg. holding 2 AxisChunks
248 
249  //-- DYNAMIC VARIABLES -----------------------------------------------------
250  AxisEth tempChunk;
251  Ip4TotalLen ip4TotLen;
252 
253  if (ilc_leftToWrite == 0) {
254  if (!siMPd_Data.empty() && !soICa_Data.full()) {
255  AxisEth currChunk = siMPd_Data.read();
256  switch (ilc_fsmState) {
257  case FSM_IDLE:
258  // Read head of shift reg, shift up one, and load current chunk into location 0
259  chunkBuffer.shift(currChunk);
260  if (ilc_chunkCount == 1) {
261  ilc_fsmState = FSM_SIZECHECK;
262  }
263  ilc_chunkCount++;
264  break;
265  case FSM_SIZECHECK:
266  // Check the IPv4/TotalLength field ([FIXME - Consider removing.])
267  ip4TotLen = currChunk.getIp4TotalLen();
268  if (ip4TotLen > MaxDatagramSize) {
269  ilc_filterPacket = 1;
270  printWarn(myName, "Current frame will be discarded because frame is too long!\n");
271  }
272  else {
273  ilc_filterPacket = 0;
274  if (DEBUG_LEVEL & TRACE_ILC) {
275  printInfo(myName, "Start of IPv4 packet - Total length = %d bytes.\n", ip4TotLen.to_int());
276  }
277  }
278  // Read head of shift reg, shift up one, and load current chunk into location 0
279  tempChunk = chunkBuffer.shift(currChunk);
280  if (ilc_filterPacket == 0) {
281  soICa_Data.write(tempChunk);
282  }
283  ilc_fsmState = FSM_STREAM;
284  break;
285  case FSM_STREAM:
286  tempChunk = chunkBuffer.shift(currChunk);
287  if (ilc_filterPacket == 0) {
288  soICa_Data.write(tempChunk);
289  }
290  break;
291  } // End of: switch
292 
293  if (currChunk.getLE_TLast()) {
294  ilc_chunkCount = 0;
295  ilc_leftToWrite = 2;
296  ilc_fsmState = FSM_IDLE;
297  }
298  }
299  }
300  else if (ilc_leftToWrite != 0 && !soICa_Data.full() ) {
301  tempChunk = chunkBuffer.shift(AxisEth(0, 0, 0));
302  if (ilc_filterPacket == 0) {
303  soICa_Data.write(tempChunk);
304  }
305  ilc_leftToWrite--;
306  }
307 }
Ip4TotalLen getIp4TotalLen()
Definition: AxisEth.hpp:243
const UdpLen MaxDatagramSize
Definition: iprx.hpp:68
#define TRACE_ILC
Definition: iprx.cpp:72
#define printInfo(callerName, format,...)
A macro to print an information message.
Definition: nts_utils.hpp:169
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pIpPacketRouter()

void pIpPacketRouter ( stream< AxisIp4 > &  siICl_Data,
stream< AxisIp4 > &  soICMP_Data,
stream< AxisIp4 > &  soICMP_Derr,
stream< AxisIp4 > &  soUOE_Data,
stream< AxisIp4 > &  soTOE_Data 
)

IPv4 Packet Router (IPr)

Parameters
[in]siICl_DataData stream from IpCutLength (ICl).
[out]soICMP_DataICMP/IP data stream to ICMP.
[out]soICMP_DerrErroneous IP data stream to ICMP.
[out]soUOE_DataUDP/IP data stream to UDP offload engine (UOE).
[out]soTOE_DataTCP/IP data stream to TCP offload engine (TOE).

This process routes the IPv4 packets to one of the 3 following engines: ICMP, TCP or UDP. If the TTL of the incoming IPv4 packet has expired, the packet is routed to the ICMP (over the 'soICMP_Derr' stream) in order for the ICMP engine to build the error messages which data section must include a copy of the erroneous IPv4 header plus at least the first eight bytes of data from the IPv4 packet that caused the error message.

Definition at line 689 of file iprx.cpp.

695 {
696  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
697  #pragma HLS INLINE off
698  #pragma HLS PIPELINE II=1 enable_flush
699 
700  const char *myName = concat3(THIS_NAME, "/", "IPr");
701 
702  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
703  static enum FsmStates { FSM_IDLE=0, FSM_LAST} ipr_fsmState=FSM_IDLE;
704  #pragma HLS RESET variable=ipr_fsmState
705  static ap_uint<2> ipr_chunkCount=0;
706  #pragma HLS RESET variable=ipr_chunkCount
707  static bool ipr_leftToWrite=false;
708  #pragma HLS RESET variable=ipr_leftToWrite
709 
710  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
711  static StsBit ipr_ttlExpired;
712  static Ip4Prot ipr_ipProtocol;
713  static AxisIp4 ipr_prevChunk;
714 
715  //-- DYNAMIC VARIABLES -----------------------------------------------------
716  AxisIp4 currChunk;
717 
718  switch (ipr_fsmState) {
719  case FSM_IDLE:
720  if (!siICl_Data.empty() &&
721  !soICMP_Derr.full() && !soICMP_Data.full() &&
722  !soUOE_Data.full() && !soTOE_Data.full()) {
723  siICl_Data.read(currChunk);
724  switch (ipr_chunkCount) {
725  case 0:
726  ipr_chunkCount++;
727  break;
728  default:
729  if (ipr_chunkCount == 1) {
730  if (currChunk.getIp4TtL() == 1) {
731  ipr_ttlExpired = 1;
732  }
733  else {
734  ipr_ttlExpired = 0;
735  }
736  ipr_ipProtocol = currChunk.getIp4Prot();
737  ipr_chunkCount++;
738  }
739  if (ipr_ttlExpired == 1) {
740  // Forward the current IP packet to ICMP for building the error message
741  soICMP_Derr.write(ipr_prevChunk);
742  }
743  else {
744  switch (ipr_ipProtocol) {
745  // FYI - There is no default case. If the current packet
746  // does not match any case, it is automatically dropped.
747  case IP4_PROT_ICMP:
748  soICMP_Data.write(ipr_prevChunk);
749  break;
750  case IP4_PROT_UDP:
751  soUOE_Data.write(ipr_prevChunk);
752  break;
753  case IP4_PROT_TCP:
754  soTOE_Data.write(ipr_prevChunk);
755  break;
756  }
757  }
758  break;
759  }
760  ipr_prevChunk = currChunk;
761  if (currChunk.getLE_TLast()) {
762  ipr_chunkCount = 0;
763  ipr_leftToWrite = true;
764  ipr_fsmState = FSM_LAST;
765  }
766  }
767  break;
768  case FSM_LAST:
769  if (!soICMP_Derr.full() &&
770  !soICMP_Data.full() && !soUOE_Data.full() && !soTOE_Data.full() ) {
771  ap_uint<log2Ceil<8>::val> bitCounter = 0;
772  bitCounter = ipr_prevChunk.getLen();
773  if (ipr_prevChunk.getLE_TKeep() != 0xFF) {
774  ipr_prevChunk.setLE_TData(0, 63, 64-((8-bitCounter.to_int())*8));
775  }
776  if (ipr_ttlExpired == 1) {
777  soICMP_Derr.write(ipr_prevChunk);
778  }
779  else {
780  switch (ipr_ipProtocol) {
781  case IP4_PROT_ICMP:
782  soICMP_Data.write(ipr_prevChunk);
783  break;
784  case IP4_PROT_UDP:
785  soUOE_Data.write(ipr_prevChunk);
786  break;
787  case IP4_PROT_TCP:
788  soTOE_Data.write(ipr_prevChunk);
789  break;
790  }
791  }
792  ipr_leftToWrite = false;
793  ipr_fsmState = FSM_IDLE;
794  }
795  break;
796  }
797 }
Ip4TtL getIp4TtL()
Definition: AxisIp4.hpp:218
Ip4Prot getIp4Prot()
Definition: AxisIp4.hpp:221
void setLE_TData(LE_tData data, int leHi=64 -1, int leLo=0)
Definition: AxisRaw.hpp:272
int getLen() const
Definition: AxisRaw.hpp:411
#define IP4_PROT_ICMP
Definition: nts_types.hpp:183
ap_uint< 8 > Ip4Prot
Definition: AxisIp4.hpp:164
ap_uint< 1 > StsBit
Definition: nts_types.hpp:116
#define IP4_PROT_UDP
Definition: nts_types.hpp:185
#define IP4_PROT_TCP
Definition: nts_types.hpp:184
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pMacProtocolDetector()

void pMacProtocolDetector ( EthAddr  piMMIO_MacAddr,
stream< AxisEth > &  siIBuf_Data,
stream< AxisArp > &  soARP_Data,
stream< AxisEth > &  soILc_Data 
)

MAC Protocol Detector (MPd)

Parameters
[in]piMMIO_MacAddrThe MAC address from MMIO.
[in]siIBuf_DataData steam from the Input Buffer (IBuf).
[out]soARP_DataData stream to ARP.
[out]soILc_DataData stream to the IPv4 Length Checker (ILc).

This process parses the Ethernet header frame to detect embedded ARP and IPv4 packets. These two types of packets are forwarded accordingly, while other types of packets are dropped.

Definition at line 133 of file iprx.cpp.

138 {
139  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
140  #pragma HLS INLINE off
141  #pragma HLS PIPELINE II=1 enable_flush
142 
143  const char *myName = concat3(THIS_NAME, "/", "MPd");
144 
145  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
146  static enum FsmStates { S0=0, S1 } mpd_fsmState=S0;
147  #pragma HLS RESET variable=mpd_fsmState
148  static ap_uint<2> mpd_chunkCount=0;
149  #pragma HLS RESET variable=mpd_chunkCount
150 
151  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
152  static EtherType mpd_etherType;
153  static AxisEth mpd_prevChunk;
154 
155  //-- DYNAMIC VARIABLES -----------------------------------------------------
156  AxisEth currChunk;
157 
158  switch (mpd_fsmState) {
159  case S0:
160  if (!siIBuf_Data.empty() && !soARP_Data.full() && !soILc_Data.full()) {
161  siIBuf_Data.read(currChunk);
162  switch (mpd_chunkCount) {
163  case 0:
164  // Compare MAC_DA with our MMIO_MacAddress and with BROADCAST
165  // [TODO - Is this really needed given ARP ?]
166  if (currChunk.getEthDstAddr() != piMMIO_MacAddr &&
167  currChunk.getEthDstAddr() != 0xFFFFFFFFFFFF) {
168  mpd_etherType = CMD_DROP;
169  printInfo(myName, "Requesting current frame with MAC destination address = 0x%16.16lX (0x%16.16lX) to be dropped\n",
170  currChunk.getEthDstAddr().to_long(), currChunk.getLE_EthDstAddr().to_long());
171  }
172  else {
173  mpd_etherType = CMD_KEEP;
174  }
175  mpd_chunkCount++;
176  break;
177  default:
178  if (mpd_chunkCount == 1) {
179  if (mpd_etherType != CMD_DROP) {
180  mpd_etherType = currChunk.getEtherType();
181  }
182  mpd_chunkCount++;
183  }
184  if (mpd_etherType == ETH_ETHERTYPE_ARP) {
185  soARP_Data.write(mpd_prevChunk);
186  }
187  else if (mpd_etherType == ETH_ETHERTYPE_IP4) {
188  soILc_Data.write(mpd_prevChunk);
189  }
190  break;
191  }
192  mpd_prevChunk = currChunk;
193  if (currChunk.getLE_TLast()) {
194  mpd_chunkCount = 0;
195  mpd_fsmState = S1;
196  }
197  }
198  break;
199  case S1:
200  if( !soARP_Data.full() && !soILc_Data.full()){
201  if (mpd_etherType == ETH_ETHERTYPE_ARP) {
202  soARP_Data.write(mpd_prevChunk);
203  }
204  else if (mpd_etherType == ETH_ETHERTYPE_IP4) {
205  soILc_Data.write(mpd_prevChunk);
206  }
207  mpd_fsmState = S0;
208  }
209  break;
210 
211  } // End of: switch
212 }
EtherType getEtherType()
Definition: AxisEth.hpp:172
LE_EthAddr getLE_EthDstAddr()
Definition: AxisEth.hpp:176
EthAddr getEthDstAddr()
Definition: AxisEth.hpp:161
#define ETH_ETHERTYPE_ARP
Definition: nts_types.hpp:156
#define ETH_ETHERTYPE_IP4
Definition: nts_types.hpp:155
ap_uint< 16 > EtherType
Definition: AxisEth.hpp:122
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ gTraceEvent

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (TRACE_MPD | TRACE_IBUF)

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (MDL_TRACE | IPS_TRACE)

Definition at line 151 of file tb_nal.cpp.

◆ MaxDatagramSize

const UdpLen MaxDatagramSize = 32768

Definition at line 68 of file iprx.hpp.