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

UDP Offload Engine (UOE) of the Network Transport Stack (NTS). More...

Collaboration diagram for UOE:

Modules

 UOE_TEST
 Testbench for the UDP Offload Engine (UOE) of the Network Transport Stack (NTS).
 

Files

file  test_uoe.cpp
 : Testbench for the UDP Offload Engine (UOE).
 
file  test_uoe.hpp
 : Testbench for the UDP Offload Engine (UOE).
 

Classes

class  IpAddrPair
 

Macros

#define THIS_NAME   "UOE"
 
#define TRACE_OFF   0x0000
 
#define TRACE_IHA   1 << 1
 
#define TRACE_IHS   1 << 2
 
#define TRACE_RPH   1 << 3
 
#define TRACE_TAI   1 << 4
 
#define TRACE_TDH   1 << 5
 
#define TRACE_UCA   1 << 6
 
#define TRACE_UCC   1 << 7
 
#define TRACE_UHA   1 << 8
 
#define TRACE_UPT   1 << 9
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define UOE_ELASTIC_DATA_BUFFER   16*1024
 
#define UOE_ELASTIC_HEADER_BUFF   64
 

Functions

void pIpHeaderStripper (CmdBit piMMIO_En, stream< AxisIp4 > &siIPRX_Data, stream< AxisUdp > &soUcc_UdpDgrm, stream< UdpCsum > &soUcc_PsdHdrSum, stream< AxisIp4 > &soRph_Ip4Hdr, stream< SigBit > &siUcc_ClearToSend, stream< ap_uint< 16 > > &soMMIO_DropCnt)
 
void pUdpChecksumChecker (stream< AxisUdp > &siIhs_UdpDgrm, stream< UdpCsum > &siIhs_PsdHdrSum, stream< AxisUdp > &soRph_UdpDgrm, stream< ValBool > &soRph_CsumVal, stream< SigBit > &soIhs_ClearToSend)
 
void pRxPacketHandler (stream< AxisUdp > &siUcc_UdpDgrm, stream< ValBool > &siUcc_CsumVal, stream< AxisIp4 > &siIhs_Ip4Hdr, stream< UdpPort > &soUpt_PortStateReq, stream< StsBool > &siUpt_PortStateRep, stream< UdpAppData > &soUAIF_Data, stream< UdpAppMeta > &soUAIF_Meta, stream< UdpAppDLen > &soUAIF_DLen, stream< AxisIcmp > &soICMP_Data)
 
void pUdpPortTable (stream< StsBool > &soMMIO_Ready, stream< UdpPort > &siRph_PortStateReq, stream< StsBool > &soRph_PortStateRep, stream< UdpPort > &siUAIF_LsnReq, stream< StsBool > &soUAIF_LsnRep, stream< UdpPort > &siUAIF_ClsReq, stream< StsBool > &soUAIF_ClsRep)
 
void pRxEngine (CmdBit piMMIO_En, stream< StsBool > &soMMIO_Ready, stream< AxisIp4 > &siIPRX_Data, stream< UdpPort > &siUAIF_LsnReq, stream< StsBool > &soUAIF_LsnRep, stream< UdpPort > &siUAIF_ClsReq, stream< StsBool > &soUAIF_ClsRep, stream< UdpAppData > &soUAIF_Data, stream< UdpAppMeta > &soUAIF_Meta, stream< UdpAppDLen > &soUAIF_DLen, stream< AxisIcmp > &soICMP_Data, stream< ap_uint< 16 > > &soMMIO_DropCnt)
 
void pTxApplicationInterface (CmdBit piMMIO_En, stream< UdpAppData > &siUAIF_Data, stream< UdpAppMeta > &siUAIF_Meta, stream< UdpAppDLen > &siUAIF_DLen, stream< UdpAppData > &soTdh_Data, stream< UdpAppMeta > &soTdh_Meta, stream< UdpAppDLen > &soTdh_DLen)
 
void pTxDatagramHandler (stream< UdpAppData > &siUAIF_Data, stream< UdpAppMeta > &siUAIF_Meta, stream< UdpAppDLen > &siUAIF_DLen, stream< UdpAppData > &soUha_Data, stream< UdpAppMeta > &soUha_Meta, stream< UdpAppDLen > &soUha_DLen, stream< AxisPsd4 > &soUca_Data)
 
void pUdpChecksumAccumulator (stream< AxisPsd4 > &siTdh_Data, stream< UdpCsum > &soUha_Csum)
 
void pUdpHeaderAdder (stream< UdpAppData > &siTdh_Data, stream< UdpAppDLen > &siTdh_DLen, stream< UdpAppMeta > &siTdh_Meta, stream< UdpCsum > &siUca_Csum, stream< AxisUdp > &soIha_Data, stream< IpAddrPair > &soIha_IpPair, stream< UdpLen > &soIha_UdpLen)
 
void pIp4HeaderAdder (stream< AxisUdp > &siUha_Data, stream< IpAddrPair > &siUha_IpPair, stream< UdpLen > &siUha_UdpLen, stream< AxisIp4 > &soIPTX_Data)
 
void pTxEngine (CmdBit piMMIO_En, stream< UdpAppData > &siUAIF_Data, stream< UdpAppMeta > &siUAIF_Meta, stream< UdpAppDLen > &siUAIF_DLen, stream< AxisIp4 > &soIPTX_Data)
 
void uoe (CmdBit piMMIO_En, stream< ap_uint< 16 > > &soMMIO_DropCnt, stream< StsBool > &soMMIO_Ready, stream< AxisIp4 > &siIPRX_Data, stream< AxisIp4 > &soIPTX_Data, stream< UdpAppLsnReq > &siUAIF_LsnReq, stream< UdpAppLsnRep > &soUAIF_LsnRep, stream< UdpAppClsReq > &siUAIF_ClsReq, stream< UdpAppClsRep > &soUAIF_ClsRep, stream< UdpAppData > &soUAIF_Data, stream< UdpAppMeta > &soUAIF_Meta, stream< UdpAppDLen > &soUAIF_DLen, stream< UdpAppData > &siUAIF_Data, stream< UdpAppMeta > &siUAIF_Meta, stream< UdpAppDLen > &siUAIF_DLen, stream< AxisIcmp > &soICMP_Data)
 Main process of the UDP Offload Engine (UOE). More...
 
void uoe_top (CmdBit piMMIO_En, stream< ap_uint< 16 > > &soMMIO_DropCnt, stream< StsBool > &soMMIO_Ready, stream< AxisRaw > &siIPRX_Data, stream< AxisRaw > &soIPTX_Data, stream< UdpAppLsnReq > &siUAIF_LsnReq, stream< UdpAppLsnRep > &soUAIF_LsnRep, stream< UdpAppClsReq > &siUAIF_ClsReq, stream< UdpAppClsRep > &soUAIF_ClsRep, stream< UdpAppData > &soUAIF_Data, stream< UdpAppMeta > &soUAIF_Meta, stream< UdpAppDLen > &soUAIF_DLen, stream< UdpAppData > &siUAIF_Data, stream< UdpAppMeta > &siUAIF_Meta, stream< UdpAppDLen > &siUAIF_DLen, stream< AxisRaw > &soICMP_Data)
 Top of UDP Offload Engine (UOE) More...
 

Variables

bool gTraceEvent
 
const int cUdpRxDataFifoSize = ( 16*1024 )/( 64 /8)
 
const int cUdpRxHdrsFifoSize = ( 64 )
 
const int cIp4RxHdrsFifoSize = (cUdpRxHdrsFifoSize * 4)
 
const int cMtuSize = (2*MTU)/( 64 /8)
 

Detailed Description

UDP Offload Engine (UOE) of the Network Transport Stack (NTS).

Macro Definition Documentation

◆ DEBUG_LEVEL

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 82 of file uoe.cpp.

◆ THIS_NAME

#define THIS_NAME   "UOE"

Definition at line 68 of file uoe.cpp.

◆ TRACE_ALL

#define TRACE_ALL   0xFFFF

Definition at line 80 of file uoe.cpp.

◆ TRACE_IHA

#define TRACE_IHA   1 << 1

Definition at line 71 of file uoe.cpp.

◆ TRACE_IHS

#define TRACE_IHS   1 << 2

Definition at line 72 of file uoe.cpp.

◆ TRACE_OFF

#define TRACE_OFF   0x0000

Definition at line 70 of file uoe.cpp.

◆ TRACE_RPH

#define TRACE_RPH   1 << 3

Definition at line 73 of file uoe.cpp.

◆ TRACE_TAI

#define TRACE_TAI   1 << 4

Definition at line 74 of file uoe.cpp.

◆ TRACE_TDH

#define TRACE_TDH   1 << 5

Definition at line 75 of file uoe.cpp.

◆ TRACE_UCA

#define TRACE_UCA   1 << 6

Definition at line 76 of file uoe.cpp.

◆ TRACE_UCC

#define TRACE_UCC   1 << 7

Definition at line 77 of file uoe.cpp.

◆ TRACE_UHA

#define TRACE_UHA   1 << 8

Definition at line 78 of file uoe.cpp.

◆ TRACE_UPT

#define TRACE_UPT   1 << 9

Definition at line 79 of file uoe.cpp.

◆ UOE_ELASTIC_DATA_BUFFER

#define UOE_ELASTIC_DATA_BUFFER   16*1024

Definition at line 77 of file uoe.hpp.

◆ UOE_ELASTIC_HEADER_BUFF

#define UOE_ELASTIC_HEADER_BUFF   64

Definition at line 78 of file uoe.hpp.

Function Documentation

◆ pIp4HeaderAdder()

void pIp4HeaderAdder ( stream< AxisUdp > &  siUha_Data,
stream< IpAddrPair > &  siUha_IpPair,
stream< UdpLen > &  siUha_UdpLen,
stream< AxisIp4 > &  soIPTX_Data 
)

IPv4 Header Adder (Iha)

Parameters
[in]siUha_DataUDM datagram stream from UdpHeaderAdder (Uha).
[in]siUha_IpPairThe IP_SA and IP_DA of this this datagram from [Uha].
[in]siUha_UdpLenThe length of the UDP datagram fro [Uha].
[out]soIPTX_DataThe IPv4 packet to IpTxHandler (IPTX).

This process creates an IPv4 header and prepends it to the UDP datagram stream coming from the UdpHeaderAdder (Uha).

Definition at line 1599 of file uoe.cpp.

1604 {
1605  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
1606  #pragma HLS INLINE off
1607  #pragma HLS pipeline II=1 enable_flush
1608 
1609  const char *myName = concat3(THIS_NAME, "/TXe/", "Iha");
1610 
1611  //-- STATIC CONTROL VARIABLES (with RESET) --------------------------------
1612  static enum FsmStates { IPH_IP1=0, IPH_IP2, IPH_IP3, IPH_FORWARD,
1613  IPH_RESIDUE} iha_fsmState;
1614  #pragma HLS RESET variable=iha_fsmState
1615 
1616 
1617  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
1618  static IpAddrPair iha_ipPair;
1619  static AxisUdp iha_prevUdpChunk;
1620 
1621  //-- DYNAMIC VARIABLES ----------------------------------------------------
1622  static AxisUdp currUdpChunk;
1623 
1624  switch(iha_fsmState) {
1625  case IPH_IP1:
1626  if(!siUha_UdpLen.empty() and !siUha_Data.empty() and !siUha_IpPair.empty() and
1627  !soIPTX_Data.full()) {
1628  UdpLen udpLen = siUha_UdpLen.read();
1629  Ip4PktLen ip4Len = udpLen + IP4_HEADER_LEN;
1630  AxisIp4 firstIp4Chunk = AxisIp4(0, 0xFF, 0);
1631  firstIp4Chunk.setIp4HdrLen(5);
1632  firstIp4Chunk.setIp4Version(4);
1633  firstIp4Chunk.setIp4ToS(0);
1634  firstIp4Chunk.setIp4TotalLen(ip4Len);
1635  firstIp4Chunk.setIp4Ident(0);
1636  firstIp4Chunk.setIp4Flags(0);
1637  firstIp4Chunk.setIp4FragOff(0);
1638  soIPTX_Data.write(firstIp4Chunk);
1639  iha_fsmState = IPH_IP2;
1640  if (DEBUG_LEVEL & TRACE_IHA) { printInfo(myName, "IPH_IP1\n"); }
1641  }
1642  break;
1643  case IPH_IP2:
1644  if(!siUha_IpPair.empty() and !siUha_Data.empty() and
1645  !soIPTX_Data.full()) {
1646  iha_ipPair = siUha_IpPair.read();
1647  AxisIp4 secondIp4Chunk = AxisIp4(0, 0xFF, 0);
1648  secondIp4Chunk.setIp4TtL(0xFF);
1649  secondIp4Chunk.setIp4Prot(IP4_PROT_UDP);
1650  secondIp4Chunk.setIp4HdrCsum(0); // FYI-HeaderCsum will be generated by [IPTX]
1651  secondIp4Chunk.setIp4SrcAddr(iha_ipPair.ipSa); // [FIXME-Replace by piMMIO_IpAddress]
1652  soIPTX_Data.write(secondIp4Chunk);
1653  iha_fsmState = IPH_IP3;
1654  }
1655  if (DEBUG_LEVEL & TRACE_IHA) { printInfo(myName, "IPH_IP2\n"); }
1656  break;
1657  case IPH_IP3:
1658  if(!siUha_Data.empty() and !soIPTX_Data.full()) {
1659  currUdpChunk = siUha_Data.read();
1660  AxisIp4 thirdIp4Chunk = AxisIp4(0x0, 0xFF, 0);
1661  thirdIp4Chunk.setIp4DstAddr(iha_ipPair.ipDa);
1662  thirdIp4Chunk.setUdpSrcPort(currUdpChunk.getUdpSrcPort());
1663  thirdIp4Chunk.setUdpDstPort(currUdpChunk.getUdpDstPort());
1664  soIPTX_Data.write(thirdIp4Chunk);
1665  iha_fsmState = IPH_FORWARD;
1666  }
1667  if (DEBUG_LEVEL & TRACE_IHA) { printInfo(myName, "IPH_IP3\n"); }
1668  break;
1669  case IPH_FORWARD:
1670  if(!siUha_Data.empty() and !soIPTX_Data.full()) {
1671  currUdpChunk = siUha_Data.read();
1672  AxisIp4 forwardIp4Chunk = AxisIp4(0x0, 0xFF, 0);
1673  forwardIp4Chunk.setTDataHi(iha_prevUdpChunk.getTDataLo());
1674  forwardIp4Chunk.setTDataLo( currUdpChunk.getTDataHi());
1675  if(currUdpChunk.getTLast()) {
1676  if (currUdpChunk.getTKeepLo() != 0) {
1677  iha_fsmState = IPH_RESIDUE;
1678  }
1679  else {
1680  forwardIp4Chunk.setTKeepHi(iha_prevUdpChunk.getTKeepLo());
1681  forwardIp4Chunk.setTKeepLo(currUdpChunk.getTKeepHi());
1682  forwardIp4Chunk.setTLast(TLAST);
1683  iha_fsmState = IPH_IP1;
1684  }
1685  }
1686  soIPTX_Data.write(forwardIp4Chunk);
1687  }
1688  if (DEBUG_LEVEL & TRACE_IHA) { printInfo(myName, "IPH_FORWARD\n"); }
1689  break;
1690  case IPH_RESIDUE:
1691  if (!soIPTX_Data.full()) {
1692  AxisIp4 forwardIp4Chunk = AxisIp4(0x0, 0x00, 0);
1693  forwardIp4Chunk.setTDataHi(iha_prevUdpChunk.getTDataLo());
1694  forwardIp4Chunk.setTKeepHi(iha_prevUdpChunk.getTKeepLo());
1695  forwardIp4Chunk.setTLast(TLAST);
1696  soIPTX_Data.write(forwardIp4Chunk);
1697  iha_fsmState = IPH_IP1;
1698  }
1699  if (DEBUG_LEVEL & TRACE_IHA) { printInfo(myName, "IPH_RESIDUE\n"); }
1700  break;
1701  }
1702  iha_prevUdpChunk = currUdpChunk;
1703 }
void setIp4FragOff(Ip4FragOff offset)
Definition: AxisIp4.hpp:210
void setIp4Prot(Ip4Prot prot)
Definition: AxisIp4.hpp:220
void setIp4HdrLen(Ip4HdrLen ihl)
Definition: AxisIp4.hpp:198
void setIp4HdrCsum(Ip4HdrCsum csum)
Definition: AxisIp4.hpp:223
void setUdpSrcPort(UdpPort port, int Lo=32)
Definition: AxisIp4.hpp:290
void setIp4DstAddr(Ip4Addr addr)
Definition: AxisIp4.hpp:229
void setIp4TotalLen(Ip4TotalLen len)
Definition: AxisIp4.hpp:204
void setIp4Flags(Ip4Flags flags)
Definition: AxisIp4.hpp:215
void setIp4Version(Ip4Version ver)
Definition: AxisIp4.hpp:195
void setIp4Ident(Ip4Ident id)
Definition: AxisIp4.hpp:207
void setIp4ToS(Ip4ToS tos)
Definition: AxisIp4.hpp:201
void setIp4SrcAddr(Ip4Addr addr)
Definition: AxisIp4.hpp:226
void setIp4TtL(Ip4TtL ttl)
Definition: AxisIp4.hpp:217
void setUdpDstPort(UdpPort port, int Lo=48)
Definition: AxisIp4.hpp:294
void setTLast(tLast last)
Definition: AxisRaw.hpp:246
void setTDataHi(tDataHalf halfData)
Definition: AxisRaw.hpp:326
void setTDataLo(tDataHalf halfData)
Definition: AxisRaw.hpp:337
tLast getTLast() const
Definition: AxisRaw.hpp:219
tDataHalf getTDataLo() const
Definition: AxisRaw.hpp:301
void setTKeepLo(tKeepHalf halfKeep)
Definition: AxisRaw.hpp:359
tKeepHalf getTKeepHi() const
Definition: AxisRaw.hpp:309
void setTKeepHi(tKeepHalf halfKeep)
Definition: AxisRaw.hpp:348
tDataHalf getTDataHi() const
Definition: AxisRaw.hpp:293
tKeepHalf getTKeepLo() const
Definition: AxisRaw.hpp:317
UdpPort getUdpDstPort()
Definition: AxisUdp.hpp:135
UdpPort getUdpSrcPort()
Definition: AxisUdp.hpp:130
Ip4Addr ipDa
Definition: uoe.hpp:98
Ip4Addr ipSa
Definition: uoe.hpp:97
ap_uint< 16 > UdpLen
Definition: nal.hpp:250
#define THIS_NAME
Definition: uoe.cpp:68
#define DEBUG_LEVEL
Definition: uoe.cpp:82
#define TRACE_IHA
Definition: uoe.cpp:71
ap_uint< 16 > Ip4PktLen
Definition: AxisIp4.hpp:172
#define IP4_PROT_UDP
Definition: nts_types.hpp:185
#define IP4_HEADER_LEN
Definition: AxisIp4.hpp:133
#define printInfo(callerName, format,...)
A macro to print an information message.
Definition: nts_utils.hpp:169
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
Definition: nts_utils.hpp:161
#define TLAST
Definition: AxisRaw.hpp:116
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pIpHeaderStripper()

void pIpHeaderStripper ( CmdBit  piMMIO_En,
stream< AxisIp4 > &  siIPRX_Data,
stream< AxisUdp > &  soUcc_UdpDgrm,
stream< UdpCsum > &  soUcc_PsdHdrSum,
stream< AxisIp4 > &  soRph_Ip4Hdr,
stream< SigBit > &  siUcc_ClearToSend,
stream< ap_uint< 16 > > &  soMMIO_DropCnt 
)

IPv4 Header Stripper (Ihs)

Parameters
[in]piMMIO_EnEnable signal from [SHELL/MMIO].
[in]siIPRX_DataIP4 data stream from IpRxHAndler (IPRX).
[out]soUcc_UdpDgrmUDP datagram stream to UdpChecksumChecker (Ucc).
[out]soUcc_PsdHdrSumSum of the pseudo header information to [Ucc].
[out]soRph_Ip4HdrThe header part of the IPv4 packet as a stream to [Rph].
[in]siUcc_ClearToSendClear to send signal from [Ucc].
[out]soMMIO_DropCntThe content of the datagram drop counter.

This process extracts the UDP pseudo header and the IP header from the incoming IPv4 packet. The IP header is forwarded to RxPacketHandler (Rph) for further processing while the UDP datagram and the UDP pseudo-header are forwarded to the UDP checksum checker. To avoid blocking the IPRX engine of the NTS, this process starts dropping incoming traffic upon one of the two following conditions: 1) If the elastic data buffer located between [Ucc] and [Rph] is full or, 2) If the maximum number of stored headers is reached. The first condition (i.e. elastic buffer full) is indicated by the clear-to- send signal not being asserted.

Definition at line 109 of file uoe.cpp.

117  {
118  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
119  #pragma HLS INLINE off
120  #pragma HLS pipeline II=1 enable_flush
121 
122  const char *myName = concat3(THIS_NAME, "/Rxe/", "Ihs");
123 
124  //-- STATIC CONTROL VARIABLES (with RESET) --------------------------------
125  static enum FsmStates {FSM_IHS_IDLE=0,
126  FSM_IHS_IPW0, FSM_IHS_IPW1,
127  FSM_IHS_IPW2, FSM_IHS_OPT,
128  FSM_IHS_UDP_HEADER, FSM_IHS_UDP_HEADER_ALIGNED,
129  FSM_IHS_FORWARD, FSM_IHS_FORWARD_ALIGNED,
130  FSM_IHS_RESIDUE, FSM_IHS_DONE,
131  FSM_IHS_DROP } ihs_fsmState=FSM_IHS_IDLE;
132  #pragma HLS RESET variable=ihs_fsmState
133  static ap_uint<16> ihs_dropCounter=0;
134  #pragma HLS reset variable=ihs_dropCounter
135 
136  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
137  static ap_uint<4> ihs_bitCount;
138  static ap_uint<3> ihs_ipHdrCnt;
139  static AxisIp4 ihs_prevChunk;
140  static Ip4HdrLen ihs_ip4HdrLen;
141  static ap_uint<17> ihs_psdHdrSum;
142 
143  //-- DYNAMIC VARIABLES ----------------------------------------------------
144  AxisIp4 currIp4Chunk;
145  AxisUdp sendChunk;
146 
147  switch(ihs_fsmState) {
148  case FSM_IHS_IDLE:
149  if ((piMMIO_En == CMD_DISABLE) and !siIPRX_Data.empty()) {
150  printWarn(myName, "FSM_IHS_IDLE - UOE is disabled. This packet will be dropped.\n");
151  ihs_fsmState = FSM_IHS_DROP;
152  }
153  else if (siUcc_ClearToSend.empty() and !siIPRX_Data.empty()) {
154  printWarn(myName, "FSM_IHS_IDLE - UOE buffers are full. This packet will be dropped.\n");
155  ihs_fsmState = FSM_IHS_DROP;
156  }
157  else if (!siUcc_ClearToSend.empty()) {
158  // We can proceed, there is at least one MTU of space is available in UOE.
159  // From now on, no need to test the 'soUcc_UdpDgrm' fullness anymore.
160  ihs_fsmState = FSM_IHS_IPW0;
161  }
162  break;
163  case FSM_IHS_IPW0:
164  if (!siIPRX_Data.empty() and (soUcc_PsdHdrSum.full() or soRph_Ip4Hdr.full())) {
165  printWarn(myName, "FSM_IHS_IPW0 - Header-buffer space is exhausted. This packet will be dropped.\n");
166  ihs_fsmState = FSM_IHS_DROP;
167  }
168  else if (!siIPRX_Data.empty() and !soUcc_PsdHdrSum.full() and !soRph_Ip4Hdr.full()) {
169  //-- READ 1st AXI-CHUNK (Frag|Flags|Id|TotLen|ToS|Ver|IHL) ---------
170  siIPRX_Data.read(currIp4Chunk);
171  ihs_ip4HdrLen = currIp4Chunk.getIp4HdrLen();
172  if (ihs_ip4HdrLen < 5) {
173  printWarn(myName, "FSM_IHS_IPW0 - Received an IPv4 packet with invalid IHL. This packet will be dropped.\n");
174  ihs_fsmState = FSM_IHS_DROP;
175  }
176  else {
177  soRph_Ip4Hdr.write(currIp4Chunk);
178  if (DEBUG_LEVEL & TRACE_IHS) {
179  printInfo(myName, "Received a new IPv4 packet (IHL=%d|TotLen=%d)\n",
180  ihs_ip4HdrLen.to_uint(), currIp4Chunk.getIp4TotalLen().to_ushort());
181  printAxisRaw(myName, "FSM_IHS_IPW0 -", currIp4Chunk);
182  }
183  ihs_ip4HdrLen -= 2;
184  ihs_fsmState = FSM_IHS_IPW1;
185  }
186  }
187  break;
188  case FSM_IHS_IPW1:
189  if (soRph_Ip4Hdr.full()) {
190  printWarn(myName, "FSM_IHS_IPW1 - Header-buffer space is exhausted. The remaining of this packet will be dropped.\n");
191  ihs_fsmState = FSM_IHS_DROP;
192  }
193  else if (!siIPRX_Data.empty()) {
194  //-- READ 2nd AXI-CHUNK (SA|HdrCsum|Prot|TTL)
195  siIPRX_Data.read(currIp4Chunk);
196  soRph_Ip4Hdr.write(currIp4Chunk);
197  //-- Csum accumulate (SA+Prot)
198  ihs_psdHdrSum = (0x00, currIp4Chunk.getIp4Prot());
199  ihs_psdHdrSum += currIp4Chunk.getIp4SrcAddr().range(31,16);
200  ihs_psdHdrSum = (ihs_psdHdrSum & 0xFFFF) + (ihs_psdHdrSum >> 16);
201  ihs_psdHdrSum += currIp4Chunk.getIp4SrcAddr().range(15, 0);
202  ihs_psdHdrSum = (ihs_psdHdrSum & 0xFFFF) + (ihs_psdHdrSum >> 16);
203  ihs_ip4HdrLen -= 2;
204  ihs_fsmState = FSM_IHS_IPW2;
205  if (DEBUG_LEVEL & TRACE_IHS) { printAxisRaw(myName, "FSM_IHS_IPW1 -", currIp4Chunk); }
206  }
207  break;
208  case FSM_IHS_IPW2:
209  if (soRph_Ip4Hdr.full()) {
210  printWarn(myName, "FSM_IHS_IPW2 - Header-buffer space is exhausted. The remaining of this packet will be dropped.\n");
211  ihs_fsmState = FSM_IHS_DROP;
212  }
213  else if (!siIPRX_Data.empty()) {
214  //-- READ 3rd AXI-CHUNK (DP|SP|DA) or (Opt|DA)
215  siIPRX_Data.read(currIp4Chunk);
216  //-- Csum accumulate (DA)
217  ihs_psdHdrSum += currIp4Chunk.getIp4DstAddr().range(31,16);
218  ihs_psdHdrSum = (ihs_psdHdrSum & 0xFFFF) + (ihs_psdHdrSum >> 16);
219  ihs_psdHdrSum += currIp4Chunk.getIp4DstAddr().range(15, 0);
220  ihs_psdHdrSum = (ihs_psdHdrSum & 0xFFFF) + (ihs_psdHdrSum >> 16);
221  if (ihs_ip4HdrLen == 1) {
222  // This a typical IPv4 header with a length of 20 bytes (5*4).
223  soRph_Ip4Hdr.write(AxisIp4(currIp4Chunk.getLE_Ip4DstAddr(), 0x0F, TLAST));
224  ihs_fsmState = FSM_IHS_UDP_HEADER;
225  }
226  else if (ihs_ip4HdrLen == 2 ) {
227  printWarn(myName, "This IPv4 packet contains one 32-bit option! FYI, IPV4 options are not supported.\n");
228  soRph_Ip4Hdr.write(AxisIp4(currIp4Chunk.getLE_TData(), currIp4Chunk.getLE_TKeep(), TLAST));
229  ihs_fsmState = FSM_IHS_UDP_HEADER_ALIGNED;
230  }
231  else { // ihs_ip4HdrLen > 2
232  printWarn(myName, "This IPv4 packet contains two+ 32-bit options! FYI, IPV4 options are not supported.\n");
233  soRph_Ip4Hdr.write(AxisIp4(currIp4Chunk.getLE_TData(), currIp4Chunk.getLE_TKeep(), 0));
234  ihs_ip4HdrLen -= 2;
235  ihs_fsmState = FSM_IHS_OPT;
236  }
237  if (DEBUG_LEVEL & TRACE_IHS) { printAxisRaw(myName, "FSM_IHS_IPW2 -", currIp4Chunk); }
238  }
239  break;
240  case FSM_IHS_OPT:
241  if (soRph_Ip4Hdr.full()) {
242  printWarn(myName, "FSM_IHS_OPT - Header-buffer space is exhausted. The remaining of this packet will be dropped.\n");
243  ihs_fsmState = FSM_IHS_DROP;
244  }
245  else if (!siIPRX_Data.empty()) {
246  printWarn(myName, "This IPv4 packet contains options! FYI, IPV4 options are not supported and will be dropped.\n");
247  //-- READ more Options (OPT|Opt) and/or Data (Data|Opt)
248  siIPRX_Data.read(currIp4Chunk);
249  if (ihs_ip4HdrLen == 1) {
250  printWarn(myName, "This IPv4 packet contains three 32-bit options!\n");
251  soRph_Ip4Hdr.write(AxisIp4(currIp4Chunk.getLE_TDataHi(), 0x0F, TLAST));
252  ihs_fsmState = FSM_IHS_UDP_HEADER;
253  }
254  else if (ihs_ip4HdrLen == 2 ) {
255  printWarn(myName, "This IPv4 packet contains four 32-bit options!\n");
256  soRph_Ip4Hdr.write(AxisIp4(currIp4Chunk.getLE_TData(), currIp4Chunk.getLE_TKeep(), TLAST));
257  ihs_fsmState = FSM_IHS_UDP_HEADER_ALIGNED;
258  }
259  else { // ihs_ip4HdrLen > 2
260  printWarn(myName, "This IPv4 packet contains four+ 32-bit options!\n");
261  soRph_Ip4Hdr.write(AxisIp4(currIp4Chunk.getLE_TData(), currIp4Chunk.getLE_TKeep(), 0));
262  ihs_ip4HdrLen -= 2;
263  ihs_fsmState = FSM_IHS_OPT;
264  }
265  if (DEBUG_LEVEL & TRACE_IHS) { printAxisRaw(myName, "FSM_IHS_OPT -", currIp4Chunk); }
266  }
267  break;
268  case FSM_IHS_UDP_HEADER:
269  // At this stage we know that !soUcc_UdpDgrm.full() and !soUcc_PsdHdrSum.full()) {
270  if (!siIPRX_Data.empty()) {
271  //-- Read end of un-aligned UDP header (Data|Csum|Len) ----------
272  siIPRX_Data.read(currIp4Chunk);
273  //-- Csum accumulate (UdpLen)
274  ihs_psdHdrSum += currIp4Chunk.getUdpLen();
275  ihs_psdHdrSum = (ihs_psdHdrSum & 0xFFFF) + (ihs_psdHdrSum >> 16);
276  //-- Forward UDP PseudoHeaderCsum to [Ucc]
277  soUcc_PsdHdrSum.write(ihs_psdHdrSum(15, 0));
278  //-- Forward the UDP Header (Csum|Len|DP|SP)
279  sendChunk.setTKeep(0xFF);
280  sendChunk.setTDataHi(ihs_prevChunk.getTDataLo());
281  sendChunk.setTDataLo(currIp4Chunk.getTDataHi());
282  if (currIp4Chunk.getTLast()) {
283  if (currIp4Chunk.getTKeep() == 0xF0) {
284  printWarn(myName, "Received a UDP datagram of length = 0!\n");
285  sendChunk.setTKeep(0xFF);
286  ihs_fsmState = FSM_IHS_DONE;
287  }
288  else {
289  sendChunk.setTKeepHi(ihs_prevChunk.getTKeepLo());
290  sendChunk.setTKeepLo(currIp4Chunk.getTKeepHi());
291  ihs_fsmState = FSM_IHS_RESIDUE;
292  }
293  }
294  else {
295  ihs_fsmState = FSM_IHS_FORWARD;
296  }
297  soUcc_UdpDgrm.write(sendChunk);
298  if (DEBUG_LEVEL & TRACE_IHS) { printAxisRaw(myName,"FSM_IHS_UDP_HEADER -", sendChunk); }
299  }
300  break;
301  case FSM_IHS_UDP_HEADER_ALIGNED:
302  // At this stage we know that !soUcc_UdpDgrm.full() and !soUcc_PsdHdrSum.full()) {
303  if (!siIPRX_Data.empty()) {
304  //-- READ Aligned UDP header (Csum|Len|DP|SP) --------
305  siIPRX_Data.read(currIp4Chunk);
306  //-- Cast incoming chunk into an AxisUdp chunk
307  AxisUdp currUdpChunk(currIp4Chunk);
308  //-- Csum accumulate (UdpLen)
309  ihs_psdHdrSum += currUdpChunk.getUdpLen();
310  ihs_psdHdrSum = (ihs_psdHdrSum & 0xFFFF) + (ihs_psdHdrSum >> 16);
311  //-- Forward UDP PseudoHeaderCsum to [Ucc]
312  soUcc_PsdHdrSum.write(ihs_psdHdrSum(15, 0));
313  //-- Forward the UDP Header (Csum|Len|DP|SP)
314  soUcc_UdpDgrm.write(currUdpChunk);
315  if (currUdpChunk.getTLast()) {
316  printWarn(myName, "Received a UDP datagram of length = 0!\n");
317  ihs_fsmState = FSM_IHS_DONE;
318  }
319  else {
320  ihs_fsmState = FSM_IHS_FORWARD_ALIGNED;
321  }
322  if (DEBUG_LEVEL & TRACE_IHS) { printAxisRaw(myName, "FSM_IHS_UDP_HEADER_ALIGNED -", currUdpChunk); }
323  }
324  break;
325  case FSM_IHS_FORWARD:
326  // At this stage we know that !soUcc_UdpDgrm.full()
327  if (!siIPRX_Data.empty()) {
328  //-- READ n-th AXI-CHUNK (Data) ----------------
329  siIPRX_Data.read(currIp4Chunk);
330  //-- Forward 1/2 of previous chunk and 1/2 of current chunk)
331  sendChunk.setTDataHi(ihs_prevChunk.getTDataLo());
332  sendChunk.setTKeepHi(ihs_prevChunk.getTKeepLo());
333  sendChunk.setTDataLo(currIp4Chunk.getTDataHi());
334  sendChunk.setTKeepLo(currIp4Chunk.getTKeepHi());
335  if (currIp4Chunk.getTLast()) {
336  if (currIp4Chunk.getTKeep() <= 0xF0) {
337  sendChunk.setTLast(TLAST);
338  ihs_fsmState = FSM_IHS_DONE;
339  }
340  else {
341  sendChunk.setTLast(0);
342  ihs_fsmState = FSM_IHS_RESIDUE;
343  }
344  }
345  else {
346  sendChunk.setTLast(0);
347  ihs_fsmState = FSM_IHS_FORWARD;
348  }
349  soUcc_UdpDgrm.write(sendChunk);
350  if (DEBUG_LEVEL & TRACE_IHS) { printAxisRaw(myName, "FSM_IHS_FORWARD -", sendChunk); }
351  }
352  break;
353  case FSM_IHS_FORWARD_ALIGNED:
354  // At this stage we know that !soUcc_UdpDgrm.full()
355  if (!siIPRX_Data.empty()) {
356  //-- READ UDP ALIGNED AXI-CHUNK --------------
357  siIPRX_Data.read(currIp4Chunk);
358  //-- Cast incoming chunk into an AxisUdp chunk
359  AxisUdp currUdpChunk(currIp4Chunk);
360  soUcc_UdpDgrm.write(currUdpChunk);
361  if (currUdpChunk.getTLast()) {
362  ihs_fsmState = FSM_IHS_DONE;
363  }
364  else {
365  ihs_fsmState = FSM_IHS_FORWARD_ALIGNED;
366  }
367  if (DEBUG_LEVEL & TRACE_IHS) { printAxisRaw(myName, "FSM_IHS_FORWARD_ALIGNED -", sendChunk); }
368  }
369  break;
370  case FSM_IHS_RESIDUE:
371  // At this stage we know that !soUcc_UdpDgrm.full()
372  //-- Forward the very last bytes of the current chunk
373  sendChunk.setTDataLo(0);
374  sendChunk.setTDataHi(ihs_prevChunk.getTDataLo());
375  sendChunk.setTKeepLo(0);
376  sendChunk.setTKeepHi(ihs_prevChunk.getTKeepLo());
377  sendChunk.setTLast(TLAST);
378  soUcc_UdpDgrm.write(sendChunk);
379  ihs_fsmState = FSM_IHS_DONE;
380  if (DEBUG_LEVEL & TRACE_IHS) { printAxisRaw(myName, "FSM_IHS_RESIDUE -", sendChunk); }
381  break;
382  case FSM_IHS_DONE:
383  // We are done with this datagram; Consume one CTS token
384  siUcc_ClearToSend.read();
385  ihs_fsmState = FSM_IHS_IDLE;
386  if (DEBUG_LEVEL & TRACE_IHS) { printInfo(myName, "FSM_IHS_DONE \n"); }
387  break;
388  case FSM_IHS_DROP:
389  if (!siIPRX_Data.empty()) {
390  //-- READ and DRAIN all AXI-CHUNKS ------------
391  siIPRX_Data.read(currIp4Chunk);
392  if (currIp4Chunk.getTLast()) {
393  ihs_dropCounter++;
394  ihs_fsmState = FSM_IHS_IDLE;
395  }
396  if (DEBUG_LEVEL & TRACE_IHS) { printAxisRaw(myName, "FSM_IHS_DROP -", currIp4Chunk); }
397  }
398  break;
399  } // End-of: switch
400 
401  //-- ALWAYS
402  ihs_prevChunk = currIp4Chunk;
403  if (!soMMIO_DropCnt.full()) {
404  soMMIO_DropCnt.write(ihs_dropCounter);
405  }
406  else {
407  printWarn(myName, "Cannot write soMMIO_DropCnt stream...");
408  }
409 
410  } // End-of: pIpHeaderStripper
UdpLen getUdpLen(int Lo=0)
Definition: AxisIp4.hpp:300
Ip4Addr getIp4DstAddr()
Definition: AxisIp4.hpp:230
Ip4TotalLen getIp4TotalLen()
Definition: AxisIp4.hpp:205
LE_Ip4Addr getLE_Ip4DstAddr()
Definition: AxisIp4.hpp:235
Ip4HdrLen getIp4HdrLen()
Definition: AxisIp4.hpp:199
Ip4Prot getIp4Prot()
Definition: AxisIp4.hpp:221
Ip4Addr getIp4SrcAddr()
Definition: AxisIp4.hpp:227
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 setTKeep(tKeep keep)
Definition: AxisRaw.hpp:239
LE_tDataHalf getLE_TDataHi() const
Definition: AxisRaw.hpp:370
tKeep getTKeep(int leHi=64/8-1, int leLo=0) const
Definition: AxisRaw.hpp:207
#define TRACE_IHS
Definition: uoe.cpp:72
void printAxisRaw(const char *callerName, AxisRaw chunk)
Prints an Axis raw data chunk (used for debugging).
Definition: nts_utils.cpp:46
#define CMD_DISABLE
Definition: nts_types.hpp:64
ap_uint< 4 > Ip4HdrLen
Definition: AxisIp4.hpp:157
#define printWarn(callerName, format,...)
A macro to print a warning message.
Definition: nts_utils.hpp:182
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pRxEngine()

void pRxEngine ( CmdBit  piMMIO_En,
stream< StsBool > &  soMMIO_Ready,
stream< AxisIp4 > &  siIPRX_Data,
stream< UdpPort > &  siUAIF_LsnReq,
stream< StsBool > &  soUAIF_LsnRep,
stream< UdpPort > &  siUAIF_ClsReq,
stream< StsBool > &  soUAIF_ClsRep,
stream< UdpAppData > &  soUAIF_Data,
stream< UdpAppMeta > &  soUAIF_Meta,
stream< UdpAppDLen > &  soUAIF_DLen,
stream< AxisIcmp > &  soICMP_Data,
stream< ap_uint< 16 > > &  soMMIO_DropCnt 
)

Rx Engine (RXe)

Parameters
[in]piMMIO_EnEnable signal from [SHELL/MMIO].
[out]soMMIO_ReadyProcess ready signal.
[in]siIPRX_DataIP4 data stream from IpRxHAndler (IPRX).
[in]siUAIF_LsnReqUDP open port request from UdpAppInterface (UAIF).
[out]soUAIF_LsnRepUDP open port reply to [UAIF].
[in]siUAIF_ClsReqUDP close port request from [UAIF].
[out]soUAIF_ClsRepUDP close port reply to [UAIF].
[out]soUAIF_DataUDP data stream to [UAIF].
[out]soUAIF_MetaUDP metadata to [UAIF].
[out]soUAIF_DLenUDP data length to [UAIF].
[out]soICMP_DataControl message to InternetControlMessageProtocol[ICMP] engine.

The Rx path of the UdpOffloadEngine (UOE). This is the path from [IPRX] to the UdpAppInterface (UAIF). To avoid blocking the IPRX engine of the NTS, this process will start dropping the incoming traffic upon one of the two following conditions: 1) If the internal elastic data buffer defined by 'cUdpRxDataFifoSize' is full or, 2) If the maximum number of stored headers defined by 'cUdpRxHdrsFifoSize' is reached.

Definition at line 982 of file uoe.cpp.

995 {
996  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
997  #pragma HLS INLINE
998 
999  //-------------------------------------------------------------------------
1000  //-- LOCAL STREAMS (Sorted by the name of the modules which generate them)
1001  //-------------------------------------------------------------------------
1002 
1003  //-- IP Header Stripper (Ihs)
1004  static stream<AxisIp4> ssIhsToRph_Ip4Hdr ("ssIhsToRph_Ip4Hdr");
1005  #pragma HLS STREAM variable=ssIhsToRph_Ip4Hdr depth=cIp4RxHdrsFifoSize
1006  static stream<AxisUdp> ssIhsToUcc_UdpDgrm ("ssIhsToUcc_UdpDgrm");
1007  #pragma HLS STREAM variable=ssIhsToUcc_UdpDgrm depth=cMtuSize
1008  static stream<UdpCsum> ssIhsToUcc_PsdHdrSum ("ssIhsToUcc_PsdHdrSum");
1009  #pragma HLS STREAM variable=ssIhsToUcc_PsdHdrSum depth=2
1010  //-- UDP Checksum Checker (Ucc)
1011  static stream<AxisUdp> ssUccToRph_UdpDgrm ("ssUccToRph_UdpDgrm");
1012  #pragma HLS STREAM variable=ssUccToRph_UdpDgrm depth=cUdpRxDataFifoSize
1013  static stream<ValBool> ssUccToRph_CsumVal ("ssUccToRph_CsumVal");
1014  #pragma HLS STREAM variable=ssUccToRph_CsumVal depth=cUdpRxHdrsFifoSize
1015  static stream<SigBit> ssUccToIhs_ClearToSend ("ssUccToIhs_ClearToSend");
1016  #pragma HLS STREAM variable=ssUccToIhs_ClearToSend depth=2
1017 
1018  //-- UDP Packet Handler (UPh)
1019  static stream<UdpPort> ssRphToUpt_PortStateReq ("ssRphToUpt_PortStateReq");
1020  #pragma HLS STREAM variable=ssRphToUpt_PortStateReq depth=2
1021 
1022  //-- UDP Port Table (Upt)
1023  static stream<StsBool> ssUptToRph_PortStateRep ("ssUptToRph_PortStateRep");
1024  #pragma HLS STREAM variable=ssUptToRph_PortStateRep depth=2
1025 
1027  piMMIO_En,
1028  siIPRX_Data,
1029  ssIhsToUcc_UdpDgrm,
1030  ssIhsToUcc_PsdHdrSum,
1031  ssIhsToRph_Ip4Hdr,
1032  ssUccToIhs_ClearToSend,
1033  soMMIO_DropCnt);
1034 
1036  ssIhsToUcc_UdpDgrm,
1037  ssIhsToUcc_PsdHdrSum,
1038  ssUccToRph_UdpDgrm,
1039  ssUccToRph_CsumVal,
1040  ssUccToIhs_ClearToSend);
1041 
1043  ssUccToRph_UdpDgrm,
1044  ssUccToRph_CsumVal,
1045  ssIhsToRph_Ip4Hdr,
1046  ssRphToUpt_PortStateReq,
1047  ssUptToRph_PortStateRep,
1048  soUAIF_Data,
1049  soUAIF_Meta,
1050  soUAIF_DLen,
1051  soICMP_Data);
1052 
1053  pUdpPortTable(
1054  soMMIO_Ready,
1055  ssRphToUpt_PortStateReq,
1056  ssUptToRph_PortStateRep,
1057  siUAIF_LsnReq,
1058  soUAIF_LsnRep,
1059  siUAIF_ClsReq,
1060  soUAIF_ClsRep);
1061 }
void pUdpPortTable(stream< StsBool > &soMMIO_Ready, stream< UdpPort > &siRph_PortStateReq, stream< StsBool > &soRph_PortStateRep, stream< UdpPort > &siUAIF_LsnReq, stream< StsBool > &soUAIF_LsnRep, stream< UdpPort > &siUAIF_ClsReq, stream< StsBool > &soUAIF_ClsRep)
Definition: uoe.cpp:865
void pRxPacketHandler(stream< AxisUdp > &siUcc_UdpDgrm, stream< ValBool > &siUcc_CsumVal, stream< AxisIp4 > &siIhs_Ip4Hdr, stream< UdpPort > &soUpt_PortStateReq, stream< StsBool > &siUpt_PortStateRep, stream< UdpAppData > &soUAIF_Data, stream< UdpAppMeta > &soUAIF_Meta, stream< UdpAppDLen > &soUAIF_DLen, stream< AxisIcmp > &soICMP_Data)
Definition: uoe.cpp:610
void pUdpChecksumChecker(stream< AxisUdp > &siIhs_UdpDgrm, stream< UdpCsum > &siIhs_PsdHdrSum, stream< AxisUdp > &soRph_UdpDgrm, stream< ValBool > &soRph_CsumVal, stream< SigBit > &soIhs_ClearToSend)
Definition: uoe.cpp:430
void pIpHeaderStripper(CmdBit piMMIO_En, stream< AxisIp4 > &siIPRX_Data, stream< AxisUdp > &soUcc_UdpDgrm, stream< UdpCsum > &soUcc_PsdHdrSum, stream< AxisIp4 > &soRph_Ip4Hdr, stream< SigBit > &siUcc_ClearToSend, stream< ap_uint< 16 > > &soMMIO_DropCnt)
Definition: uoe.cpp:109
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pRxPacketHandler()

void pRxPacketHandler ( stream< AxisUdp > &  siUcc_UdpDgrm,
stream< ValBool > &  siUcc_CsumVal,
stream< AxisIp4 > &  siIhs_Ip4Hdr,
stream< UdpPort > &  soUpt_PortStateReq,
stream< StsBool > &  siUpt_PortStateRep,
stream< UdpAppData > &  soUAIF_Data,
stream< UdpAppMeta > &  soUAIF_Meta,
stream< UdpAppDLen > &  soUAIF_DLen,
stream< AxisIcmp > &  soICMP_Data 
)

Rx Packet Handler (Rph)

Parameters
[in]siIhs_UdpDgrmUDP datagram stream from IpHeaderStripper (Ihs).
[in]siIhs_Ip4HdrThe header part of the IPv4 packet from [Ihs].
[in]siUcc_CsumValChecksum valid information from UdpChecksumChecker (Ucc).
[out]soUpt_PortStateReqRequest for the state of port to UdpPortTable (Upt).
[in]siUpt_PortStateRepPort state reply from [Upt].
[out]soUAIF_DataUDP data stream to UDP Application Interface (UAIF).
[out]soUAIF_MetaUDP metadata to [UAIF].
[out]soUAIF_DLenUDP data length to [UAIF]
[out]soICMP_DataControl message to InternetControlMessageProtocol[ICMP] engine.

This process handles the payload of the incoming IP4 packet and forwards it the UdpAppInterface (UAIF). If the UDP checksum of incoming datagram is wrong, the datagram is dropped. If the destination UDP port is not opened, the incoming IP header and the first 8 bytes of the datagram are forwarded to the Internet Control Message Protocol (ICMP) Server which will build a 'Destination Unreachable' message.

Definition at line 610 of file uoe.cpp.

620 {
621  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
622  #pragma HLS INLINE off
623  #pragma HLS PIPELINE II=1 enable_flush
624 
625  const char *myName = concat3(THIS_NAME, "/", "Rph");
626 
627  //-- STATIC CONTROL VARIABLES (with RESET) --------------------------------
628  static enum FsmStates { FSM_RPH_IDLE=0, FSM_RPH_PORT_LOOKUP,
629  FSM_RPH_STREAM, FSM_RPH_STREAM_FIRST,
630  FSM_RPH_DRAIN_DATAGRAM_STREAM,FSM_RPH_DRAIN_IP4HDR_STREAM,
631  FSM_RPH_PORT_UNREACHABLE_1ST, FSM_RPH_PORT_UNREACHABLE_2ND,
632  FSM_RPH_PORT_UNREACHABLE_STREAM,
633  FSM_RPH_PORT_UNREACHABLE_LAST } rph_fsmState=FSM_RPH_IDLE;
634  #pragma HLS RESET variable=rph_fsmState
635 
636  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
637  static AxisIp4 rph_1stIp4HdrChunk;
638  static AxisIp4 rph_2ndIp4HdrChunk;
639  static AxisUdp rph_udpHeaderChunk;
640  static FlagBit rph_emptyPayloadFlag;
641  static FlagBool rph_doneWithIpHdrStream;
642  static UdpLen rph_dgrmLen;
643 
644  static SocketPair rph_udpMeta = SocketPair(SockAddr(0, 0), SockAddr(0, 0));
645 
646  switch(rph_fsmState) {
647  case FSM_RPH_IDLE:
648  if (!siUcc_UdpDgrm.empty() and !siIhs_Ip4Hdr.empty() and
649  !soUpt_PortStateReq.full()) {
650  rph_doneWithIpHdrStream = false;
651  // Read the 1st IPv4 header chunk retrieve the IHL
652  siIhs_Ip4Hdr.read(rph_1stIp4HdrChunk);
653  // Read the the 1st datagram chunk
654  siUcc_UdpDgrm.read(rph_udpHeaderChunk);
655  // Request the state of this port to UdpPortTable (Upt)
656  soUpt_PortStateReq.write(rph_udpHeaderChunk.getUdpDstPort());
657  // Check if payload of datagram is empty
658  if (rph_udpHeaderChunk.getUdpLen() > 8) {
659  rph_emptyPayloadFlag = 0;
660  // Update the UDP metadata
661  rph_udpMeta.src.port = rph_udpHeaderChunk.getUdpSrcPort();
662  rph_udpMeta.dst.port = rph_udpHeaderChunk.getUdpDstPort();
663  // Save the length of the datagram
664  rph_dgrmLen = rph_udpHeaderChunk.getUdpLen() - 8;
665  }
666  else {
667  rph_emptyPayloadFlag = 1;
668  rph_dgrmLen = 0;
669  }
670  if (DEBUG_LEVEL & TRACE_RPH) {
671  printInfo(myName, "FSM_RPH_IDLE - Receive new datagram (UdpLen=%d)\n",
672  rph_udpHeaderChunk.getUdpLen().to_ushort());
673  }
674  rph_fsmState = FSM_RPH_PORT_LOOKUP;
675  }
676  break;
677  case FSM_RPH_PORT_LOOKUP:
678  if (!siUpt_PortStateRep.empty() and !siUcc_CsumVal.empty() and
679  !siIhs_Ip4Hdr.empty() and !soUAIF_DLen.full()) {
680  bool csumResult = siUcc_CsumVal.read();
681  bool portLkpRes = siUpt_PortStateRep.read();
682  // Read the 2nd IPv4 header chunk and update the metadata structure
683  siIhs_Ip4Hdr.read(rph_2ndIp4HdrChunk);
684  rph_udpMeta.src.addr = rph_2ndIp4HdrChunk.getIp4SrcAddr();
685  if (DEBUG_LEVEL & TRACE_RPH) {
686  printInfo(myName, "FSM_RPH_PORT_LOOKUP - CsumValid=%d and portLkpRes=%d.\n",
687  csumResult, portLkpRes);
688  }
689  if(portLkpRes and csumResult) {
690  soUAIF_DLen.write(rph_dgrmLen);
691  rph_fsmState = FSM_RPH_STREAM_FIRST;
692  }
693  else if (not csumResult) {
694  rph_fsmState = FSM_RPH_DRAIN_DATAGRAM_STREAM;
695  }
696  else {
697  rph_fsmState = FSM_RPH_PORT_UNREACHABLE_1ST;
698  }
699  }
700  break;
701  case FSM_RPH_STREAM_FIRST:
702  if (DEBUG_LEVEL & TRACE_RPH) { printInfo(myName, "FSM_RPH_STREAM_FIRST \n"); }
703  if (!siUcc_UdpDgrm.empty() and !siIhs_Ip4Hdr.empty() and
704  !soUAIF_Data.full() and !soUAIF_Meta.full()) {
705  // Read the 3rd IPv4 header chunk, update and forward the metadata
706  AxisIp4 thirdIp4HdrChunk;
707  siIhs_Ip4Hdr.read(thirdIp4HdrChunk);
708  rph_udpMeta.dst.addr = thirdIp4HdrChunk.getIp4DstAddr();
709  if (thirdIp4HdrChunk.getTLast()) {
710  rph_doneWithIpHdrStream = true;
711  }
712  AxisUdp dgrmChunk;
713  if (not rph_emptyPayloadFlag) {
714  soUAIF_Meta.write(rph_udpMeta);
715  // Read the 1st datagram chunk and forward to [UAIF]
716  siUcc_UdpDgrm.read(dgrmChunk);
717  soUAIF_Data.write(UdpAppData(dgrmChunk));
718  }
719  if (dgrmChunk.getTLast() or rph_emptyPayloadFlag) {
720  if (thirdIp4HdrChunk.getTLast()) {
721  // Both incoming stream are empty. We are done.
722  rph_fsmState = FSM_RPH_IDLE;
723  }
724  else {
725  // They were options chunk that remain to be drained
726  rph_fsmState = FSM_RPH_DRAIN_IP4HDR_STREAM;
727  }
728  }
729  else {
730  rph_fsmState = FSM_RPH_STREAM;
731  }
732  }
733  break;
734  case FSM_RPH_STREAM:
735  if (!siUcc_UdpDgrm.empty() and !soUAIF_Data.full() and !soUAIF_Meta.full()) {
736  // Forward datagram chunk
737  AxisUdp dgrmChunk;
738  siUcc_UdpDgrm.read(dgrmChunk);
739  soUAIF_Data.write(UdpAppData(dgrmChunk));
740  if (DEBUG_LEVEL & TRACE_RPH) {
741  printInfo(myName, "FSM_RPH_STREAM\n");
742  }
743  if (dgrmChunk.getTLast()) {
744  if (rph_doneWithIpHdrStream) {
745  // Both incoming stream are empty. We are done.
746  rph_fsmState = FSM_RPH_IDLE;
747  }
748  else {
749  // They are IPv4 header chunk that remain to be drained
750  rph_fsmState = FSM_RPH_DRAIN_IP4HDR_STREAM;
751  }
752  }
753  else if (!siIhs_Ip4Hdr.empty() and not rph_doneWithIpHdrStream) {
754  // Drain any pending IPv4 header chunk
755  AxisIp4 currIp4HdrChunk;
756  siIhs_Ip4Hdr.read(currIp4HdrChunk);
757  if (currIp4HdrChunk.getTLast()) {
758  rph_doneWithIpHdrStream = true;
759  // Both incoming stream are empty. We are done.
760  // rph_fsmState = FSM_RPH_IDLE;
761  }
762  }
763  }
764  break;
765  case FSM_RPH_DRAIN_DATAGRAM_STREAM:
766  //-- Drop and drain the entire datagram
767  if (!siUcc_UdpDgrm.empty()) {
768  AxisUdp currChunk;
769  siUcc_UdpDgrm.read(currChunk);
770  if (DEBUG_LEVEL & TRACE_RPH) {
771  printInfo(myName, "FSM_RPH_DRAIN_DATAGRAM_STREAM -\n");
772  }
773  if (currChunk.getTLast()) {
774  if (rph_doneWithIpHdrStream) {
775  // Both incoming stream are empty. We are done.
776  rph_fsmState = FSM_RPH_IDLE;
777  }
778  else {
779  // Now go and drain the corresponding IPV4 header stream
780  rph_fsmState = FSM_RPH_DRAIN_IP4HDR_STREAM;
781  }
782  }
783  }
784  break;
785  case FSM_RPH_DRAIN_IP4HDR_STREAM :
786  //-- Drain the IPv4 Header Stream
787  if (!siIhs_Ip4Hdr.empty()) {
788  AxisIp4 currChunk;
789  siIhs_Ip4Hdr.read(currChunk);
790  if (DEBUG_LEVEL & TRACE_RPH) {
791  printInfo(myName, "FSM_RPH_DRAIN_IP4HDR_STREAM -\n");
792  }
793  if (currChunk.getTLast()) {
794  rph_fsmState = FSM_RPH_IDLE;
795  }
796  }
797  break;
798  case FSM_RPH_PORT_UNREACHABLE_1ST:
799  if (!soICMP_Data.full()) {
800  // Forward the 1st chunk of the IPv4 header
801  soICMP_Data.write(rph_1stIp4HdrChunk);
802  if (DEBUG_LEVEL & TRACE_RPH) {
803  printInfo(myName, "FSM_RPH_PORT_UNREACHABLE_1ST -\n");
804  }
805  rph_fsmState = FSM_RPH_PORT_UNREACHABLE_2ND;
806  }
807  break;
808  case FSM_RPH_PORT_UNREACHABLE_2ND:
809  if (!soICMP_Data.full()) {
810  // Forward the 2nd chunk of the IPv4 header
811  soICMP_Data.write(rph_2ndIp4HdrChunk);
812  if (DEBUG_LEVEL & TRACE_RPH) {
813  printInfo(myName, "FSM_RPH_PORT_UNREACHABLE_2ND -\n");
814  }
815  rph_fsmState = FSM_RPH_PORT_UNREACHABLE_STREAM;
816  }
817  break;
818  case FSM_RPH_PORT_UNREACHABLE_STREAM:
819  if (!siIhs_Ip4Hdr.empty() and !soICMP_Data.full()) {
820  // Forward remaining of the IPv4 header chunks
821  AxisIp4 ip4Chunk;
822  siIhs_Ip4Hdr.read(ip4Chunk);
823  // Always clear the LAST bit because the UDP header will follow
824  soICMP_Data.write(AxisIcmp(ip4Chunk.getLE_TData(), ip4Chunk.getLE_TKeep(), 0));
825  if (DEBUG_LEVEL & TRACE_RPH) {
826  printInfo(myName, "FSM_RPH_PORT_UNREACHABLE_STREAM -\n");
827  }
828  if (ip4Chunk.getTLast()) {
829  rph_doneWithIpHdrStream = true;
830  rph_fsmState = FSM_RPH_PORT_UNREACHABLE_LAST;
831  }
832  }
833  break;
834  case FSM_RPH_PORT_UNREACHABLE_LAST:
835  if (DEBUG_LEVEL & TRACE_RPH) { printInfo(myName, "FSM_RPH_PORT_UNREACHABLE_LAST -\n"); }
836  if (!soICMP_Data.full()) {
837  // Forward the first 8 bytes of the datagram (.i.e, the UDP header)
838  soICMP_Data.write(AxisIcmp(rph_udpHeaderChunk.getLE_TData(), rph_udpHeaderChunk.getLE_TKeep(), TLAST));
839  rph_fsmState = FSM_RPH_DRAIN_DATAGRAM_STREAM;
840  }
841  break;
842  } // End-of: switch()
843 }
UdpLen getUdpLen()
Definition: AxisUdp.hpp:140
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
#define TRACE_RPH
Definition: uoe.cpp:73
ap_uint< 1 > FlagBit
Definition: nts_types.hpp:110
bool FlagBool
Definition: nts_types.hpp:124
AxisRaw UdpAppData
Definition: nts.hpp:214
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pTxApplicationInterface()

void pTxApplicationInterface ( CmdBit  piMMIO_En,
stream< UdpAppData > &  siUAIF_Data,
stream< UdpAppMeta > &  siUAIF_Meta,
stream< UdpAppDLen > &  siUAIF_DLen,
stream< UdpAppData > &  soTdh_Data,
stream< UdpAppMeta > &  soTdh_Meta,
stream< UdpAppDLen > &  soTdh_DLen 
)

Tx Application Interface (Tai)

Parameters
[in]piMMIO_EnEnable signal from [SHELL/MMIO].
[in]siUAIF_DataData stream from UserAppInterface (UAIF).
[in]siUAIF_MetaMetadata from [UAIF].
[in]siUAIF_DLenData payload length from [UAIF].
[out]soTdh_DataData stream to UdpHeaderAdder (Uha).
[out]soTdh_MetaMetadata stream to [Uha].
[out]soTdh_DLenData payload length to [Uha].

This process is the front-end interface to the Tx part of the Udp Application Interface (UAIF). The APP must provide the data as a stream of 'AxisRaw' chunks, and every stream must be accompanied by a metadata and payload length information. The metadata specifies the socket-pair that the stream belongs to, while the payload length specifies its length. Two modes of operations are supported by the UDP application interface: 1) DATAGRAM_MODE: If the 'DLen' field is loaded with a length != 0, this length is used as reference for handling the corresponding stream. If the length is larger than UDP_MDS bytes (.i.e, MTU_ZYC2-IP_HEADER_LEN-UDP_HEADER_LEN), this process will split the incoming datagram and generate as many sub-datagrams as required to transport all 'DLen' bytes over Ethernet frames. 2) STREAMING_MODE: If the 'DLen' field is configured with a length == 0, the corresponding stream will be forwarded based on the same metadata information until the 'TLAST' bit of the data stream is set. In this mode, the UOE will wait for the reception of UDP_MDS bytes before generating a new UDP-over-IPv4 packet, unless the 'TLAST' bit of the data stream is set.

Warning
In DATAGRAM_MODE, the setting of the 'TLAST' bit of the data stream is not required but highly recommended. In STREAMING_MODE, it is the responsibility of the application to set the 'TLAST' bit to avoid a connection from monopolizing the UOE indefinitely.

Definition at line 1101 of file uoe.cpp.

1109 {
1110  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
1111  #pragma HLS INLINE off
1112  #pragma HLS pipeline II=1 enable_flush
1113 
1114  const char *myName = concat3(THIS_NAME, "/TXe/", "Tai");
1115 
1116  //-- STATIC CONTROL VARIABLES (with RESET) --------------------------------
1117  static enum FsmStates { FSM_TAI_IDLE=0,
1118  FSM_TAI_DRGM_DATA, FSM_TAI_DRGM_META,
1119  FSM_TAI_STRM_DATA, FSM_TAI_STRM_META,
1120  } tai_fsmState=FSM_TAI_IDLE;
1121  #pragma HLS RESET variable=tai_fsmState
1122  static FlagBool tai_streamMode=false;
1123  #pragma HLS RESET variable=tai_streamMode
1124 
1125  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
1126  static UdpAppMeta tai_appMeta; // The socket-pair information
1127  static UdpAppDLen tai_appDLen; // Application's datagram length (0 to 2^16)
1128  static UdpAppDLen tai_splitCnt; // Split counter (from 0 to 1422-1)
1129 
1130  switch(tai_fsmState) {
1131  case FSM_TAI_IDLE:
1132  if (!siUAIF_Meta.empty() and !siUAIF_DLen.empty() and (piMMIO_En == CMD_ENABLE)) {
1133  siUAIF_Meta.read(tai_appMeta);
1134  siUAIF_DLen.read(tai_appDLen);
1135  if (tai_appDLen == 0) {
1136  tai_streamMode = true;
1137  tai_fsmState = FSM_TAI_STRM_DATA;
1138  }
1139  else {
1140  tai_streamMode = false;
1141  tai_fsmState = FSM_TAI_DRGM_DATA;
1142  }
1143  tai_splitCnt = 0;
1144  if (DEBUG_LEVEL & TRACE_TAI) { printInfo(myName, "FSM_TAI_IDLE\n"); }
1145  }
1146  //[TODO] else if (!siUAIF_Data.empty() and soTdh_Data.full() ) {
1147  // In streaming-mode, we may accept up to the depth of 'ssTaiToTdh_Data'
1148  // bytes to be received ahead of the pair {Meta, DLen}
1149  // siUAIF_Meta.read(tai_appMeta);
1150  //}
1151  break;
1152  case FSM_TAI_DRGM_DATA:
1153  if (!siUAIF_Data.empty() and !soTdh_Data.full() ) {
1154  //-- Forward data in 'datagram' mode
1155  UdpAppData currChunk = siUAIF_Data.read();
1156  tai_appDLen -= currChunk.getLen();
1157  tai_splitCnt += currChunk.getLen();
1158  if ((tai_appDLen == 0) or (tai_splitCnt == UDP_MDS)) {
1159  // Always enforce TLAST
1160  currChunk.setTLast(TLAST);
1161  tai_fsmState = FSM_TAI_DRGM_META;
1162  }
1163  soTdh_Data.write(currChunk);
1164  if (DEBUG_LEVEL & TRACE_TAI) {
1165  printInfo(myName, "FSM_TAI_DRGM_DATA - DLen=%4d - Remainder=%5d \n",
1166  tai_splitCnt.to_ushort(), tai_appDLen.to_ushort());
1167  }
1168  }
1169  break;
1170  case FSM_TAI_DRGM_META:
1171  if (!soTdh_Meta.full() and !soTdh_DLen.full()) {
1172  //-- Forward metadata and length in 'datagram' mode
1173  soTdh_Meta.write(tai_appMeta);
1174  soTdh_DLen.write(tai_splitCnt);
1175  if (tai_appDLen == 0) {
1176  tai_fsmState = FSM_TAI_IDLE;
1177  }
1178  else {
1179  tai_fsmState = FSM_TAI_DRGM_DATA;
1180  tai_splitCnt = 0;
1181  }
1182  if (DEBUG_LEVEL & TRACE_TAI) {
1183  printInfo(myName, "FSM_TAI_DRGM_META - DLen=%4d - Remainder=0 \n",
1184  tai_splitCnt.to_ushort(), tai_appDLen.to_ushort());
1185  }
1186  }
1187  break;
1188  case FSM_TAI_STRM_DATA:
1189  if (!siUAIF_Data.empty() and !soTdh_Data.full() ) {
1190  //-- Forward data in 'streaming' mode
1191  UdpAppData currChunk = siUAIF_Data.read();
1192  tai_appDLen -= currChunk.getLen();
1193  tai_splitCnt += currChunk.getLen();
1194  if (currChunk.getTLast()) {
1195  tai_streamMode = false;
1196  tai_fsmState = FSM_TAI_STRM_META;
1197  }
1198  else if (tai_splitCnt == UDP_MDS) {
1199  // Always enforce TLAST
1200  currChunk.setTLast(TLAST);
1201  tai_fsmState = FSM_TAI_STRM_META;
1202  }
1203  soTdh_Data.write(currChunk);
1204  if (DEBUG_LEVEL & TRACE_TAI) {
1205  printInfo(myName, "FSM_TAI_STRM_DATA - DLen=%4d \n",
1206  tai_splitCnt.to_ushort());
1207  }
1208  }
1209  break;
1210  case FSM_TAI_STRM_META:
1211  if (!soTdh_Meta.full() and !soTdh_DLen.full()) {
1212  //-- Forward metadata and length in 'datagram' mode
1213  soTdh_Meta.write(tai_appMeta);
1214  soTdh_DLen.write(tai_splitCnt);
1215  if (tai_streamMode == false) {
1216  tai_fsmState = FSM_TAI_IDLE;
1217  }
1218  else {
1219  tai_fsmState = FSM_TAI_STRM_DATA;
1220  tai_splitCnt = 0;
1221  }
1222  if (DEBUG_LEVEL & TRACE_TAI) {
1223  printInfo(myName, "FSM_TAI_STRM_META - DLen=%4d - Remainder=0 \n",
1224  tai_splitCnt.to_ushort(), tai_appDLen.to_ushort());
1225  }
1226  }
1227  break;
1228  }
1229 }
int getLen() const
Definition: AxisRaw.hpp:411
UdpLen UdpAppDLen
Definition: nal.hpp:255
#define TRACE_TAI
Definition: uoe.cpp:74
#define CMD_ENABLE
Definition: nts_types.hpp:63
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pTxDatagramHandler()

void pTxDatagramHandler ( stream< UdpAppData > &  siUAIF_Data,
stream< UdpAppMeta > &  siUAIF_Meta,
stream< UdpAppDLen > &  siUAIF_DLen,
stream< UdpAppData > &  soUha_Data,
stream< UdpAppMeta > &  soUha_Meta,
stream< UdpAppDLen > &  soUha_DLen,
stream< AxisPsd4 > &  soUca_Data 
)

Tx Datagram Handler (Tdh)

Parameters
[in]siUAIF_DataData stream from UserAppInterface (UAIF).
[in]siUAIF_MetaMetadata stream from [UAIF].
[in]siUAIF_DLenData payload length from [UAIF].
[out]soUha_DataData stream to UdpHeaderAdder (Uha).
[out]soUha_MetaMetadata stream to [Uha].
[out]soUha_DLenData payload length to [Uha].
[out]soUca_DataUDP data stream to UdpChecksumAccumulator (Uca).

This process handles the raw data coming from the UdpAppInterface (UAIF). Data are received as a stream from the application layer. They come with a metadata information that specifies the connection the data belong to, as well as a data-length information. Two main tasks are performed by this process: 1) a UDP pseudo-packet is generated and forwarded to the process UdpChecksumAccumulator (Uca) which will compute the UDP checksum. 2) the length of the incoming data stream is measured while the AppData is streamed forward to the process UdpHeaderAdder (Uha).

Definition at line 1254 of file uoe.cpp.

1262 {
1263  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
1264  #pragma HLS INLINE off
1265  #pragma HLS pipeline II=1 enable_flush
1266 
1267  const char *myName = concat3(THIS_NAME, "/TXe/", "Tdh");
1268 
1269  //-- STATIC CONTROL VARIABLES (with RESET) --------------------------------
1270  static enum FsmStates { FSM_TDH_PSD_PKT1=0, FSM_TDH_PSD_PKT2, FSM_TDH_PSD_PKT3,
1271  FSM_TDH_PSD_PKT4, FSM_TDH_STREAM, FSM_TDH_PSD_RESIDUE,
1272  FSM_TDH_LAST } tdh_fsmState=FSM_TDH_PSD_PKT1;
1273  #pragma HLS RESET variable=tdh_fsmState
1274 
1275  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
1276  static UdpAppData tdh_currChunk;
1277  static UdpAppMeta tdh_udpMeta;
1278  static UdpAppDLen tdh_appLen; // The length of the application data stream
1279  static UdpLen tdh_udpLen; // the length of the UDP datagram stream
1280 
1281  switch(tdh_fsmState) {
1282  case FSM_TDH_PSD_PKT1:
1283  if (!siUAIF_Meta.empty() and
1284  !soUha_Meta.full() and !soUca_Data.full()) {
1285  siUAIF_Meta.read(tdh_udpMeta);
1286  // Generate 1st pseudo-packet chunk [DA|SA]
1287  AxisPsd4 firstPseudoPktChunk(0, 0xFF, 0);
1288  firstPseudoPktChunk.setPsd4SrcAddr(tdh_udpMeta.ip4SrcAddr);
1289  firstPseudoPktChunk.setPsd4DstAddr(tdh_udpMeta.ip4DstAddr);
1290  // Forward & next
1291  soUca_Data.write(firstPseudoPktChunk);
1292  soUha_Meta.write(tdh_udpMeta);
1293  tdh_fsmState = FSM_TDH_PSD_PKT2;
1294  if (DEBUG_LEVEL & TRACE_TDH) {
1295  printInfo(myName, "FSM_TDH_PSD_PKT1 - Receive new metadata information.\n");
1296  SocketPair socketPair(SockAddr(tdh_udpMeta.ip4SrcAddr, tdh_udpMeta.udpSrcPort), SockAddr(tdh_udpMeta.ip4DstAddr, tdh_udpMeta.udpDstPort));
1297  printSockPair(myName, socketPair);
1298  }
1299  }
1300  break;
1301  case FSM_TDH_PSD_PKT2:
1302  if (!siUAIF_DLen.empty() and
1303  !soUha_DLen.full() and !soUca_Data.full()) {
1304  siUAIF_DLen.read(tdh_appLen);
1305  // Generate UDP length from incoming payload length
1306  tdh_udpLen = tdh_appLen + UDP_HEADER_LEN;
1307  // Generate 2nd pseudo-packet chunk [DP|SP|Len|Prot|0x00]
1308  AxisPsd4 secondPseudoPktChunk(0, 0xFF, 0);
1309  secondPseudoPktChunk.setPsd4Prot(IP4_PROT_UDP);
1310  secondPseudoPktChunk.setPsd4Len(tdh_udpLen);
1311  secondPseudoPktChunk.setUdpSrcPort(tdh_udpMeta.udpSrcPort);
1312  secondPseudoPktChunk.setUdpDstPort(tdh_udpMeta.udpDstPort);
1313  // Forward & next
1314  soUha_DLen.write(tdh_appLen);
1315  soUca_Data.write(secondPseudoPktChunk);
1316  tdh_fsmState = FSM_TDH_PSD_PKT3;
1317  }
1318  if (DEBUG_LEVEL & TRACE_TDH) { printInfo(myName, "FSM_TDH_PSD_PKT2\n"); }
1319  break;
1320  case FSM_TDH_PSD_PKT3:
1321  if (!siUAIF_Data.empty() and
1322  !soUca_Data.full() and !soUha_Data.full()) {
1323  // Read 1st data payload chunk
1324  siUAIF_Data.read(tdh_currChunk);
1325  // Generate 3rd pseudo-packet chunk [Data|Csum|Len]
1326  AxisPsd4 thirdPseudoPktChunk(0, 0xFF, 0);
1327  thirdPseudoPktChunk.setUdpLen(tdh_udpLen);
1328  thirdPseudoPktChunk.setUdpCsum(0x0000);
1329  thirdPseudoPktChunk.setTDataLo(tdh_currChunk.getTDataHi());
1330  if (tdh_currChunk.getTLast()) {
1331  tdh_currChunk.clearUnusedBytes();
1332  soUha_Data.write(tdh_currChunk);
1333  if (tdh_currChunk.getTKeepLo() == 0) {
1334  // Done. Payload <= 4 bytes fits into current pseudo-pkt
1335  tdh_fsmState = FSM_TDH_PSD_PKT1;
1336  thirdPseudoPktChunk.setTKeepLo(tdh_currChunk.getTKeepHi());
1337  thirdPseudoPktChunk.setTLast(TLAST);
1338  }
1339  else {
1340  // Needs an additional pseudo-pkt-chunk for remaining 1-4 bytes
1341  tdh_fsmState = FSM_TDH_PSD_PKT4;
1342  }
1343  }
1344  else {
1345  tdh_fsmState = FSM_TDH_STREAM;
1346  }
1347  soUca_Data.write(thirdPseudoPktChunk);
1348  }
1349  if (DEBUG_LEVEL & TRACE_TDH) { printInfo(myName, "FSM_TDH_PSD_PKT3\n"); }
1350  break;
1351  case FSM_TDH_PSD_PKT4:
1352  if (!soUca_Data.full()) {
1353  // Generate 4th and last pseudo-packet chunk to hold remaining 1-4 bytes
1354  AxisPsd4 fourthPseudoPktChunk(0, 0x00, TLAST);
1355  fourthPseudoPktChunk.setTDataHi(tdh_currChunk.getTDataLo());
1356  fourthPseudoPktChunk.setTKeepHi(tdh_currChunk.getTKeepLo());
1357  soUca_Data.write(fourthPseudoPktChunk);
1358  tdh_fsmState = FSM_TDH_PSD_PKT1;
1359  }
1360  if (DEBUG_LEVEL & TRACE_TDH) { printInfo(myName, "FSM_TDH_PSD_PKT4\n"); }
1361  break;
1362  case FSM_TDH_STREAM:
1363  // This state streams both the pseudo-packet chunks into the checksum
1364  // calculation stage and the next stage
1365  if (!siUAIF_Data.empty() and
1366  !soUha_Data.full() and !soUca_Data.full()) {
1367  // Always forward the current AppData chunk to next-stage [Uha]
1368  soUha_Data.write(tdh_currChunk);
1369  // Save previous AppData and read a new one from [UAIF]
1370  AxisPsd4 currPseudoChunk(0, 0xFF, 0);
1371  UdpAppData prevAppDataChunk(tdh_currChunk);
1372  siUAIF_Data.read(tdh_currChunk);
1373  // Generate new pseudo-packet chunk
1374  currPseudoChunk.setTDataHi(prevAppDataChunk.getTDataLo());
1375  currPseudoChunk.setTDataLo(tdh_currChunk.getTDataHi());
1376  if (tdh_currChunk.getTLast()) {
1377  if (tdh_currChunk.getTKeepLo() != 0) {
1378  // Last AppData chunk won't fit in current pseudo-chunk.
1379  tdh_fsmState = FSM_TDH_PSD_RESIDUE;
1380  }
1381  else {
1382  // Done. Payload <= 4 bytes fits into current pseudo-pkt
1383  tdh_fsmState = FSM_TDH_LAST;
1384  currPseudoChunk.setTKeepLo(tdh_currChunk.getTKeepHi());
1385  currPseudoChunk.setTLast(TLAST);
1386  }
1387  }
1388  soUca_Data.write(currPseudoChunk);
1389  }
1390  if (DEBUG_LEVEL & TRACE_TDH) { printInfo(myName, "FSM_TDH_STREAM\n"); }
1391  break;
1392  case FSM_TDH_LAST:
1393  if (!soUha_Data.full()) {
1394  soUha_Data.write(tdh_currChunk);
1395  tdh_fsmState = FSM_TDH_PSD_PKT1;
1396  }
1397  if (DEBUG_LEVEL & TRACE_TDH) { printInfo(myName, "FSM_TDH_LAST\n"); }
1398  break;
1399  case FSM_TDH_PSD_RESIDUE:
1400  if (!soUha_Data.full() and !soUca_Data.full()) {
1401  // Always forward the last AppData chunk
1402  soUha_Data.write(tdh_currChunk);
1403  // Generate the last pseudo-packet chunk and forward it to [Uca]
1404  AxisPsd4 lastPseudoPktChunk(0, 0x00, TLAST);
1405  lastPseudoPktChunk.setTDataHi(tdh_currChunk.getTDataLo());
1406  lastPseudoPktChunk.setTKeepHi(tdh_currChunk.getTKeepLo());
1407  soUca_Data.write(lastPseudoPktChunk);
1408  tdh_fsmState = FSM_TDH_PSD_PKT1;
1409  }
1410  if (DEBUG_LEVEL & TRACE_TDH) { printInfo(myName, "FSM_TDH_PSD_RESIDUE\n"); }
1411  break;
1412  }
1413 }
void clearUnusedBytes()
Definition: AxisRaw.hpp:391
Ly4Port udpDstPort
Definition: nts.hpp:229
Ly4Port udpSrcPort
Definition: nts.hpp:227
Ip4Addr ip4SrcAddr
Definition: nts.hpp:226
Ip4Addr ip4DstAddr
Definition: nts.hpp:228
#define TRACE_TDH
Definition: uoe.cpp:75
#define UDP_HEADER_LEN
Definition: AxisUdp.hpp:81
void printSockPair(const char *callerName, SocketPair sockPair)
Print a socket pair association.
Definition: nts_utils.cpp:114
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pTxEngine()

void pTxEngine ( CmdBit  piMMIO_En,
stream< UdpAppData > &  siUAIF_Data,
stream< UdpAppMeta > &  siUAIF_Meta,
stream< UdpAppDLen > &  siUAIF_DLen,
stream< AxisIp4 > &  soIPTX_Data 
)

Tx Engine (TXe)

Parameters
[in]piMMIO_EnEnable signal from [SHELL/MMIO].
[in]siUAIF_DataData stream from UserAppInterface (UAIF).
[in]siUAIF_MetaMetadata stream from [UAIF].
[in]siUAIF_DLenData length from [UAIF].
[out]soIPTX_DataData stream to IpTxHandler (IPTX).

The Tx path of the UdpOffloadEngine (UOE). This is the path from the UdpAppInterface (UAIF).

Definition at line 1718 of file uoe.cpp.

1724 {
1725  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
1726  #pragma HLS INLINE
1727 
1728  const char *myName = concat3(THIS_NAME, "/", "TXe");
1729 
1730  //-------------------------------------------------------------------------
1731  //-- LOCAL STREAMS (Sorted by the name of the modules which generate them)
1732  //-------------------------------------------------------------------------
1733 
1734  //-- Tx Application Interface (Tai)
1735  static stream<UdpAppData> ssTaiToTdh_Data ("ssTaiToTdh_Data");
1736  #pragma HLS STREAM variable=ssTaiToTdh_Data depth=1024
1737  static stream<UdpAppMeta> ssTaiToTdh_Meta ("ssTaiToTdh_Meta");
1738  #pragma HLS STREAM variable=ssTaiToTdh_Meta depth=32
1739  #pragma HLS DATA_PACK variable=ssTaiToTdh_Meta
1740  static stream<UdpAppDLen> ssTaiToTdh_DLen ("ssTaiToTdh_DLen");
1741  #pragma HLS STREAM variable=ssTaiToTdh_DLen depth=32
1742 
1743  //-- Tx Datagram Handler (Tdh)
1744  static stream<UdpAppData> ssTdhToUha_Data ("ssTdhToUha_Data");
1745  #pragma HLS STREAM variable=ssTdhToUha_Data depth=1024
1746  static stream<UdpAppMeta> ssTdhToUha_Meta ("ssTdhToUha_Meta");
1747  #pragma HLS STREAM variable=ssTdhToUha_Meta depth=32
1748  #pragma HLS DATA_PACK variable=ssTdhToUha_Meta
1749  static stream<UdpAppDLen> ssTdhToUha_DLen ("ssTdhToUha_DLen");
1750  #pragma HLS STREAM variable=ssTdhToUha_DLen depth=32
1751  static stream<AxisPsd4> ssTdhToUca_Data ("ssTdhToUca_Data");
1752  #pragma HLS STREAM variable=ssTdhToUca_Data depth=8
1753 
1754  // UdpChecksumAccumulator (Uca)
1755  static stream<UdpCsum> ssUcaToUha_Csum ("ssUcaToUha_Csum");
1756  #pragma HLS STREAM variable=ssUcaToUha_Csum depth=32
1757 
1758  // UdpHeaderAdder (Uha)
1759  static stream<AxisUdp> ssUhaToIha_Data ("ssUhaToIha_Data");
1760  #pragma HLS STREAM variable=ssUhaToIha_Data depth=1024
1761  static stream<UdpLen> ssUhaToIha_UdpLen ("ssUhaToIha_UdpLen");
1762  #pragma HLS STREAM variable=ssUhaToIha_UdpLen depth=32
1763  static stream<IpAddrPair> ssUhaToIha_IpPair ("ssUhaToIha_IpPair");
1764  #pragma HLS STREAM variable=ssUhaToIha_IpPair depth=32
1765  #pragma HLS DATA_PACK variable=ssUhaToIha_IpPair
1766 
1767  //-------------------------------------------------------------------------
1768  //-- PROCESS FUNCTIONS
1769  //-------------------------------------------------------------------------
1770 
1772  piMMIO_En,
1773  siUAIF_Data,
1774  siUAIF_Meta,
1775  siUAIF_DLen,
1776  ssTaiToTdh_Data,
1777  ssTaiToTdh_Meta,
1778  ssTaiToTdh_DLen);
1779 
1781  ssTaiToTdh_Data,
1782  ssTaiToTdh_Meta,
1783  ssTaiToTdh_DLen,
1784  ssTdhToUha_Data,
1785  ssTdhToUha_Meta,
1786  ssTdhToUha_DLen,
1787  ssTdhToUca_Data);
1788 
1790  ssTdhToUca_Data,
1791  ssUcaToUha_Csum);
1792 
1794  ssTdhToUha_Data,
1795  ssTdhToUha_DLen,
1796  ssTdhToUha_Meta,
1797  ssUcaToUha_Csum,
1798  ssUhaToIha_Data,
1799  ssUhaToIha_IpPair,
1800  ssUhaToIha_UdpLen);
1801 
1803  ssUhaToIha_Data,
1804  ssUhaToIha_IpPair,
1805  ssUhaToIha_UdpLen,
1806  soIPTX_Data);
1807 
1808 }
void pUdpChecksumAccumulator(stream< AxisPsd4 > &siTdh_Data, stream< UdpCsum > &soUha_Csum)
Definition: uoe.cpp:1415
void pIp4HeaderAdder(stream< AxisUdp > &siUha_Data, stream< IpAddrPair > &siUha_IpPair, stream< UdpLen > &siUha_UdpLen, stream< AxisIp4 > &soIPTX_Data)
Definition: uoe.cpp:1599
void pTxApplicationInterface(CmdBit piMMIO_En, stream< UdpAppData > &siUAIF_Data, stream< UdpAppMeta > &siUAIF_Meta, stream< UdpAppDLen > &siUAIF_DLen, stream< UdpAppData > &soTdh_Data, stream< UdpAppMeta > &soTdh_Meta, stream< UdpAppDLen > &soTdh_DLen)
Definition: uoe.cpp:1101
void pTxDatagramHandler(stream< UdpAppData > &siUAIF_Data, stream< UdpAppMeta > &siUAIF_Meta, stream< UdpAppDLen > &siUAIF_DLen, stream< UdpAppData > &soUha_Data, stream< UdpAppMeta > &soUha_Meta, stream< UdpAppDLen > &soUha_DLen, stream< AxisPsd4 > &soUca_Data)
Definition: uoe.cpp:1254
void pUdpHeaderAdder(stream< UdpAppData > &siTdh_Data, stream< UdpAppDLen > &siTdh_DLen, stream< UdpAppMeta > &siTdh_Meta, stream< UdpCsum > &siUca_Csum, stream< AxisUdp > &soIha_Data, stream< IpAddrPair > &soIha_IpPair, stream< UdpLen > &soIha_UdpLen)
Definition: uoe.cpp:1516
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pUdpChecksumAccumulator()

void pUdpChecksumAccumulator ( stream< AxisPsd4 > &  siTdh_Data,
stream< UdpCsum > &  soUha_Csum 
)

Definition at line 1415 of file uoe.cpp.

1418 {
1419  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1420  #pragma HLS INLINE off
1421  #pragma HLS PIPELINE II=1 enable_flush
1422 
1423  const char *myName = concat3(THIS_NAME, "/TXe/", "Uca");
1424 
1425  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1426  static enum FsmStates { FSM_UCA_ACCUMULATE=0, FSM_UCA_LAST, FSM_UCA_DONE } \
1427  uca_fsmState=FSM_UCA_ACCUMULATE;
1428  #pragma HLS RESET variable=uca_fsmState
1429  static ap_uint<17> uca_csum0;
1430  #pragma HLS RESET variable=uca_csum0
1431  static ap_uint<17> uca_csum1;
1432  #pragma HLS RESET variable=uca_csum1
1433  static ap_uint<17> uca_csum2;
1434  #pragma HLS RESET variable=uca_csum2
1435  static ap_uint<17> uca_csum3;
1436  #pragma HLS RESET variable=uca_csum3
1437  static AxisPsd4 uca_lastChunk;
1438  #pragma HLS RESET variable=uca_lastChunk
1439 
1440  switch (uca_fsmState) {
1441  case FSM_UCA_ACCUMULATE:
1442  if (!siTdh_Data.empty()) {
1443  AxisPsd4 currChunk = siTdh_Data.read();
1444  if (currChunk.getTLast()) {
1445  uca_lastChunk = currChunk;
1446  uca_lastChunk.clearUnusedBytes();
1447  uca_fsmState = FSM_UCA_LAST;
1448  }
1449  else {
1450  uca_csum0 += byteSwap16(currChunk.getLE_TData().range(63, 48));
1451  uca_csum0 = (uca_csum0 & 0xFFFF) + (uca_csum0 >> 16);
1452  uca_csum1 += byteSwap16(currChunk.getLE_TData().range(47, 32));
1453  uca_csum1 = (uca_csum1 & 0xFFFF) + (uca_csum1 >> 16);
1454  uca_csum2 += byteSwap16(currChunk.getLE_TData().range(31, 16));
1455  uca_csum2 = (uca_csum2 & 0xFFFF) + (uca_csum2 >> 16);
1456  uca_csum3 += byteSwap16(currChunk.getLE_TData().range(15, 0));
1457  uca_csum3 = (uca_csum3 & 0xFFFF) + (uca_csum3 >> 16);
1458  }
1459  if (DEBUG_LEVEL & TRACE_UCA) {
1460  printAxisRaw(myName, "Received a new pseudo-header chunk: ", currChunk);
1461  }
1462  }
1463  break;
1464  case FSM_UCA_LAST:
1465  uca_csum0 += byteSwap16(uca_lastChunk.getLE_TData().range(63, 48));
1466  uca_csum0 = (uca_csum0 & 0xFFFF) + (uca_csum0 >> 16);
1467  uca_csum1 += byteSwap16(uca_lastChunk.getLE_TData().range(47, 32));
1468  uca_csum1 = (uca_csum1 & 0xFFFF) + (uca_csum1 >> 16);
1469  uca_csum2 += byteSwap16(uca_lastChunk.getLE_TData().range(31, 16));
1470  uca_csum2 = (uca_csum2 & 0xFFFF) + (uca_csum2 >> 16);
1471  uca_csum3 += byteSwap16(uca_lastChunk.getLE_TData().range(15, 0));
1472  uca_csum3 = (uca_csum3 & 0xFFFF) + (uca_csum3 >> 16);
1473  uca_fsmState = FSM_UCA_DONE;
1474  break;
1475  case FSM_UCA_DONE:
1476  if (!soUha_Csum.full()) {
1477  ap_uint<17> csum01, csum23, csum0123;
1478  csum01 = uca_csum0 + uca_csum1;
1479  csum01 = (csum01 & 0xFFFF) + (csum01 >> 16);
1480  csum23 = uca_csum2 + uca_csum3;
1481  csum23 = (csum23 & 0xFFFF) + (csum23 >> 16);
1482  csum0123 = csum01 + csum23;
1483  csum0123 = (csum0123 & 0xFFFF) + (csum0123 >> 16);
1484  csum0123 = ~csum0123;
1485  soUha_Csum.write(csum0123.range(15, 0));
1486  //-- Clear the csum accumulators
1487  uca_csum0 = 0;
1488  uca_csum1 = 0;
1489  uca_csum2 = 0;
1490  uca_csum3 = 0;
1491  if (DEBUG_LEVEL & TRACE_UCA) {
1492  printInfo(myName, "End of pseudo-header packet.\n");
1493  }
1494  uca_fsmState = FSM_UCA_ACCUMULATE;
1495  break;
1496  }
1497  }
1498 }
#define TRACE_UCA
Definition: uoe.cpp:76
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:

◆ pUdpChecksumChecker()

void pUdpChecksumChecker ( stream< AxisUdp > &  siIhs_UdpDgrm,
stream< UdpCsum > &  siIhs_PsdHdrSum,
stream< AxisUdp > &  soRph_UdpDgrm,
stream< ValBool > &  soRph_CsumVal,
stream< SigBit > &  soIhs_ClearToSend 
)

UDP Checksum Checker (Ucc)

Parameters
[in]siUcc_UdpDgrmUDP datagram stream from IpHeaderStripper (Ihs).
[in]siUcc_PsdHdrSumPseudo header sum (SA+DA+Prot+Len) from [Ihs].
[out]soRph_UdpDgrmUDP datagram stream to RxPacketHandler (Rph).
[out]soRph_CsumValChecksum valid information to [Rph].
[out]soIhs_ClearToSendClear to send signal to [Ihs].

This process accumulates the checksum over the UDP header and the UDP data. The computed checksum is compared with the embedded checksum when 'TLAST' is reached, and the result is forwarded to the RxPacketHandler (Rph). This process controls the total amount of data stored in the elastic buffer of the UOE. When issued, a 'soIhs_ClearToSend' signal indicates that the UOE is able to accept another datagram of up to MTU bytes.

Definition at line 430 of file uoe.cpp.

436 {
437  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
438  #pragma HLS INLINE off
439  #pragma HLS pipeline II=1 enable_flush
440 
441  const char *myName = concat3(THIS_NAME, "/RXe/", "Ucc");
442 
443  //-- STATIC CONTROL VARIABLES (with RESET) --------------------------------
444  static enum FsmStates { FSM_UCC_INIT=0, FSM_UCC_IDLE, FSM_UCC_START,
445  FSM_UCC_CHK0, FSM_UCC_CHK1, FSM_UCC_ACCUMULATE,
446  FSM_UCC_STREAM } ucc_fsmState=FSM_UCC_INIT;
447  #pragma HLS RESET variable=ucc_fsmState
448  static ap_uint<10> ucc_chunkCount=0;
449  #pragma HLS RESET variable=ucc_chunkCount
450 
451  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
452  static ap_uint<17> ucc_csum0;
453  static ap_uint<17> ucc_csum1;
454  static ap_uint<17> ucc_csum2;
455  static ap_uint<17> ucc_csum3;
456  static UdpCsum ucc_psdHdrCsum;
457 
458  //-- DYNAMIC VARIABLES ----------------------------------------------------
459  AxisUdp currChunk;
460 
461  switch (ucc_fsmState) {
462  case FSM_UCC_INIT:
463  // Initialize the first CTS token
464  soIhs_ClearToSend.write(1);
465  ucc_fsmState = FSM_UCC_IDLE;
466  break;
467  case FSM_UCC_IDLE:
468  if (!soIhs_ClearToSend.full()) {
469  // Init 2nd CTS token. We are now able to accept up 2 MTUs bytes
470  soIhs_ClearToSend.write(1);
471  ucc_fsmState = FSM_UCC_START;
472  }
473  break;
474  case FSM_UCC_START:
475  if (!siIhs_UdpDgrm.empty() and !siIhs_PsdHdrSum.empty() and
476  !soRph_UdpDgrm.full() and !soRph_CsumVal.full()) {
477  //-- READ 1st DTGM-CHUNK (CSUM|LEN|DP|SP)
478  siIhs_UdpDgrm.read(currChunk);
479  //-- READ the checksum of the pseudo header
480  siIhs_PsdHdrSum.read(ucc_psdHdrCsum);
481  // Always forward datagram to [Rph]
482  soRph_UdpDgrm.write(currChunk);
483  if (currChunk.getUdpCsum() == 0x0000) {
484  // An all zero transmitted checksum value means that the
485  // transmitter generated no checksum.
486  soRph_CsumVal.write(true);
487  ucc_fsmState = FSM_UCC_STREAM;
488  }
489  else {
490  // Accumulate the UDP header
491  ucc_csum0 = 0x00000 | currChunk.getUdpSrcPort();
492  ucc_csum0 += ucc_psdHdrCsum;
493  ucc_csum0 = (ucc_csum0 & 0xFFFF) + (ucc_csum0 >> 16);
494  ucc_csum1 = 0x00000 | currChunk.getUdpDstPort();
495  ucc_csum2 = 0x00000 | currChunk.getUdpLen();
496  ucc_csum3 = 0x00000 | currChunk.getUdpCsum();
497  if (currChunk.getUdpLen() == 8) {
498  // Payload is empty
499  ucc_fsmState = FSM_UCC_CHK0;
500  }
501  else {
502  ucc_fsmState = FSM_UCC_ACCUMULATE;
503  }
504  }
505  if (DEBUG_LEVEL & TRACE_UCC) { printAxisRaw(myName,"FSM_UCC_START -", currChunk); }
506  }
507  break;
508  case FSM_UCC_STREAM:
509  if (!siIhs_UdpDgrm.empty() and !soRph_UdpDgrm.full()) {
510  siIhs_UdpDgrm.read(currChunk);
511  soRph_UdpDgrm.write(currChunk);
512  if (currChunk.getTLast()) {
513  ucc_fsmState = FSM_UCC_IDLE;
514  }
515  if (DEBUG_LEVEL & TRACE_UCC) { printAxisRaw(myName,"FSM_UCC_STREAM - ", currChunk); }
516  }
517  break;
518  case FSM_UCC_ACCUMULATE:
519  if (!siIhs_UdpDgrm.empty() and !soRph_UdpDgrm.full()) {
520  siIhs_UdpDgrm.read(currChunk);
521  // Always set the disabled bytes to zero
522  LE_tData cleanChunk = 0;
523  if (currChunk.getLE_TKeep() & 0x01)
524  cleanChunk.range( 7, 0) = (currChunk.getLE_TData()).range( 7, 0);
525  if (currChunk.getLE_TKeep() & 0x02)
526  cleanChunk.range(15, 8) = (currChunk.getLE_TData()).range(15, 8);
527  if (currChunk.getLE_TKeep() & 0x04)
528  cleanChunk.range(23,16) = (currChunk.getLE_TData()).range(23,16);
529  if (currChunk.getLE_TKeep() & 0x08)
530  cleanChunk.range(31,24) = (currChunk.getLE_TData()).range(31,24);
531  if (currChunk.getLE_TKeep() & 0x10)
532  cleanChunk.range(39,32) = (currChunk.getLE_TData()).range(39,32);
533  if (currChunk.getLE_TKeep() & 0x20)
534  cleanChunk.range(47,40) = (currChunk.getLE_TData()).range(47,40);
535  if (currChunk.getLE_TKeep() & 0x40)
536  cleanChunk.range(55,48) = (currChunk.getLE_TData()).range(55,48);
537  if (currChunk.getLE_TKeep() & 0x80)
538  cleanChunk.range(63,56) = (currChunk.getLE_TData()).range(63,56);
539  soRph_UdpDgrm.write(AxisUdp(cleanChunk, currChunk.getLE_TKeep(), currChunk.getLE_TLast()));
540 
541  ucc_csum0 += byteSwap16(cleanChunk.range(63, 48));
542  ucc_csum0 = (ucc_csum0 & 0xFFFF) + (ucc_csum0 >> 16);
543  ucc_csum1 += byteSwap16(cleanChunk.range(47, 32));
544  ucc_csum1 = (ucc_csum1 & 0xFFFF) + (ucc_csum1 >> 16);
545  ucc_csum2 += byteSwap16(cleanChunk.range(31, 16));
546  ucc_csum2 = (ucc_csum2 & 0xFFFF) + (ucc_csum2 >> 16);
547  ucc_csum3 += byteSwap16(cleanChunk.range(15, 0));
548  ucc_csum3 = (ucc_csum3 & 0xFFFF) + (ucc_csum3 >> 16);
549 
550  if (currChunk.getTLast()) {
551  ucc_fsmState = FSM_UCC_CHK0;
552  }
553  if (DEBUG_LEVEL & TRACE_UCC) { printAxisRaw(myName,"FSM_UCC_ACCUMULATE -", currChunk); }
554  }
555  break;
556  case FSM_UCC_CHK0:
557  if (DEBUG_LEVEL & TRACE_UCC) { printInfo(myName,"FSM_UCC_CHK0 - \n"); }
558  ucc_csum0 += ucc_csum2;
559  ucc_csum0 = (ucc_csum0 & 0xFFFF) + (ucc_csum0 >> 16);
560  ucc_csum1 += ucc_csum3;
561  ucc_csum1 = (ucc_csum1 & 0xFFFF) + (ucc_csum1 >> 16);
562  ucc_fsmState = FSM_UCC_CHK1;
563  break;
564  case FSM_UCC_CHK1:
565  if (!soRph_CsumVal.full()) {
566  if (DEBUG_LEVEL & TRACE_UCC) { printInfo(myName,"FSM_UCC_CHK1 - \n"); }
567  ucc_csum0 += ucc_csum1;
568  ucc_csum0 = (ucc_csum0 & 0xFFFF) + (ucc_csum0 >> 16);
569  UdpCsum csumChk = ~(ucc_csum0(15, 0));
570  if (csumChk == 0) {
571  // The checksum is correct. UDP datagram is valid.
572  soRph_CsumVal.write(true);
573  }
574  else {
575  soRph_CsumVal.write(false);
576  if (DEBUG_LEVEL & TRACE_UCC) {
577  printWarn(myName, "The current UDP datagram will be dropped because:\n");
578  printWarn(myName, " csum = 0x%4.4X instead of 0x0000\n", csumChk.to_ushort());
579  }
580  }
581  ucc_fsmState = FSM_UCC_IDLE;
582  }
583  break;
584  } // End-of: switch
585 
586 } // End-of: pUdpChecksumChecker
LE_tLast getLE_TLast() const
Definition: AxisRaw.hpp:268
UdpCsum getUdpCsum()
Definition: AxisUdp.hpp:145
#define TRACE_UCC
Definition: uoe.cpp:77
ap_uint< 64 > LE_tData
Definition: AxisRaw.hpp:122
ap_uint< 16 > UdpCsum
Definition: AxisUdp.hpp:101
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pUdpHeaderAdder()

void pUdpHeaderAdder ( stream< UdpAppData > &  siTdh_Data,
stream< UdpAppDLen > &  siTdh_DLen,
stream< UdpAppMeta > &  siTdh_Meta,
stream< UdpCsum > &  siUca_Csum,
stream< AxisUdp > &  soIha_Data,
stream< IpAddrPair > &  soIha_IpPair,
stream< UdpLen > &  soIha_UdpLen 
)

UDP Header Adder (Uha)

Parameters
[in]siTdh_DataAppData stream from TxDatagramHandler (Tdh).
[in]siTdh_DLenData payload length from [Tdh].
[in]siTdh_MetaMetadata from [tdH].
[in]siUca_CsumThe UDP checksum from UdpChecksumAccumaulato (Uca).
[out]soIha_DataUdpData strem to IpHeaderAdder (Iha).
[out]soIha_IpPairThe IP_SA and IP_DA for this datagram.
[out]soIha_UdpLenThe length of the UDP datagram to [Iha].

This process creates a UDP header and prepends it to the AppData stream coming from the TxDatagramHandler (Tdh). The UDP checksum is read from the process UdpChecksumAccumulator(Uca).

Definition at line 1516 of file uoe.cpp.

1524 {
1525  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
1526  #pragma HLS INLINE off
1527  #pragma HLS PIPELINE II=1 enable_flush
1528 
1529  const char *myName = concat3(THIS_NAME, "/TXe/", "Uha");
1530 
1531  //-- STATIC CONTROL VARIABLES (with RESET) --------------------------------
1532  static enum FsmStates{ UHA_IDLE=0, UHA_STREAM} uha_fsmState;
1533  #pragma HLS RESET variable=uha_fsmState
1534 
1535  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
1536  static UdpAppDLen uha_appDLen;
1537 
1538  switch(uha_fsmState) {
1539  case UHA_IDLE:
1540  if (!siTdh_DLen.empty() and !siTdh_Meta.empty() and !siUca_Csum.empty() and
1541  !soIha_UdpLen.full() and !soIha_Data.full() and !soIha_IpPair.full()) {
1542  // Read data payload length
1543  siTdh_DLen.read(uha_appDLen);
1544  UdpLen udpLen = uha_appDLen + UDP_HEADER_LEN;
1545  soIha_UdpLen.write(udpLen);
1546  // Read metadata and generate UDP header
1547  UdpAppMeta udpAppMeta = siTdh_Meta.read();
1548  AxisUdp udpHdrChunk = AxisUdp(0, 0xFF, 0);
1549  udpHdrChunk.setUdpSrcPort(udpAppMeta.udpSrcPort);
1550  udpHdrChunk.setUdpDstPort(udpAppMeta.udpDstPort);
1551  udpHdrChunk.setUdpLen(udpLen);
1552  udpHdrChunk.setUdpCsum(siUca_Csum.read());
1553  soIha_Data.write(udpHdrChunk);
1554  IpAddrPair ipAddrPair = IpAddrPair(udpAppMeta.ip4SrcAddr, udpAppMeta.ip4DstAddr);
1555  soIha_IpPair.write(ipAddrPair);
1556  uha_fsmState = UHA_STREAM;
1557  if (DEBUG_LEVEL & TRACE_UHA) { printInfo(myName, "UHA_IDLE\n"); }
1558  }
1559  break;
1560  case UHA_STREAM:
1561  if (!siTdh_Data.empty() and !soIha_Data.full()) {
1562  UdpAppData currAppData = siTdh_Data.read();
1563  if (uha_appDLen > 8) {
1564  uha_appDLen -= 8;
1565  if (currAppData.getTLast() == TLAST) {
1566  printWarn(myName, "Malformed - TLAST bit is set but end of Axis stream is not reached !!!\n");
1567  // [FIXME - Must go to state that drains remaining chunks]
1568  uha_fsmState = UHA_IDLE;
1569  }
1570  }
1571  else {
1572  if (currAppData.getTLast() != TLAST) {
1573  printWarn(myName, "Malformed - End of Axis stream is reached but TLAST bit is not set!!!\n");
1574  // [FIXME - Must go to state that drains remaining chunks]
1575  currAppData.setTLast(TLAST);
1576  }
1577  uha_appDLen = 0;
1578  uha_fsmState = UHA_IDLE;
1579  }
1580  soIha_Data.write(AxisUdp(currAppData.getLE_TData(), currAppData.getLE_TKeep(), currAppData.getLE_TLast()));
1581  }
1582  if (DEBUG_LEVEL & TRACE_UHA) { printInfo(myName, "UHA_STREAM\n"); }
1583  break;
1584  }
1585 }
void setUdpSrcPort(UdpPort port)
Definition: AxisUdp.hpp:129
void setUdpDstPort(UdpPort port)
Definition: AxisUdp.hpp:134
void setUdpCsum(UdpCsum csum)
Definition: AxisUdp.hpp:144
void setUdpLen(UdpLen length)
Definition: AxisUdp.hpp:139
#define TRACE_UHA
Definition: uoe.cpp:78
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pUdpPortTable()

void pUdpPortTable ( stream< StsBool > &  soMMIO_Ready,
stream< UdpPort > &  siRph_PortStateReq,
stream< StsBool > &  soRph_PortStateRep,
stream< UdpPort > &  siUAIF_LsnReq,
stream< StsBool > &  soUAIF_LsnRep,
stream< UdpPort > &  siUAIF_ClsReq,
stream< StsBool > &  soUAIF_ClsRep 
)

UDP Port Table (Upt)

param[out] soMMIO_Ready Process ready signal. param[in] siRph_PortStateReq Port state request from RxPacketHandler (Rph). param[out] soRph_PortStateRep Port state reply to [Rph]. param[in] siUAIF_LsnReq Listen port request from [UAIF]. param[out] soUAIF_LsnRep Listen port reply to UAIF. param[in] siUAIF_ClsReq Close port request from [UAIF]. param[out] soUAIF_ClsRep Close port reply to UAIF.

The UDP Port Table (Upt) keeps track of the opened ports. A port is opened if its state is 'true' and closed otherwise.

Note
: We are using a stream to signal that UOE is ready because the C/RTL co-simulation only only supports the following 'ap_ctrl_none' designs: (1) combinational designs; (2) pipelined design with task interval of 1; (3) designs with array streaming or hls_stream or AXI4 stream ports.

Definition at line 865 of file uoe.cpp.

873 {
874  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
875  // None
876 
877  const char *myName = concat3(THIS_NAME, "/RXe/", "Upt");
878 
879  //-- STATIC ARRAYS --------------------------------------------------------
880  static ValBool PORT_TABLE[0x10000];
881  #pragma HLS RESOURCE variable=PORT_TABLE core=RAM_T2P_BRAM
882  #pragma HLS DEPENDENCE variable=PORT_TABLE inter false
883 
884  //-- STATIC CONTROL VARIABLES (with RESET) --------------------------------
885  static enum FsmStates { UPT_WAIT4REQ=0, UPT_RPH_LKP, UPT_LSN_REP,
886  UPT_CLS_REP } upt_fsmState=UPT_WAIT4REQ;
887  #pragma HLS RESET variable=upt_fsmState
888  static bool upt_isInit=false;
889  #pragma HLS reset variable=upt_isInit
890  static UdpPort upt_initPtr=(0x10000-1);
891  #pragma HLS reset variable=upt_initPtr
892 
893  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
894  static UdpPort upt_portNum;
895 
896  // The PORT_TABLE must be initialized upon reset
897  if (!upt_isInit) {
898  PORT_TABLE[upt_initPtr] = STS_CLOSED;
899  if (upt_initPtr == 0) {
900  if (!soMMIO_Ready.full()) {
901  soMMIO_Ready.write(true);
902  upt_isInit = true;
903  if (DEBUG_LEVEL & TRACE_UPT) {
904  printInfo(myName, "Done with initialization of the PORT_TABLE.\n");
905  }
906  }
907  else {
908  printWarn(myName, "Cannot signal INIT_DONE because HLS stream is not empty.\n");
909  }
910  }
911  else {
912  upt_initPtr = upt_initPtr - 1;
913  }
914  return;
915  }
916 
917  switch (upt_fsmState) {
918  case UPT_WAIT4REQ:
919  if (!siRph_PortStateReq.empty()) {
920  // Request to lookup the table from [RPh]
921  siRph_PortStateReq.read(upt_portNum);
922  upt_fsmState = UPT_RPH_LKP;
923  }
924  else if (!siUAIF_LsnReq.empty()) {
925  // Request to open a port from [UAIF]
926  siUAIF_LsnReq.read(upt_portNum);
927  upt_fsmState = UPT_LSN_REP;
928  }
929  else if (!siUAIF_ClsReq.empty()) {
930  // Request to close a port from [UAIF]
931  siUAIF_ClsReq.read(upt_portNum);
932  upt_fsmState = UPT_CLS_REP;
933  }
934  break;
935  case UPT_RPH_LKP: // Lookup Reply
936  if (!soRph_PortStateRep.full()) {
937  soRph_PortStateRep.write(PORT_TABLE[upt_portNum]);
938  upt_fsmState = UPT_WAIT4REQ;
939  }
940  break;
941  case UPT_LSN_REP: // Listen Reply
942  if (!soUAIF_LsnRep.full()) {
943  PORT_TABLE[upt_portNum] = STS_OPENED;
944  soUAIF_LsnRep.write(STS_OPENED);
945  upt_fsmState = UPT_WAIT4REQ;
946  }
947  break;
948  case UPT_CLS_REP: // Close Reply
949  if (!soUAIF_ClsRep.full()) {
950  PORT_TABLE[upt_portNum] = STS_CLOSED;
951  soUAIF_ClsRep.write(STS_CLOSED);
952  upt_fsmState = UPT_WAIT4REQ;
953  }
954  break;
955  }
956 }
ap_uint< 16 > UdpPort
Definition: nal.hpp:249
#define TRACE_UPT
Definition: uoe.cpp:79
bool ValBool
Definition: nts_types.hpp:131
#define STS_CLOSED
Definition: nts_types.hpp:82
#define STS_OPENED
Definition: nts_types.hpp:81
Here is the caller graph for this function:

◆ uoe()

void uoe ( CmdBit  piMMIO_En,
stream< ap_uint< 16 > > &  soMMIO_DropCnt,
stream< StsBool > &  soMMIO_Ready,
stream< AxisIp4 > &  siIPRX_Data,
stream< AxisIp4 > &  soIPTX_Data,
stream< UdpAppLsnReq > &  siUAIF_LsnReq,
stream< UdpAppLsnRep > &  soUAIF_LsnRep,
stream< UdpAppClsReq > &  siUAIF_ClsReq,
stream< UdpAppClsRep > &  soUAIF_ClsRep,
stream< UdpAppData > &  soUAIF_Data,
stream< UdpAppMeta > &  soUAIF_Meta,
stream< UdpAppDLen > &  soUAIF_DLen,
stream< UdpAppData > &  siUAIF_Data,
stream< UdpAppMeta > &  siUAIF_Meta,
stream< UdpAppDLen > &  siUAIF_DLen,
stream< AxisIcmp > &  soICMP_Data 
)

Main process of the UDP Offload Engine (UOE).

– MMIO Interface

Parameters
[in]piMMIO_EnEnable signal from [SHELL/MMIO].
[out]soMMIO_DropCntRx drop counter to [SHELL/MMIO].
[out]soMMIO_ReadyUOE ready stream to [SHELL/MMIO]. – IPRX / IP Rx / Data Interface
[in]siIPRX_DataIP4 data stream from IpRxHAndler (IPRX). – IPTX / IP Tx / Data Interface
[out]soIPTX_DataIP4 data stream to IpTxHandler (IPTX). – UAIF / Control Port Interfaces
[in]siUAIF_LsnReqUDP open port request from UdpAppInterface (UAIF).
[out]soUAIF_LsnRepUDP open port reply to UAIF.
[in]siUAIF_ClsReqUDP close port request from [UAIF].
[out]soUAIF_ClsRepUDP close port reply to UAIF. – UAIF / Rx Data Interfaces
[out]soUAIF_DataUDP data stream to [UAIF].
[out]soUAIF_MetaUDP metadata to [UAIF].
[out]soUAIF_DLenUDP data length to [UAIF]. – UAIF / Tx Data Interfaces
[in]siUAIF_DataUDP data stream from [UAIF].
[in]siUAIF_MetaUDP metadata stream from [UAIF].
[in]siUAIF_DLenUDP data length form [UAIF]. – ICMP / Message Data Interface
[out]soICMP_DataData stream to [ICMP].

Definition at line 1838 of file uoe.cpp.

1876 {
1877  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1878  #pragma HLS INLINE
1879  #pragma HLS INTERFACE ap_ctrl_none port=return
1880  #if HLS_VERSION == 2017
1881  #pragma HLS DATAFLOW
1882  #else
1883  #pragma HLS DATAFLOW disable_start_propagation
1884  #endif
1885 
1886  //-- PROCESS FUNCTIONS -----------------------------------------------------
1887 
1888  pRxEngine(
1889  piMMIO_En,
1890  soMMIO_Ready,
1891  siIPRX_Data,
1892  siUAIF_LsnReq,
1893  soUAIF_LsnRep,
1894  siUAIF_ClsReq,
1895  soUAIF_ClsRep,
1896  soUAIF_Data,
1897  soUAIF_Meta,
1898  soUAIF_DLen,
1899  soICMP_Data,
1900  soMMIO_DropCnt);
1901 
1902  pTxEngine(
1903  piMMIO_En,
1904  siUAIF_Data,
1905  siUAIF_Meta,
1906  siUAIF_DLen,
1907  soIPTX_Data);
1908 
1909 }
void pRxEngine(CmdBit piMMIO_En, stream< StsBool > &soMMIO_Ready, stream< AxisIp4 > &siIPRX_Data, stream< UdpPort > &siUAIF_LsnReq, stream< StsBool > &soUAIF_LsnRep, stream< UdpPort > &siUAIF_ClsReq, stream< StsBool > &soUAIF_ClsRep, stream< UdpAppData > &soUAIF_Data, stream< UdpAppMeta > &soUAIF_Meta, stream< UdpAppDLen > &soUAIF_DLen, stream< AxisIcmp > &soICMP_Data, stream< ap_uint< 16 > > &soMMIO_DropCnt)
Definition: uoe.cpp:982
void pTxEngine(CmdBit piMMIO_En, stream< UdpAppData > &siUAIF_Data, stream< UdpAppMeta > &siUAIF_Meta, stream< UdpAppDLen > &siUAIF_DLen, stream< AxisIp4 > &soIPTX_Data)
Definition: uoe.cpp:1718
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uoe_top()

void uoe_top ( CmdBit  piMMIO_En,
stream< ap_uint< 16 > > &  soMMIO_DropCnt,
stream< StsBool > &  soMMIO_Ready,
stream< AxisRaw > &  siIPRX_Data,
stream< AxisRaw > &  soIPTX_Data,
stream< UdpAppLsnReq > &  siUAIF_LsnReq,
stream< UdpAppLsnRep > &  soUAIF_LsnRep,
stream< UdpAppClsReq > &  siUAIF_ClsReq,
stream< UdpAppClsRep > &  soUAIF_ClsRep,
stream< UdpAppData > &  soUAIF_Data,
stream< UdpAppMeta > &  soUAIF_Meta,
stream< UdpAppDLen > &  soUAIF_DLen,
stream< UdpAppData > &  siUAIF_Data,
stream< UdpAppMeta > &  siUAIF_Meta,
stream< UdpAppDLen > &  siUAIF_DLen,
stream< AxisRaw > &  soICMP_Data 
)

Top of UDP Offload Engine (UOE)

– MMIO Interface

Parameters
[in]piMMIO_EnEnable signal from [SHELL/MMIO].
[out]soMMIO_DropCntRx drop counter to [SHELL/MMIO].
[out]soMMIO_ReadyUOE ready stream to [SHELL/MMIO]. – IPRX / IP Rx / Data Interface
[in]siIPRX_DataIP4 data stream from IpRxHAndler (IPRX). – IPTX / IP Tx / Data Interface
[out]soIPTX_DataIP4 data stream to IpTxHandler (IPTX). – UAIF / Control Port Interfaces
[in]siUAIF_LsnReqUDP open port request from UdpAppInterface (UAIF).
[out]soUAIF_LsnRepUDP open port reply to UAIF.
[in]siUAIF_ClsReqUDP close port request from [UAIF].
[out]soUAIF_ClsRepUDP close port reply to UAIF. – UAIF / Rx Data Interfaces
[out]soUAIF_DataUDP data stream to [UAIF].
[out]soUAIF_MetaUDP metadata stream to [UAIF]. – UAIF / Tx Data Interfaces
[in]siUAIF_DataUDP data stream from [UAIF].
[in]siUAIF_MetaUDP metadata stream from [UAIF].
[in]siUAIF_DLenUDP data length form [UAIF]. – ICMP / Message Data Interface
[out]soICMP_DataData stream to [ICMP].

ENTITY - UDP OFFLOAD ENGINE (UOE)

Definition at line 2042 of file uoe.cpp.

2080 {
2081 
2082  //-- DIRECTIVES FOR THE INTERFACES -----------------------------------------
2083  #pragma HLS INTERFACE ap_ctrl_none port=return
2084 
2085  #pragma HLS INTERFACE ap_stable port=piMMIO_En name=piMMIO_En
2086 
2087  #pragma HLS INTERFACE axis register both port=soMMIO_DropCnt name=soMMIO_DropCnt
2088  #pragma HLS INTERFACE axis register both port=soMMIO_Ready name=soMMIO_Ready
2089 
2090  #pragma HLS INTERFACE axis off port=siIPRX_Data name=siIPRX_Data
2091  #pragma HLS INTERFACE axis register both port=soIPTX_Data name=soIPTX_Data
2092 
2093  #pragma HLS INTERFACE axis off port=siUAIF_LsnReq name=siUAIF_LsnReq
2094  #pragma HLS INTERFACE axis off port=soUAIF_LsnRep name=soUAIF_LsnRep
2095  #pragma HLS INTERFACE axis off port=siUAIF_ClsReq name=siUAIF_ClsReq
2096  #pragma HLS INTERFACE axis off port=soUAIF_ClsRep name=soUAIF_ClsRep
2097 
2098  #pragma HLS INTERFACE axis off port=soUAIF_Data name=soUAIF_Data
2099  #pragma HLS INTERFACE axis off port=soUAIF_Meta name=soUAIF_Meta
2100  #pragma HLS DATA_PACK variable=soUAIF_Meta instance=soUAIF_Meta
2101  #pragma HLS INTERFACE axis off port=soUAIF_DLen name=soUAIF_DLen
2102 
2103  #pragma HLS INTERFACE axis off port=siUAIF_Data name=siUAIF_Data
2104  #pragma HLS INTERFACE axis off port=siUAIF_Meta name=siUAIF_Meta
2105  #pragma HLS DATA_PACK variable=siUAIF_Meta instance=siUAIF_Meta
2106  #pragma HLS INTERFACE axis off port=siUAIF_DLen name=siUAIF_DLen
2107 
2108  #pragma HLS INTERFACE axis register both port=soICMP_Data name=soICMP_Data
2109 
2110  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
2111  #pragma HLS DATAFLOW disable_start_propagation
2112 
2113  //-- LOCAL INPUT and OUTPUT STREAMS ----------------------------------------
2114  static stream<AxisIp4> ssiIPRX_Data;
2115  #pragma HLS STREAM variable=ssiIPRX_Data depth=32
2116  static stream<AxisIp4> ssoIPTX_Data;
2117  static stream<AxisIcmp> ssoICMP_Data;
2118 
2119  //-- INPUT STREAM CASTING --------------------------------------------------
2120  pAxisRawCast(siIPRX_Data, ssiIPRX_Data);
2121 
2122  //-- MAIN IPRX PROCESS -----------------------------------------------------
2123  uoe(
2124  //-- MMIO Interface
2125  piMMIO_En,
2126  soMMIO_DropCnt,
2127  soMMIO_Ready,
2128  //-- IPRX / IP Rx / Data Interface
2129  ssiIPRX_Data,
2130  //-- IPTX / IP Tx / Data Interface
2131  ssoIPTX_Data,
2132  //-- UAIF / Control Port Interfaces
2133  siUAIF_LsnReq,
2134  soUAIF_LsnRep,
2135  siUAIF_ClsReq,
2136  soUAIF_ClsRep,
2137  //-- UAIF / Rx Data Interfaces
2138  soUAIF_Data,
2139  soUAIF_Meta,
2140  soUAIF_DLen,
2141  //-- UAIF / Tx Data Interfaces
2142  siUAIF_Data,
2143  siUAIF_Meta,
2144  siUAIF_DLen,
2145  //-- ICMP / Message Data Interface (Port Unreachable)
2146  ssoICMP_Data);
2147 
2148  //-- OUTPUT STREAM CASTING ----------------------------
2149  pAxisRawCast(ssoIPTX_Data, soIPTX_Data);
2150  pAxisRawCast(ssoICMP_Data, soICMP_Data);
2151 
2152 }
void uoe(CmdBit piMMIO_En, stream< ap_uint< 16 > > &soMMIO_DropCnt, stream< StsBool > &soMMIO_Ready, stream< AxisIp4 > &siIPRX_Data, stream< AxisIp4 > &soIPTX_Data, stream< UdpAppLsnReq > &siUAIF_LsnReq, stream< UdpAppLsnRep > &soUAIF_LsnRep, stream< UdpAppClsReq > &siUAIF_ClsReq, stream< UdpAppClsRep > &soUAIF_ClsRep, stream< UdpAppData > &soUAIF_Data, stream< UdpAppMeta > &soUAIF_Meta, stream< UdpAppDLen > &soUAIF_DLen, stream< UdpAppData > &siUAIF_Data, stream< UdpAppMeta > &siUAIF_Meta, stream< UdpAppDLen > &siUAIF_DLen, stream< AxisIcmp > &soICMP_Data)
Main process of the UDP Offload Engine (UOE).
Definition: uoe.cpp:1838
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:

Variable Documentation

◆ cIp4RxHdrsFifoSize

const int cIp4RxHdrsFifoSize = (cUdpRxHdrsFifoSize * 4)

Definition at line 85 of file uoe.hpp.

◆ cMtuSize

const int cMtuSize = (2*MTU)/( 64 /8)

Definition at line 86 of file uoe.hpp.

◆ cUdpRxDataFifoSize

const int cUdpRxDataFifoSize = ( 16*1024 )/( 64 /8)

Definition at line 83 of file uoe.hpp.

◆ cUdpRxHdrsFifoSize

const int cUdpRxHdrsFifoSize = ( 64 )

Definition at line 84 of file uoe.hpp.

◆ 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.