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

TCP Offload Engine (TOE) of the Network Transport Stack (NTS). More...

Collaboration diagram for TOE:

Modules

 TOE_TEST
 Testbench for the TCP Offload Engine (TOE) of the Network Transport Stack (NTS).
 

Files

file  test_ack_delay.cpp
 : Testbench for ACK delayer (AKd) function of TOE.
 
file  test_ack_delay.hpp
 : Testbench for or ACK delayer (AKd) function of TOE.
 
file  test_rx_engine.cpp
 : Testbench for RX Engine (RXe) of the TCP Offload Engine (TOE).
 
file  test_rx_engine.hpp
 : Testbench for RX Engine (RXe) of the TCP Offload Engine (TOE).
 
file  tx_app_interface.cpp
 : Tx Application Interface (TAi)
 
file  tx_app_interface.hpp
 : Tx Application Interface (TAi)
 
file  test_tx_engine.cpp
 : Testbench for TX Engine (TXe) of the TCP Offload Engine (TOE).
 
file  test_rx_engine.hpp
 : Testbench for RX Engine (RXe) of the TCP Offload Engine (TOE).
 
file  test_toe.cpp
 : Testbench for the TCP Offload Engine (TOE).
 
file  test_toe.hpp
 : Testbench for the TCP Offload Engine (TOE)
 

Classes

class  AckEntry
 
class  RXeMeta
 
class  RXeFsmMeta
 
class  RxSarEntry
 
class  SLcQuery
 
class  SLcReverseLkp
 
class  CloseTimerEntry
 
class  ProbeTimerEntry
 
class  ReTxTimerEntry
 
struct  ipTuple
 
class  SessionLookupQuery
 
class  SessionLookupReply
 
class  StateQuery
 
class  RxSarReply
 
class  RXeRxSarQuery
 
class  RAiRxSarQuery
 
class  RAiRxSarReply
 
class  RXeTxSarQuery
 
class  RXeTxSarReply
 
class  TXeTxSarQuery
 
class  TXeTxSarReply
 
class  TXeTxSarRtQuery
 
class  TAiTxSarPush
 
class  TStTxSarPush
 
class  TxAppTableQuery
 
class  TxAppTableReply
 
class  RXeReTransTimerCmd
 
class  TXeReTransTimerCmd
 
class  Event
 
class  ExtendedEvent
 
struct  rstEvent
 
class  TxAppTableEntry
 
class  AppMemMeta
 
class  TXeMeta
 
struct  SubCSums
 
class  IpAddrPair
 
class  TxSarEntry
 
class  DummyMemory
 

Macros

#define THIS_NAME   "TOE/AKd"
 
#define TRACE_OFF   0x0000
 
#define TRACE_AKD   1 << 1
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define THIS_NAME   "TOE/EVe"
 
#define TRACE_OFF   0x0000
 
#define TRACE_EVE   1 << 1
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define THIS_NAME   "TOE/PRt"
 
#define TRACE_OFF   0x0000
 
#define TRACE_IRR   1 << 1
 
#define TRACE_ORM   1 << 2
 
#define TRACE_LPT   1 << 3
 
#define TRACE_FPT   1 << 4
 
#define TRACE_RDY   1 << 5
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define ACT_FREE_PORT   false
 
#define ACT_USED_PORT   true
 
#define ACTIVE_PORT   false
 
#define LISTEN_PORT   true
 
#define PortRange   bool
 
#define THIS_NAME   "TOE/RAi"
 
#define TRACE_OFF   0x0000
 
#define TRACE_LAI   1 << 1
 
#define TRACE_ASS   1 << 2
 
#define TRACE_NMX   1 << 3
 
#define TRACE_RAS   1 << 4
 
#define TRACE_MRD   1 << 5
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define THIS_NAME   "TOE/RXe"
 
#define TRACE_OFF   0x0000
 
#define TRACE_TLE   1 << 1
 
#define TRACE_IPH   1 << 2
 
#define TRACE_CSA   1 << 3
 
#define TRACE_MDH   1 << 4
 
#define TRACE_TID   1 << 5
 
#define TRACE_TSD   1 << 6
 
#define TRACE_EVM   1 << 7
 
#define TRACE_FSM   1 << 8
 
#define TRACE_MWR   1 << 9
 
#define TRACE_RAN   1 << 10
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define THIS_NAME   "TOE/RSt"
 
#define TRACE_OFF   0x0000
 
#define TRACE_RST   1 << 1
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define THIS_NAME   "TOE/SLc"
 
#define TRACE_OFF   0x0000
 
#define TRACE_LRH   1 << 1
 
#define TRACE_RLT   1 << 2
 
#define TRACE_SIM   1 << 3
 
#define TRACE_URH   1 << 4
 
#define TRACE_URS   1 << 5
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define THIS_NAME   "TOE/STt"
 
#define TRACE_OFF   0x0000
 
#define TRACE_STT   1 << 1
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define THIS_NAME   "TOE/TIm"
 
#define TRACE_OFF   0x0000
 
#define TRACE_CLT   1 << 1
 
#define TRACE_PBT   1 << 2
 
#define TRACE_RTT   1 << 3
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define USE_DEPRECATED_DIRECTIVES
 
#define THIS_NAME   "TOE"
 
#define TRACE_OFF   0x0000
 
#define TRACE_RDY   1 << 1
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define TOE_SIZEOF_LISTEN_PORT_TABLE   0x8000
 
#define TOE_SIZEOF_ACTIVE_PORT_TABLE   0x8000
 
#define TOE_FIRST_EPHEMERAL_PORT_NUM   0x8000
 
#define TOE_FEATURE_USED_FOR_DEBUGGING   0
 
#define cIP4_ADDR_WIDTH   32
 
#define cTCP_PORT_WIDTH   16
 
#define cSHL_TOE_SESS_ID_WIDTH   16
 
#define cSHL_TOE_LSN_ACK_WIDTH   1
 
#define cSHL_TOE_LSN_REQ_WIDTH   cSHL_TOE_SESS_ID_WIDTH
 
#define cSHL_TOE_OPN_REQ_WIDTH   (cIP4_ADDR_WIDTH + cTCP_PORT_WIDTH)
 
#define cSHL_TOE_CLS_REQ_WIDTH   cSHL_TOE_SESS_ID_WIDTH
 
#define TLAST   1
 
#define RXMEMBUF   65536
 
#define TXMEMBUF   65536
 
#define THIS_NAME   "ToeUtils"
 
#define THIS_NAME   "TOE/TAi"
 
#define TRACE_OFF   0x0000
 
#define TRACE_SML   1 << 1
 
#define TRACE_SLG   1 << 2
 
#define TRACE_MWR   1 << 3
 
#define TRACE_TAC   1 << 4
 
#define TRACE_TAS   1 << 5
 
#define TRACE_TAT   1 << 6
 
#define TRACE_TASH   1 << 7
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define PRAGMA_SUB(x)   _Pragma (#x)
 
#define DO_PRAGMA(x)   PRAGMA_SUB(x)
 
#define DEPTH_ssEmxToTash_Event   2
 
#define DEPTH_ssTacToEmx_Event   2
 
#define DEPTH_ssTatToSml_AccessRep   2
 
#define DEPTH_ssSmlToTat_AccessQry   2
 
#define DEPTH_ssSmlToMwr_SegMeta   128
 
#define DEPTH_ssSmlToEmx_Event   2
 
#define DEPTH_ssSlgToMwr_Data   256
 
#define DEPTH_ssSlgToSml_SegLen   32
 
#define THIS_NAME   "TOE/TXe"
 
#define FIXME   1
 
#define TRACE_OFF   0x0000
 
#define TRACE_MDL   1 << 1
 
#define TRACE_IHC   1 << 2
 
#define TRACE_SPS   1 << 3
 
#define TRACE_PHC   1 << 4
 
#define TRACE_MRD   1 << 5
 
#define TRACE_TSS   1 << 6
 
#define TRACE_SCA   1 << 7
 
#define TRACE_TCA   1 << 8
 
#define TRACE_IPS   1 << 9
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define THIS_NAME   "TOE/TSt"
 
#define TRACE_OFF   0x0000
 
#define TRACE_TST   1 << 1
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 

Typedefs

typedef AckBit PortState
 
typedef FourTuple SLcFourTuple
 
typedef ap_uint< 16 > SessionId
 
typedef ap_uint< 1 > LsnAck
 
typedef ap_uint< 16 > LsnReq
 
typedef ap_uint<(32+16) > OpnReq
 
typedef ap_uint< 16 > ClsReq
 
typedef ap_uint< 64 > LE_tData
 
typedef ap_uint< 8 > LE_tKeep
 
typedef ap_uint< 64 > tData
 
typedef ap_uint< 32 > tDataHalf
 
typedef ap_uint< 8 > tKeep
 
typedef ap_uint< 1 > tLast
 
typedef TcpAppOpnRep SessState
 
typedef ap_uint< 15 > TcpStaPort
 
typedef ap_uint< 15 > TcpDynPort
 
typedef TcpSeqNum RxSeqNum
 
typedef TcpAckNum TxAckNum
 
typedef TcpWindow RemotWinSize
 
typedef TcpWindow LocalWinSize
 
typedef ap_uint< 32 > RxMemPtr
 
typedef ap_uint< 32 > TxMemPtr
 
typedef ap_uint< TOE_WINDOW_BITS > TcpBufAdr
 
typedef TcpBufAdr RxBufPtr
 
typedef TcpBufAdr TxBufPtr
 
typedef bool HitState
 

Enumerations

enum  StateEntry { DISABLED_ENTRY = false , ACTIVE_ENTRY = true }
 
enum  notificationType { PKG , CLOSE , TIME_OUT , RESET }
 
enum  {
  WORD_0 , WORD_1 , WORD_2 , WORD_3 ,
  WORD_4 , WORD_5
}
 
enum  {
  CHUNK_0 , CHUNK_1 , CHUNK_2 , CHUNK_3 ,
  CHUNK_4 , CHUNK_5
}
 
enum  EventType {
  TX_EVENT =0 , RT_EVENT , ACK_EVENT , SYN_EVENT ,
  SYN_ACK_EVENT , FIN_EVENT , RST_EVENT , ACK_NODELAY_EVENT
}
 
enum  HitStates { SESSION_UNKNOWN = false , SESSION_EXISTS = true }
 
enum  TimerCmd { LOAD_TIMER = false , STOP_TIMER = true }
 

Functions

void ack_delay (stream< ExtendedEvent > &siEVe_Event, stream< SigBit > &soEVe_RxEventSig, stream< SigBit > &soEVe_TxEventSig, stream< ExtendedEvent > &soTXe_Event)
 ACK Delayer (AKd) More...
 
void ack_delay_OBSO (stream< ExtendedEvent > &siEVe_Event, stream< SigBit > &soEVe_RxEventSig, stream< SigBit > &soEVe_TxEventSig, stream< ExtendedEvent > &soTXe_Event)
 
void event_engine (stream< Event > &siTAi_Event, stream< ExtendedEvent > &siRXe_Event, stream< Event > &siTIm_Event, stream< ExtendedEvent > &soAKd_Event, stream< SigBit > &siAKd_RxEventSig, stream< SigBit > &siAKd_TxEventSig, stream< SigBit > &siTXe_RxEventSig)
 The Event Engine (EVe) arbitrates the incoming events and forwards them to the Tx Engine (TXe) via the ACK Delayer (AKd). More...
 
template<class T >
void pAnd2 (T &pi1, T &pi2, T &po)
 A two inputs 'AND' gate. More...
 
void pReady (StsBool &piLpt_Ready, StsBool &piFpt_Ready, StsBool &poTOE_Ready)
 Ready Logic (Rdy) More...
 
void pListeningPortTable (StsBool &poRdy_Ready, stream< TcpPort > &siRAi_OpenLsnPortReq, stream< RepBit > &soRAi_OpenLsnPortRep, stream< TcpStaPort > &siIrr_GetPortStateCmd, stream< RspBit > &soOrm_GetPortStateRsp)
 Listening Port Table (Lpt) More...
 
void pFreePortTable (StsBool &poRdy_Ready, stream< TcpPort > &siSLc_CloseActPortCmd, stream< TcpDynPort > &siIrr_GetPortStateCmd, stream< RspBit > &soOrm_GetPortStateRsp, stream< ReqBit > &siTAi_GetFreePortReq, stream< TcpPort > &soTAi_GetFreePortRep)
 Free Port Table (Fpt) More...
 
void pInputRequestRouter (stream< TcpPort > &siRXe_GetPortStateCmd, stream< TcpStaPort > &soLpt_GetLsnPortStateCmd, stream< TcpDynPort > &soFpt_GetActPortStateCmd, stream< bool > &soOrm_QueryRange)
 Input Request Router (Irr) More...
 
void pOutputReplyMultiplexer (stream< bool > &siIrr_QueryRange, stream< RspBit > &siLpt_GetLsnPortStateRsp, stream< RspBit > &siFpt_GetActPortStateRsp, stream< RspBit > &soRXe_GetPortStateRsp)
 Output Reply Multiplexer (Orm) More...
 
void port_table (StsBool &poTOE_Ready, stream< TcpPort > &siRXe_GetPortStateReq, stream< RepBit > &soRXe_GetPortStateRep, stream< TcpPort > &siRAi_OpenLsnPortReq, stream< AckBit > &soRAi_OpenLsnPortAck, stream< ReqBit > &siTAi_GetFreePortReq, stream< TcpPort > &soTAi_GetFreePortRep, stream< TcpPort > &siSLc_CloseActPortCmd)
 Port Table (PRt) More...
 
void pNotificationMux (stream< TcpAppNotif > &siRXe_Notif, stream< TcpAppNotif > &siTIm_Notif, stream< TcpAppNotif > &soTAIF_Notif, stream< ap_uint< 8 > > &soMMIO_NotifDropCnt)
 Rx Notification Multiplexer (Nmx) More...
 
void pRxAppStream (stream< TcpAppRdReq > &siTAIF_DataReq, stream< TcpAppMeta > &soTAIF_Meta, stream< RAiRxSarQuery > &soRSt_RxSarQry, stream< RAiRxSarReply > &siRSt_RxSarRep, stream< DmCmd > &soMrd_MemRdCmd, stream< ap_uint< 8 > > &soMMIO_MetaDropCnt)
 Rx Application Stream (RAs) More...
 
void pRxMemoryReader (stream< DmCmd > &siRas_MemRdCmd, stream< DmCmd > &soMEM_RxpRdCmd, stream< FlagBool > &soAss_SplitSeg)
 Rx Memory Reader (Mrd) More...
 
void pAppSegmentStitcher (stream< AxisApp > &siMEM_RxP_Data, stream< TcpAppData > &soTAIF_Data, stream< FlagBool > &siMrd_SplitSegFlag, stream< ap_uint< 8 > > &soMMIO_DataDropCnt)
 Application Segment Stitcher (Ass) More...
 
void pLsnAppInterface (stream< TcpAppLsnReq > &siTAIF_LsnReq, stream< TcpAppLsnRep > &soTAIF_LsnRep, stream< TcpPort > &soPRt_LsnReq, stream< RepBit > &siPRt_LsnRep)
 Listen Application Interface (Lai) More...
 
void rx_app_interface (stream< TcpAppNotif > &soTAIF_Notif, stream< TcpAppRdReq > &siTAIF_DataReq, stream< TcpAppData > &soTAIF_Data, stream< TcpAppMeta > &soTAIF_Meta, stream< TcpAppLsnReq > &siTAIF_LsnReq, stream< TcpAppLsnRep > &soTAIF_LsnRep, stream< TcpPort > &soPRt_LsnReq, stream< AckBit > &siPRt_LsnAck, stream< TcpAppNotif > &siRXe_Notif, stream< TcpAppNotif > &siTIm_Notif, stream< RAiRxSarQuery > &soRSt_RxSarReq, stream< RAiRxSarReply > &siRSt_RxSarRep, stream< DmCmd > &soMEM_RxP_RdCmd, stream< AxisApp > &siMEM_RxP_Data, stream< ap_uint< 8 > > &soMMIO_NotifDropCnt, stream< ap_uint< 8 > > &soMMIO_MetaDropCnt, stream< ap_uint< 8 > > &soMMIO_DataDropCnt)
 Rx Application Interface (RAi) More...
 
void pTcpLengthExtractor (stream< AxisIp4 > &siIPRX_Data, stream< AxisRaw > &soIph_Data, stream< TcpSegLen > &soIph_TcpSegLen)
 TCP Length Extraction (Tle) More...
 
void pInsertPseudoHeader (stream< AxisRaw > &siTle_Data, stream< TcpSegLen > &siTle_TcpSegLen, stream< AxisPsd4 > &soCsa_PseudoPkt)
 Insert pseudo header (Iph) More...
 
void pCheckSumAccumulator (stream< AxisPsd4 > &siIph_PseudoPkt, stream< AxisApp > &soTid_Data, stream< ValBit > &soTid_DataVal, stream< RXeMeta > &soMdh_Meta, stream< SocketPair > &soMdh_SockPair, stream< TcpPort > &soPRt_GetState)
 TCP checksum accumulator (Csa) More...
 
void pTcpInvalidDropper (stream< AxisApp > &siCsa_Data, stream< ValBit > &siCsa_DataVal, stream< AxisApp > &soTsd_Data, stream< ap_uint< 8 > > &soMMIO_CrcDropCnt)
 TCP Invalid checksum Dropper (Tid) More...
 
void pTcpSegmentDropper (stream< AxisApp > &siTid_Data, stream< CmdBit > &siMdh_DropCmd, stream< CmdBit > &siFsm_DropCmd, stream< AxisApp > &soMwr_Data)
 TCP Segment Dropper (Tsd) More...
 
void pRxMemoryWriter (stream< AxisApp > &siTsd_Data, stream< DmCmd > &siFsm_MemWrCmd, stream< DmCmd > &soMEM_WrCmd, stream< AxisApp > &soMEM_WrData, stream< FlagBool > &soRan_SplitSeg)
 Rx Memory Writer (Mwr) More...
 
void pRxAppNotifier (stream< DmSts > &siMEM_WrSts, stream< TcpAppNotif > &siFsm_Notif, stream< TcpAppNotif > &soRAi_RxNotif, stream< FlagBool > &siMwr_SplitSeg, stream< StsBit > &soMMIO_MemWrErr)
 Rx Application Notifier (Ran) More...
 
void pMetaDataHandler (stream< RXeMeta > &siCsa_Meta, stream< SocketPair > &siCsa_SockPair, stream< SessionLookupQuery > &soSLc_SessLkpReq, stream< SessionLookupReply > &siSLc_SessLkpRep, stream< StsBit > &siPRt_PortSts, stream< ExtendedEvent > &soEVe_Event, stream< CmdBit > &soTsd_DropCmd, stream< RXeFsmMeta > &soFsm_Meta, stream< ap_uint< 8 > > &soMMIO_SessDropCnt)
 MetaData Handler (Mdh) More...
 
void pFiniteStateMachine (stream< RXeFsmMeta > &siMdh_FsmMeta, stream< StateQuery > &soSTt_StateQry, stream< TcpState > &siSTt_StateRep, stream< RXeRxSarQuery > &soRSt_RxSarQry, stream< RxSarReply > &siRSt_RxSarRep, stream< RXeTxSarQuery > &soTSt_TxSarQry, stream< RXeTxSarReply > &siTSt_TxSarRep, stream< RXeReTransTimerCmd > &soTIm_ReTxTimerCmd, stream< SessionId > &soTIm_ClearProbeTimer, stream< SessionId > &soTIm_CloseTimer, stream< SessState > &soTAi_SessOpnSts, stream< Event > &soEVe_Event, stream< CmdBit > &soTsd_DropCmd, stream< DmCmd > &soMwr_WrCmd, stream< TcpAppNotif > &soRan_RxNotif, stream< ap_uint< 8 > > &soMMIO_OooDropCnt, stream< RxBufPtr > &soDBG_RxFreeSpace, stream< ap_uint< 32 > > &soDBG_TcpIpRxByteCnt, stream< ap_uint< 8 > > &soDBG_OooDebug)
 Finite State machine (Fsm) More...
 
void pEventMultiplexer (stream< ExtendedEvent > &siMdh_Event, stream< Event > &siFsm_Event, stream< ExtendedEvent > &soEVe_Event)
 Event Multiplexer (Evm) More...
 
void rx_engine (stream< AxisIp4 > &siIPRX_Data, stream< SessionLookupQuery > &soSLc_SessLkReq, stream< SessionLookupReply > &siSLc_SessLkRep, stream< StateQuery > &soSTt_StateQry, stream< TcpState > &siSTt_StateRep, stream< TcpPort > &soPRt_PortStateReq, stream< RepBit > &siPRt_PortStateRep, stream< RXeRxSarQuery > &soRSt_RxSarQry, stream< RxSarReply > &siRSt_RxSarRep, stream< RXeTxSarQuery > &soTSt_TxSarQry, stream< RXeTxSarReply > &siTSt_TxSarRep, stream< RXeReTransTimerCmd > &soTIm_ReTxTimerCmd, stream< SessionId > &soTIm_ClearProbeTimer, stream< SessionId > &soTIm_CloseTimer, stream< ExtendedEvent > &soEVe_SetEvent, stream< SessState > &soTAi_SessOpnSts, stream< TcpAppNotif > &soRAi_RxNotif, stream< DmCmd > &soMEM_WrCmd, stream< AxisApp > &soMEM_WrData, stream< DmSts > &siMEM_WrSts, stream< StsBit > &soMMIO_RxMemWrErr, stream< ap_uint< 8 > > &soMMIO_CrcDropCnt, stream< ap_uint< 8 > > &soMMIO_SessDropCnt, stream< ap_uint< 8 > > &soMMIO_OooDropCnt, stream< RxBufPtr > &soDBG_RxFreeSpace, stream< ap_uint< 32 > > &soDBG_TcpIpRxByteCnt, stream< ap_uint< 8 > > &soDBG_OooDebug)
 Receive Engine (RXe) More...
 
void rx_sar_table (stream< RXeRxSarQuery > &siRXe_RxSarQry, stream< RxSarReply > &soRXe_RxSarRep, stream< RAiRxSarQuery > &siRAi_RxSarQry, stream< RAiRxSarReply > &soRAi_RxSarRep, stream< SessionId > &siTXe_RxSarReq, stream< RxSarReply > &soTxe_RxSarRep)
 Rx SAR Table (RSt) More...
 
void pSessionIdManager (stream< RtlSessId > &siUrs_FreeId, stream< RtlSessId > &soLrh_FreeList)
 Session Id Manager (Sim) More...
 
void pLookupReplyHandler (stream< CamSessionLookupRequest > &soCAM_SessLookupReq, stream< CamSessionLookupReply > &siCAM_SessLookupRep, stream< CamSessionUpdateReply > &siUrh_SessUpdateRsp, stream< SessionLookupQuery > &siRXe_SessLookupReq, stream< SessionLookupReply > &soRXe_SessLookupRep, stream< SocketPair > &siTAi_SessLookupReq, stream< SessionLookupReply > &soTAi_SessLookupRep, stream< RtlSessId > &siSim_FreeList, stream< CamSessionUpdateRequest > &soUrs_InsertSessReq, stream< SLcReverseLkp > &soRlt_ReverseLkpRsp)
 Lookup Reply Handler (Lrh) More...
 
void pUpdateRequestSender (stream< CamSessionUpdateRequest > &siLrh_InsertSessReq, stream< CamSessionUpdateRequest > &siRlt_SessDeleteReq, stream< CamSessionUpdateRequest > &soCAM_SessUpdateReq, stream< RtlSessId > &soSim_FreeId, stream< ap_uint< 16 > > &soSssRelCnt, stream< ap_uint< 16 > > &soSssRegCnt)
 Update Request Sender (Urs) More...
 
void pUpdateReplyHandler (stream< CamSessionUpdateReply > &siCAM_SessUpdateRep, stream< CamSessionUpdateReply > &soLrh_SessUpdateRsp)
 Update Reply Handler (Urh) More...
 
void pReverseLookupTable (stream< SLcReverseLkp > &siLrh_ReverseLkpRsp, stream< SessionId > &siSTt_SessReleaseCmd, stream< SessionId > &siTXe_ReverseLkpReq, stream< fourTuple > &soTXe_ReverseLkpRep, stream< TcpPort > &soPRt_ClosePortCmd, stream< CamSessionUpdateRequest > &soUrs_SessDeleteReq)
 Reverse Lookup Table (Rlt) More...
 
void session_lookup_controller (stream< SessionLookupQuery > &siRXe_SessLookupReq, stream< SessionLookupReply > &soRXe_SessLookupRep, stream< SessionId > &siSTt_SessReleaseCmd, stream< TcpPort > &soPRt_ClosePortCmd, stream< SocketPair > &siTAi_SessLookupReq, stream< SessionLookupReply > &soTAi_SessLookupRep, stream< SessionId > &siTXe_ReverseLkpReq, stream< fourTuple > &soTXe_ReverseLkpRep, stream< CamSessionLookupRequest > &soCAM_SessLookupReq, stream< CamSessionLookupReply > &siCAM_SessLookupRep, stream< CamSessionUpdateRequest > &soCAM_SessUpdateReq, stream< CamSessionUpdateReply > &siCAM_SessUpdateRep, stream< ap_uint< 16 > > &soSssRelCnt, stream< ap_uint< 16 > > &soSssRegCnt)
 Session Lookup Controller (SLc) More...
 
void state_table (stream< StateQuery > &siRXe_SessStateQry, stream< TcpState > &soRXe_SessStateRep, stream< StateQuery > &siTAi_ConnectStateQry, stream< TcpState > &soTAi_ConnectStateRep, stream< SessionId > &siTAi_StreamStateReq, stream< TcpState > &soTAi_StreamStateRep, stream< SessionId > &siTIm_SessCloseCmd, stream< SessionId > &soSLc_SessReleaseCmd)
 State Table (STt) More...
 
template<typename T >
void pStreamMux (stream< T > &si1, stream< T > &si2, stream< T > &so)
 A 2-to-1 generic Stream Multiplexer. More...
 
void pRetransmitTimer (stream< RXeReTransTimerCmd > &siRXe_ReTxTimerCmd, stream< TXeReTransTimerCmd > &siTXe_ReTxTimerCmd, stream< Event > &soEmx_Event, stream< SessionId > &soSmx_SessCloseCmd, stream< SessState > &soTAi_Notif, stream< TcpAppNotif > &soRAi_Notif)
 ReTransmit Timer (Rtt) process. More...
 
void pProbeTimer (stream< SessionId > &siRXe_ClrProbeTimer, stream< SessionId > &siTXe_SetProbeTimer, stream< Event > &soEmx_Event)
 Probe Timer (Prb) process. More...
 
void pCloseTimer (stream< SessionId > &siRXe_CloseTimer, stream< SessionId > &soSmx_SessCloseCmd)
 Close Timer (Clt) process. More...
 
void timers (stream< RXeReTransTimerCmd > &siRXe_ReTxTimerCmd, stream< SessionId > &siRXe_ClrProbeTimer, stream< SessionId > &siRXe_CloseTimer, stream< TXeReTransTimerCmd > &siTXe_ReTxTimerCmd, stream< SessionId > &siTXe_SetProbeTimer, stream< SessionId > &soSTt_SessCloseCmd, stream< Event > &soEVe_Event, stream< SessState > &soTAi_Notif, stream< TcpAppNotif > &soRAi_Notif)
 The Timers (TIm) More...
 
void pReady (StsBool &piPRt_Ready, StsBit &poNTS_Ready)
 Ready (Rdy) More...
 
void pTbSimCount (volatile ap_uint< 32 > &poSimCycCount)
 Testbench Simulation Counter. More...
 
void toe (Ip4Addr piMMIO_IpAddr, stream< StsBit > &soMMIO_RxMemWrErr, stream< ap_uint< 8 > > &soMMIO_NotifDropCnt, stream< ap_uint< 8 > > &soMMIO_MetaDropCnt, stream< ap_uint< 8 > > &soMMIO_DataDropCnt, stream< ap_uint< 8 > > &soMMIO_CrcDropCnt, stream< ap_uint< 8 > > &soMMIO_SessDropCnt, stream< ap_uint< 8 > > &soMMIO_OooDropCnt, StsBit &poNTS_Ready, stream< AxisIp4 > &siIPRX_Data, stream< AxisIp4 > &soIPTX_Data, stream< TcpAppNotif > &soTAIF_Notif, stream< TcpAppRdReq > &siTAIF_DReq, stream< TcpAppData > &soTAIF_Data, stream< TcpAppMeta > &soTAIF_Meta, stream< TcpAppLsnReq > &siTAIF_LsnReq, stream< TcpAppLsnRep > &soTAIF_LsnRep, stream< TcpAppData > &siTAIF_Data, stream< TcpAppSndReq > &siTAIF_SndReq, stream< TcpAppSndRep > &soTAIF_SndRep, stream< TcpAppOpnReq > &siTAIF_OpnReq, stream< TcpAppOpnRep > &soTAIF_OpnRep, stream< TcpAppClsReq > &siTAIF_ClsReq, stream< DmCmd > &soMEM_RxP_RdCmd, stream< AxisApp > &siMEM_RxP_Data, stream< DmSts > &siMEM_RxP_WrSts, stream< DmCmd > &soMEM_RxP_WrCmd, stream< AxisApp > &soMEM_RxP_Data, stream< DmCmd > &soMEM_TxP_RdCmd, stream< AxisApp > &siMEM_TxP_Data, stream< DmSts > &siMEM_TxP_WrSts, stream< DmCmd > &soMEM_TxP_WrCmd, stream< AxisApp > &soMEM_TxP_Data, stream< CamSessionLookupRequest > &soCAM_SssLkpReq, stream< CamSessionLookupReply > &siCAM_SssLkpRep, stream< CamSessionUpdateRequest > &soCAM_SssUpdReq, stream< CamSessionUpdateReply > &siCAM_SssUpdRep, stream< ap_uint< 16 > > &soDBG_SssRelCnt, stream< ap_uint< 16 > > &soDBG_SssRegCnt, stream< RxBufPtr > &soDBG_RxFreeSpace, stream< ap_uint< 32 > > &soDBG_TcpIpRxByteCnt, stream< ap_uint< 8 > > &soDBG_OooDebug)
 Main process of the TCP Offload Engine (TOE0. More...
 
void toe_top (Ip4Addr piMMIO_IpAddr, stream< StsBit > &soMMIO_RxMemWrErr, stream< ap_uint< 8 > > &soMMIO_NotifDropCnt, stream< ap_uint< 8 > > &soMMIO_MetaDropCnt, stream< ap_uint< 8 > > &soMMIO_DataDropCnt, stream< ap_uint< 8 > > &soMMIO_CrcDropCnt, stream< ap_uint< 8 > > &soMMIO_SessDropCnt, stream< ap_uint< 8 > > &soMMIO_OooDropCnt, StsBit &poNTS_Ready, stream< AxisRaw > &siIPRX_Data, stream< AxisRaw > &soIPTX_Data, stream< TcpAppNotif > &soTAIF_Notif, stream< TcpAppRdReq > &siTAIF_DReq, stream< TcpAppData > &soTAIF_Data, stream< TcpAppMeta > &soTAIF_Meta, stream< TcpAppLsnReq > &siTAIF_LsnReq, stream< TcpAppLsnRep > &soTAIF_LsnRep, stream< TcpAppData > &siTAIF_Data, stream< TcpAppSndReq > &siTAIF_SndReq, stream< TcpAppSndRep > &soTAIF_SndRep, stream< TcpAppOpnReq > &siTAIF_OpnReq, stream< TcpAppOpnRep > &soTAIF_OpnRep, stream< TcpAppClsReq > &siTAIF_ClsReq, stream< DmCmd > &soMEM_RxP_RdCmd, stream< AxisApp > &siMEM_RxP_Data, stream< DmSts > &siMEM_RxP_WrSts, stream< DmCmd > &soMEM_RxP_WrCmd, stream< AxisApp > &soMEM_RxP_Data, stream< DmCmd > &soMEM_TxP_RdCmd, stream< AxisApp > &siMEM_TxP_Data, stream< DmSts > &siMEM_TxP_WrSts, stream< DmCmd > &soMEM_TxP_WrCmd, stream< AxisApp > &soMEM_TxP_Data, stream< CamSessionLookupRequest > &soCAM_SssLkpReq, stream< CamSessionLookupReply > &siCAM_SssLkpRep, stream< CamSessionUpdateRequest > &soCAM_SssUpdReq, stream< CamSessionUpdateReply > &siCAM_SssUpdRep, stream< ap_uint< 16 > > &soDBG_SssRelCnt, stream< ap_uint< 16 > > &soDBG_SssRegCnt, stream< RxBufPtr > &soDBG_RxFreeSpace, stream< ap_uint< 32 > > &soDBG_TcpIpRxByteCnt, stream< ap_uint< 8 > > &soDBG_OooDebug)
 Top of TCP Offload Engine (TOE) More...
 
const char * getEventName (EventType evType)
 Returns the name of an enum-based event as a user friendly string. More...
 
void printFourTuple (const char *callerName, int src, FourTuple fourTuple)
 Print a socket pair association from an internal FourTuple encoding. More...
 
void pTxAppConnect (stream< TcpAppOpnReq > &siTAIF_OpnReq, stream< TcpAppOpnRep > &soTAIF_OpnRep, stream< TcpAppClsReq > &siTAIF_ClsReq, stream< SocketPair > &soSLc_SessLookupReq, stream< SessionLookupReply > &siSLc_SessLookupRep, stream< ReqBit > &soPRt_GetFreePortReq, stream< TcpPort > &siPRt_GetFreePortRep, stream< StateQuery > &soSTt_ConnectStateQry, stream< TcpState > &siSTt_ConnectStateRep, stream< SessState > &siRXe_ActSessState, stream< Event > &soEVe_Event, stream< SessState > &siTIm_Notif, Ip4Address piMMIO_IpAddr)
 Tx Application Connect (Tac) More...
 
void pTxAppStatusHandler (stream< DmSts > &siMEM_TxP_WrSts, stream< Event > &siEmx_Event, stream< TAiTxSarPush > &soTSt_PushCmd, stream< Event > &soEVe_Event)
 Tx Application Status Handler (Tash) More...
 
void pTxAppTable (stream< TStTxSarPush > &siTSt_PushCmd, stream< TxAppTableQuery > &siTas_AccessQry, stream< TxAppTableReply > &siTas_AccessRep)
 Tx Application Table (Tat) More...
 
void pStreamMetaLoader (stream< TcpAppSndReq > &siTAIF_SndReq, stream< TcpAppSndRep > &soTAIF_SndRep, stream< SessionId > &soSTt_SessStateReq, stream< TcpState > &siSTt_SessStateRep, stream< TxAppTableQuery > &soTat_AccessReq, stream< TxAppTableReply > &siTat_AccessRep, stream< AppMemMeta > &soMwr_AppMeta, stream< Event > &soEmx_Event)
 Stream Metadata Loader (Sml) More...
 
void pTxMemoryWriter (stream< TcpAppData > &siTAIF_Data, stream< AppMemMeta > &siSml_AppMeta, stream< DmCmd > &soMEM_WrCmd, stream< AxisApp > &soMEM_WrData)
 Tx Memory Writer (Mwr) More...
 
void tx_app_interface (stream< TcpAppOpnReq > &siTAIF_OpnReq, stream< TcpAppOpnRep > &soTAIF_OpnRep, stream< TcpAppClsReq > &siTAIF_ClsReq, stream< TcpAppData > &siTAIF_Data, stream< TcpAppSndReq > &siTAIF_SndReq, stream< TcpAppSndRep > &soTAIF_SndRep, stream< DmCmd > &soMEM_TxP_WrCmd, stream< AxisApp > &soMEM_TxP_Data, stream< DmSts > &siMEM_TxP_WrSts, stream< SessionId > &soSTt_SessStateReq, stream< TcpState > &siSTt_SessStateRep, stream< StateQuery > &soSTt_ConnectStateQry, stream< TcpState > &siSTt_ConnectStateRep, stream< SocketPair > &soSLc_SessLookupReq, stream< SessionLookupReply > &siSLc_SessLookupRep, stream< ReqBit > &soPRt_GetFreePortReq, stream< TcpPort > &siPRt_GetFreePortRep, stream< TStTxSarPush > &siTSt_PushCmd, stream< TAiTxSarPush > &soTSt_PushCmd, stream< SessState > &siRXe_ActSessState, stream< Event > &soEVe_Event, stream< SessState > &siTIm_Notif, Ip4Addr piMMIO_IpAddr)
 Tx Application Interface (TAi) More...
 
void pMetaDataLoader (stream< ExtendedEvent > &siAKd_Event, stream< SessionId > &soRSt_RxSarReq, stream< RxSarReply > &siRSt_RxSarRep, stream< TXeTxSarQuery > &soTSt_TxSarQry, stream< TXeTxSarReply > &siTSt_TxSarRep, stream< TXeReTransTimerCmd > &soTIm_ReTxTimerCmd, stream< SessionId > &soTIm_SetProbeTimer, stream< TcpDatLen > &soIhc_TcpDatLen, stream< TXeMeta > &soPhc_TxeMeta, stream< DmCmd > &soMrd_BufferRdCmd, stream< SessionId > &soSLc_ReverseLkpReq, stream< StsBool > &soSps_IsLookup, stream< LE_SocketPair > &soSps_RstSockPair, stream< SigBit > &soEVe_RxEventSig)
 Meta Data Loader (Mdl) More...
 
void pSocketPairSplitter (stream< fourTuple > &siSLc_ReverseLkpRsp, stream< LE_SocketPair > &siMdl_RstSockPair, stream< StsBool > &siMdl_IsLookup, stream< IpAddrPair > &soIhc_IpAddrPair, stream< SocketPair > &soPhc_SocketPair)
 
void pIpHeaderConstructor (stream< TcpDatLen > &siMdl_TcpDatLen, stream< IpAddrPair > &siSps_IpAddrPair, stream< AxisIp4 > &soIPs_IpHeader)
 IPv4 Header Constructor (Ihc) More...
 
void pPseudoHeaderConstructor (stream< TXeMeta > &siMdl_TxeMeta, stream< SocketPair > &siSps_SockPair, stream< AxisPsd4 > &soTss_PseudoHdr)
 Pseudo Header Constructor (Phc) More...
 
void pTcpSegStitcher (stream< AxisPsd4 > &siPhc_PseudoHdr, stream< AxisApp > &siMEM_TxP_Data, stream< AxisPsd4 > &soSca_PseudoPkt, stream< FlagBool > &siMrd_SplitSegFlag)
 
void pSubChecksumAccumulators (stream< AxisPsd4 > &siTss_PseudoPkt, stream< AxisPsd4 > &soIps_PseudoPkt, stream< SubCSums > &soTca_4SubCsums)
 Sub-Checksum Accumulator (Sca) More...
 
void pTcpChecksumAccumulator (stream< SubCSums > &siSca_FourSubCsums, stream< TcpChecksum > &soIps_TcpCsum)
 TCP Checksum Accumulator (Tca) More...
 
void pIpPktStitcher (stream< AxisIp4 > &siIhc_IpHeader, stream< AxisPsd4 > &siSca_PseudoPkt, stream< TcpChecksum > &siTca_TcpCsum, stream< AxisIp4 > &soIPTX_Data)
 IPv4 Packet Stitcher (Ips) More...
 
void pTxMemoryReader (stream< DmCmd > &siMdl_BufferRdCmd, stream< DmCmd > &soMEM_TxpRdCmd, stream< FlagBool > &soTss_SplitMemAcc)
 Tx Memory Reader (Mrd) More...
 
void tx_engine (stream< ExtendedEvent > &siAKd_Event, stream< SigBit > &soEVe_RxEventSig, stream< SessionId > &soRSt_RxSarReq, stream< RxSarReply > &siRSt_RxSarRep, stream< TXeTxSarQuery > &soTSt_TxSarQry, stream< TXeTxSarReply > &siTSt_TxSarRep, stream< DmCmd > &soMEM_Txp_RdCmd, stream< AxisApp > &siMEM_TxP_Data, stream< TXeReTransTimerCmd > &soTIm_ReTxTimerCmd, stream< SessionId > &soTIm_SetProbeTimer, stream< SessionId > &soSLc_ReverseLkpReq, stream< fourTuple > &siSLc_ReverseLkpRep, stream< AxisIp4 > &soIPTX_Data)
 Transmit Engine (TXe) More...
 
void tx_sar_table (stream< RXeTxSarQuery > &siRXe_TxSarQry, stream< RXeTxSarReply > &soRXe_TxSarRep, stream< TXeTxSarQuery > &siTXe_TxSarQry, stream< TXeTxSarReply > &soTXe_TxSarRep, stream< TAiTxSarPush > &siTAi_PushCmd, stream< TStTxSarPush > &soTAi_PushCmd)
 Tx Sar Table (TSt). Stores the data structures for managing the TCP Tx buffer and Tx sliding window. More...
 
void DummyMemory::setReadCmd (DmCmd cmd)
 
void DummyMemory::setWriteCmd (DmCmd cmd)
 
void DummyMemory::readChunk (AxisApp &chunk)
 
void DummyMemory::writeChunk (AxisApp &chunk)
 

Variables

bool gTraceEvent
 
bool gTraceEvent
 
bool gTraceEvent
 
bool gTraceEvent
 
bool gTraceEvent
 
const int cDepth_FsmToEve_Event = 4
 
const int cDepth_FsmToMwr_WrCmd = 16
 
const int cDepth_FsmToRan_Notif = 16
 
const int cDepth_FsmToTsd_DropCmd = 16
 
const int cDepth_MdhToEvm_Event = 4
 
const int cDepth_MdhToTsd_DropCmd = 16
 
const int cDepth_MwrToRan_SplitSeg = 16
 
bool gTraceEvent
 
bool gTraceEvent
 
bool gTraceEvent
 
bool gTraceEvent
 
bool gTraceEvent
 
uint32_t packetCounter
 
uint32_t idleCycCnt
 
unsigned int gSimCycCnt
 
const int cDepth_AKdToEVe_Event = 8
 
const int cDepth_AKdToTXe_Event = 16
 
const int cDepth_EVeToAKd_Event = 8
 
const int cDepth_RAiToRSt_Qry = 4
 
const int cDepth_RXeToEVe_Event = 64
 
const int cDepth_RXeToRSt_Qry = 4
 
const int cDepth_RXeToTSt_Qry = 4
 
const int cDepth_STtToRXe_Rep = 2
 
const int cDepth_STtToTAi_Rep = 2
 
const int cDepth_TAiToEVe_Event = 8
 
const int cDepth_TAiToTSt_Cmd = 4
 
const int cDepth_TStToRXe_Rep = 2
 
const int cDepth_TStToTAi_Cmd = 4
 
const int cDepth_TStToTXe_Rep = 2
 
const int cDepth_TImToEVe_Event = 4
 
const int cDepth_TXeToEVe_Event = 8
 
const int cDepth_TXeToRSt_Req = 4
 
const int cDepth_TXeToTSt_Qry = 4
 
bool gTraceEvent
 
bool gTraceEvent
 
bool gTraceEvent
 

Detailed Description

TCP Offload Engine (TOE) of the Network Transport Stack (NTS).

Macro Definition Documentation

◆ ACT_FREE_PORT

#define ACT_FREE_PORT   false

Definition at line 66 of file port_table.hpp.

◆ ACT_USED_PORT

#define ACT_USED_PORT   true

Definition at line 67 of file port_table.hpp.

◆ ACTIVE_PORT

#define ACTIVE_PORT   false

Definition at line 69 of file port_table.hpp.

◆ cIP4_ADDR_WIDTH

#define cIP4_ADDR_WIDTH   32

GLOBAL DEFINES and GENERIC TYPES

Definition at line 187 of file toe.hpp.

◆ cSHL_TOE_CLS_REQ_WIDTH

#define cSHL_TOE_CLS_REQ_WIDTH   cSHL_TOE_SESS_ID_WIDTH

Definition at line 195 of file toe.hpp.

◆ cSHL_TOE_LSN_ACK_WIDTH

#define cSHL_TOE_LSN_ACK_WIDTH   1

Definition at line 192 of file toe.hpp.

◆ cSHL_TOE_LSN_REQ_WIDTH

#define cSHL_TOE_LSN_REQ_WIDTH   cSHL_TOE_SESS_ID_WIDTH

Definition at line 193 of file toe.hpp.

◆ cSHL_TOE_OPN_REQ_WIDTH

#define cSHL_TOE_OPN_REQ_WIDTH   (cIP4_ADDR_WIDTH + cTCP_PORT_WIDTH)

Definition at line 194 of file toe.hpp.

◆ cSHL_TOE_SESS_ID_WIDTH

#define cSHL_TOE_SESS_ID_WIDTH   16

Definition at line 191 of file toe.hpp.

◆ cTCP_PORT_WIDTH

#define cTCP_PORT_WIDTH   16

Definition at line 189 of file toe.hpp.

◆ DEBUG_LEVEL [1/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 75 of file ack_delay.cpp.

◆ DEBUG_LEVEL [2/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 75 of file event_engine.cpp.

◆ DEBUG_LEVEL [3/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 78 of file port_table.cpp.

◆ DEBUG_LEVEL [4/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 79 of file rx_app_interface.cpp.

◆ DEBUG_LEVEL [5/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 83 of file rx_engine.cpp.

◆ DEBUG_LEVEL [6/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 74 of file rx_sar_table.cpp.

◆ DEBUG_LEVEL [7/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 77 of file session_lookup_controller.cpp.

◆ DEBUG_LEVEL [8/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 74 of file state_table.cpp.

◆ DEBUG_LEVEL [9/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 76 of file timers.cpp.

◆ DEBUG_LEVEL [10/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 92 of file toe.cpp.

◆ DEBUG_LEVEL [11/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 80 of file tx_app_interface.cpp.

◆ DEBUG_LEVEL [12/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 83 of file tx_engine.cpp.

◆ DEBUG_LEVEL [13/13]

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 73 of file tx_sar_table.cpp.

◆ DEPTH_ssEmxToTash_Event

#define DEPTH_ssEmxToTash_Event   2

DEFINITIONS OF THE LOCAL STREAM DEPTHS Postponed for the time being:

See also
https://www.xilinx.com/support/answers/46111.html

Definition at line 79 of file tx_app_interface.hpp.

◆ DEPTH_ssSlgToMwr_Data

#define DEPTH_ssSlgToMwr_Data   256

Definition at line 85 of file tx_app_interface.hpp.

◆ DEPTH_ssSlgToSml_SegLen

#define DEPTH_ssSlgToSml_SegLen   32

Definition at line 86 of file tx_app_interface.hpp.

◆ DEPTH_ssSmlToEmx_Event

#define DEPTH_ssSmlToEmx_Event   2

Definition at line 84 of file tx_app_interface.hpp.

◆ DEPTH_ssSmlToMwr_SegMeta

#define DEPTH_ssSmlToMwr_SegMeta   128

Definition at line 83 of file tx_app_interface.hpp.

◆ DEPTH_ssSmlToTat_AccessQry

#define DEPTH_ssSmlToTat_AccessQry   2

Definition at line 82 of file tx_app_interface.hpp.

◆ DEPTH_ssTacToEmx_Event

#define DEPTH_ssTacToEmx_Event   2

Definition at line 80 of file tx_app_interface.hpp.

◆ DEPTH_ssTatToSml_AccessRep

#define DEPTH_ssTatToSml_AccessRep   2

Definition at line 81 of file tx_app_interface.hpp.

◆ DO_PRAGMA

#define DO_PRAGMA (   x)    PRAGMA_SUB(x)

Definition at line 72 of file tx_app_interface.hpp.

◆ FIXME

#define FIXME   1

Definition at line 69 of file tx_engine.cpp.

◆ LISTEN_PORT

#define LISTEN_PORT   true

Definition at line 70 of file port_table.hpp.

◆ PortRange

#define PortRange   bool

Definition at line 72 of file port_table.hpp.

◆ PRAGMA_SUB

#define PRAGMA_SUB (   x)    _Pragma (#x)

HELPERS FOR USING DEFINES IN PRAGMAS

See also
https://www.xilinx.com/support/answers/46111.html

Definition at line 71 of file tx_app_interface.hpp.

◆ RXMEMBUF

#define RXMEMBUF   65536

DDR MEMORY SUB-SYSTEM INTERFACES

Terminology & Conventions (see Xilinx LogiCORE PG022). [DM] stands for AXI Data Mover [DRE] stands for Data Realignment Engine.

Definition at line 727 of file toe.hpp.

◆ THIS_NAME [1/14]

#define THIS_NAME   "TOE/AKd"

Definition at line 69 of file ack_delay.cpp.

◆ THIS_NAME [2/14]

#define THIS_NAME   "TOE/EVe"

Definition at line 69 of file event_engine.cpp.

◆ THIS_NAME [3/14]

#define THIS_NAME   "TOE/PRt"

Definition at line 68 of file port_table.cpp.

◆ THIS_NAME [4/14]

#define THIS_NAME   "TOE/RAi"

Definition at line 69 of file rx_app_interface.cpp.

◆ THIS_NAME [5/14]

#define THIS_NAME   "TOE/RXe"

Definition at line 68 of file rx_engine.cpp.

◆ THIS_NAME [6/14]

#define THIS_NAME   "TOE/RSt"

Definition at line 68 of file rx_sar_table.cpp.

◆ THIS_NAME [7/14]

#define THIS_NAME   "TOE/SLc"

Definition at line 68 of file session_lookup_controller.cpp.

◆ THIS_NAME [8/14]

#define THIS_NAME   "TOE/STt"

Definition at line 68 of file state_table.cpp.

◆ THIS_NAME [9/14]

#define THIS_NAME   "TOE/TIm"

Definition at line 68 of file timers.cpp.

◆ THIS_NAME [10/14]

#define THIS_NAME   "TOE"

Definition at line 86 of file toe.cpp.

◆ THIS_NAME [11/14]

#define THIS_NAME   "ToeUtils"

DEBUG PRINT HELPERS

Definition at line 35 of file toe_utils.cpp.

◆ THIS_NAME [12/14]

#define THIS_NAME   "TOE/TAi"

Definition at line 68 of file tx_app_interface.cpp.

◆ THIS_NAME [13/14]

#define THIS_NAME   "TOE/TXe"

Definition at line 67 of file tx_engine.cpp.

◆ THIS_NAME [14/14]

#define THIS_NAME   "TOE/TSt"

Definition at line 67 of file tx_sar_table.cpp.

◆ TLAST

#define TLAST   1

Definition at line 247 of file toe.hpp.

◆ TOE_FEATURE_USED_FOR_DEBUGGING

#define TOE_FEATURE_USED_FOR_DEBUGGING   0

Definition at line 103 of file toe.hpp.

◆ TOE_FIRST_EPHEMERAL_PORT_NUM

#define TOE_FIRST_EPHEMERAL_PORT_NUM   0x8000

Definition at line 101 of file toe.hpp.

◆ TOE_SIZEOF_ACTIVE_PORT_TABLE

#define TOE_SIZEOF_ACTIVE_PORT_TABLE   0x8000

Definition at line 100 of file toe.hpp.

◆ TOE_SIZEOF_LISTEN_PORT_TABLE

#define TOE_SIZEOF_LISTEN_PORT_TABLE   0x8000

DEFINITIONS

Definition at line 99 of file toe.hpp.

◆ TRACE_AKD

#define TRACE_AKD   1 << 1

Definition at line 72 of file ack_delay.cpp.

◆ TRACE_ALL [1/12]

#define TRACE_ALL   0xFFFF

Definition at line 73 of file ack_delay.cpp.

◆ TRACE_ALL [2/12]

#define TRACE_ALL   0xFFFF

Definition at line 73 of file event_engine.cpp.

◆ TRACE_ALL [3/12]

#define TRACE_ALL   0xFFFF

Definition at line 76 of file port_table.cpp.

◆ TRACE_ALL [4/12]

#define TRACE_ALL   0xFFFF

Definition at line 77 of file rx_app_interface.cpp.

◆ TRACE_ALL [5/12]

#define TRACE_ALL   0xFFFF

Definition at line 81 of file rx_engine.cpp.

◆ TRACE_ALL [6/12]

#define TRACE_ALL   0xFFFF

Definition at line 72 of file rx_sar_table.cpp.

◆ TRACE_ALL [7/12]

#define TRACE_ALL   0xFFFF

Definition at line 72 of file state_table.cpp.

◆ TRACE_ALL [8/12]

#define TRACE_ALL   0xFFFF

Definition at line 74 of file timers.cpp.

◆ TRACE_ALL [9/12]

#define TRACE_ALL   0xFFFF

Definition at line 90 of file toe.cpp.

◆ TRACE_ALL [10/12]

#define TRACE_ALL   0xFFFF

Definition at line 78 of file tx_app_interface.cpp.

◆ TRACE_ALL [11/12]

#define TRACE_ALL   0xFFFF

Definition at line 81 of file tx_engine.cpp.

◆ TRACE_ALL [12/12]

#define TRACE_ALL   0xFFFF

Definition at line 71 of file tx_sar_table.cpp.

◆ TRACE_ASS

#define TRACE_ASS   1 << 2

Definition at line 73 of file rx_app_interface.cpp.

◆ TRACE_CLT

#define TRACE_CLT   1 << 1

Definition at line 71 of file timers.cpp.

◆ TRACE_CSA

#define TRACE_CSA   1 << 3

Definition at line 73 of file rx_engine.cpp.

◆ TRACE_EVE

#define TRACE_EVE   1 << 1

Definition at line 72 of file event_engine.cpp.

◆ TRACE_EVM

#define TRACE_EVM   1 << 7

Definition at line 77 of file rx_engine.cpp.

◆ TRACE_FPT

#define TRACE_FPT   1 << 4

Definition at line 74 of file port_table.cpp.

◆ TRACE_FSM

#define TRACE_FSM   1 << 8

Definition at line 78 of file rx_engine.cpp.

◆ TRACE_IHC

#define TRACE_IHC   1 << 2

Definition at line 73 of file tx_engine.cpp.

◆ TRACE_IPH

#define TRACE_IPH   1 << 2

Definition at line 72 of file rx_engine.cpp.

◆ TRACE_IPS

#define TRACE_IPS   1 << 9

Definition at line 80 of file tx_engine.cpp.

◆ TRACE_IRR

#define TRACE_IRR   1 << 1

Definition at line 71 of file port_table.cpp.

◆ TRACE_LAI

#define TRACE_LAI   1 << 1

Definition at line 72 of file rx_app_interface.cpp.

◆ TRACE_LPT

#define TRACE_LPT   1 << 3

Definition at line 73 of file port_table.cpp.

◆ TRACE_LRH

#define TRACE_LRH   1 << 1

Definition at line 71 of file session_lookup_controller.cpp.

◆ TRACE_MDH

#define TRACE_MDH   1 << 4

Definition at line 74 of file rx_engine.cpp.

◆ TRACE_MDL

#define TRACE_MDL   1 << 1

Definition at line 72 of file tx_engine.cpp.

◆ TRACE_MRD [1/2]

#define TRACE_MRD   1 << 5

Definition at line 76 of file rx_app_interface.cpp.

◆ TRACE_MRD [2/2]

#define TRACE_MRD   1 << 5

Definition at line 76 of file tx_engine.cpp.

◆ TRACE_MWR [1/2]

#define TRACE_MWR   1 << 9

Definition at line 79 of file rx_engine.cpp.

◆ TRACE_MWR [2/2]

#define TRACE_MWR   1 << 3

Definition at line 73 of file tx_app_interface.cpp.

◆ TRACE_NMX

#define TRACE_NMX   1 << 3

Definition at line 74 of file rx_app_interface.cpp.

◆ TRACE_OFF [1/13]

#define TRACE_OFF   0x0000

Definition at line 71 of file ack_delay.cpp.

◆ TRACE_OFF [2/13]

#define TRACE_OFF   0x0000

Definition at line 71 of file event_engine.cpp.

◆ TRACE_OFF [3/13]

#define TRACE_OFF   0x0000

Definition at line 70 of file port_table.cpp.

◆ TRACE_OFF [4/13]

#define TRACE_OFF   0x0000

Definition at line 71 of file rx_app_interface.cpp.

◆ TRACE_OFF [5/13]

#define TRACE_OFF   0x0000

Definition at line 70 of file rx_engine.cpp.

◆ TRACE_OFF [6/13]

#define TRACE_OFF   0x0000

Definition at line 70 of file rx_sar_table.cpp.

◆ TRACE_OFF [7/13]

#define TRACE_OFF   0x0000

Definition at line 70 of file session_lookup_controller.cpp.

◆ TRACE_OFF [8/13]

#define TRACE_OFF   0x0000

Definition at line 70 of file state_table.cpp.

◆ TRACE_OFF [9/13]

#define TRACE_OFF   0x0000

Definition at line 70 of file timers.cpp.

◆ TRACE_OFF [10/13]

#define TRACE_OFF   0x0000

Definition at line 88 of file toe.cpp.

◆ TRACE_OFF [11/13]

#define TRACE_OFF   0x0000

Definition at line 70 of file tx_app_interface.cpp.

◆ TRACE_OFF [12/13]

#define TRACE_OFF   0x0000

Definition at line 71 of file tx_engine.cpp.

◆ TRACE_OFF [13/13]

#define TRACE_OFF   0x0000

Definition at line 69 of file tx_sar_table.cpp.

◆ TRACE_ORM

#define TRACE_ORM   1 << 2

Definition at line 72 of file port_table.cpp.

◆ TRACE_PBT

#define TRACE_PBT   1 << 2

Definition at line 72 of file timers.cpp.

◆ TRACE_PHC

#define TRACE_PHC   1 << 4

Definition at line 75 of file tx_engine.cpp.

◆ TRACE_RAN

#define TRACE_RAN   1 << 10

Definition at line 80 of file rx_engine.cpp.

◆ TRACE_RAS

#define TRACE_RAS   1 << 4

Definition at line 75 of file rx_app_interface.cpp.

◆ TRACE_RDY [1/2]

#define TRACE_RDY   1 << 5

Definition at line 75 of file port_table.cpp.

◆ TRACE_RDY [2/2]

#define TRACE_RDY   1 << 1

Definition at line 89 of file toe.cpp.

◆ TRACE_RLT

#define TRACE_RLT   1 << 2

Definition at line 72 of file session_lookup_controller.cpp.

◆ TRACE_RST

#define TRACE_RST   1 << 1

Definition at line 71 of file rx_sar_table.cpp.

◆ TRACE_RTT

#define TRACE_RTT   1 << 3

Definition at line 73 of file timers.cpp.

◆ TRACE_SCA

#define TRACE_SCA   1 << 7

Definition at line 78 of file tx_engine.cpp.

◆ TRACE_SIM

#define TRACE_SIM   1 << 3

Definition at line 73 of file session_lookup_controller.cpp.

◆ TRACE_SLG

#define TRACE_SLG   1 << 2

Definition at line 72 of file tx_app_interface.cpp.

◆ TRACE_SML

#define TRACE_SML   1 << 1

Definition at line 71 of file tx_app_interface.cpp.

◆ TRACE_SPS

#define TRACE_SPS   1 << 3

Definition at line 74 of file tx_engine.cpp.

◆ TRACE_STT

#define TRACE_STT   1 << 1

Definition at line 71 of file state_table.cpp.

◆ TRACE_TAC

#define TRACE_TAC   1 << 4

Definition at line 74 of file tx_app_interface.cpp.

◆ TRACE_TAS

#define TRACE_TAS   1 << 5

Definition at line 75 of file tx_app_interface.cpp.

◆ TRACE_TASH

#define TRACE_TASH   1 << 7

Definition at line 77 of file tx_app_interface.cpp.

◆ TRACE_TAT

#define TRACE_TAT   1 << 6

Definition at line 76 of file tx_app_interface.cpp.

◆ TRACE_TCA

#define TRACE_TCA   1 << 8

Definition at line 79 of file tx_engine.cpp.

◆ TRACE_TID

#define TRACE_TID   1 << 5

Definition at line 75 of file rx_engine.cpp.

◆ TRACE_TLE

#define TRACE_TLE   1 << 1

Definition at line 71 of file rx_engine.cpp.

◆ TRACE_TSD

#define TRACE_TSD   1 << 6

Definition at line 76 of file rx_engine.cpp.

◆ TRACE_TSS

#define TRACE_TSS   1 << 6

Definition at line 77 of file tx_engine.cpp.

◆ TRACE_TST

#define TRACE_TST   1 << 1

Definition at line 70 of file tx_sar_table.cpp.

◆ TRACE_URH

#define TRACE_URH   1 << 4

Definition at line 74 of file session_lookup_controller.cpp.

◆ TRACE_URS

#define TRACE_URS   1 << 5

Definition at line 75 of file session_lookup_controller.cpp.

◆ TXMEMBUF

#define TXMEMBUF   65536

Definition at line 728 of file toe.hpp.

◆ USE_DEPRECATED_DIRECTIVES

#define USE_DEPRECATED_DIRECTIVES

INTERFACE SYNTHESIS DIRECTIVES For the time being, we continue designing with the DEPRECATED directives because the new PRAGMAs do not work for us.

Definition at line 77 of file toe.cpp.

Typedef Documentation

◆ ClsReq

typedef ap_uint< 16 > ClsReq

Definition at line 201 of file toe.hpp.

◆ HitState

typedef bool HitState

INTERFACE TYPES and CLASSES USED BY SESSION LOOKUP CONTROLLER (SLc)

Definition at line 314 of file toe.hpp.

◆ LE_tData

typedef ap_uint<64> LE_tData

AXIS TYPE FIELDS DEFINITION FYI - 'LE' stands for Little-Endian order.

Definition at line 253 of file toe.hpp.

◆ LE_tKeep

typedef ap_uint< 8> LE_tKeep

Definition at line 254 of file toe.hpp.

◆ LocalWinSize

Definition at line 293 of file toe.hpp.

◆ LsnAck

typedef ap_uint< 1 > LsnAck

Definition at line 198 of file toe.hpp.

◆ LsnReq

typedef ap_uint< 16 > LsnReq

Definition at line 199 of file toe.hpp.

◆ OpnReq

typedef ap_uint< ( 32 + 16 ) > OpnReq

Definition at line 200 of file toe.hpp.

◆ PortState

typedef AckBit PortState

Definition at line 65 of file port_table.hpp.

◆ RemotWinSize

Definition at line 292 of file toe.hpp.

◆ RxBufPtr

Definition at line 298 of file toe.hpp.

◆ RxMemPtr

typedef ap_uint<32> RxMemPtr

Definition at line 295 of file toe.hpp.

◆ RxSeqNum

Definition at line 290 of file toe.hpp.

◆ SessionId

typedef ap_uint< 16 > SessionId

Definition at line 197 of file toe.hpp.

◆ SessState

Definition at line 279 of file toe.hpp.

◆ SLcFourTuple

GLOBAL DEFINITIONS USED BY SLc INTERNAL TYPES and CLASSES USED BY SLc

Definition at line 71 of file session_lookup_controller.hpp.

◆ TcpBufAdr

typedef ap_uint<TOE_WINDOW_BITS> TcpBufAdr

Definition at line 297 of file toe.hpp.

◆ TcpDynPort

typedef ap_uint<15> TcpDynPort

Definition at line 285 of file toe.hpp.

◆ TcpStaPort

typedef ap_uint<15> TcpStaPort

Definition at line 284 of file toe.hpp.

◆ tData

typedef ap_uint<64> tData

Definition at line 255 of file toe.hpp.

◆ tDataHalf

typedef ap_uint<32> tDataHalf

Definition at line 256 of file toe.hpp.

◆ tKeep

typedef ap_uint< 8> tKeep

Definition at line 257 of file toe.hpp.

◆ tLast

typedef ap_uint< 1> tLast

Definition at line 258 of file toe.hpp.

◆ TxAckNum

Definition at line 291 of file toe.hpp.

◆ TxBufPtr

Definition at line 299 of file toe.hpp.

◆ TxMemPtr

typedef ap_uint<32> TxMemPtr

Definition at line 296 of file toe.hpp.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
WORD_0 
WORD_1 
WORD_2 
WORD_3 
WORD_4 
WORD_5 

Definition at line 243 of file toe.hpp.

@ WORD_3
Definition: toe.hpp:243
@ WORD_1
Definition: toe.hpp:243
@ WORD_5
Definition: toe.hpp:243
@ WORD_2
Definition: toe.hpp:243
@ WORD_4
Definition: toe.hpp:243
@ WORD_0
Definition: toe.hpp:243

◆ anonymous enum

anonymous enum
Enumerator
CHUNK_0 
CHUNK_1 
CHUNK_2 
CHUNK_3 
CHUNK_4 
CHUNK_5 

Definition at line 244 of file toe.hpp.

@ CHUNK_2
Definition: toe.hpp:244
@ CHUNK_1
Definition: toe.hpp:244
@ CHUNK_4
Definition: toe.hpp:244
@ CHUNK_5
Definition: toe.hpp:244
@ CHUNK_3
Definition: toe.hpp:244
@ CHUNK_0
Definition: toe.hpp:244

◆ EventType

enum EventType

INTERNAL TYPES and CLASSES USED BY TOE

Terminology & Conventions

  • .
  • .
Enumerator
TX_EVENT 
RT_EVENT 
ACK_EVENT 
SYN_EVENT 
SYN_ACK_EVENT 
FIN_EVENT 
RST_EVENT 
ACK_NODELAY_EVENT 

Definition at line 273 of file toe.hpp.

274  SYN_ACK_EVENT, FIN_EVENT, RST_EVENT, ACK_NODELAY_EVENT };
@ RST_EVENT
Definition: toe.hpp:274
@ SYN_EVENT
Definition: toe.hpp:273
@ ACK_EVENT
Definition: toe.hpp:273
@ FIN_EVENT
Definition: toe.hpp:274
@ TX_EVENT
Definition: toe.hpp:273
@ RT_EVENT
Definition: toe.hpp:273
@ ACK_NODELAY_EVENT
Definition: toe.hpp:274

◆ HitStates

enum HitStates
Enumerator
SESSION_UNKNOWN 
SESSION_EXISTS 

Definition at line 315 of file toe.hpp.

315 { SESSION_UNKNOWN = false, SESSION_EXISTS = true};
@ SESSION_EXISTS
Definition: toe.hpp:315
@ SESSION_UNKNOWN
Definition: toe.hpp:315

◆ notificationType

GENERAL ENUMERATIONS

WARNING ABOUT ENUMERATIONS: Avoid using 'enum' for boolean variables because scoped enums are only available with -std=c++. E.g.: enum PortState : bool { CLOSED_PORT=false, OPENED_PORT=true };

Enumerator
PKG 
CLOSE 
TIME_OUT 
RESET 

Definition at line 242 of file toe.hpp.

242 {PKG, CLOSE, TIME_OUT, RESET};
@ TIME_OUT
Definition: toe.hpp:242
@ RESET
Definition: toe.hpp:242
@ CLOSE
Definition: toe.hpp:242
@ PKG
Definition: toe.hpp:242

◆ StateEntry

enum StateEntry
Enumerator
DISABLED_ENTRY 
ACTIVE_ENTRY 

Definition at line 66 of file timers.hpp.

66  {DISABLED_ENTRY = false,
67  ACTIVE_ENTRY = true};
@ ACTIVE_ENTRY
Definition: timers.hpp:67
@ DISABLED_ENTRY
Definition: timers.hpp:66

◆ TimerCmd

enum TimerCmd

Timers (TIm)

Enumerator
LOAD_TIMER 
STOP_TIMER 

Definition at line 622 of file toe.hpp.

622  {LOAD_TIMER = false,
623  STOP_TIMER = true};
@ LOAD_TIMER
Definition: toe.hpp:622
@ STOP_TIMER
Definition: toe.hpp:623

Function Documentation

◆ ack_delay()

void ack_delay ( stream< ExtendedEvent > &  siEVe_Event,
stream< SigBit > &  soEVe_RxEventSig,
stream< SigBit > &  soEVe_TxEventSig,
stream< ExtendedEvent > &  soTXe_Event 
)

ACK Delayer (AKd)

ENTITY - Acknowledgment Delayer (AKd)

Parameters
[in]siEVe_EventEvent from Event Engine (EVe).
[out]soEVe_RxEventSigSignals the reception of an event.
[out]soEVe_TxEventSigSignals the transmission of an event.
[out]soTXe_EventEvent to Tx Engine (TXe).

This process manages the transmission delay of the ACKs. Upon reception of an ACK, the counter associated to the corresponding session is initialized to (64us/MAX_SESSIONS). Next, this counter is decremented every (MAX_SESSIONS) until it reaches zero. At that time, a request to generate an ACK for that session is forwarded to the TxEngine (Txe). If the pace of incoming segments increases, the rate of returned ACKs is also increased.

switch (ACK_TABLE[ev.sessionID].count) { case 0: // There is no delayed ACK pending --> Schedule a new one ACK_TABLE[ev.sessionID] = AckEntry(ACKD_64us, 1); break; case 1: // Received a second ACK --> Decrease the delay if (ACK_TABLE[ev.sessionID].delay > ACKD_32us) { ACK_TABLE[ev.sessionID].delay = ACKD_32us; } ACK_TABLE[ev.sessionID].count++; break; case 2: // Received a third ACK --> Decrease the delay if (ACK_TABLE[ev.sessionID].delay > ACKD_16us) { ACK_TABLE[ev.sessionID].delay = ACKD_16us; } ACK_TABLE[ev.sessionID].count++; break; case 3: // Received a fourth ACK --> Decrease the delay if (ACK_TABLE[ev.sessionID].delay > ACKD_8us) { ACK_TABLE[ev.sessionID].delay = ACKD_8us; } ACK_TABLE[ev.sessionID].count++; break; case 4: // Received a fifth ACK --> Decrease the delay if (ACK_TABLE[ev.sessionID].delay > ACKD_4us) { ACK_TABLE[ev.sessionID].delay = ACKD_4us; } ACK_TABLE[ev.sessionID].count++; break; case 5: // Received a sixth ACK --> Decrease the delay if (ACK_TABLE[ev.sessionID].delay > ACKD_2us) { ACK_TABLE[ev.sessionID].delay = ACKD_2us; } ACK_TABLE[ev.sessionID].count++; break; case 6: // Received a seventh ACK --> Decrease the delay if (ACK_TABLE[ev.sessionID].delay > ACKD_1us) { ACK_TABLE[ev.sessionID].delay = ACKD_1us; } ACK_TABLE[ev.sessionID].count++; break; default: // Received a eight+ ACK --> Set delay to ONE ACK_TABLE[ev.sessionID].delay = 1; ACK_TABLE[ev.sessionID].count = 8; break; } // End of: switch

Definition at line 95 of file ack_delay.cpp.

100 {
101  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
102  #pragma HLS PIPELINE II=1 enable_flush
103 
104  const char *myName = THIS_NAME;
105 
106  //-- STATIC ARRAYS ---------------------------------------------------------
107  static AckEntry ACK_TABLE[TOE_MAX_SESSIONS];
108  #pragma HLS RESOURCE variable=ACK_TABLE core=RAM_T2P_BRAM
109  #pragma HLS DEPENDENCE variable=ACK_TABLE inter false
110 
111  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
112  // [TODO - The type of 'akd_Ptr' could be configured as a functions of 'MAX_SESSIONS']
113  // [ E.g. - static const int NR_BITS = ceil(log10(MAX_SESSIONS)/log10(2));
114  static SessionId akd_Ptr;
115  #pragma HLS RESET variable=akd_Ptr
116 
117  //-- DYNAMIC VARIABLES -----------------------------------------------------
118  ExtendedEvent ev;
119 
120  if (!siEVe_Event.empty()) {
121 
122  // Read incoming event and inform [EVe] that the FiFo stream was read
123  siEVe_Event.read(ev);
124  assessSize(myName, soEVe_RxEventSig, "soEVe_RxEventSig", cDepth_AKdToEVe_Event);
125  soEVe_RxEventSig.write(1);
126 
127  if (ev.type == ACK_EVENT) {
128 
176  if (ACK_TABLE[ev.sessionID].delay == 0) {
177  // There is no delayed ACK pending --> Schedule a new one
178  ACK_TABLE[ev.sessionID] = AckEntry(ACKD_64us, 1);
179  }
180  else if (ACK_TABLE[ev.sessionID].count == 1) {
181  // Received a second ACK --> Decrease the delay
182  if (ACK_TABLE[ev.sessionID].delay > ACKD_32us) {
183  ACK_TABLE[ev.sessionID].delay = ACKD_32us;
184  }
185  ACK_TABLE[ev.sessionID].count++;
186  }
187  else if (ACK_TABLE[ev.sessionID].count == 2) {
188  // Received a third ACK --> Decrease the delay
189  if (ACK_TABLE[ev.sessionID].delay > ACKD_16us) {
190  ACK_TABLE[ev.sessionID].delay = ACKD_16us;
191  }
192  ACK_TABLE[ev.sessionID].count++;
193  }
194  else if (ACK_TABLE[ev.sessionID].count == 3) {
195  // Received a fourth ACK --> Decrease the delay
196  if (ACK_TABLE[ev.sessionID].delay > ACKD_8us) {
197  ACK_TABLE[ev.sessionID].delay = ACKD_8us;
198  }
199  ACK_TABLE[ev.sessionID].count++;
200  }
201  else if (ACK_TABLE[ev.sessionID].count == 4) {
202  // Received a fifth ACK --> Decrease the delay
203  if (ACK_TABLE[ev.sessionID].delay > ACKD_4us) {
204  ACK_TABLE[ev.sessionID].delay = ACKD_4us;
205  }
206  ACK_TABLE[ev.sessionID].count++;
207  }
208  else if (ACK_TABLE[ev.sessionID].count == 5) {
209  // Received a sixth ACK --> Decrease the delay
210  if (ACK_TABLE[ev.sessionID].delay > ACKD_2us) {
211  ACK_TABLE[ev.sessionID].delay = ACKD_2us;
212  }
213  ACK_TABLE[ev.sessionID].count++;
214  }
215  else if (ACK_TABLE[ev.sessionID].count == 6) {
216  // Received a seventh ACK --> Decrease the delay
217  if (ACK_TABLE[ev.sessionID].delay > ACKD_1us) {
218  ACK_TABLE[ev.sessionID].delay = ACKD_1us;
219  }
220  ACK_TABLE[ev.sessionID].count++;
221  }
222  else if (ACK_TABLE[ev.sessionID].count == 7) {
223  // Received a eight+ ACK --> Set delay to ONE
224  ACK_TABLE[ev.sessionID].delay = 1;
225  ACK_TABLE[ev.sessionID].count = 8;
226  }
227  // Debug trace
228  if (DEBUG_LEVEL & TRACE_AKD) {
229  printInfo(myName, "S%d - Received \'%s\' - Setting ACK_TABLE[%d]={D=%4.4d,C=%2.2d}\n",
230  ev.sessionID.to_int(), getEventName(ev.type),
231  ev.sessionID.to_uint(),
232  ACK_TABLE[ev.sessionID].delay.to_uint(),
233  ACK_TABLE[ev.sessionID].count.to_uint());
234  }
235  }
236  else {
237  // Received any other event --> Reset current entry
238  ACK_TABLE[ev.sessionID] = AckEntry(0, 0);
239  // Forward event to TxEngine
240  assessSize(myName, soTXe_Event, "soTXe_Event", cDepth_AKdToTXe_Event);
241  soTXe_Event.write(ev);
242  // Tell the EventEngine that we just forwarded an none-ACK event to TXe
243  assessSize(myName, soEVe_TxEventSig, "soEVe_TxEventSig", cDepth_AKdToEVe_Event);
244  soEVe_TxEventSig.write(1);
245  // Debug trace
246  if (DEBUG_LEVEL & TRACE_AKD) {
247  printInfo(myName, "S%d - Received '%s' - Clearing ACK_TABLE[%d]={D=%4.4d,C=%2.2d}\n",
248  ev.sessionID.to_int(), getEventName(ev.type),
249  ev.sessionID.to_uint(),
250  ACK_TABLE[ev.sessionID].delay.to_uint(),
251  ACK_TABLE[ev.sessionID].count.to_uint());
252  }
253  }
254  }
255  else {
256  if (ACK_TABLE[akd_Ptr].delay > 0 and !soTXe_Event.full()) {
257  if (ACK_TABLE[akd_Ptr].delay == 1) {
258  soTXe_Event.write(Event(ACK_EVENT, akd_Ptr));
259  // Tell the EventEngine that we just forwarded an event to TXe
260  assessSize(myName, soEVe_TxEventSig, "soEVe_TxEventSig", cDepth_AKdToEVe_Event);
261  soEVe_TxEventSig.write(1);
262  // Do not clear the received ACK counter here. It will anyhow be
263  // cleared whenever a new event comes in. Until then, it gives
264  // us a good indication of its usage in the trace.
265  if (DEBUG_LEVEL & TRACE_AKD) {
266  printInfo(myName, "S%d - It's ACK Time (count=%d) - Requesting [TXe] to generate an new ACK\n",
267  akd_Ptr.to_int(), ACK_TABLE[akd_Ptr].count.to_uint());
268  }
269  }
270  ACK_TABLE[akd_Ptr].delay -= 1;
271  }
272  akd_Ptr++;
273  if (akd_Ptr == TOE_MAX_SESSIONS) {
274  akd_Ptr = 0;
275  }
276  }
277 }
ap_uint< 4 > count
Definition: ack_delay.hpp:76
ap_uint< 12 > delay
Definition: ack_delay.hpp:75
Definition: toe.hpp:661
SessionId sessionID
Definition: toe.hpp:664
EventType type
Definition: toe.hpp:663
void delay(unsigned int mseconds)
Definition: common.hpp:85
#define TRACE_AKD
Definition: ack_delay.cpp:72
const int cDepth_AKdToTXe_Event
Definition: toe.hpp:207
const char * getEventName(EventType evType)
Returns the name of an enum-based event as a user friendly string.
Definition: toe_utils.cpp:43
const int cDepth_AKdToEVe_Event
Definition: toe.hpp:206
#define THIS_NAME
Definition: ack_delay.cpp:69
#define DEBUG_LEVEL
Definition: ack_delay.cpp:75
#define assessSize(callerName, stream, streamName, depth)
A macro that checks if a stream is full.
Definition: nts_utils.hpp:223
ap_uint< 16 > SessionId
Definition: nts_types.hpp:136
#define printInfo(callerName, format,...)
A macro to print an information message.
Definition: nts_utils.hpp:169
Here is the caller graph for this function:

◆ ack_delay_OBSO()

void ack_delay_OBSO ( stream< ExtendedEvent > &  siEVe_Event,
stream< SigBit > &  soEVe_RxEventSig,
stream< SigBit > &  soEVe_TxEventSig,
stream< ExtendedEvent > &  soTXe_Event 
)

Definition at line 280 of file ack_delay.cpp.

285 {
286  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
287  #pragma HLS PIPELINE II=1 enable_flush
288 
289  const char *myName = THIS_NAME;
290 
291  //-- STATIC ARRAYS ---------------------------------------------------------
292  // [TODO - The type of 'ACK_TABLE' can be configured as a functions of 'TIME_XXX' and 'MAX_SESSIONS']
293  // [ E.g. - TIME_64us = ( 64.000/0.0064/32) + 1 = 313 = 0x139 ( 9-bits)
294  // [ E.g. - TIME_64us = ( 64.000/0.0064/ 8) + 1 = 1251 = 0x4E3 (11-bits)
295  // [ E.g. - TIME_128us = (128.000/0.0064/32) + 1 = 626 = 0x271 (10-bits)
296  static ap_uint<12> ACK_TABLE[TOE_MAX_SESSIONS];
297  #pragma HLS RESOURCE variable=ACK_TABLE core=RAM_T2P_BRAM
298  #pragma HLS DEPENDENCE variable=ACK_TABLE inter false
299  #pragma HLS RESET variable=ACK_TABLE
300 
301  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
302  // [TODO - The type of 'akd_Ptr' could be configured as a functions of 'MAX_SESSIONS']
303  // [ E.g. - static const int NR_BITS = ceil(log10(MAX_SESSIONS)/log10(2));
304  static SessionId akd_Ptr;
305  #pragma HLS RESET variable=akd_Ptr
306 
307  //-- DYNAMIC VARIABLES -----------------------------------------------------
308  ExtendedEvent ev;
309 
310  if (!siEVe_Event.empty()) {
311 
312  // Read incoming event and inform [EVe] that the FiFo stream was read
313  siEVe_Event.read(ev);
314  assessSize(myName, soEVe_RxEventSig, "soEVe_RxEventSig", cDepth_AKdToEVe_Event);
315  soEVe_RxEventSig.write(1);
316 
317  if (ev.type == ACK_EVENT) {
318  if (ACK_TABLE[ev.sessionID] == 0) {
319  // There is no delayed ACK pending --> Schedule a new one
320  ACK_TABLE[ev.sessionID] = ACKD_64us;
321  if (DEBUG_LEVEL & TRACE_AKD) {
322  printInfo(myName, "S%d - Received \'%s\' - Setting ACK_TABLE[%d]=%d\n",
323  ev.sessionID.to_int(), getEventName(ev.type), ev.sessionID.to_uint(), ACK_TABLE[ev.sessionID].to_uint());
324  }
325  }
326  else {
327  if (DEBUG_LEVEL & TRACE_AKD) {
328  printInfo(myName, "S%d - Received \'%s\' - Current ACK_TABLE[%d]=%d\n",
329  ev.sessionID.to_int(), getEventName(ev.type), ev.sessionID.to_uint(), ACK_TABLE[ev.sessionID].to_uint());
330  }
331  }
332  }
333  else {
334  // Any other event
335  ACK_TABLE[ev.sessionID] = 0;
336  // Forward event to TxEngine
337  assessSize(myName, soTXe_Event, "soTXe_Event", cDepth_AKdToTXe_Event);
338  soTXe_Event.write(ev);
339  // Tell the EventEngine that we just forwarded an mone-ACK event to TXe
340  assessSize(myName, soEVe_TxEventSig, "soEVe_TxEventSig", cDepth_AKdToEVe_Event);
341  soEVe_TxEventSig.write(1);
342  // Debug trace
343  if (DEBUG_LEVEL & TRACE_AKD) {
344  printInfo(myName, "S%d - Received '%s' - Clearing ACK_TABLE[%d]=%d\n",
345  ev.sessionID.to_int(), getEventName(ev.type), ev.sessionID.to_uint(), ACK_TABLE[ev.sessionID].to_uint());
346  }
347  }
348  }
349  else {
350  if (ACK_TABLE[akd_Ptr] > 0 and !soTXe_Event.full()) {
351  if (ACK_TABLE[akd_Ptr] == 1) {
352  soTXe_Event.write(Event(ACK_EVENT, akd_Ptr));
353  // Tell the EventEngine that we just forwarded an event to TXe
354  assessSize(myName, soEVe_TxEventSig, "soEVe_TxEventSig", cDepth_AKdToEVe_Event);
355  soEVe_TxEventSig.write(1);
356  if (DEBUG_LEVEL & TRACE_AKD) {
357  printInfo(myName, "S%d - It's ACK Time - Requesting [TXe] to generate an new ACK\n",
358  akd_Ptr.to_int());
359  }
360  }
361  ACK_TABLE[akd_Ptr] -= 1;
362  }
363  akd_Ptr++;
364  if (akd_Ptr == TOE_MAX_SESSIONS) {
365  akd_Ptr = 0;
366  }
367  }
368 }

◆ event_engine()

void event_engine ( stream< Event > &  siTAi_Event,
stream< ExtendedEvent > &  siRXe_Event,
stream< Event > &  siTIm_Event,
stream< ExtendedEvent > &  soAKd_Event,
stream< SigBit > &  siAKd_RxEventSig,
stream< SigBit > &  siAKd_TxEventSig,
stream< SigBit > &  siTXe_RxEventSig 
)

The Event Engine (EVe) arbitrates the incoming events and forwards them to the Tx Engine (TXe) via the ACK Delayer (AKd).

ENTITY - Event Engine (EVe)

Parameters
[in]siTAi_EventEvent from TxApplicationInterface (TAi).
[in]siRXe_EventEvent from RxEngine (RXe).
[in]siTIm_EventEvent from Timers (TIm).
[out]soAKd_EventEvent to AckDelayer (AKd).
[in]siAKd_RxEventSigThe AckDelayer just received an event.
[in]siAKd_TxEventSigThe AckDelayer just forwarded an event.
[in]siTXe_RxEventSigThe TxEngine (TXe) just received an event.

Definition at line 90 of file event_engine.cpp.

98 {
99  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
100  #pragma HLS PIPELINE II=1 enable_flush
101 
102  const char *myName = THIS_NAME;
103 
104  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
105  //---- Warning: the following counters depend on the FiFo depth between EVe and AKd
106  static ap_uint<8> eve_eve2akd_WrCnt; // #events forwarded by [EVe] to [AKd]
107  #pragma HLS RESET variable = eve_eve2akd_WrCnt
108  static ap_uint<8> eve_eve2akd_RdCnt; // #events received by [AKd] from [EVe].
109  #pragma HLS RESET variable = eve_eve2akd_RdCnt
110  static ap_uint<8> eve_akd2txe_WrCnt; // #events forwarded by [AKd] to [TXe]
111  #pragma HLS RESET variable = eve_akd2txe_WrCnt
112  static ap_uint<8> eve_akd2txe_RdCnt; // #events received by [TXe] from [Akd]
113  #pragma HLS RESET variable = eve_akd2txe_RdCnt
114 
115  //-- DYNAMIC VARIABLES -----------------------------------------------------
116  ExtendedEvent ev;
117 
118  //------------------------------------------
119  // Handle input from [RxEngine]
120  //------------------------------------------
121  if (!siRXe_Event.empty() and !soAKd_Event.full()) {
122  siRXe_Event.read(ev);
123  soAKd_Event.write(ev);
124  if (DEBUG_LEVEL & TRACE_EVE) {
125  printInfo(myName, "S%d - Received '%s' from [RXe] (WrCnt=%3d|RdCnt=%3d).\n",
126  ev.sessionID.to_int(), getEventName(ev.type), eve_eve2akd_WrCnt.to_uint(), eve_eve2akd_RdCnt.to_uint());
127  }
128  eve_eve2akd_WrCnt++;
129  }
130  else if (eve_eve2akd_WrCnt == eve_eve2akd_RdCnt and
131  eve_akd2txe_WrCnt == eve_akd2txe_RdCnt) {
132  //------------------------------------------
133  // Handle input from [Timers]
134  // RetransmitTimer and ProbeTimer events have priority
135  //------------------------------------------
136  if (!siTIm_Event.empty()) {
137  siTIm_Event.read(ev);
138  soAKd_Event.write(ev);
139  if (DEBUG_LEVEL & TRACE_EVE) {
140  printInfo(myName, "S%d - Received '%s' from [TIm] (WrCnt=%3d|RdCnt=%3d).\n",
141  ev.sessionID.to_int(), getEventName(ev.type), eve_eve2akd_WrCnt.to_uint(), eve_eve2akd_RdCnt.to_uint());
142  }
143  eve_eve2akd_WrCnt++;
144  }
145  //--------------------------------------------
146  // Handle input from [TcpApplicationInterface]
147  //--------------------------------------------
148  else if (!siTAi_Event.empty()) {
149  siTAi_Event.read(ev);
150  assessSize(myName, soAKd_Event, "soAKd_Event", cDepth_EVeToAKd_Event);
151  soAKd_Event.write(ev);
152  if (DEBUG_LEVEL & TRACE_EVE) {
153  printInfo(myName, "S%d - Received '%s' from [TAi] (WrCnt=%3d|RdCnt=%3d).\n",
154  ev.sessionID.to_int(), getEventName(ev.type), eve_eve2akd_WrCnt.to_uint(), eve_eve2akd_RdCnt.to_uint());
155  }
156  eve_eve2akd_WrCnt++;
157  }
158  }
159 
160  //------------------------------------------
161  // Handle inputs from [AckDelayer]
162  //------------------------------------------
163  if (!siAKd_RxEventSig.empty()) {
164  // Remote [AKd] just received an event from [EVe]
165  siAKd_RxEventSig.read();
166  eve_eve2akd_RdCnt++;
167  }
168 
169  if (!siAKd_TxEventSig.empty()) {
170  // Remote [AKd] just forwarded an event to [TXe]
171  siAKd_TxEventSig.read();
172  eve_akd2txe_WrCnt++;
173  }
174 
175  //------------------------------------------
176  // Handle input from [TxEngine]
177  //------------------------------------------
178  if (!siTXe_RxEventSig.empty()) {
179  siTXe_RxEventSig.read();
180  eve_akd2txe_RdCnt++;
181  }
182 }
#define TRACE_EVE
const int cDepth_EVeToAKd_Event
Definition: toe.hpp:209
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getEventName()

const char * getEventName ( EventType  evType)

Returns the name of an enum-based event as a user friendly string.

Parameters
[in]evTypeAn enumerated type of event.
Returns
the event type as a string.

PRINT HELPERS - PROTOTYPE DEFINITIONS

Definition at line 43 of file toe_utils.cpp.

43  {
44  switch (evType) {
45  case TX_EVENT:
46  return "TX";
47  case RT_EVENT:
48  return "RT";
49  case ACK_EVENT:
50  return "ACK";
51  case SYN_EVENT:
52  return "SYN";
53  case SYN_ACK_EVENT:
54  return "SYN_ACK";
55  case FIN_EVENT:
56  return "";
57  case RST_EVENT:
58  return "";
59  case ACK_NODELAY_EVENT:
60  return "ACK_NODELAY";
61  default:
62  return "ERROR: UNKNOWN EVENT!";
63  }
64 }
@ SYN_ACK_EVENT
Definition: toe.hpp:274
Here is the caller graph for this function:

◆ pAnd2()

template<class T >
void pAnd2 ( T &  pi1,
T &  pi2,
T &  po 
)

A two inputs 'AND' gate.

Definition at line 84 of file port_table.cpp.

88 {
89  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
90  #pragma HLS INLINE off
91 
92  po = pi1 & pi2;
93 }

◆ pAppSegmentStitcher()

void pAppSegmentStitcher ( stream< AxisApp > &  siMEM_RxP_Data,
stream< TcpAppData > &  soTAIF_Data,
stream< FlagBool > &  siMrd_SplitSegFlag,
stream< ap_uint< 8 > > &  soMMIO_DataDropCnt 
)

Application Segment Stitcher (Ass)

Parameters
[in]siMEM_RxP_DataRx data segment from [MEM].
[out]soTAIF_DataRx data stream to TcpAppInterface (TAIF).
[in]siMrd_SplitSegSplit segment from Rx MemoryReader (MRd).
[out]soMMIO_DataDropCntThe value of the data drop counter.

This process is the data read front-end of the memory sub-system (MEM). It reads in the data from the TCP Rx buffer memory and forwards them to the application [APP] via the TcpAppInterface (TAIF). If a received data segment was splitted and stored as two Rx memory buffers as indicated by the signal flag 'siMrd_SplitSeg', this process will stitch them back into a single stream of bytes before delivering them to the [APP].

Warning
To avoid any blocking of the [RAi], the current data to be sent on the outgoing stream 'soTAIF_Data' will be dropped if that stream is full. This implies that the application process must provision enough buffering to store all the bytes that were requested to be read from the TCP Rx buffer, or the application must read them as fast as they come in i.e., as fast as one chunk per clock cycle. A 16-bit data drop counter register is provided in MMIO to help diagnose such issues.

Definition at line 371 of file rx_app_interface.cpp.

376 {
377  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
378  #pragma HLS PIPELINE II=1 enable_flush
379  #pragma HLS INLINE off
380 
381  const char *myName = concat3(THIS_NAME, "/", "Ass");
382 
383  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
384  static enum FsmState { ASS_IDLE,
385  ASS_FWD_1ST_BUF, ASS_FWD_2ND_BUF,
386  ASS_JOIN_2ND_BUF, ASS_RESIDUE } \
387  ass_fsmState=ASS_IDLE;
388  #pragma HLS RESET variable=ass_fsmState
389  static ap_uint<3> ass_psdHdrChunkCount = 0;
390  #pragma HLS RESET variable=ass_psdHdrChunkCount
391  static ap_uint<16> ass_dataDropCounter=0;
392  #pragma HLS reset variable=ass_dataDropCounter
393 
394  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
395  static AxisApp ass_prevChunk;
396  static ap_uint<4> ass_memRdOffset;
397  static FlagBool ass_mustJoin;
398 
399  switch(ass_fsmState) {
400  case ASS_IDLE:
401  //-- Handle the very 1st data chunk from the 1st memory buffer
402  if (!siMEM_RxP_Data.empty() and !siMrd_SplitSegFlag.empty()) {
403  siMrd_SplitSegFlag.read(ass_mustJoin);
404  AxisApp currAppChunk = siMEM_RxP_Data.read();
405  if (currAppChunk.getTLast()) {
406  // We are done with the 1st memory buffer
407  if (ass_mustJoin == false) {
408  // The TCP segment was not splitted.
409  // We are done with this segment. Stay in this state.
410  if (!soTAIF_Data.full()) {
411  soTAIF_Data.write(currAppChunk);
412  if (DEBUG_LEVEL & TRACE_ASS) { printAxisRaw(myName, "soTAIF_Data =", currAppChunk); }
413  }
414  else {
415  // Drop this data and increment the Data Drop Counter
416  ass_dataDropCounter++;
417  printFatal(myName, "Cannot write 'soTAIF_Data()'. Stream is full!");
418  }
419  ass_fsmState = ASS_IDLE;
420  }
421  else {
422  // The TCP segment was splitted in two parts
423  ass_memRdOffset = currAppChunk.getLen();
424  if (ass_memRdOffset != 8) {
425  // The last chunk of the 1st memory buffer is not fully populated.
426  // Don't output anything here. Save the current chunk and goto 'ASS_JOIN_2ND'.
427  // There, we will fetch more data to fill in the current chunk.
428  ass_prevChunk = currAppChunk;
429  ass_fsmState = ASS_JOIN_2ND_BUF;
430  }
431  else {
432  // The last chunk of the 1st memory buffer is populated with
433  // 8 valid bytes and is therefore also aligned.
434  // Forward this chunk and goto 'ASS_FWD_2ND_BUF'.
435  if (!soTAIF_Data.full()) {
436  soTAIF_Data.write(currAppChunk);
437  if (DEBUG_LEVEL & TRACE_ASS) { printAxisRaw(myName, "soTAIF_Data =", currAppChunk); }
438  }
439  else {
440  // Drop this data and increment the Data Drop Counter
441  ass_dataDropCounter++;
442  printFatal(myName, "Cannot write 'soTAIF_Data()'. Stream is full!");
443  }
444  ass_fsmState = ASS_FWD_2ND_BUF;
445  }
446  }
447  }
448  else {
449  // The 1st memory buffer contains more than one chunk
450  if (!soTAIF_Data.full()) {
451  soTAIF_Data.write(currAppChunk);
452  if (DEBUG_LEVEL & TRACE_ASS) { printAxisRaw(myName, "soTAIF_Data =", currAppChunk); }
453  }
454  else {
455  // Drop this data and increment the Data Drop Counter
456  ass_dataDropCounter++;
457  printFatal(myName, "Cannot write 'soTAIF_Data()'. Stream is full!");
458  }
459  ass_fsmState = ASS_FWD_1ST_BUF;
460  }
461  }
462  break;
463  case ASS_FWD_1ST_BUF:
464  //-- Forward all the data chunks of the 1st memory buffer
465  if (!siMEM_RxP_Data.empty()) {
466  AxisApp currAppChunk = siMEM_RxP_Data.read();
467 
468  if (currAppChunk.getTLast()) {
469  // We are done with the 1st memory buffer
470  if (ass_mustJoin == false) {
471  // The TCP segment was not splitted.
472  // We are done with this segment. Go back to 'ASS_IDLE'.
473  if (!soTAIF_Data.full()) {
474  soTAIF_Data.write(currAppChunk);
475  if (DEBUG_LEVEL & TRACE_ASS) { printAxisRaw(myName, "soTAIF_Data =", currAppChunk); }
476  }
477  else {
478  // Drop this chunk
479  printFatal(myName, "Cannot write 'soTAIF_Data()'. Stream is full!");
480  }
481  ass_fsmState = ASS_IDLE;
482  }
483  else {
484  // The TCP segment was splitted in two parts
485  ass_memRdOffset = currAppChunk.getLen();
486  // Always clear the last bit of the last chunk of 1st part
487  currAppChunk.setTLast(0);
488  if (ass_memRdOffset != 8) {
489  // The last chunk of the 1st memory buffer is not fully populated.
490  // Don't output anything here. Save the current chunk and goto 'TSS_JOIN_2ND'.
491  // There, we will fetch more data to fill in the current chunk.
492  ass_prevChunk = currAppChunk;
493  ass_fsmState = ASS_JOIN_2ND_BUF;
494  }
495  else {
496  // The last chunk of the 1st memory buffer is populated with
497  // 8 valid bytes and is therefore also aligned.
498  // Forward this chunk and goto 'TSS_FWD_2ND_BUF'.
499  if (!soTAIF_Data.full()) {
500  soTAIF_Data.write(currAppChunk);
501  if (DEBUG_LEVEL & TRACE_ASS) { printAxisRaw(myName, "soTAIF_Data =", currAppChunk); }
502  }
503  else {
504  // Drop this data and increment the Data Drop Counter
505  ass_dataDropCounter++;
506  printFatal(myName, "Cannot write 'soTAIF_Data()'. Stream is full!");
507  }
508  ass_fsmState = ASS_FWD_2ND_BUF;
509  }
510  }
511  }
512  else {
513  // Remain in this state and continue streaming the 1st memory buffer
514  if (!soTAIF_Data.full()) {
515  soTAIF_Data.write(currAppChunk);
516  if (DEBUG_LEVEL & TRACE_ASS) { printAxisRaw(myName, "soTAIF_Data =", currAppChunk); }
517  }
518  else {
519  // Drop this data and increment the Data Drop Counter
520  ass_dataDropCounter++;
521  printFatal(myName, "Cannot write 'soTAIF_Data()'. Stream is full!");
522  }
523  }
524  }
525  break;
526  case ASS_FWD_2ND_BUF:
527  //-- Forward all the data chunks of the 2nd memory buffer
528  if (!siMEM_RxP_Data.empty()) {
529  AxisApp currAppChunk = siMEM_RxP_Data.read();
530  if (!soTAIF_Data.full()) {
531  soTAIF_Data.write(currAppChunk);
532  if (DEBUG_LEVEL & TRACE_ASS) { printAxisRaw(myName, "soTAIF_Data =", currAppChunk); }
533  }
534  else {
535  // Drop this data and increment the Data Drop Counter
536  ass_dataDropCounter++;
537  printFatal(myName, "Cannot write 'soTAIF_Data()'. Stream is full!");
538  }
539  if (currAppChunk.getTLast()) {
540  // We are done with the 2nd memory buffer
541  ass_fsmState = ASS_IDLE;
542  }
543  }
544  break;
545  case ASS_JOIN_2ND_BUF:
546  //-- Join the bytes from the 2nd memory buffer to the stream of bytes of
547  //-- the 1st memory buffer when the 1st buffer was not fully populated.
548  //-- The re-alignment occurs between the previously read chunk stored
549  //-- in 'tss_prevChunk' and the latest chunk stored in 'currAppChunk',
550  //-- and 'tss_memRdOffset' specifies the number of valid bytes in 'tss_prevChunk'.
551  if (!siMEM_RxP_Data.empty()) {
552  AxisApp currAppChunk = siMEM_RxP_Data.read();
553 
554  AxisApp joinedChunk(0,0,0); // [FIXME-Create a join method in AxisRaw]
555  // Set lower-part of the joined chunk with the last bytes of the previous chunk
556  joinedChunk.setLE_TData(ass_prevChunk.getLE_TData(((int)ass_memRdOffset*8)-1, 0),
557  ((int)ass_memRdOffset*8)-1, 0);
558  joinedChunk.setLE_TKeep(ass_prevChunk.getLE_TKeep( (int)ass_memRdOffset -1, 0),
559  (int)ass_memRdOffset -1, 0);
560  // Set higher part of the joined chunk with the first bytes of the current chunk
561  joinedChunk.setLE_TData(currAppChunk.getLE_TData( ARW -1-((int)ass_memRdOffset*8), 0),
562  ARW -1,((int)ass_memRdOffset*8));
563  joinedChunk.setLE_TKeep(currAppChunk.getLE_TKeep((ARW/8)-1- (int)ass_memRdOffset, 0),
564  (ARW/8)-1, (int)ass_memRdOffset);
565  if (currAppChunk.getLE_TKeep()[8-(int)ass_memRdOffset] == 0) {
566  // The entire current chunk fits into the remainder of the previous chunk.
567  // We are done with this 2nd memory buffer.
568  joinedChunk.setLE_TLast(TLAST);
569  ass_fsmState = ASS_IDLE;
570  }
571  else if (currAppChunk.getLE_TLast()) {
572  // This cannot be the last chunk because it doesn't fit into the
573  // available space of the previous chunk. Goto the 'ASS_RESIDUE'
574  // and handle the remainder of this data chunk
575  ass_fsmState = ASS_RESIDUE;
576  }
577 
578  if (!soTAIF_Data.full()) {
579  soTAIF_Data.write(joinedChunk);
580  if (DEBUG_LEVEL & TRACE_ASS) { printAxisRaw(myName, "soTAIF_Data =", joinedChunk); }
581  }
582  else {
583  // Drop this data and increment the Data Drop Counter
584  ass_dataDropCounter++;
585  printFatal(myName, "Cannot write 'soTAIF_Data()'. Stream is full!");
586  }
587 
588  // Move remainder of current chunk to previous chunk
589  ass_prevChunk.setLE_TData(currAppChunk.getLE_TData(64-1, 64-(int)ass_memRdOffset*8),
590  ((int)ass_memRdOffset*8)-1, 0);
591  ass_prevChunk.setLE_TKeep(currAppChunk.getLE_TKeep(8-1, 8-(int)ass_memRdOffset),
592  (int)ass_memRdOffset-1, 0);
593  }
594  break;
595  case ASS_RESIDUE:
596  //-- Output the very last unaligned chunk
597  AxisApp lastChunk = AxisApp(0, 0, TLAST);
598  lastChunk.setLE_TData(ass_prevChunk.getLE_TData(((int)ass_memRdOffset*8)-1, 0),
599  ((int)ass_memRdOffset*8)-1, 0);
600  lastChunk.setLE_TKeep(ass_prevChunk.getLE_TKeep((int)ass_memRdOffset-1, 0),
601  (int)ass_memRdOffset-1, 0);
602 
603  if (!soTAIF_Data.full()) {
604  soTAIF_Data.write(lastChunk);
605  if (DEBUG_LEVEL & TRACE_ASS) { printAxisRaw(myName, "soTAIF_Data =", lastChunk); }
606  }
607  else {
608  // Drop this data and increment the Data Drop Counter
609  ass_dataDropCounter++;
610  printFatal(myName, "Cannot write 'soTAIF_Data()'. Stream is full!");
611  }
612  ass_fsmState = ASS_IDLE;
613  break;
614  } // End-of: switch
615 
616  //-- ALWAYS
617  if (!soMMIO_DataDropCnt.full()) {
618  soMMIO_DataDropCnt.write(ass_dataDropCounter);
619  }
620  else {
621  printFatal(myName, "Cannot write soMMIO_DataDropCnt stream...");
622  }
623 
624 } // End-of: pAppSegmentStitcher
void setTLast(tLast last)
Definition: AxisRaw.hpp:246
tLast getTLast() const
Definition: AxisRaw.hpp:219
LE_tKeep getLE_TKeep(int leHi=64/8-1, int leLo=0) const
Definition: AxisRaw.hpp:264
LE_tData getLE_TData(int leHi=64 -1, int leLo=0) const
Definition: AxisRaw.hpp:260
void setLE_TData(LE_tData data, int leHi=64 -1, int leLo=0)
Definition: AxisRaw.hpp:272
int getLen() const
Definition: AxisRaw.hpp:411
void setLE_TKeep(LE_tKeep keep, int leHi=64/8-1, int leLo=0)
Definition: AxisRaw.hpp:276
LE_tLast getLE_TLast() const
Definition: AxisRaw.hpp:268
#define TRACE_ASS
void printAxisRaw(const char *callerName, AxisRaw chunk)
Prints an Axis raw data chunk (used for debugging).
Definition: nts_utils.cpp:46
#define ARW
Definition: AxisRaw.hpp:114
bool FlagBool
Definition: nts_types.hpp:124
AxisRaw AxisApp
Definition: nts.hpp:51
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
Definition: nts_utils.hpp:161
#define printFatal(callerName, format,...)
A macro to print a fatal error message and exit.
Definition: nts_utils.hpp:208
#define TLAST
Definition: AxisRaw.hpp:116
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pCheckSumAccumulator()

void pCheckSumAccumulator ( stream< AxisPsd4 > &  siIph_PseudoPkt,
stream< AxisApp > &  soTid_Data,
stream< ValBit > &  soTid_DataVal,
stream< RXeMeta > &  soMdh_Meta,
stream< SocketPair > &  soMdh_SockPair,
stream< TcpPort > &  soPRt_GetState 
)

TCP checksum accumulator (Csa)

Parameters
[in]siIph_PseudoPktA pseudo TCP packet from InsertPseudoHeader (Iph).
[out]soTid_DataTCP data stream to TcpInvalidDropper (Tid).
[out]soTid_DataValTCP data valid to [Tid].
[out]soMdh_MetaTCP metadata to MetaDataHandler (Mdh).
[out]soMdh_SockPairTCP socket pair to [Mdh].
[out]soPRt_GetStateReq state of the TCP DestPort to PortTable (PRt).

This process extracts the data section from the incoming pseudo IP packet and forwards it to the TcpInvalidDropper (Tid) together with a valid bit indicating the result of the checksum validation. It also extracts the socket pair information and some metadata information from the TCP segment and forwards them to the MetaDataHandler (Mdh). Next, the TCP destination port number is extracted and forwarded to the PortTable (PRt) process to check if the port is open.

The format of the incoming pseudo TCP segment is as follows (

See also
AxisPsd4.hpp):
   6                   5                   4                   3                   2                   1                   0
3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DA (LL) | DA (L) | DA (H) | DA (HH) | SA (LL) | SA (L) | SA (H) | SA (HH) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DP (L) | DP (H) | SP (L) | SP (H) | Segment Len | 0x06 | 0x00 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Ack (LL) | Ack (L) | Ack (H) | Ack (HH) | Seq (LL) | Seq (L) | Seq (H) | Seq (HH) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | | | | |U|A|P|R|S|F| Data | | | UrgPtr(L) | UrgPtr(H) | CSum (L) | CSum (H) | Win (L) | Win (H) |Res|R|C|S|S|Y|I| Offset| Res | | | | | | | | |G|K|H|T|N|N| | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data 7 | Data 6 | Data 5 | Data 4 | Data 3 | Data 2 | Data 1 | Data 0 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ *

Definition at line 444 of file rx_engine.cpp.

451 {
452  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
453  #pragma HLS PIPELINE II=1 enable_flush
454  #pragma HLS INLINE off
455 
456  const char *myName = concat3(THIS_NAME, "/", "Csa");
457 
458  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
459  static ap_uint<3> csa_chunkCount=0;
460  #pragma HLS RESET variable=csa_chunkCount
461  static bool csa_doCSumVerif=false;
462  #pragma HLS RESET variable=csa_doCSumVerif
463  static bool csa_residue=false;
464  #pragma HLS RESET variable=csa_residue
465  static ap_uint<3> csa_cc_state=0;
466  #pragma HLS RESET variable=csa_cc_state
467  static ap_uint<17> csa_tcp_sums[4]={0, 0, 0, 0};
468  #pragma HLS RESET variable=csa_tcp_sums
469  #pragma HLS ARRAY_PARTITION \
470  variable=csa_tcp_sums complete dim=1
471 
472  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
473  static TcpDataOff csa_dataOffset;
474  static bool csa_doShift;
475  static SocketPair csa_socketPair;
476  static RXeMeta csa_meta;
477  static TcpDstPort csa_tcpDstPort;
478  static TcpChecksum csa_tcpCSum;
479  static ap_uint<32> csa_half_tdata;
480  static ap_uint<4> csa_half_tkeep;
481 
482  //-- DYNAMIC VARIABLES -----------------------------------------------------
483  AxisPsd4 currChunk(0,0,0);
484  AxisApp sendChunk(0,0,0);
485 
486  if (!siIph_PseudoPkt.empty() and !soTid_Data.full() and !csa_doCSumVerif) {
487  currChunk = siIph_PseudoPkt.read();
488 
489  switch (csa_chunkCount) {
490  case CHUNK_0:
491  csa_doShift = false;
492  // Get IP-SA & IP-DA
493  csa_socketPair.src.addr = currChunk.getPsd4SrcAddr();
494  csa_socketPair.dst.addr = currChunk.getPsd4DstAddr();
495  sendChunk.setTLast(currChunk.getTLast());
496  csa_chunkCount++;
497  break;
498  case CHUNK_1:
499  // Get Segment length
500  csa_meta.length = currChunk.getPsd4Len();
501  // Get TCP-SP & TCP-DP
502  csa_socketPair.src.port = currChunk.getTcpSrcPort();
503  csa_socketPair.dst.port = currChunk.getTcpDstPort();
504  csa_tcpDstPort = currChunk.getTcpDstPort();
505  sendChunk.setTLast(currChunk.getTLast());
506  csa_chunkCount++;
507  break;
508  case CHUNK_2:
509  // Get Sequence and Acknowledgment Numbers
510  csa_meta.seqNumb = currChunk.getTcpSeqNum();
511  csa_meta.ackNumb = currChunk.getTcpAckNum();
512  sendChunk.setTLast(currChunk.getTLast());
513  csa_chunkCount++;
514  break;
515  case CHUNK_3:
516  // Get Data Offset
517  csa_dataOffset = currChunk.getTcpDataOff();
518  csa_meta.length -= (csa_dataOffset * 4);
519  // Get Control Bits
520  // [ 8] == FIN | [ 9] == SYN | [10] == RST
521  // [11] == PSH | [12] == ACK | [13] == URG
522  csa_meta.ack = currChunk.getTcpCtrlAck();
523  csa_meta.rst = currChunk.getTcpCtrlRst();
524  csa_meta.syn = currChunk.getTcpCtrlSyn();
525  csa_meta.fin = currChunk.getTcpCtrlFin();
526  // Get Window Size
527  csa_meta.winSize = currChunk.getTcpWindow();
528  // Get the checksum of the pseudo-header (only for debug purposes)
529  csa_tcpCSum = currChunk.getTcpChecksum();
530  sendChunk.setTLast(currChunk.getTLast());
531  csa_chunkCount++;
532  break;
533  default:
534  if (csa_dataOffset >= 6) {
535  // Handle TCP options.
536  // Warning: At this point, we only support one TCP option and
537  // we further assume that this option is always 32-bit aligned.
538  // [TODO] Must add support for Window Scaling and unaligned options.
539  TcpOptKind optionKind = currChunk.getTcpOptKind();
540  if (optionKind == TCP_OPT_KIND_MSS) {
541  // Extract the MSS value
542  TcpOptMss theirMSS = currChunk.getTcpOptMss();
543  if (DEBUG_LEVEL & TRACE_CSA) {
544  printInfo(myName, "TCP segment includes 4 option bytes (OptKind=2, OptLen=4, MSS=%d)\n",
545  theirMSS.to_uint());
546  }
547  }
548  else {
549  printWarn(myName, "The TCP option %d is not yet supported and will be dropped.\n", optionKind.to_uchar());
550  }
551  if (csa_dataOffset == 6) {
552  csa_dataOffset -= 1;
553  csa_doShift = true;
554  csa_half_tdata = currChunk.getLE_TData(63, 32);
555  csa_half_tkeep = currChunk.getLE_TKeep( 7, 4);
556  }
557  else {
558  csa_dataOffset -= 2;
559  }
560  }
561  else {
562  // The DataOffset == 5 (or less)
563  if (!csa_doShift) {
564  sendChunk = currChunk;
565  soTid_Data.write(sendChunk);
566  }
567  else {
568  sendChunk.setLE_TData( csa_half_tdata, 31, 0);
569  sendChunk.setLE_TKeep( csa_half_tkeep, 3, 0);
570  sendChunk.setLE_TData(currChunk.getLE_TData(31, 0), 63, 32);
571  sendChunk.setLE_TKeep(currChunk.getLE_TKeep( 3, 0), 7, 4);
572  sendChunk.setTLast( currChunk.getLE_TKeep()[4] == 0);
573  soTid_Data.write(sendChunk);
574  if (DEBUG_LEVEL & TRACE_CSA) { printAxisRaw(myName, "soTid_Data() =", sendChunk); }
575  csa_half_tdata = currChunk.getLE_TData(63, 32);
576  csa_half_tkeep = currChunk.getLE_TKeep( 7, 4);
577  }
578  }
579  break;
580  } // End of: switch
581 
582  // Accumulate TCP checksum
583  for (int i = 0; i < 4; i++) {
584  #pragma HLS UNROLL
585  TcpCsum temp;
586  if (currChunk.getLE_TKeep(i*2+1, i*2) == 0x3) {
587  temp( 7, 0) = currChunk.getLE_TData(i*16+15, i*16+8);
588  temp(15, 8) = currChunk.getLE_TData(i*16+ 7, i*16);
589  csa_tcp_sums[i] += temp;
590  csa_tcp_sums[i] = (csa_tcp_sums[i] + (csa_tcp_sums[i] >> 16)) & 0xFFFF;
591  }
592  else if (currChunk.getLE_TKeep()[i*2] == 0x1) {
593  temp( 7, 0) = 0;
594  temp(15, 8) = currChunk.getLE_TData(i*16+7, i*16);
595  csa_tcp_sums[i] += temp;
596  csa_tcp_sums[i] = (csa_tcp_sums[i] + (csa_tcp_sums[i] >> 16)) & 0xFFFF;
597  }
598  }
599 
600  // Handle last chunk
601  if(currChunk.getTLast()) {
602  csa_chunkCount = 0;
603  csa_residue = !sendChunk.getTLast();
604  csa_doCSumVerif = true;
605  }
606  } // End of: if (!siIph_Data.empty() && !csa_doCSumVerif)
607  else if(csa_residue and !soTid_Data.full()) {
608  if (csa_meta.length != 0) {
609  sendChunk.setLE_TData(csa_half_tdata, 31, 0);
610  sendChunk.setLE_TData( 0x00000000, 63, 32);
611  sendChunk.setLE_TKeep(csa_half_tkeep, 3, 0);
612  sendChunk.setLE_TKeep( 0x0, 7, 4);
613  sendChunk.setLE_TLast(TLAST);
614  soTid_Data.write(sendChunk);
615  if (DEBUG_LEVEL & TRACE_CSA) { printAxisRaw(myName, "soTid_Data() =", currChunk); }
616  }
617  csa_residue = false;
618  }
619  else if (csa_doCSumVerif) {
620  switch (csa_cc_state) {
621  case 0:
622  csa_tcp_sums[0] = (csa_tcp_sums[0] + (csa_tcp_sums[0] >> 16)) & 0xFFFF;
623  csa_tcp_sums[1] = (csa_tcp_sums[1] + (csa_tcp_sums[1] >> 16)) & 0xFFFF;
624  csa_tcp_sums[2] = (csa_tcp_sums[2] + (csa_tcp_sums[2] >> 16)) & 0xFFFF;
625  csa_tcp_sums[3] = (csa_tcp_sums[3] + (csa_tcp_sums[3] >> 16)) & 0xFFFF;
626  csa_cc_state++;
627  break;
628  case 1:
629  csa_tcp_sums[0] += csa_tcp_sums[2];
630  csa_tcp_sums[1] += csa_tcp_sums[3];
631  csa_tcp_sums[0] = (csa_tcp_sums[0] + (csa_tcp_sums[0] >> 16)) & 0xFFFF;
632  csa_tcp_sums[1] = (csa_tcp_sums[1] + (csa_tcp_sums[1] >> 16)) & 0xFFFF;
633  csa_cc_state++;
634  break;
635  case 2:
636  csa_tcp_sums[0] += csa_tcp_sums[1];
637  csa_tcp_sums[0] = (csa_tcp_sums[0] + (csa_tcp_sums[0] >> 16)) & 0xFFFF;
638  csa_cc_state++;
639  break;
640  case 3:
641  csa_tcp_sums[0] = ~csa_tcp_sums[0];
642  csa_cc_state++;
643  break;
644  case 4:
645  if (csa_tcp_sums[0](15, 0) == 0) {
646  // The checksum is correct. TCP segment is valid.
647  // Forward to metadata to MetaDataHandler
648  soMdh_Meta.write(csa_meta);
649  soMdh_SockPair.write(csa_socketPair);
650  if (csa_meta.length != 0) {
651  // Forward valid checksum info to TcpInvalidDropper
652  soTid_DataVal.write(OK);
653  if (DEBUG_LEVEL & TRACE_CSA) {
654  printInfo(myName, "Received end-of-packet. Checksum is correct.\n");
655  }
656  }
657  // Request state of TCP_DP
658  soPRt_GetState.write(csa_tcpDstPort);
659  }
660  else {
661  printWarn(myName, "RECEIVED BAD CHECKSUM (0x%4.4X - Delta= 0x%4.4X).\n",
662  csa_tcpCSum.to_uint(), (~csa_tcp_sums[0](15, 0).to_uint() & 0xFFFF));
663  if(csa_meta.length != 0) {
664  // Packet has some TCP payload
665  soTid_DataVal.write(KO);
666  }
667  if (DEBUG_LEVEL & TRACE_CSA) {
668  printSockPair(myName, csa_socketPair);
669  }
670  }
671  csa_doCSumVerif = false;
672  csa_tcp_sums[0] = 0;
673  csa_tcp_sums[1] = 0;
674  csa_tcp_sums[2] = 0;
675  csa_tcp_sums[3] = 0;
676  csa_cc_state = 0;
677  break;
678  } // End of: switch
679  }
680 } // End of: pCheckSumAccumulator
TcpSegLen length
Definition: rx_engine.hpp:77
TcpCtrlBit ack
Definition: rx_engine.hpp:78
TcpCtrlBit fin
Definition: rx_engine.hpp:81
TcpCtrlBit rst
Definition: rx_engine.hpp:79
TcpSeqNum seqNumb
Definition: rx_engine.hpp:74
TcpWindow winSize
Definition: rx_engine.hpp:76
TcpCtrlBit syn
Definition: rx_engine.hpp:80
TcpAckNum ackNumb
Definition: rx_engine.hpp:75
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_CSA
Definition: rx_engine.cpp:73
ap_uint< 8 > TcpOptKind
Definition: AxisTcp.hpp:117
ap_uint< 16 > TcpCsum
Definition: AxisTcp.hpp:114
ap_uint< 16 > TcpDstPort
Definition: AxisTcp.hpp:104
#define OK
Definition: nts_types.hpp:57
#define printWarn(callerName, format,...)
A macro to print a warning message.
Definition: nts_utils.hpp:182
#define KO
Definition: nts_types.hpp:58
ap_uint< 4 > TcpDataOff
Definition: AxisTcp.hpp:109
ap_uint< 16 > TcpOptMss
Definition: AxisTcp.hpp:119
void printSockPair(const char *callerName, SocketPair sockPair)
Print a socket pair association.
Definition: nts_utils.cpp:114
ap_uint< 16 > TcpChecksum
Definition: AxisTcp.hpp:113
#define TCP_OPT_KIND_MSS
Definition: AxisTcp.hpp:129
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pCloseTimer()

void pCloseTimer ( stream< SessionId > &  siRXe_CloseTimer,
stream< SessionId > &  soSmx_SessCloseCmd 
)

Close Timer (Clt) process.

Parameters
[in]siRXe_CloseTimerThe session-id that is closing from [RXe].
[out]soSmx_SessCloseCmdClose command to StateTableMux (Smx).

This process reads in the session-id that is currently closing. This sessId is kept in the 'TIME-WAIT' state for an additional 60s before it gets closed.

Definition at line 426 of file timers.cpp.

429 {
430  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
431  #pragma HLS PIPELINE II=1 enable_flush
432  #pragma HLS INLINE off
433 
434  //-- STATIC ARRAYS ---------------------------------------------------------
435  static CloseTimerEntry CLOSE_TIMER_TABLE[TOE_MAX_SESSIONS];
436  #pragma HLS RESOURCE variable=CLOSE_TIMER_TABLE core=RAM_T2P_BRAM
437  #pragma HLS DATA_PACK variable=CLOSE_TIMER_TABLE
438  #pragma HLS DEPENDENCE variable=CLOSE_TIMER_TABLE inter false
439  #pragma HLS RESET variable=CLOSE_TIMER_TABLE
440 
441  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
442  static bool clt_waitForWrite=false;
443  #pragma HLS RESET variable=clt_waitForWrite
444  static SessionId clt_currSessId=0;
445  #pragma HLS RESET variable=clt_currSessId
446  static SessionId clt_prevSessId=0;
447  #pragma HLS RESET variable=clt_prevSessId
448 
449  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
450  static SessionId clt_sessIdToSet;
451 
452  if (clt_waitForWrite) {
453  //-- Update the table
454  if (clt_sessIdToSet != clt_prevSessId) {
455  CLOSE_TIMER_TABLE[clt_sessIdToSet].time = TIME_60s;
456  CLOSE_TIMER_TABLE[clt_sessIdToSet].active = true;
457  clt_waitForWrite = false;
458  }
459  clt_prevSessId--;
460  }
461  else if (!siRXe_CloseTimer.empty()) {
462  //-- Read the Session-Id to set
463  siRXe_CloseTimer.read(clt_sessIdToSet);
464  clt_waitForWrite = true;
465  }
466  else {
467  clt_prevSessId = clt_currSessId;
468  // Check if timer is 0, otherwise decrement
469  if (CLOSE_TIMER_TABLE[clt_currSessId].active) {
470  if (CLOSE_TIMER_TABLE[clt_currSessId].time > 0) {
471  CLOSE_TIMER_TABLE[clt_currSessId].time -= 1;
472  }
473  else {
474  CLOSE_TIMER_TABLE[clt_currSessId].time = 0;
475  CLOSE_TIMER_TABLE[clt_currSessId].active = false;
476  soSmx_SessCloseCmd.write(clt_currSessId);
477  }
478  }
479 
480  if (clt_currSessId == TOE_MAX_SESSIONS) {
481  clt_currSessId = 0;
482  }
483  else {
484  clt_currSessId++;
485  }
486  }
487 }
ap_uint< 32 > time
Definition: timers.hpp:75
Here is the caller graph for this function:

◆ pEventMultiplexer()

void pEventMultiplexer ( stream< ExtendedEvent > &  siMdh_Event,
stream< Event > &  siFsm_Event,
stream< ExtendedEvent > &  soEVe_Event 
)

Event Multiplexer (Evm)

Parameters
[in]siMdh_EventEvent from MetaDataHandler (Mdh).
[in]siFsm_EventEvent from FiniteStateMachine (Fsm).
[out]soEVe_EventEvent to EVentEngine (EVe).

This process takes two events as inputs and muxes them on a single output. Note that the first input has priority over the second one.

Definition at line 1943 of file rx_engine.cpp.

1947 {
1948  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1949  #pragma HLS PIPELINE II=1 enable_flush
1950  #pragma HLS INLINE
1951 
1952  const char *myName = concat3(THIS_NAME, "/", "Evm");
1953 
1954  if (!siMdh_Event.empty()) {
1955  soEVe_Event.write(siMdh_Event.read());
1956  }
1957  else if (!siFsm_Event.empty()) {
1958  soEVe_Event.write(siFsm_Event.read());
1959  }
1960 }
Here is the caller graph for this function:

◆ pFiniteStateMachine()

void pFiniteStateMachine ( stream< RXeFsmMeta > &  siMdh_FsmMeta,
stream< StateQuery > &  soSTt_StateQry,
stream< TcpState > &  siSTt_StateRep,
stream< RXeRxSarQuery > &  soRSt_RxSarQry,
stream< RxSarReply > &  siRSt_RxSarRep,
stream< RXeTxSarQuery > &  soTSt_TxSarQry,
stream< RXeTxSarReply > &  siTSt_TxSarRep,
stream< RXeReTransTimerCmd > &  soTIm_ReTxTimerCmd,
stream< SessionId > &  soTIm_ClearProbeTimer,
stream< SessionId > &  soTIm_CloseTimer,
stream< SessState > &  soTAi_SessOpnSts,
stream< Event > &  soEVe_Event,
stream< CmdBit > &  soTsd_DropCmd,
stream< DmCmd > &  soMwr_WrCmd,
stream< TcpAppNotif > &  soRan_RxNotif,
stream< ap_uint< 8 > > &  soMMIO_OooDropCnt,
stream< RxBufPtr > &  soDBG_RxFreeSpace,
stream< ap_uint< 32 > > &  soDBG_TcpIpRxByteCnt,
stream< ap_uint< 8 > > &  soDBG_OooDebug 
)

Finite State machine (Fsm)

Parameters
[in]siMdh_FsmMetaFSM metadata from MetaDataHandler (Mdh).
[out]soSTt_StateQryState query to StateTable (STt).
[in]siSTt_StateRepState reply from [STt].
[out]soRSt_RxSarQryQuery to RxSarTable (RSt).
[in]siRSt_RxSarRepReply from [RSt].
[out]soTSt_TxSarQryQuery to TxSarTable (TSt).
[in]siTSt_TxSarRepReply from [TSt].
[out]soTIm_ReTxTimerCmdCommand for a retransmit timer to Timers (TIm).
[out]soTIm_ClearProbeTimerClear the probing timer to [TIm].
[out]soTIm_CloseTimerClose session timer to [TIm].
[out]soTAi_SessOpnStsOpen status of the session to TxAppInterface (TAi).
[out]soEVe_EventEvent to EventEngine (EVe).
[out]soTsd_DropCmdDrop command to TcpSegmentDropper (Tsd).
[out]soMwr_WrCmdMemory write command to MemoryWriter (Mwr).
[out]soRan_RxNotifRx data notification to RxAppNotifier (Ran).
[out]soMMIO_OooDropCntThe value of the out-of-order drop counter.

This process implements the typical TCP state and metadata management. It contains all the logic that updates the metadata and keeps track of the events related to the reception of segments and their handshaking. This is the key central part of the Rx engine.

Definition at line 1358 of file rx_engine.cpp.

1378 {
1379  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1380  #pragma HLS PIPELINE II=1 enable_flush
1381  #pragma HLS INLINE off
1382 
1383  const char *myName = concat3(THIS_NAME, "/", "Fsm");
1384 
1385  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1386  static enum FsmStates { FSM_LOAD=0, FSM_TRANSITION } \
1387  fsm_fsmState=FSM_LOAD;
1388  #pragma HLS RESET variable=fsm_fsmState
1389  static bool fsm_txSarRequest=false;
1390  #pragma HLS RESET variable=fsm_txSarRequest
1391  static ap_uint<8 > fsm_oooDropCounter=0;
1392  #pragma HLS RESET variable=fsm_oooDropCounter
1393  static RxBufPtr fsm_freeSpace=0;
1394  #pragma HLS RESET variable=fsm_freeSpace
1395  static ap_uint<32> fsm_rxByteCounter;
1396  #pragma HLS RESET variable=fsm_rxByteCounter
1397  static ap_uint<8 > fsm_oooDebugState=0;
1398  #pragma HLS RESET variable=fsm_oooDebugState
1399 
1400  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
1401  static RXeFsmMeta fsm_Meta;
1402 
1403  //-- DYNAMIC VARIABLES -----------------------------------------------------
1404  ap_uint<4> control_bits;
1405  TcpState tcpState;
1406  RxSarReply rxSar;
1407  RXeTxSarReply txSar;
1408 
1409  fsm_oooDebugState = 0;
1410 
1411  switch(fsm_fsmState) {
1412  case FSM_LOAD:
1413  if (!siMdh_FsmMeta.empty()) {
1414  siMdh_FsmMeta.read(fsm_Meta);
1415  // Request the current state of this session
1416  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, QUERY_RD));
1417  // Always request the RxSarTable, even though not required for SYN-ACK
1418  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, QUERY_RD));
1419  if (fsm_Meta.meta.ack) {
1420  // Only request the txSar when (ACK+ANYTHING); not for SYN
1421  soTSt_TxSarQry.write(RXeTxSarQuery(fsm_Meta.sessionId, QUERY_RD));
1422  fsm_txSarRequest = true;
1423  }
1424  fsm_fsmState = FSM_TRANSITION;
1425  fsm_oooDebugState = 1;
1426  }
1427  break;
1428  case FSM_TRANSITION:
1429  // Check if transition to FSM_LOAD occurs
1430  if (!siSTt_StateRep.empty() and !siRSt_RxSarRep.empty() and
1431  !(fsm_txSarRequest and siTSt_TxSarRep.empty())) {
1432  fsm_fsmState = FSM_LOAD;
1433  fsm_txSarRequest = false;
1434  }
1435  control_bits[0] = fsm_Meta.meta.ack;
1436  control_bits[1] = fsm_Meta.meta.syn;
1437  control_bits[2] = fsm_Meta.meta.fin;
1438  control_bits[3] = fsm_Meta.meta.rst;
1439  switch (control_bits) {
1440  case 1:
1441  //--------------------------------------
1442  //-- ACK
1443  //--------------------------------------
1444  if (fsm_fsmState == FSM_LOAD) {
1445  siSTt_StateRep.read(tcpState);
1446  siRSt_RxSarRep.read(rxSar);
1447  siTSt_TxSarRep.read(txSar);
1448 
1449  //-- ALWAYS - Compute free space to ensure that 'appd' pointer is not overtaken
1450  fsm_freeSpace = ((rxSar.appd - rxSar.oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
1451  soDBG_RxFreeSpace.write(fsm_freeSpace);
1452 
1453  if (DEBUG_LEVEL & TRACE_FSM) {
1454  printInfo(myName, "Entering 'ACK' processing.\n \
1455  \t\t Meta.seqNum =0x%8.8x \n \
1456  \t\t RxSar.appd =0x%8.8x \n \
1457  \t\t RxSar.oooHead=0x%8.8x \n \
1458  \t\t RxSar.oooTail=0x%8.8x \n \
1459  \t\t FreeSpace = %8d\n",
1460  fsm_Meta.meta.seqNumb.to_uint(),
1461  rxSar.oooHead.to_uint(),
1462  rxSar.oooTail.to_uint(),
1463  fsm_freeSpace.to_uint());
1464  }
1465 
1466  TimerCmd timerCmd;
1467  if (fsm_Meta.meta.ackNumb == txSar.prevUnak) {
1468  timerCmd = STOP_TIMER;
1469  }
1470  else {
1471  timerCmd = LOAD_TIMER;
1472  }
1473  soTIm_ReTxTimerCmd.write(RXeReTransTimerCmd(fsm_Meta.sessionId, timerCmd));
1474  if ( (tcpState == ESTABLISHED) || (tcpState == SYN_RECEIVED) ||
1475  (tcpState == FIN_WAIT_1) || (tcpState == CLOSING) ||
1476  (tcpState == LAST_ACK) ) {
1477  // Check if new ACK arrived
1478  if ( (fsm_Meta.meta.ackNumb == txSar.prevAckd) and
1479  (txSar.prevAckd != txSar.prevUnak) ) {
1480  // Not new ACK; increase counter but only if it does not contain data
1481  if (fsm_Meta.meta.length == 0) {
1482  txSar.count++;
1483  }
1484  }
1485  else {
1486  // Notify probeTimer about new ACK
1487  soTIm_ClearProbeTimer.write(fsm_Meta.sessionId);
1488  // Check for SlowStart & Increase Congestion Window
1489  if (txSar.cong_window <= (txSar.slowstart_threshold-ZYC2_MSS)) {
1490  txSar.cong_window += ZYC2_MSS;
1491  }
1492  else if (txSar.cong_window <= TOE_MAX_CONGESTION_WINDOW) { // 0xF7FF
1493  txSar.cong_window += 365; //TODO replace by approx. of (MSS x MSS) / cong_window
1494  }
1495  txSar.count = 0;
1496  txSar.fastRetransmitted = false;
1497  }
1498  // Update TxSarTable (only if count or retransmit)
1499  if ( ( (fsm_Meta.meta.ackNumb >= txSar.prevAckd) and (fsm_Meta.meta.ackNumb <= txSar.prevUnak)) or
1500  (((fsm_Meta.meta.ackNumb >= txSar.prevAckd) or (fsm_Meta.meta.ackNumb <= txSar.prevUnak)) and (txSar.prevUnak < txSar.prevAckd))) {
1501  soTSt_TxSarQry.write((RXeTxSarQuery(fsm_Meta.sessionId,
1502  fsm_Meta.meta.ackNumb,
1503  fsm_Meta.meta.winSize,
1504  txSar.cong_window,
1505  txSar.count,
1506  ((txSar.count == 3) || txSar.fastRetransmitted))));
1507  }
1508 
1509  // If packet contains payload
1510  // We must handle Out-Of-Order delivered segments
1511  if (fsm_Meta.meta.length != 0) {
1512 
1513  // Build a DDR memory address for this segment
1514  // FYI - The TCP Rx buffers use up to 1GB (16Kx64KB).
1515  RxMemPtr memSegAddr = TOE_RX_MEMORY_BASE;
1516  memSegAddr(29, TOE_WINDOW_BITS) = fsm_Meta.sessionId(13, 0);
1517  memSegAddr(TOE_WINDOW_BITS-1, 0) = fsm_Meta.meta.seqNumb.range(TOE_WINDOW_BITS-1, 0);
1518 
1519  // Increment the Rx byte counter
1520  fsm_rxByteCounter += fsm_Meta.meta.length;
1521 
1522  RxSeqNum newRcvd = 0;
1523  RxSeqNum newOooHead = 0;
1524  RxSeqNum newOooTail = 0;
1525 
1526  //-- DEFAULT : No OOO and Rx segment is in expected sequence order
1527  if (!rxSar.ooo and (fsm_Meta.meta.seqNumb == rxSar.rcvd) and
1528  (fsm_freeSpace > fsm_Meta.meta.length)) {
1529  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "OOO-DEFAULT : Rx segment is in-order.\n"); }
1530  // Generate new received pointer
1531  newRcvd = fsm_Meta.meta.seqNumb + fsm_Meta.meta.length;
1532  // Update RxSar pointers
1533  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, newRcvd, QUERY_WR));
1534  // Send memory write command
1535  assessSize(myName, soMwr_WrCmd, "soMwr_WrCmd", cDepth_FsmToMwr_WrCmd);
1536  soMwr_WrCmd.write(DmCmd(memSegAddr, fsm_Meta.meta.length));
1537  // Send Rx data notify to [APP]
1538  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, fsm_Meta.meta.length,
1539  fsm_Meta.ip4SrcAddr, fsm_Meta.tcpSrcPort,
1540  fsm_Meta.tcpDstPort));
1541  // Send keep command
1542  soTsd_DropCmd.write(CMD_KEEP);
1543  fsm_oooDebugState = 2;
1544  }
1545  //-- START : No OOO but Rx segment arrived out-of-order
1546  else if (!rxSar.ooo and (fsm_Meta.meta.seqNumb > rxSar.rcvd) and
1547  (fsm_freeSpace > (fsm_Meta.meta.seqNumb+fsm_Meta.meta.length-rxSar.oooHead)(TOE_WINDOW_BITS-1, 0))) {
1548  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "OOO-START : Rx segment is out-of-order.\n"); }
1549  // Generate new oooHead and oooTail pointers
1550  newOooHead = fsm_Meta.meta.seqNumb + fsm_Meta.meta.length;
1551  newOooTail = fsm_Meta.meta.seqNumb;
1552  // Update RxSar pointers
1553  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, rxSar.rcvd, FLAG_OOO, newOooHead, newOooTail, QUERY_WR));
1554  // Send memory write command
1555  soMwr_WrCmd.write(DmCmd(memSegAddr, fsm_Meta.meta.length));
1556  // Prevent [Ran] to send Rx data notify to [APP] by setting LENGTH=0 !!!
1557  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, 0,
1558  fsm_Meta.ip4SrcAddr, fsm_Meta.tcpSrcPort,
1559  fsm_Meta.tcpDstPort));
1560  // Send keep command
1561  soTsd_DropCmd.write(CMD_KEEP);
1562  fsm_oooDebugState = 3;
1563  }
1564  //-- CONTINUE: OOO exists and Rx segment is in-order with respect to 'oooHead' pointer
1565  else if (rxSar.ooo and (fsm_Meta.meta.seqNumb == rxSar.oooHead) and
1566  (fsm_freeSpace > fsm_Meta.meta.length)) {
1567  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "OOO-CONTINUE: Rx segment is in-order with respect to 'oooHead'.\n"); }
1568  // Generate new oooHead pointer
1569  newOooHead = fsm_Meta.meta.seqNumb + fsm_Meta.meta.length;
1570  // Update RxSar pointers
1571  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, rxSar.rcvd, FLAG_OOO, newOooHead, rxSar.oooTail, QUERY_WR));
1572  // Send memory write command
1573  soMwr_WrCmd.write(DmCmd(memSegAddr, fsm_Meta.meta.length));
1574  // Prevent [Ran] to send Rx data notify to [APP] by setting LENGTH=0 !!!
1575  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, 0,
1576  fsm_Meta.ip4SrcAddr, fsm_Meta.tcpSrcPort,
1577  fsm_Meta.tcpDstPort));
1578  // Send keep command
1579  soTsd_DropCmd.write(CMD_KEEP);
1580  fsm_oooDebugState = 4;
1581  }
1582  //-- CONTINUE: OOO exists, Rx segment is in-order with respect to 'rcvd' pointer but it does not fill the gap
1583  else if (rxSar.ooo and (fsm_Meta.meta.seqNumb == rxSar.rcvd) and
1584  ((fsm_Meta.meta.seqNumb + fsm_Meta.meta.length) < rxSar.oooTail)) {
1585  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "OOO-CONTINUE: Rx segment is in-order with respect to 'rcvd' but it does not fill the gap.\n"); }
1586  // Generate new received pointer
1587  newRcvd = fsm_Meta.meta.seqNumb + fsm_Meta.meta.length;
1588  // Update RxSar pointers
1589  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, newRcvd, FLAG_OOO, rxSar.oooHead, rxSar.oooTail, QUERY_WR));
1590  // Send memory write command
1591  soMwr_WrCmd.write(DmCmd(memSegAddr, fsm_Meta.meta.length));
1592  // Send Rx data notify to [APP]
1593  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, fsm_Meta.meta.length,
1594  fsm_Meta.ip4SrcAddr, fsm_Meta.tcpSrcPort,
1595  fsm_Meta.tcpDstPort));
1596  // Send keep command
1597  soTsd_DropCmd.write(CMD_KEEP);
1598  fsm_oooDebugState = 5;
1599  }
1600  //-- END : OOO exists, Rx segment is in-order with respect to 'rcvd' pointer and it fills the gap
1601  else if (rxSar.ooo and (fsm_Meta.meta.seqNumb == rxSar.rcvd) and
1602  ((fsm_Meta.meta.seqNumb + fsm_Meta.meta.length) == rxSar.oooTail)) {
1603  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "OOO-END : Rx segment is in-order with respect to 'rcvd' and it fills the gap.\n"); }
1604  // Generate new received pointer
1605  newRcvd = rxSar.oooHead;
1606  // Update RxSar pointers
1607  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, newRcvd, FLAG_INO, rxSar.oooHead, rxSar.oooTail, QUERY_WR));
1608  // Send memory write command
1609  soMwr_WrCmd.write(DmCmd(memSegAddr, fsm_Meta.meta.length));
1610  // Send Rx data notify to [APP]
1611  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, (rxSar.oooHead - rxSar.rcvd),
1612  fsm_Meta.ip4SrcAddr, fsm_Meta.tcpSrcPort,
1613  fsm_Meta.tcpDstPort));
1614  // Send keep command
1615  soTsd_DropCmd.write(CMD_KEEP);
1616  fsm_oooDebugState = 6;
1617  }
1618  //-- OOO-DROP : Always drop segment in all other cases
1619  else {
1620  soTsd_DropCmd.write(CMD_DROP);
1621  fsm_oooDropCounter++;
1622  fsm_oooDebugState = 10;
1623  if ( (fsm_Meta.meta.seqNumb < rxSar.rcvd)) {
1624  printInfo(myName, "OOO-Dropping Rx segment (Frame is a retransmission because of a lost or delayed ACK). \n");
1625  fsm_oooDebugState = 11;
1626  }
1627  else if ( (!rxSar.ooo and (fsm_Meta.meta.seqNumb == rxSar.rcvd) and (fsm_freeSpace < fsm_Meta.meta.length)) or
1628  (!rxSar.ooo and (fsm_Meta.meta.seqNumb > rxSar.rcvd) and (fsm_freeSpace > (fsm_Meta.meta.seqNumb+fsm_Meta.meta.length-rxSar.rcvd)(TOE_WINDOW_BITS-1, 0))) ) {
1629  printInfo(myName, "OOO-Dropping Rx segment (Not enough space left in the Rx ring buffer).\n");
1630  fsm_oooDebugState = 12;
1631  }
1632  else if (fsm_Meta.meta.seqNumb+fsm_Meta.meta.length == rxSar.rcvd) {
1633  printInfo(myName, "OOO-Dropping Rx segment (Segment is a duplicate).\n");
1634  fsm_oooDebugState = 13;
1635  }
1636  else {
1637  printFatal(myName, "OOO-Dropping Rx segment (Reason is unknown).\n");
1638  fsm_oooDebugState = 14;
1639  }
1640  }
1641  }
1642 
1643  //-- Generate ACK Event -------------------------------------
1644 # if FAST_RETRANSMIT
1645  if (txSar.count == 3 && !txSar.fastRetransmitted) { // [FIXME - Use a constant here]
1646  soEVe_Event.write(event(RT, fsm_Meta.sessionId));
1647  }
1648  else if (fsm_meta.meta.length != 0) {
1649 #else
1650  if (fsm_Meta.meta.length != 0) {
1651 #endif
1652  if (!rxSar.ooo and (fsm_Meta.meta.seqNumb == rxSar.rcvd) and
1653  (fsm_freeSpace > fsm_Meta.meta.length)) {
1654  // No OOO and Rx segment is in expected sequence order
1655  soEVe_Event.write(Event(ACK_EVENT, fsm_Meta.sessionId));
1656  }
1657  else {
1658  // TCP retransmission frame
1659  soEVe_Event.write(Event(ACK_NODELAY_EVENT, fsm_Meta.sessionId));
1660  fsm_oooDebugState += 100;
1661  }
1662  }
1663 
1664  //-- Reset Retransmit Timer --------------------------------
1665  if (fsm_Meta.meta.ackNumb == txSar.prevUnak) {
1666  switch (tcpState) {
1667  case SYN_RECEIVED:
1668  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, ESTABLISHED, QUERY_WR));
1669  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "Session[%d] - TCP State = ESTABISHED.\n", fsm_Meta.sessionId.to_uint()); }
1670  break;
1671  case CLOSING:
1672  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, TIME_WAIT, QUERY_WR));
1673  soTIm_CloseTimer.write(fsm_Meta.sessionId); // [TDOD - rename]
1674  break;
1675  case LAST_ACK:
1676  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, CLOSED, QUERY_WR));
1677  break;
1678  default:
1679  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1680  break;
1681  }
1682  }
1683  else { // we have to release the lock
1684  // Reset rtTimer
1685  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR)); // or ESTABLISHED
1686  }
1687  } // End of : if ( (tcpState == ...
1688  // TODO if timewait just send ACK, can it be time wait??
1689  else { // state == (CLOSED || SYN_SENT || CLOSE_WAIT || FIN_WAIT_2 || TIME_WAIT)
1690  // SENT RST, RFC 793: fig.11
1691  soEVe_Event.write(rstEvent(fsm_Meta.sessionId, fsm_Meta.meta.seqNumb+fsm_Meta.meta.length)); // noACK ?
1692  // if data is in the pipe it needs to be droppped
1693  if (fsm_Meta.meta.length != 0) {
1694  soTsd_DropCmd.write(CMD_DROP);
1695  }
1696  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1697  }
1698  } // End of: ACK processing
1699  break;
1700  case 2:
1701  //--------------------------------------
1702  //-- SYN
1703  //--------------------------------------
1704  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "Entering 'SYN' processing.\n"); }
1705  if (fsm_fsmState == FSM_LOAD) {
1706  siSTt_StateRep.read(tcpState);
1707  siRSt_RxSarRep.read(rxSar);
1708  if (tcpState == CLOSED or tcpState == SYN_SENT) {
1709  // Initialize RxSar with received SeqNum
1710  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, fsm_Meta.meta.seqNumb+1,
1711  QUERY_WR, QUERY_INIT));
1712  // Initialize TxSar with received WindowSize
1713  // All other parameters are zero or false; they will be initialized by [TXe]
1714  soTSt_TxSarQry.write((RXeTxSarQuery(fsm_Meta.sessionId, 0, fsm_Meta.meta.winSize,
1715  0, 0, false)));
1716  // Post a SYN_ACK event request
1717  soEVe_Event.write(Event(SYN_ACK_EVENT, fsm_Meta.sessionId));
1718  if (DEBUG_LEVEL & TRACE_FSM) printInfo(myName, "Requesting [TXe] to send a [SYN,ACK] for SessId %d.\n", fsm_Meta.sessionId.to_uint());
1719  // Change TcpState to SYN_RECEIVED
1720  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, SYN_RECEIVED, QUERY_WR));
1721  }
1722  else if (tcpState == SYN_RECEIVED) { // && mdh_meta.seqNumb+1 == rxSar.recvd) // Maybe Check for seq
1723  // If it is the same SYN, we resent SYN-ACK, almost like quick RT, we could also wait for RT timer
1724  if (fsm_Meta.meta.seqNumb+1 == rxSar.rcvd) {
1725  // Retransmit SYN_ACK
1726  ap_uint<3> rtCount = 1;
1727  soEVe_Event.write(Event(SYN_ACK_EVENT, fsm_Meta.sessionId, rtCount));
1728  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1729  }
1730  else { // Sent RST, RFC 793: fig.9 (old) duplicate SYN(+ACK)
1731  soEVe_Event.write(rstEvent(fsm_Meta.sessionId, fsm_Meta.meta.seqNumb+1)); //length == 0
1732  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, CLOSED, QUERY_WR));
1733  }
1734  }
1735  else { // Any synchronized state
1736  // Unexpected SYN arrived, reply with normal ACK, RFC 793: fig.10
1737  soEVe_Event.write(Event(ACK_NODELAY_EVENT, fsm_Meta.sessionId));
1738  // TODo send RST, has no ACK??
1739  // Respond with RST, no ACK, seq ==
1740  //eventEngine.write(rstEvent(mdh_meta.seqNumb, mh_meta.length, true));
1741  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1742  }
1743  }
1744  break;
1745  case 3:
1746  //--------------------------------------
1747  //-- SYN_ACK
1748  //--------------------------------------
1749  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "Entering 'SYN_ACK' processing.\n"); }
1750  if (fsm_fsmState == FSM_LOAD) {
1751  siSTt_StateRep.read(tcpState);
1752  siRSt_RxSarRep.read(rxSar);
1753  siTSt_TxSarRep.read(txSar);
1754  TimerCmd timerCmd = (fsm_Meta.meta.ackNumb == txSar.prevUnak) ? STOP_TIMER : LOAD_TIMER;
1755  soTIm_ReTxTimerCmd.write(RXeReTransTimerCmd(fsm_Meta.sessionId, timerCmd));
1756  if ( (tcpState == SYN_SENT) and (fsm_Meta.meta.ackNumb == txSar.prevUnak) ) { // && !mh_lup.created)
1757  // Initialize RxSar with received SeqNum
1758  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, fsm_Meta.meta.seqNumb+1,
1759  QUERY_WR, QUERY_INIT));
1760  // Update TxSar with received AckNum and WindowSize
1761  soTSt_TxSarQry.write(RXeTxSarQuery(fsm_Meta.sessionId,
1762  fsm_Meta.meta.ackNumb,
1763  fsm_Meta.meta.winSize,
1764  txSar.cong_window, 0, false)); // [TODO - maybe include count check]
1765  // Set ACK event
1766  soEVe_Event.write(Event(ACK_NODELAY_EVENT, fsm_Meta.sessionId));
1767  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, ESTABLISHED, QUERY_WR));
1768  // Signal [TAi] that the active connection was successfully established
1769  soTAi_SessOpnSts.write(SessState(fsm_Meta.sessionId, ESTABLISHED));
1770  }
1771  else if (tcpState == SYN_SENT) { //TODO correct answer?
1772  // Sent RST, RFC 793: fig.9 (old) duplicate SYN(+ACK)
1773  soEVe_Event.write(rstEvent(fsm_Meta.sessionId,
1774  fsm_Meta.meta.seqNumb+fsm_Meta.meta.length+1));
1775  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, CLOSED, QUERY_WR));
1776  }
1777  else {
1778  // Unexpected SYN arrived, reply with normal ACK, RFC 793: fig.10
1779  soEVe_Event.write(Event(ACK_NODELAY_EVENT, fsm_Meta.sessionId));
1780  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1781  }
1782  }
1783  break;
1784  case 5:
1785  //--------------------------------------
1786  //-- FIN (_ACK)
1787  //--------------------------------------
1788  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "Entering 'FIN_ACK' processing.\n"); }
1789  if (fsm_fsmState == FSM_LOAD) {
1790  siSTt_StateRep.read(tcpState);
1791  siRSt_RxSarRep.read(rxSar);
1792  siTSt_TxSarRep.read(txSar);
1793  TimerCmd timerCmd = (fsm_Meta.meta.ackNumb == txSar.prevUnak) ? STOP_TIMER : LOAD_TIMER;
1794  soTIm_ReTxTimerCmd.write(RXeReTransTimerCmd(fsm_Meta.sessionId, timerCmd));
1795  // Check state and if FIN in order, Current out of order FINs are not accepted
1796  if ( (tcpState == ESTABLISHED or tcpState == FIN_WAIT_1 or tcpState == FIN_WAIT_2) and (rxSar.rcvd == fsm_Meta.meta.seqNumb) ) {
1797  soTSt_TxSarQry.write((RXeTxSarQuery(fsm_Meta.sessionId,
1798  fsm_Meta.meta.ackNumb, fsm_Meta.meta.winSize,
1799  txSar.cong_window, txSar.count,
1800  ~QUERY_FAST_RETRANSMIT))); //TODO include count check
1801  // +1 for phantom byte, there might be data too
1802  soRSt_RxSarQry.write(RXeRxSarQuery(fsm_Meta.sessionId, fsm_Meta.meta.seqNumb+fsm_Meta.meta.length+1,
1803  QUERY_WR)); // diff to ACK
1804  // Clear the probe timer
1805  soTIm_ClearProbeTimer.write(fsm_Meta.sessionId);
1806  // Check if there is payload
1807  if (fsm_Meta.meta.length != 0) {
1808  // Build a DDR memory address for this segment
1809  RxMemPtr memSegAddr = TOE_RX_MEMORY_BASE;
1810  memSegAddr(29, 16) = fsm_Meta.sessionId(13, 0);
1811  memSegAddr(15, 0) = fsm_Meta.meta.seqNumb(15, 0);
1812 #if !(RX_DDR_BYPASS)
1813  soMwr_WrCmd.write(DmCmd(memSegAddr, fsm_Meta.meta.length));
1814 #endif
1815  // Tell Application new data is available and connection got closed
1816  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, fsm_Meta.meta.length, fsm_Meta.ip4SrcAddr,
1817  fsm_Meta.tcpSrcPort, fsm_Meta.tcpDstPort, CLOSED));
1818  soTsd_DropCmd.write(CMD_KEEP);
1819  }
1820  else if (tcpState == ESTABLISHED) {
1821  // Tell Application connection got closed
1822  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, 0, fsm_Meta.ip4SrcAddr,
1823  fsm_Meta.tcpSrcPort, fsm_Meta.tcpDstPort, CLOSED));
1824  }
1825  // Update state
1826  if (tcpState == ESTABLISHED) {
1827  soEVe_Event.write(Event(FIN_EVENT, fsm_Meta.sessionId));
1828  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, LAST_ACK, QUERY_WR));
1829  }
1830  else { //FIN_WAIT_1 || FIN_WAIT_2
1831  if (fsm_Meta.meta.ackNumb == txSar.prevUnak) {
1832  // Check if final FIN is ACK'd -> LAST_ACK
1833  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, TIME_WAIT, QUERY_WR));
1834  soTIm_CloseTimer.write(fsm_Meta.sessionId);
1835  }
1836  else {
1837  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, CLOSING, QUERY_WR));
1838  }
1839  soEVe_Event.write(Event(ACK_EVENT, fsm_Meta.sessionId));
1840  }
1841  }
1842  else { // NOT (ESTABLISHED || FIN_WAIT_1 || FIN_WAIT_2)
1843  soEVe_Event.write(Event(ACK_EVENT, fsm_Meta.sessionId));
1844  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1845  // If there is payload we need to drop it
1846  if (fsm_Meta.meta.length != 0) {
1847  soTsd_DropCmd.write(CMD_DROP);
1848  }
1849  }
1850  }
1851  break;
1852  default: //TODO MAYBE load everything all the time
1853  if (DEBUG_LEVEL & TRACE_FSM) { printInfo(myName, "Received segment. CtrlBits=0x%X\n", control_bits.to_uchar()); }
1854  // stateTable is locked, make sure it is released in at the end
1855  // If there is an ACK we read txSar
1856  // We always read rxSar
1857  if (fsm_fsmState == FSM_LOAD) {
1858  siSTt_StateRep.read(tcpState);
1859  siRSt_RxSarRep.read(rxSar); //TODO not sure nb works
1860  siTSt_TxSarRep.read_nb(txSar);
1861  }
1862  if (fsm_fsmState == FSM_LOAD) {
1863  // Handle if RST
1864  if (fsm_Meta.meta.rst) {
1865  if (tcpState == SYN_SENT) {
1866  // [TODO this would be a RST,ACK i think]
1867  // Check if matching SYN
1868  if (fsm_Meta.meta.ackNumb == txSar.prevUnak) {
1869  // The connection culd not be established
1870  soTAi_SessOpnSts.write(SessState(fsm_Meta.sessionId, CLOSED));
1871  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, CLOSED, QUERY_WR));
1872  soTIm_ReTxTimerCmd.write(RXeReTransTimerCmd(fsm_Meta.sessionId, STOP_TIMER));
1873  }
1874  else {
1875  // Ignore since not matching
1876  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1877  }
1878  }
1879  else {
1880  // Check if in window
1881  if (fsm_Meta.meta.seqNumb == rxSar.rcvd) {
1882  // Tell application, RST occurred, abort
1883  soRan_RxNotif.write(TcpAppNotif(fsm_Meta.sessionId, 0, fsm_Meta.ip4SrcAddr,
1884  fsm_Meta.tcpSrcPort, fsm_Meta.tcpDstPort, CLOSED)); // RESET-CLOSED
1885  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, CLOSED, QUERY_WR)); //TODO maybe some TIME_WAIT state
1886  soTIm_ReTxTimerCmd.write(RXeReTransTimerCmd(fsm_Meta.sessionId, STOP_TIMER));
1887  }
1888  else {
1889  // Ignore since not matching window
1890  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1891  }
1892  }
1893  }
1894  else { // Handle non RST bogus packages
1895  //TODO maybe sent RST ourselves, or simply ignore
1896  // For now ignore, sent ACK??
1897  //eventsOut.write(rstEvent(mh_meta.seqNumb, 0, true));
1898  soSTt_StateQry.write(StateQuery(fsm_Meta.sessionId, tcpState, QUERY_WR));
1899  } // End of: if (fsm_meta.meta.rst)
1900  } // if fsm_stat
1901  break;
1902  } // End of: switch control_bits
1903  if (DEBUG_LEVEL & TRACE_FSM) {
1904  printInfo(myName, "Flags - [0x%X] \n", control_bits.to_uint());
1905  }
1906  break;
1907  } // End of: switch state
1908 
1909  //-- ALWAYS -------------------------------------------
1910  if (!soMMIO_OooDropCnt.full()) {
1911  soMMIO_OooDropCnt.write(fsm_oooDropCounter);
1912  }
1913  else {
1914  printFatal(myName, "Cannot write soMMIO_OooDropCnt stream...");
1915  }
1916  if (!soDBG_TcpIpRxByteCnt.full()) {
1917  soDBG_TcpIpRxByteCnt.write(fsm_rxByteCounter);
1918  }
1919  else {
1920  printFatal(myName, "Cannot write soDBG_TcpIpRxByteCnt stream...");
1921  }
1922  if (!soDBG_OooDebug.full()) {
1923  soDBG_OooDebug.write(fsm_oooDebugState);
1924  }
1925  else {
1926  printFatal(myName, "Cannot write soDBG_OooDebug stream...");
1927  }
1928 
1929 } // End of: pFiniteStateMachine(
RXeMeta meta
Definition: rx_engine.hpp:94
Ip4SrcAddr ip4SrcAddr
Definition: rx_engine.hpp:91
TcpDstPort tcpDstPort
Definition: rx_engine.hpp:93
TcpSrcPort tcpSrcPort
Definition: rx_engine.hpp:92
SessionId sessionId
Definition: rx_engine.hpp:90
TxAckNum prevUnak
Definition: toe.hpp:471
ap_uint< 2 > count
Definition: toe.hpp:474
CmdBool fastRetransmitted
Definition: toe.hpp:475
TcpWindow slowstart_threshold
Definition: toe.hpp:473
TcpWindow cong_window
Definition: toe.hpp:472
TxAckNum prevAckd
Definition: toe.hpp:470
FlagBool ooo
Definition: toe.hpp:374
RxSeqNum oooTail
Definition: toe.hpp:373
RxBufPtr appd
Definition: toe.hpp:370
RxSeqNum oooHead
Definition: toe.hpp:372
RxSeqNum rcvd
Definition: toe.hpp:371
TcpAppOpnRep SessState
Definition: toe.hpp:279
const int cDepth_FsmToMwr_WrCmd
Definition: rx_engine.hpp:104
TcpSeqNum RxSeqNum
Definition: toe.hpp:290
TimerCmd
Definition: toe.hpp:622
#define TRACE_FSM
Definition: rx_engine.cpp:78
TcpBufAdr RxBufPtr
Definition: toe.hpp:298
ap_uint< 32 > RxMemPtr
Definition: toe.hpp:295
#define QUERY_FAST_RETRANSMIT
Definition: nts_types.hpp:68
TcpState
Definition: nts_types.hpp:296
#define QUERY_RD
Definition: nts_types.hpp:65
#define CMD_DROP
Definition: nts_types.hpp:61
#define QUERY_WR
Definition: nts_types.hpp:66
#define FLAG_OOO
Definition: nts_types.hpp:73
#define QUERY_INIT
Definition: nts_types.hpp:67
#define CMD_KEEP
Definition: nts_types.hpp:62
#define FLAG_INO
Definition: nts_types.hpp:74
@ LAST_ACK
Definition: nts_types.hpp:298
@ FIN_WAIT_2
Definition: nts_types.hpp:297
@ FIN_WAIT_1
Definition: nts_types.hpp:297
@ SYN_SENT
Definition: nts_types.hpp:296
@ TIME_WAIT
Definition: nts_types.hpp:297
@ ESTABLISHED
Definition: nts_types.hpp:296
@ CLOSING
Definition: nts_types.hpp:297
@ CLOSED
Definition: nts_types.hpp:296
@ SYN_RECEIVED
Definition: nts_types.hpp:296
tuple ZYC2_MSS
Definition: tc_utils.py:42
Here is the caller graph for this function:

◆ pFreePortTable()

void pFreePortTable ( StsBool poRdy_Ready,
stream< TcpPort > &  siSLc_CloseActPortCmd,
stream< TcpDynPort > &  siIrr_GetPortStateCmd,
stream< RspBit > &  soOrm_GetPortStateRsp,
stream< ReqBit > &  siTAi_GetFreePortReq,
stream< TcpPort > &  soTAi_GetFreePortRep 
)

Free Port Table (Fpt)

Parameters
[out]poRdy_ReadyReady signal to ReadyLogic (Rdy).
[in]siSLc_CloseActPortCmdCommand to release a port from SessionLookupController (SLc).
[in]siIrr_GetPortStateCmdCommand to get port state from InputRequestRouter (Irr).
[out]soOrm_GetPortStateRspResponse to get port state to OutputReplyMux (Orm).
[in]siTAi_GetFreePortReqGet free port request from TxAppInterface (TAi).
[out]soTAi_GetFreePortRepGet free port reply to [TAi].

This process keeps track of the opened source ports used in by active connections. It consists of a table containing a free list of ephemeral ports (also referred as dynamic ports) that the TOE uses as local source ports when it opens new active connections. A dynamic source port is implicitly assigned in the range (32,768 to 65,535) and there is no way (or reason) to explicitly specify such a port number. This table is accessed by one local [Irr] and 2 remote [SLc][TAi] processes.

@Warning The initial design point assumed a maximum of 10K sessions, which is much less than the possible 32K active ports.

Definition at line 232 of file port_table.cpp.

240 {
241  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
242  #pragma HLS PIPELINE II=1 enable_flush
243  #pragma HLS INLINE off
244 
245  const char *myName = concat3(THIS_NAME, "/", "Fpt");
246 
247  //-- STATIC ARRAYS ---------------------------------------------------------
248  static PortRange ACTIVE_PORT_TABLE[0x8000];
249  #pragma HLS RESOURCE variable=ACTIVE_PORT_TABLE core=RAM_T2P_BRAM
250  #pragma HLS DEPENDENCE variable=ACTIVE_PORT_TABLE inter false
251 
252  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
253  static bool fpt_isFPtInit=false;
254  #pragma HLS reset variable=fpt_isFPtInit
255  static bool fpt_searching=false;
256  #pragma HLS reset variable=fpt_searching
257  static bool fpt_eval=false;
258  #pragma HLS reset variable=fpt_eval
259  static TcpDynPort fpt_dynPortNum=0x7FFF;
260  #pragma HLS reset variable=fpt_dynPortNum
261 
262  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
263  static bool portState = ACT_USED_PORT;
264  #pragma HLS DEPENDENCE variable=portState inter false
265 
266  // The table is a free list that must be initialized upon reset
267  if (!fpt_isFPtInit) {
268  ACTIVE_PORT_TABLE[fpt_dynPortNum] = ACT_FREE_PORT;
269  fpt_dynPortNum -= 1;
270  if (fpt_dynPortNum == 0) {
271  fpt_isFPtInit = true;
272  if (DEBUG_LEVEL & TRACE_FPT) {
273  printInfo(myName, "Done with initialization of ACTIVE_PORT_TABLE.\n");
274  }
275  }
276  }
277  else {
278  if (fpt_searching) {
279  portState = ACTIVE_PORT_TABLE[fpt_dynPortNum];
280  fpt_searching = false;
281  fpt_eval = true;
282  }
283  else if (fpt_eval) {
284  if (portState == ACT_FREE_PORT) {
285  // Found a free entry port in the table
286  if (!soTAi_GetFreePortRep.full()) {
287  // Stop evaluating. Set port number to USED and forward to [TAi]
288  fpt_eval = false;
289  ACTIVE_PORT_TABLE[fpt_dynPortNum] = ACT_USED_PORT;
290  // Add 0x8000 before sending back
291  soTAi_GetFreePortRep.write(0x8000 + fpt_dynPortNum);
292  }
293  }
294  else {
295  // Continue searching
296  fpt_searching = true;
297  }
298  fpt_dynPortNum++;
299  }
300  else if (!siIrr_GetPortStateCmd.empty()) {
301  // Warning: Cannot add "and !soOrm_GetPortStateRsp.full()" here because
302  // it increases the task interval from 1 to 2!
303  TcpDynPort portNum = siIrr_GetPortStateCmd.read();
304  soOrm_GetPortStateRsp.write(ACTIVE_PORT_TABLE[portNum]);
305  }
306  else if (!siTAi_GetFreePortReq.empty()) {
307  siTAi_GetFreePortReq.read();
308  fpt_searching = true;
309  }
310  else if (!siSLc_CloseActPortCmd.empty()) {
311  TcpPort tcpPort = siSLc_CloseActPortCmd.read();
312  if (tcpPort.bit(15) == 1) {
313  // Assess that port number >= 0x8000
314  ACTIVE_PORT_TABLE[tcpPort.range(14, 0)] = ACT_FREE_PORT;
315  }
316  #ifndef __SYNTHESIS__
317  else {
318  printError(myName, "SLc is not allowed to release a static port.\n");
319  exit(1);
320  }
321  #endif
322  }
323  }
324  // ALWAYS
325  poRdy_Ready = fpt_isFPtInit;
326 }
#define PortRange
Definition: port_table.hpp:72
#define ACT_USED_PORT
Definition: port_table.hpp:67
#define ACT_FREE_PORT
Definition: port_table.hpp:66
#define TRACE_FPT
Definition: port_table.cpp:74
ap_uint< 15 > TcpDynPort
Definition: toe.hpp:285
#define printError(callerName, format,...)
A macro to print an error message.
Definition: nts_utils.hpp:195
ap_uint< 16 > TcpPort
Definition: AxisTcp.hpp:105
Here is the caller graph for this function:

◆ pInputRequestRouter()

void pInputRequestRouter ( stream< TcpPort > &  siRXe_GetPortStateCmd,
stream< TcpStaPort > &  soLpt_GetLsnPortStateCmd,
stream< TcpDynPort > &  soFpt_GetActPortStateCmd,
stream< bool > &  soOrm_QueryRange 
)

Input Request Router (Irr)

Parameters
[in]siRXe_GetPortStateCmdGet state of a port from RxEngine (RXe).
[out]soLpt_GetLsnPortStateCmdGet state of a listen port to ListenPortTable (LPt).
[out]soFpt_GetActPortStateCmdGet state of an active port to FreePortTable (Fpt).
[out]soOrm_QueryRangeRange of the forwarded query to OutputReplyMux (Orm).

This process checks the range of the port to be looked-up and forwards that request to the corresponding lookup table ([Lpt] or [Fpt]). The [PRt] supports two port ranges; one for static ports (0 to 32,767) which are used for listening ports, and one for dynamically assigned or ephemeral ports (32,768 to 65,535) which are used for active connections.

Definition at line 343 of file port_table.cpp.

348 {
349  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
350  #pragma HLS PIPELINE II=1 enable_flush
351  #pragma HLS INLINE off
352 
353  const char *myName = concat3(THIS_NAME, "/", "Irr");
354 
355  // Forward request according to port number,
356  if (!siRXe_GetPortStateCmd.empty()) {
357  TcpPort portToCheck = siRXe_GetPortStateCmd.read();
358  if (DEBUG_LEVEL & TRACE_IRR) {
359  printInfo(myName, "[RXe] is requesting the state of port #%d.\n", portToCheck.to_int());
360  }
361  if (portToCheck < 0x8000) {
362  // Listening ports are in the range [0x0000..0x7FFF]
363  soLpt_GetLsnPortStateCmd.write(portToCheck.range(14, 0));
364  soOrm_QueryRange.write(LISTEN_PORT);
365  }
366  else {
367  // Active ports are in the range [0x8000..0xFFFF]
368  soFpt_GetActPortStateCmd.write(portToCheck.range(14, 0));
369  soOrm_QueryRange.write(ACTIVE_PORT);
370  }
371  }
372 }
#define ACTIVE_PORT
Definition: port_table.hpp:69
#define TRACE_IRR
Definition: port_table.cpp:71
#define LISTEN_PORT
Definition: port_table.hpp:70
Here is the caller graph for this function:

◆ pInsertPseudoHeader()

void pInsertPseudoHeader ( stream< AxisRaw > &  siTle_Data,
stream< TcpSegLen > &  siTle_TcpSegLen,
stream< AxisPsd4 > &  soCsa_PseudoPkt 
)

Insert pseudo header (Iph)

Parameters
[in]siTle_DataA custom-made pseudo packet from TcpLengthExtractor (Tle).
[in]siTle_TcpSegLenThe length of the incoming TCP segment from [Tle].
[out]soCsa_PseudoPktPseudo TCP/IP packet to CheckSumAccumulator (Csa).

Constructs a TCP pseudo header and prepends it to the TCP payload. The result is a TCP pseudo packet (

See also
AxisPsd4.hpp).

The format of the incoming custom-made pseudo packet is as follows (see [TLe]):

   6                   5                   4                   3                   2                   1                   0

3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DA (LL) | DA (L) | DA (H) | DA (HH) | SA (LL) | SA (L) | SA (H) | SA (HH) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Seq (LL) | Seq (L) | Seq (H) | Seq (HH) | DP (L) | DP (H) | SP (L) | SP (H) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | |U|A|P|R|S|F| Data | | | | | | | Win (L) | Win (H) |Res|R|C|S|S|Y|I| Offset| Res | Ack (LL) | Ack (L) | Ack (H) | Ack (HH) | | | | |G|K|H|T|N|N| | | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | | | | | | | Data 3 | Data 2 | Data 1 | Data 0 | UrgPtr(L) | UrgPtr(H) | CSum (L) | CSum (H) | | | | | | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | NU | Data 7 | Data 6 | Data 5 | Data 4 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The format of the outgoing pseudo TCP segment is as follows (see also AxisPsd4.hpp):

 6                   5                   4                   3                   2                   1                   0

3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DA (LL) | DA (L) | DA (H) | DA (HH) | SA (LL) | SA (L) | SA (H) | SA (HH) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DP (L) | DP (H) | SP (L) | SP (H) | Segment Len | 0x06 | 0x00 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Ack (LL) | Ack (L) | Ack (H) | Ack (HH) | Seq (LL) | Seq (L) | Seq (H) | Seq (HH) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | | | |C|E|U|A|P|R|S|F| Data | |N| | UrgPtr(L) | UrgPtr(H) | CSum (L) | CSum (H) | Win (L) | Win (H) |W|C|R|C|S|S|Y|I| Offset| Res |S| | | | | | | |R|E|G|K|H|T|N|N| | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data 7 | Data 6 | Data 5 | Data 4 | Data 3 | Data 2 | Data 1 | Data 0 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Definition at line 320 of file rx_engine.cpp.

324 {
325  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
326  #pragma HLS PIPELINE II=1 enable_flush
327  #pragma HLS INLINE off
328 
329  const char *myName = concat3(THIS_NAME, "/", "Iph");
330 
331  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
332  static bool iph_residue=false;
333  #pragma HLS RESET variable=iph_residue
334  static ap_uint<2> iph_chunkCount=0;
335  #pragma HLS RESET variable=iph_chunkCount
336 
337  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
338  static AxisRaw iph_prevChunk;
339 
340  //-- DYNAMIC VARIABLES -----------------------------------------------------
341  ValBit valid;
343  AxisRaw currChunk;
344  AxisPsd4 sendChunk;
345 
346  if (iph_residue) {
347  sendChunk.setLE_TData(iph_prevChunk.getLE_TData(63, 32), 31, 0);
348  sendChunk.setLE_TKeep(iph_prevChunk.getLE_TKeep( 7, 4), 3, 0);
349  sendChunk.setLE_TData( 0x00000000, 63, 32);
350  sendChunk.setLE_TKeep( 0x0, 7, 4);
351  sendChunk.setLE_TLast(TLAST);
352  soCsa_PseudoPkt.write(sendChunk);
353  iph_residue = false;
354  if (DEBUG_LEVEL & TRACE_IPH) { printAxisRaw(myName, "soCsa_PseudoPkt =", sendChunk); }
355  }
356  else if(!siTle_Data.empty() and !soCsa_PseudoPkt.full()) {
357  switch (iph_chunkCount) {
358  case CHUNK_0:
359  // Forward [IP_DA|IP_SA]
360  siTle_Data.read(currChunk);
361  soCsa_PseudoPkt.write(currChunk);
362  iph_chunkCount++;
363  if (DEBUG_LEVEL & TRACE_IPH) { printAxisRaw(myName, "soCsa_PseudoPkt =", currChunk); }
364  break;
365  case CHUNK_1:
366  // Forward [TCP_DP|TCP_SP|TCP_LEN|PROT|0x00]
367  if (!siTle_TcpSegLen.empty()) {
368  siTle_TcpSegLen.read(tcpSegLen);
369  siTle_Data.read(currChunk);
370  // Assemble outgoing chunk
371  sendChunk.setPsd4ResBits(0x00);
372  sendChunk.setPsd4Prot(IP4_PROT_TCP);
373  sendChunk.setPsd4Len(tcpSegLen);
374  sendChunk.setTcpSrcPort(byteSwap16(currChunk.getLE_TData(15, 0)));
375  sendChunk.setTcpDstPort(byteSwap16(currChunk.getLE_TData(31, 16)));
376  sendChunk.setLE_TKeep(0xFF);
377  sendChunk.setLE_TLast(0);
378  soCsa_PseudoPkt.write(sendChunk);
379  iph_chunkCount++;
380  if (DEBUG_LEVEL & TRACE_IPH) printAxisRaw(myName, "soCsa_PseudoPkt =", sendChunk);
381  }
382  break;
383  default:
384  siTle_Data.read(currChunk);
385  // Forward [ ACK_NUM | SEQ_NUM ] or
386  // [URG_PTR|CHEKSUM|WINSIZE| FLAGS ] or
387  // [ DATA ]
388  sendChunk.setLE_TData(iph_prevChunk.getLE_TData(63, 32), 31, 0);
389  sendChunk.setLE_TKeep(iph_prevChunk.getLE_TKeep( 7, 4), 3, 0);
390  sendChunk.setLE_TData( currChunk.getLE_TData(31, 0), 63, 32);
391  sendChunk.setLE_TKeep( currChunk.getLE_TKeep( 3, 0), 7, 4);
392  sendChunk.setLE_TLast(currChunk.getLE_TKeep()[4] == 0);
393  soCsa_PseudoPkt.write(sendChunk);
394  if (DEBUG_LEVEL & TRACE_IPH) printAxisRaw(myName, "soCsa_PseudoPkt =", sendChunk);
395  break;
396  }
397  // Always copy 'currChunk' into 'prevChunk'
398  iph_prevChunk = currChunk;
399  if (currChunk.getTLast()) {
400  iph_chunkCount = 0;
401  iph_residue = currChunk.getLE_TKeep()[4] != 0;
402  }
403  }
404 }
void setTcpDstPort(TcpPort port)
Definition: AxisPsd4.hpp:148
void setPsd4Len(Ly4Len len)
Definition: AxisPsd4.hpp:138
void setTcpSrcPort(TcpPort port)
Definition: AxisPsd4.hpp:145
void setPsd4ResBits(Psd4Res res)
Definition: AxisPsd4.hpp:132
void setPsd4Prot(Ip4Prot prot)
Definition: AxisPsd4.hpp:135
void setLE_TLast(LE_tLast last)
Definition: AxisRaw.hpp:280
TcpSegLen tcpSegLen
Definition: tb_nal.cpp:833
#define TRACE_IPH
Definition: rx_engine.cpp:72
ap_uint< 16 > TcpSegLen
Definition: AxisTcp.hpp:121
ap_uint< 1 > ValBit
Definition: nts_types.hpp:117
#define IP4_PROT_TCP
Definition: nts_types.hpp:184
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:

◆ pIpHeaderConstructor()

void pIpHeaderConstructor ( stream< TcpDatLen > &  siMdl_TcpDatLen,
stream< IpAddrPair > &  siSps_IpAddrPair,
stream< AxisIp4 > &  soIPs_IpHeader 
)

IPv4 Header Constructor (Ihc)

Parameters
[in]siMdl_TcpDatLenTCP data length from Meta Data Loader (Mdl).
[in]siSps_Ip4AddrPairThe IP_SA and IP_DA from Socket Pair Splitter (Sps).
[out]soIps_IpHeaderIP4 header stream to Ip Packet Stitcher (Ips).

Constructs an IPv4 header and forwards it to the IP Packet Stitcher (Ips).

@Warning The IP header is formatted for transmission to the Ethernet MAC. Remember that this 64-bits interface is logically divided into lane #0 (7:0) to lane #7 (63:56). The format of the outgoing IPv4 header is then:

  6                   5                   4                   3                   2                   1                   0

3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Frag Ofst (L) |Flags| FO(H) | Ident (L) | Ident (H) | Total Len (L) | Total Len (H) |Type of Service|Version| IHL | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | SA (LL) | SA (L) | SA (H) | SA (HH) | Hd Chksum (L) | Hd Chksum (H) | Protocol | Time to Live | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Definition at line 710 of file tx_engine.cpp.

714 {
715  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
716  #pragma HLS INLINE off
717  #pragma HLS PIPELINE II=1 enable_flush
718 
719  const char *myName = concat3(THIS_NAME, "/", "Ihc");
720 
721  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
722  static ap_uint<2> ihc_chunkCounter=0;
723  #pragma HLS RESET variable=ihc_chunkCounter
724 
725  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
726  static IpAddrPair ihc_ipAddrPair;
727 
728  //-- DYNAMIC VARIABLES -----------------------------------------------------
729  AxisIp4 currIpHdrChunk;
730  Ip4TotalLen ip4TotLen = 0;
731  TcpDatLen tcpDatLen;
732 
733  switch(ihc_chunkCounter) {
734  case CHUNK_0:
735  if (!siMdl_TcpDatLen.empty()) {
736  siMdl_TcpDatLen.read(tcpDatLen);
737  currIpHdrChunk.setIp4Version(4);
738  currIpHdrChunk.setIp4HdrLen(5);
739  currIpHdrChunk.setIp4ToS(0);
740  ip4TotLen = IP4_HEADER_LEN + TCP_HEADER_LEN + tcpDatLen;
741  currIpHdrChunk.setIp4TotalLen(ip4TotLen);
742  currIpHdrChunk.setIp4Ident(0);
743  currIpHdrChunk.setIp4Flags(0);
744  currIpHdrChunk.setIp4FragOff(0);
745  currIpHdrChunk.setLE_TKeep(0xFF);
746  currIpHdrChunk.setLE_TLast(0);
747  if (DEBUG_LEVEL & TRACE_IHC) {
748  printAxisRaw(myName, currIpHdrChunk);
749  }
750  soIPs_IpHeader.write(currIpHdrChunk);
751  ihc_chunkCounter++;
752  }
753  break;
754  case CHUNK_1:
755  if (!siSps_IpAddrPair.empty()) {
756  siSps_IpAddrPair.read(ihc_ipAddrPair);
757  currIpHdrChunk.setIp4TtL(0x40);
758  currIpHdrChunk.setIp4Prot((ap_uint<8>)IP4_PROT_TCP);
759  currIpHdrChunk.setIp4HdrCsum(0);
760  currIpHdrChunk.setIp4SrcAddr(ihc_ipAddrPair.src);
761  currIpHdrChunk.setLE_TKeep(0xFF);
762  currIpHdrChunk.setLE_TLast(0);
763  if (DEBUG_LEVEL & TRACE_IHC) {
764  printAxisRaw(myName, currIpHdrChunk);
765  }
766  soIPs_IpHeader.write(currIpHdrChunk);
767  ihc_chunkCounter++;
768  }
769  break;
770  case CHUNK_2:
771  currIpHdrChunk.setIp4DstAddr(ihc_ipAddrPair.dst);
772  currIpHdrChunk.setLE_TKeep(0x0F);
773  currIpHdrChunk.setLE_TLast(TLAST);
774  if (DEBUG_LEVEL & TRACE_IHC) {
775  printAxisRaw(myName, currIpHdrChunk);
776  }
777  soIPs_IpHeader.write(currIpHdrChunk);
778  ihc_chunkCounter = 0;
779  break;
780  }
781 
782 } // End of: pIpHeaderConstructor
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 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
Ip4Addr src
Definition: tx_engine.hpp:115
Ip4Addr dst
Definition: tx_engine.hpp:116
#define TRACE_IHC
Definition: tx_engine.cpp:73
#define TCP_HEADER_LEN
Definition: AxisTcp.hpp:81
ap_uint< 16 > TcpDatLen
Definition: AxisTcp.hpp:123
#define IP4_HEADER_LEN
Definition: AxisIp4.hpp:133
ap_uint< 16 > Ip4TotalLen
Definition: AxisIp4.hpp:159
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pIpPktStitcher()

void pIpPktStitcher ( stream< AxisIp4 > &  siIhc_IpHeader,
stream< AxisPsd4 > &  siSca_PseudoPkt,
stream< TcpChecksum > &  siTca_TcpCsum,
stream< AxisIp4 > &  soIPTX_Data 
)

IPv4 Packet Stitcher (Ips)

Parameters
[in]siIhc_IpHeaderIP4 header stream from IP Header Constructor (Ihc).
[in]siSca_PseudoPktTCP pseudo packet stream from Sub Checksum Accumulator (Sca).
[in]siTca_TcpCsumTCP checksum from TCP Checksum Accumulator (Tca).
[out]soIPTX_DataPacket stream to IPv4 Tx Handler (IPTX).

Assembles an IPv4 packet from the incoming IP header stream and the TCP pseudo data packet stream from Sub Checksum Accumulator (Sca). This process also inserts the IPv4 header checksum and the TCP checksum. This is the actual IPv4 packet being streamed out by the TCP Offload Engine.

Definition at line 1316 of file tx_engine.cpp.

1321 {
1322  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1323  #pragma HLS INLINE off
1324  #pragma HLS PIPELINE II=1 enable_flush
1325 
1326  const char *myName = concat3(THIS_NAME, "/", "Ips");
1327 
1328  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1329  static ap_uint<3> ips_chunkCount=0;
1330  #pragma HLS RESET variable=ips_chunkCount
1331 
1332  //-- DYNAMIC VARIABLES -----------------------------------------------------
1333  AxisIp4 ip4HdrChunk;
1334  AxisPsd4 tcpPsdChunk;
1335  AxisIp4 currChunk(0, 0xFF, 0);
1336  TcpCsum tcpCsum;
1337 
1338  switch (ips_chunkCount) {
1339  case CHUNK_0:
1340  case CHUNK_1:
1341  if (!siIhc_IpHeader.empty() and !soIPTX_Data.full()) {
1342  siIhc_IpHeader.read(ip4HdrChunk);
1343  currChunk = ip4HdrChunk;
1344  soIPTX_Data.write(currChunk);
1345  ips_chunkCount++;
1346  if (DEBUG_LEVEL & TRACE_IPS) { printAxisRaw(myName, "soIPTX_Data =", currChunk); }
1347  }
1348  break;
1349  case CHUNK_2:
1350  // Start concatenating IPv4 header and TCP segment
1351  if (!siIhc_IpHeader.empty() && !siSca_PseudoPkt.empty() and !soIPTX_Data.full()) {
1352  siIhc_IpHeader.read(ip4HdrChunk);
1353  siSca_PseudoPkt.read(tcpPsdChunk);
1354  currChunk.setIp4DstAddr(ip4HdrChunk.getIp4DstAddr());
1355  currChunk.setTcpSrcPort(tcpPsdChunk.getTcpSrcPort());
1356  currChunk.setTcpDstPort(tcpPsdChunk.getTcpDstPort());
1357  soIPTX_Data.write(currChunk);
1358  ips_chunkCount++;
1359  if (DEBUG_LEVEL & TRACE_IPS) { printAxisRaw(myName, "soIPTX_Data =", currChunk); }
1360  }
1361  break;
1362  case CHUNK_3:
1363  if (!siSca_PseudoPkt.empty() and !soIPTX_Data.full()) {
1364  siSca_PseudoPkt.read(tcpPsdChunk);
1365  currChunk.setTcpSeqNum(tcpPsdChunk.getTcpSeqNum());
1366  currChunk.setTcpAckNum(tcpPsdChunk.getTcpAckNum());
1367  soIPTX_Data.write(currChunk);
1368  ips_chunkCount++;
1369  if (DEBUG_LEVEL & TRACE_IPS) { printAxisRaw(myName, "soIPTX_Data =", currChunk); }
1370  }
1371  break;
1372  case CHUNK_4:
1373  if (!siSca_PseudoPkt.empty() and !siTca_TcpCsum.empty() and !soIPTX_Data.full()) {
1374  siSca_PseudoPkt.read(tcpPsdChunk);
1375  siTca_TcpCsum.read(tcpCsum);
1376  // Get CtrlBits & Window & TCP UrgPtr & Checksum
1377  currChunk = tcpPsdChunk;
1378  // Now overwrite TCP checksum
1379  currChunk.setTcpChecksum(tcpCsum);
1380  soIPTX_Data.write(currChunk);
1381  if (DEBUG_LEVEL & TRACE_IPS) { printAxisRaw(myName, "soIPTX_Data =", currChunk); }
1382  ips_chunkCount++;
1383  if (tcpPsdChunk.getTLast()) {
1384  // This is the last chunk if/when there is no data payload
1385  ips_chunkCount = 0;
1386  }
1387  }
1388  break;
1389  default:
1390  if (!siSca_PseudoPkt.empty() and !soIPTX_Data.full()) {
1391  siSca_PseudoPkt.read(tcpPsdChunk); // TCP Data
1392  currChunk = tcpPsdChunk;
1393  soIPTX_Data.write(currChunk);
1394  if (DEBUG_LEVEL & TRACE_IPS) { printAxisRaw(myName, "soIPTX_Data =", currChunk); }
1395  if (tcpPsdChunk.getTLast()) {
1396  ips_chunkCount = 0;
1397  }
1398  }
1399  break;
1400  }
1401 }
Ip4Addr getIp4DstAddr()
Definition: AxisIp4.hpp:230
TcpPort getTcpDstPort()
Definition: AxisPsd4.hpp:149
TcpSeqNum getTcpSeqNum()
Definition: AxisPsd4.hpp:152
void setTcpChecksum(TcpChecksum csum)
Definition: AxisPsd4.hpp:186
TcpPort getTcpSrcPort()
Definition: AxisPsd4.hpp:146
TcpAckNum getTcpAckNum()
Definition: AxisPsd4.hpp:155
#define TRACE_IPS
Definition: tx_engine.cpp:80
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pListeningPortTable()

void pListeningPortTable ( StsBool poRdy_Ready,
stream< TcpPort > &  siRAi_OpenLsnPortReq,
stream< RepBit > &  soRAi_OpenLsnPortRep,
stream< TcpStaPort > &  siIrr_GetPortStateCmd,
stream< RspBit > &  soOrm_GetPortStateRsp 
)

Listening Port Table (Lpt)

Parameters
[out]poRdy_ReadyReady signal to ReadyLogic (Rdy).
[in]siRAi_OpenLsnPortReqOpen port request from RxAppInterface (RAi).
[out]soRAi_OpenLsnPortRepOpen port reply to [RAi].
[in]siIrr_GetPortStateCmdRequest port state from InputRequestRouter (Irr).
[out]soOrm_GetPortStateRspPort state response to OutputReplyMultiplexer (Orm).

This process keeps track of the port opened in listening mode. It consists of a port table which is accessed by two remote processes: 1) the RxAppInterface (TAi) when the application (APP) is requesting to open a port in listening mode. 2) the RxEngine (RXe) via the local InputRequestRouter (Irr) process, when the [RXe] is requesting the status of a destination port.

If a read and a write operation occur at the same time, the write operation (.i.e the opening of the port) takes precedence over the read operation.

Definition at line 141 of file port_table.cpp.

147 {
148  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
149  #pragma HLS PIPELINE II=1 enable_flush
150  #pragma HLS INLINE off
151 
152  const char *myName = concat3(THIS_NAME, "/", "Lpt");
153 
154  //-- STATIC ARRAYS ---------------------------------------------------------
155  static PortState LISTEN_PORT_TABLE[0x8000];
156  #pragma HLS RESOURCE variable=LISTEN_PORT_TABLE core=RAM_T2P_BRAM
157  #pragma HLS DEPENDENCE variable=LISTEN_PORT_TABLE inter false
158 
159  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
160  static bool lpt_isLPtInit=false;
161  #pragma HLS reset variable=lpt_isLPtInit
162  static TcpPort lpt_lsnPortNum=0;
163  #pragma HLS reset variable=lpt_lsnPortNum
164 
165  // This table must be cleared upon reset
166  if (!lpt_isLPtInit) {
167  LISTEN_PORT_TABLE[lpt_lsnPortNum(14, 0)] = STS_CLOSED;
168  lpt_lsnPortNum += 1;
169  if (lpt_lsnPortNum == 0x8000) {
170  lpt_isLPtInit = true;
171  if (DEBUG_LEVEL & TRACE_LPT) {
172  printInfo(myName, "Done with initialization of LISTEN_PORT_TABLE.\n");
173  }
174  }
175  }
176  else {
177  if (!siRAi_OpenLsnPortReq.empty() and !soRAi_OpenLsnPortRep.full()) {
178  siRAi_OpenLsnPortReq.read(lpt_lsnPortNum);
179  // [TODO] Let's add a specific bit to specifically open/close a port.
180  if (lpt_lsnPortNum < 0x8000) {
181  // Listening port number falls in the range [0..32,767]
182  // We can set the listening port table entry to true
183  LISTEN_PORT_TABLE[lpt_lsnPortNum] = STS_OPENED;
184  // Sent reply to RAi
185  soRAi_OpenLsnPortRep.write(STS_OPENED);
186  if (DEBUG_LEVEL & TRACE_LPT)
187  printInfo(myName, "[RAi] is requesting to open port #%d in listen mode.\n",
188  lpt_lsnPortNum.to_uint());
189  }
190  else {
191  soRAi_OpenLsnPortRep.write(STS_CLOSED);
192  }
193  }
194  else if (!siIrr_GetPortStateCmd.empty()) {
195  // Warning: Cannot add "and !soOrm_GetPortStateRsp.full()" here because
196  // it increases the task interval from 1 to 2!
197  TcpStaPort staticPortNum = siIrr_GetPortStateCmd.read();
198  // Sent status of that portNum to Orm
199  soOrm_GetPortStateRsp.write(LISTEN_PORT_TABLE[staticPortNum]);
200  if (DEBUG_LEVEL & TRACE_LPT)
201  printInfo(myName, "[RXe] is querying the state of listen port #%d \n",
202  staticPortNum.to_uint());
203  }
204  }
205  //-- ALWAYS
206  poRdy_Ready = lpt_isLPtInit;
207 }
AckBit PortState
Definition: port_table.hpp:65
ap_uint< 15 > TcpStaPort
Definition: toe.hpp:284
#define TRACE_LPT
Definition: port_table.cpp:73
#define STS_CLOSED
Definition: nts_types.hpp:82
#define STS_OPENED
Definition: nts_types.hpp:81
Here is the caller graph for this function:

◆ pLookupReplyHandler()

void pLookupReplyHandler ( stream< CamSessionLookupRequest > &  soCAM_SessLookupReq,
stream< CamSessionLookupReply > &  siCAM_SessLookupRep,
stream< CamSessionUpdateReply > &  siUrh_SessUpdateRsp,
stream< SessionLookupQuery > &  siRXe_SessLookupReq,
stream< SessionLookupReply > &  soRXe_SessLookupRep,
stream< SocketPair > &  siTAi_SessLookupReq,
stream< SessionLookupReply > &  soTAi_SessLookupRep,
stream< RtlSessId > &  siSim_FreeList,
stream< CamSessionUpdateRequest > &  soUrs_InsertSessReq,
stream< SLcReverseLkp > &  soRlt_ReverseLkpRsp 
)

Lookup Reply Handler (Lrh)

Parameters
[out]soCAM_SessLookupReqRequest to ternary CAM (CAM).
[in]siCAM_SessLookupRepReply from ternary CAM.
[in]siUrh_SessUpdateRspUpdate response from Update Reply Handler (Urh).
[in]siRXe_SessLookupReqRequest from Rx Engine (RXe).
[out]soRXe_SessLookupRepReply from CAM to RXe.
[in]siTAi_SessLookupReqRequest from Tx App. I/F (TAi).
[out]soTAi_SessLookupRepReply from CAM to TAi.
[in]siSim_FreeListFree liste from Session Id Manager (Sid).
[out]soUrs_InsertSessReqRequest to insert session to Update Request Sender (Urs).
[out]soRlt_ReverseLkpRspReverse lookup response to Reverse Lookup Table (Rlt).

This is the front-end process of the ternary content addressable memory (TCAM or CAM for short). It handles the session lookup requests from [RXe] and [TAi]. The process prioritizes [TAi] over [RXe] when forwarding the lookup request to the ternary content addressable memory. If there was no hit and the request is allowed to create a new session entry in the CAM, such a new entry is created. Otherwise, the session ID corresponding to the matching lookup is sent back to lookup requester. [TODO-FIXME - This process does not yet handle the deletion of a session].

Definition at line 140 of file session_lookup_controller.cpp.

151 {
152  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
153  #pragma HLS PIPELINE II=1 enable_flush
154  #pragma HLS INLINE off
155 
156  const char *myName = concat3(THIS_NAME, "/", "Lrh");
157 
158  //-- LOCAL STREAMS --------------------------------------------------------
159  static stream<SLcFourTuple> ssInsertPipe ("ssInsertPipe");
160  #pragma HLS STREAM variable=ssInsertPipe depth=4
161 
162  static stream<SLcQuery> ssLookupPipe ("ssLookupPipe");
163  #pragma HLS STREAM variable=ssLookupPipe depth=8
164 
165  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
166  static enum FsmStates { WAIT_FOR_SESS_LKP_REQ=0, WAIT_FOR_CAM_LKP_REP, WAIT_FOR_CAM_UPD_REP } \
167  lrh_fsmState=WAIT_FOR_SESS_LKP_REQ;
168  #pragma HLS RESET variable=lrh_fsmState
169 
170  switch (lrh_fsmState) {
171  case WAIT_FOR_SESS_LKP_REQ:
172  if (!siTAi_SessLookupReq.empty()) {
173  SocketPair sockPair = siTAi_SessLookupReq.read();
174  fourTuple toeTuple = fourTuple(byteSwap32(sockPair.src.addr), byteSwap32(sockPair.dst.addr),
175  byteSwap16(sockPair.src.port), byteSwap16(sockPair.dst.port));
176  // Create internal query { myIp, TheirIp, myPort, theirPort}
177  SLcQuery slcQuery = SLcQuery(SLcFourTuple(
178  toeTuple.srcIp, toeTuple.dstIp,
179  toeTuple.srcPort, toeTuple.dstPort), true, FROM_TAi);
180  soCAM_SessLookupReq.write(CamSessionLookupRequest(slcQuery.tuple, slcQuery.source));
181  ssLookupPipe.write(slcQuery);
182  lrh_fsmState = WAIT_FOR_CAM_LKP_REP;
183  }
184  else if (!siRXe_SessLookupReq.empty()) {
185  SessionLookupQuery query = siRXe_SessLookupReq.read();
186  // Create internal query { myIp, TheirIp, myPort, theirPort}
187  SLcQuery slcQuery = SLcQuery(SLcFourTuple(
188  query.tuple.dst.addr, query.tuple.src.addr,
189  query.tuple.dst.port, query.tuple.src.port),
190  query.allowCreation, FROM_RXe);
191  soCAM_SessLookupReq.write(CamSessionLookupRequest(slcQuery.tuple, slcQuery.source));
192  ssLookupPipe.write(slcQuery);
193  lrh_fsmState = WAIT_FOR_CAM_LKP_REP;
194  }
195  break;
196  case WAIT_FOR_CAM_LKP_REP:
197  if(!siCAM_SessLookupRep.empty() && !ssLookupPipe.empty()) {
198  CamSessionLookupReply lupReply = siCAM_SessLookupRep.read();
199  SLcQuery slcQuery = ssLookupPipe.read();
200  if (!lupReply.hit && slcQuery.allowCreation && !siSim_FreeList.empty()) {
201  RtlSessId freeID = siSim_FreeList.read();
202  // Request to insert a new session into the CAM
203  soUrs_InsertSessReq.write(CamSessionUpdateRequest(slcQuery.tuple, freeID, INSERT, lupReply.source));
204  ssInsertPipe.write(slcQuery.tuple);
205  lrh_fsmState = WAIT_FOR_CAM_UPD_REP;
206  }
207  else {
208  // We have a HIT
209  if (lupReply.source == FROM_RXe) {
210  soRXe_SessLookupRep.write(SessionLookupReply(lupReply.sessionID, lupReply.hit));
211  }
212  else {
213  soTAi_SessLookupRep.write(SessionLookupReply(lupReply.sessionID, lupReply.hit));
214  }
215  lrh_fsmState = WAIT_FOR_SESS_LKP_REQ;
216  }
217  }
218  break;
219  case WAIT_FOR_CAM_UPD_REP:
220  if (!siUrh_SessUpdateRsp.empty() && !ssInsertPipe.empty()) {
221  CamSessionUpdateReply insertReply = siUrh_SessUpdateRsp.read();
222  SLcFourTuple tuple = ssInsertPipe.read();
223  if (insertReply.source == FROM_RXe) {
224  soRXe_SessLookupRep.write(SessionLookupReply(insertReply.sessionID, true));
225  }
226  else {
227  soTAi_SessLookupRep.write(SessionLookupReply(insertReply.sessionID, true));
228  }
229  soRlt_ReverseLkpRsp.write(SLcReverseLkp(insertReply.sessionID, tuple));
230  lrh_fsmState = WAIT_FOR_SESS_LKP_REQ;
231  }
232  break;
233  }
234 } // End of: pLookupReplyHandler
LE_Ip4Address addr
Definition: nts_types.hpp:222
LE_Ly4Port port
Definition: nts_types.hpp:223
LE_SockAddr dst
Definition: nts_types.hpp:263
LE_SockAddr src
Definition: nts_types.hpp:262
bool allowCreation
Definition: toe.hpp:323
LE_SocketPair tuple
Definition: toe.hpp:322
FourTuple SLcFourTuple
#define FROM_TAi
Definition: nts_types.hpp:381
#define FROM_RXe
Definition: nts_types.hpp:380
ap_uint< 14 > RtlSessId
Definition: nts_types.hpp:378
@ INSERT
Definition: nts_types.hpp:382
ap_uint< 32 > dstIp
Definition: nts_types.hpp:231
ap_uint< 32 > srcIp
Definition: nts_types.hpp:230
ap_uint< 16 > dstPort
Definition: nts_types.hpp:233
ap_uint< 16 > srcPort
Definition: nts_types.hpp:232
ap_uint< 32 > byteSwap32(ap_uint< 32 > inputVector)
Definition: udp.cpp:78
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pLsnAppInterface()

void pLsnAppInterface ( stream< TcpAppLsnReq > &  siTAIF_LsnReq,
stream< TcpAppLsnRep > &  soTAIF_LsnRep,
stream< TcpPort > &  soPRt_LsnReq,
stream< RepBit > &  siPRt_LsnRep 
)

Listen Application Interface (Lai)

Parameters
[in]siTAIF_LsnReqTCP listen port request from TcpAppInterface (TAIF).
[out]soTAIF_LsnRepTCP listen port reply to [TAIF].
[out]soPRt_LsnReqListen port request to PortTable (PRt).
[in]siPRt_LsnRepListen port reply from [PRt].

This process is used to open/close a port in listen mode. This puts the TOE in passive listening mode and ready to accept an incoming connection on the socket {MY_IP, THIS_PORT}. [TODO-FIXME] The tear down of a connection is not implemented yet.

Warning
To avoid any blocking of [RAi], the current reply to be sent on the outgoing stream 'soTAIF_LsnRep' will be dropped if the stream is full. As a result, the application process must provision enough buffering to store the listen reply returned by this process upon a granted request to open a new port in listen mode.

Definition at line 647 of file rx_app_interface.cpp.

654 {
655  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
656  #pragma HLS PIPELINE II=1 enable_flush
657  #pragma HLS INLINE off
658 
659  const char *myName = concat3(THIS_NAME, "/", "Lai");
660 
661  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
662  static bool lai_waitForPRtRep=false;
663  #pragma HLS reset variable=lai_waitForPRtRep
664 
665  //-- DYNAMIC VARIABLES -----------------------------------------------------
666  TcpPort listenPort;
667  RepBit listenRep;
668 
669  if (!siTAIF_LsnReq.empty() and !lai_waitForPRtRep) {
670  siTAIF_LsnReq.read(listenPort);
671  soPRt_LsnReq.write(listenPort);
672  lai_waitForPRtRep = true;
673  }
674  else if (!siPRt_LsnRep.empty() and lai_waitForPRtRep) {
675  siPRt_LsnRep.read(listenRep);
676  if (!soTAIF_LsnRep.full()) {
677  soTAIF_LsnRep.write((RepBool)listenRep);
678  }
679  else {
680  // Drop this reply
681  printFatal(myName, "Cannot write 'soTAIF_Meta()'. Stream is full!");
682  }
683  lai_waitForPRtRep = false;
684  }
685 
690 }
ap_uint< 1 > RepBit
Definition: nts_types.hpp:113
bool RepBool
Definition: nts_types.hpp:127
Here is the caller graph for this function:

◆ pMetaDataHandler()

void pMetaDataHandler ( stream< RXeMeta > &  siCsa_Meta,
stream< SocketPair > &  siCsa_SockPair,
stream< SessionLookupQuery > &  soSLc_SessLkpReq,
stream< SessionLookupReply > &  siSLc_SessLkpRep,
stream< StsBit > &  siPRt_PortSts,
stream< ExtendedEvent > &  soEVe_Event,
stream< CmdBit > &  soTsd_DropCmd,
stream< RXeFsmMeta > &  soFsm_Meta,
stream< ap_uint< 8 > > &  soMMIO_SessDropCnt 
)

MetaData Handler (Mdh)

Parameters
[in]siCsa_MetaTCP metadata from CheckSumAccumulator (Csa).
[in]siCsa_SockPairTCP socket pair from [Csa].
[out]soSLc_SessLkpReqSession lookup request to Session Lookup Controller (SLc).
[in]siSLc_SessLkpRepSession Lookup reply from [SLc].
[in]siPRt_PortStsPort state (opened/closed) from PortTable (PRt).
[out]soEVe_EventEvent to EventEngine (EVe).
[out]soTsd_DropCmdDrop command to Tcp Segment Dropper (Tsd).
[out]soFsm_MetaMetadata to RXe's Finite State Machine (Fsm).
[out]soMMIO_SessDropThe value of the session drop counter.

This process waits until it gets a response from the PortTable (PRt). It then loads the metadata and socket pair generated by the Checksum- Accumulator (Csa) process and evaluates them. Next, if the destination port is opened, it requests the SessionLookupController (SLc) to perform a session lookup and waits for its reply. If a session is opened for this socket pair, a new metadata structure is generated and is forwarded to the FiniteStateMachine (FSm) of the RxEngine (RXe). If the target destination port is not opened, the process creates an event requesting a 'RST+ACK' TCP segment to be sent back to the initiating host.

Definition at line 1197 of file rx_engine.cpp.

1207 {
1208  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1209  #pragma HLS PIPELINE II=1 enable_flush
1210  #pragma HLS INLINE off
1211 
1212  const char *myName = concat3(THIS_NAME, "/", "Mdh");
1213 
1214  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1215  static enum FsmStates { MDH_META=0, \
1216  MDH_LOOKUP } mdh_fsmState;
1217  #pragma HLS RESET variable=mdh_fsmState
1218  static ap_uint<8 > mdh_SessDropCounter=0;
1219  #pragma HLS reset variable=mdh_SessDropCounter
1220 
1221  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
1222  static RXeMeta mdh_meta;
1223  static SessionLookupReply mdh_sessLookupReply;
1224  static Ip4Address mdh_ip4SrcAddr;
1225  static TcpPort mdh_tcpSrcPort;
1226  static TcpPort mdh_tcpDstPort;
1227 
1228  //-- DYNAMIC VARIABLES -----------------------------------------------------
1229  SocketPair socketPair;
1230  StsBit dstPortStatus;
1231 
1232  switch (mdh_fsmState) {
1233  case MDH_META:
1234  // Wait until we get a reply from the PortTable (PRt)
1235  if (!siPRt_PortSts.empty()) {
1236  // Read metadata and socket pair
1237  if (!siCsa_Meta.empty() && !siCsa_SockPair.empty()) {
1238  siPRt_PortSts.read(dstPortStatus);
1239  siCsa_Meta.read(mdh_meta);
1240  siCsa_SockPair.read(socketPair);
1241  mdh_ip4SrcAddr = socketPair.src.addr;
1242  mdh_tcpSrcPort = socketPair.src.port;
1243  mdh_tcpDstPort = socketPair.dst.port;
1244  if (dstPortStatus == STS_CLOSED) {
1245  // The destination port is closed
1246  if (DEBUG_LEVEL & TRACE_MDH) {
1247  printWarn(myName, "Port 0x%4.4X (%d) is not open.\n",
1248  mdh_tcpDstPort.to_uint(), mdh_tcpDstPort.to_uint());
1249  }
1250  if (!mdh_meta.rst) {
1251  // Reply with 'RST+ACK' and send necessary socket-pair through event
1252  LE_SocketPair switchedTuple; // [FIXME]
1253  switchedTuple.src.addr = byteSwap32(socketPair.dst.addr);
1254  switchedTuple.dst.addr = byteSwap32(socketPair.src.addr);
1255  switchedTuple.src.port = byteSwap16(socketPair.dst.port);
1256  switchedTuple.dst.port = byteSwap16(socketPair.src.port);
1257  if (mdh_meta.syn || mdh_meta.fin) {
1258  soEVe_Event.write(ExtendedEvent(rstEvent(mdh_meta.seqNumb+mdh_meta.length+1),
1259  switchedTuple)); //always 0
1260  }
1261  else {
1262  soEVe_Event.write(ExtendedEvent(rstEvent(mdh_meta.seqNumb+mdh_meta.length),
1263  switchedTuple));
1264  }
1265  }
1266  else {
1267  // The RST bit is set. Ignore => do nothing
1268  }
1269  if (mdh_meta.length != 0) {
1270  soTsd_DropCmd.write(CMD_DROP);
1271  mdh_SessDropCounter++;
1272  }
1273  }
1274  else {
1275  // Destination Port is opened
1276  if (DEBUG_LEVEL & TRACE_MDH) {
1277  printInfo(myName, "Destination port 0x%4.4X (%d) is open.\n",
1278  mdh_tcpDstPort.to_uint(), mdh_tcpDstPort.to_uint());
1279  }
1280  // Query a session lookup. Only allow creation of a new entry when SYN or SYN_ACK
1281  LE_SocketPair leSocketPair(LE_SockAddr(byteSwap32(socketPair.src.addr),byteSwap16(socketPair.src.port)),
1282  LE_SockAddr(byteSwap32(socketPair.dst.addr),byteSwap16(socketPair.dst.port)));
1283  soSLc_SessLkpReq.write(SessionLookupQuery(leSocketPair,
1284  (mdh_meta.syn && !mdh_meta.rst && !mdh_meta.fin))); // [FIXME - Endianess
1285  if (DEBUG_LEVEL & TRACE_MDH) {
1286  printInfo(myName, "Request the SLc to lookup the following session:\n");
1287  printSockPair(myName, socketPair);
1288  }
1289  mdh_fsmState = MDH_LOOKUP;
1290  }
1291  }
1292  }
1293  break;
1294  case MDH_LOOKUP:
1295  // Wait until we get a reply from the SessionLookupController (SLc)
1296  // Warning: There may be a large delay for the lookup to complete
1297  if (!siSLc_SessLkpRep.empty()) {
1298  siSLc_SessLkpRep.read(mdh_sessLookupReply);
1299  if (mdh_sessLookupReply.hit) {
1300  // Forward metadata to the TCP FiniteStateMachine (Fsm)
1301  soFsm_Meta.write(RXeFsmMeta(mdh_sessLookupReply.sessionID,
1302  mdh_ip4SrcAddr, mdh_tcpSrcPort,
1303  mdh_tcpDstPort, mdh_meta));
1304  if (DEBUG_LEVEL & TRACE_MDH)
1305  printInfo(myName, "Successful session lookup. \n");
1306  }
1307  else {
1308  // [TODO - Port is Open, but we have no sessionID for it]
1309  if (DEBUG_LEVEL & TRACE_MDH)
1310  printWarn(myName, "Session lookup failed! \n");
1311  }
1312  if (mdh_meta.length != 0) {
1313  soTsd_DropCmd.write(!mdh_sessLookupReply.hit);
1314  if (!mdh_sessLookupReply.hit) {
1315  mdh_SessDropCounter++;
1316  }
1317  }
1318  mdh_fsmState = MDH_META;
1319  }
1320  break;
1321  } // End of: switch
1322 
1323  //-- ALWAYS
1324  if (!soMMIO_SessDropCnt.full()) {
1325  soMMIO_SessDropCnt.write(mdh_SessDropCounter);
1326  }
1327  else {
1328  printFatal(myName, "Cannot write soMMIO_SessDropCnt stream...");
1329  }
1330 } // End of: pMetaDataHandler
SessionId sessionID
Definition: toe.hpp:334
HitState hit
Definition: toe.hpp:335
#define TRACE_MDH
Definition: rx_engine.cpp:74
ap_uint< 1 > StsBit
Definition: nts_types.hpp:116
ap_uint< 32 > Ip4Address
Definition: AxisIp4.hpp:168
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pMetaDataLoader()

void pMetaDataLoader ( stream< ExtendedEvent > &  siAKd_Event,
stream< SessionId > &  soRSt_RxSarReq,
stream< RxSarReply > &  siRSt_RxSarRep,
stream< TXeTxSarQuery > &  soTSt_TxSarQry,
stream< TXeTxSarReply > &  siTSt_TxSarRep,
stream< TXeReTransTimerCmd > &  soTIm_ReTxTimerCmd,
stream< SessionId > &  soTIm_SetProbeTimer,
stream< TcpDatLen > &  soIhc_TcpDatLen,
stream< TXeMeta > &  soPhc_TxeMeta,
stream< DmCmd > &  soMrd_BufferRdCmd,
stream< SessionId > &  soSLc_ReverseLkpReq,
stream< StsBool > &  soSps_IsLookup,
stream< LE_SocketPair > &  soSps_RstSockPair,
stream< SigBit > &  soEVe_RxEventSig 
)

Meta Data Loader (Mdl)

Parameters
[in]siAKd_EventEvent from Ack Delayer (AKd).
[out]soRSt_RxSarReqRead request to RxSarTable (RSt).
[in]siRSt_RxSarRepRead reply from [RSt].
[out]soTSt_TxSarQryTxSar query to Tx SAR Table (TSt).
[in]siTSt_TxSarRep,TxSarreply from [TSt].
[out]soTIm_ReTxTimerCmdSend retransmit timer command to Timers (TIm).
[out]soTIm_SetProbeTimerSet a probe timer to [TIm].
[out]soIhc_TcpDatLenTCP data length to Ip Header Constructor (Ihc).
[out]soPhc_TxeMetaTx Engine metadata to Pseudo Header Constructor (Phc).
[out]soMrd_BufferRdCmdBuffer read command to Memory Reader (Mrd).
[out]soSLc_ReverseLkpReqReverse lookup request to Session Lookup Controller (SLc).
[out]soSps_IsLookupTells the Socket Pair Splitter (Sps) that a reverse lookup is to be expected.
[out]soTODO_IsDdrBypass[TODO]
[out]soSps_RstSockPairTells the [Sps] about the socket pair to reset.
[out]soEVe_RxEventSigSignals the reception of an event to EventEngine (EVe).

The meta data loader reads the events from the Event Engine (EVe) and loads the necessary data from the metadata structures (Rx & Tx SAR Tables). Depending on the event type, it generates the necessary metadata for the 'pIpHeaderConstructor' and the 'pPseudoHeaderConstructor'. Additionally it requests the IP tuples from Session Lookup Controller (SLc). In some special cases the IP tuple is delivered directly from the RxEngine (RXe) and it does not have to be loaded from the SLc. The 'isLookUpFifo' indicates this special cases. Depending on the Event Type the retransmit or/and probe Timer is set.

Definition at line 117 of file tx_engine.cpp.

135 {
136  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
137  #pragma HLS INLINE off
138  #pragma HLS PIPELINE II=1 enable_flush
139 
140  const char *myName = concat3(THIS_NAME, "/", "Mdl");
141 
142  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
143  static enum FsmStates { MDL_WAIT_EVENT=0, MDL_PROCESS_EVENT } \
144  mdl_fsmState=MDL_WAIT_EVENT;
145  #pragma HLS RESET variable=mdl_fsmState
146  static FlagBool mdl_sarLoaded=false;
147  #pragma HLS RESET variable=mdl_sarLoaded
148  static ap_uint<2> mdl_segmentCount=0; // [FIXME - Too small for re-transmit?]
149  #pragma HLS RESET variable=mdl_segmentCount
150 
151  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
152  static ExtendedEvent mdl_curEvent;
153  static RxSarReply mdl_rxSar;
154  static TXeTxSarReply mdl_txSar;
155  static ap_uint<32> mdl_randomValue = 100000; // [FIXME - Add a random Initial Sequence Number in EMIF]
156  static TXeMeta mdl_txeMeta;
157 
158  //-- DYNAMIC VARIABLES -----------------------------------------------------
159  TcpWindow winSize;
160  TcpWindow usableWindow;
161  TcpDatLen currDatLen;
162  ap_uint<16> slowstart_threshold;
163  rstEvent resetEvent;
164 
165  switch (mdl_fsmState) {
166  case MDL_WAIT_EVENT:
167  if (!siAKd_Event.empty()) {
168  siAKd_Event.read(mdl_curEvent);
169  if (DEBUG_LEVEL & TRACE_MDL) {
170  printInfo(myName, "Received event '%s' for session #%d from [AKd].\n",
171  getEventName(mdl_curEvent.type), mdl_curEvent.sessionID.to_uint());
172  }
173  mdl_sarLoaded = false;
174  assessSize(myName, soEVe_RxEventSig, "soEVe_RxEventSig", 2); // [FIXME-Use constant for the length]
175  soEVe_RxEventSig.write(1);
176 
177  // NOT necessary for SYN/SYN_ACK only needs one
178  switch(mdl_curEvent.type) {
179  case RT_EVENT:
180  case TX_EVENT:
181  case SYN_ACK_EVENT:
182  case FIN_EVENT:
183  case ACK_EVENT:
184  case ACK_NODELAY_EVENT:
185  assessSize(myName, soRSt_RxSarReq, "soRSt_RxSarReq", cDepth_TXeToRSt_Req);
186  soRSt_RxSarReq.write(mdl_curEvent.sessionID);
187  assessSize(myName, soTSt_TxSarQry, "soTSt_TxSarQry", cDepth_TXeToTSt_Qry);
188  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID, QUERY_RD));
189  break;
190  case RST_EVENT:
191  // Get txSar for SEQ numb
192  resetEvent = mdl_curEvent;
193  if (resetEvent.hasSessionID()) {
194  assessSize(myName, soTSt_TxSarQry, "soTSt_TxSarQry", cDepth_TXeToTSt_Qry);
195  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID, QUERY_RD));
196  }
197  break;
198  case SYN_EVENT:
199  if (mdl_curEvent.rt_count != 0) {
200  assessSize(myName, soTSt_TxSarQry, "soTSt_TxSarQry", cDepth_TXeToTSt_Qry);
201  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID, QUERY_RD));
202  }
203  break;
204  default:
205  break;
206  }
207  mdl_fsmState = MDL_PROCESS_EVENT;
208  // [FIXME - Add a random Initial Sequence Number in EMIF and move this out of here]
209  mdl_randomValue++;
210  }
211  mdl_segmentCount = 0;
212  break;
213  case MDL_PROCESS_EVENT:
214  switch(mdl_curEvent.type) {
215  // When Nagle's algorithm disabled; Can bypass DDR
216 #if (TCP_NODELAY)
217  case TX:
218  if (DEBUG_LEVEL & TRACE_MDL)
219  printInfo(myName, "Got TX event.\n");
220  if ((!rxSar2txEng_rsp.empty() && !txSar2txEng_upd_rsp.empty()) || ml_sarLoaded) {
221  if (!ml_sarLoaded) {
222  rxSar2txEng_rsp.read(rxSar);
223  txSar2txEng_upd_rsp.read(mdl_txSar);
224  }
225 
226  // Compute our space, Advertise at least a quarter/half, otherwise 0
227  winSize = (rxSar.appd - ((ap_uint<16>)rxSar.recvd)) - 1; // This works even for wrap around
228  meta.ackNumb = rxSar.recvd;
229  meta.seqNumb = mdl_txSar.not_ackd;
230  meta.window_size = winSize;
231  meta.ack = 1; // ACK is always set when established
232  meta.rst = 0;
233  meta.syn = 0;
234  meta.fin = 0;
235 
236  //TODO this is hack, makes sure that probeTimer is never set.
237  if (0x7FFF < ml_curEvent.length) {
238  txEng2timer_setProbeTimer.write(ml_curEvent.sessionID);
239  }
240 
241  meta.length = ml_curEvent.length;
242 
243  // TODO some checking
244  mdl_txSar.not_ackd += ml_curEvent.length;
245 
246  txEng2txSar_upd_req.write(txTxSarQuery(ml_curEvent.sessionID, mdl_txSar.not_ackd, 1));
247  ml_FsmState = 0;
248 
249  // Send a packet only if there is data or we want to send an empty probing message
250  if (meta.length != 0) { // || ml_curEvent.retransmit) //TODO retransmit boolean currently not set, should be removed
251  txEng_ipMetaFifoOut.write(meta.length);
252  txEng_tcpMetaFifoOut.write(meta);
253  txEng_isLookUpFifoOut.write(true);
254  txEng_isDDRbypass.write(true);
255  txEng2sLookup_rev_req.write(ml_curEvent.sessionID);
256 
257  // Only set RT timer if we actually send sth, TODO only set if we change state and sent sth
258  txEng2timer_setRetransmitTimer.write(txRetransmitTimerSet(ml_curEvent.sessionID));
259  } //TODO if probe send msg length 1
260  ml_sarLoaded = true;
261  }
262  break;
263 #else
264  case TX_EVENT:
265  if (DEBUG_LEVEL & TRACE_MDL) {
266  printInfo(myName, "Entering the 'TX' processing.\n");
267  }
268  // Send everything between txSar.not_ackd and txSar.app
269  if ((!siRSt_RxSarRep.empty() and !siTSt_TxSarRep.empty()) or mdl_sarLoaded) {
270  if (!mdl_sarLoaded) {
271  siRSt_RxSarRep.read(mdl_rxSar);
272  siTSt_TxSarRep.read(mdl_txSar);
273  }
274  // Compute our space, Advertise at least a quarter/half, otherwise 0
275  //[FIXME-TODO: It is better to compute and maintain the window_size in the [Rst] module]
276  winSize = ((mdl_rxSar.appd - (RxBufPtr)mdl_rxSar.oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
277  mdl_txeMeta.ackNumb = mdl_rxSar.rcvd;
278  mdl_txeMeta.seqNumb = mdl_txSar.not_ackd;
279  mdl_txeMeta.winSize = winSize;
280  mdl_txeMeta.ack = 1; // ACK is always set when ESTABISHED
281  mdl_txeMeta.rst = 0;
282  mdl_txeMeta.syn = 0;
283  mdl_txeMeta.fin = 0;
284  mdl_txeMeta.length = 0;
285  currDatLen = (mdl_txSar.app - ((TxBufPtr)mdl_txSar.not_ackd));
286 
287  TxBufPtr usedLength = ((TxBufPtr)mdl_txSar.not_ackd - mdl_txSar.ackd);
288  if (mdl_txSar.min_window > usedLength) {
289  // FYI: min_window = Min(txSar.recv_window, mdl_txSar.cong_window)
290  usableWindow = mdl_txSar.min_window - usedLength;
291  }
292  else {
293  usableWindow = 0;
294  }
295 
296  // Construct address before modifying mdl_txSar.not_ackd
297  // FYI - The TCP Tx buffers use up to 1GB (16Kx64KB). They are located at base@+1GB
298  TxMemPtr memSegAddr = TOE_TX_MEMORY_BASE;
299  memSegAddr(29, 16) = mdl_curEvent.sessionID(13, 0);
300  memSegAddr(15, 0) = mdl_txSar.not_ackd(15, 0);
301 
302  // Check if length is bigger than Usable Window or MSS
303  if (currDatLen <= usableWindow) {
304  if (currDatLen+TCP_HEADER_LEN > ZYC2_MSS) {
305  //-- Start IP Fragmentation ----------------------------
306  //-- We stay in this state
307  mdl_txSar.not_ackd += ZYC2_MSS-TCP_HEADER_LEN;
308  mdl_txeMeta.length = ZYC2_MSS-TCP_HEADER_LEN;
309  }
310  else {
311  //-- No IP Fragmentation or End of Fragmentation -------
312  //-- If we sent all data, we might also need to send a FIN
313  if (mdl_txSar.finReady and (mdl_txSar.ackd == mdl_txSar.not_ackd or currDatLen == 0)) {
314  mdl_curEvent.type = FIN_EVENT;
315  }
316  else {
317  mdl_txSar.not_ackd += currDatLen;
318  mdl_txeMeta.length = currDatLen;
319  mdl_fsmState = MDL_WAIT_EVENT;
320  }
321  // Write back 'txSar.not_ackd' pointer
322  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID,
323  mdl_txSar.not_ackd, QUERY_WR));
324  }
325  }
326  else {
327  // Code duplication, but better timing.
328  if (usableWindow+TCP_HEADER_LEN >= ZYC2_MSS) {
329  //-- Start IP Fragmentation ----------------------------
330  //-- We stay in this state
331  mdl_txSar.not_ackd += ZYC2_MSS-TCP_HEADER_LEN;
332  mdl_txeMeta.length = ZYC2_MSS-TCP_HEADER_LEN;
333  }
334  else {
335  // Check if we sent >= MSS data
336  //OBSO if (mdl_txSar.ackd == mdl_txSar.not_ackd) {
337  mdl_txSar.not_ackd += usableWindow;
338  mdl_txeMeta.length = usableWindow;
339  //OBSO }
340  //OBSO // Set probe Timer to try again later
341  //OBSO soTIm_SetProbeTimer.write(mdl_curEvent.sessionID);
342  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID,
343  mdl_txSar.not_ackd, QUERY_WR));
344  mdl_fsmState = MDL_WAIT_EVENT;
345  }
346  }
347 
348  if (mdl_txeMeta.length != 0) {
349  soMrd_BufferRdCmd.write(DmCmd(memSegAddr, mdl_txeMeta.length));
350  }
351  // Send a packet only if there is data or we want to send an empty probing message
352  if (mdl_txeMeta.length != 0) { // || mdl_curEvent.retransmit) //TODO retransmit boolean currently not set, should be removed
353  soIhc_TcpDatLen.write(mdl_txeMeta.length);
354  soPhc_TxeMeta.write(mdl_txeMeta);
355  soSps_IsLookup.write(true);
356  soSLc_ReverseLkpReq.write(mdl_curEvent.sessionID);
357  // Only set RT timer if we actually send sth,
358  // [TODO - Only set if we change state and sent sth]
359  soTIm_ReTxTimerCmd.write(TXeReTransTimerCmd(mdl_curEvent.sessionID));
360  } // [TODO - if probe send msg length 1]
361  mdl_sarLoaded = true;
362  }
363  break;
364 #endif
365  case RT_EVENT:
366  if (DEBUG_LEVEL & TRACE_MDL) { printInfo(myName, "Entering the 'RT' processing.\n"); }
367  if ((!siRSt_RxSarRep.empty() && !siTSt_TxSarRep.empty()) || mdl_sarLoaded) {
368  if (!mdl_sarLoaded) {
369  siRSt_RxSarRep.read(mdl_rxSar);
370  siTSt_TxSarRep.read(mdl_txSar);
371  }
372  // Compute our window size
373  //[FIXME-TODO: It is better to compute and maintain the window_size in the [Rst] module]
374  winSize = ((mdl_rxSar.appd - (RxBufPtr)mdl_rxSar.oooHead(TOE_WINDOW_BITS-1, 0)) - 1); // This works even for wrap around
375  if (!mdl_txSar.finSent) // No FIN sent
376  currDatLen = ((TxBufPtr) mdl_txSar.not_ackd - mdl_txSar.ackd);
377  else // FIN already sent
378  currDatLen = ((TxBufPtr) mdl_txSar.not_ackd - mdl_txSar.ackd)-1;
379  mdl_txeMeta.ackNumb = mdl_rxSar.rcvd;
380  mdl_txeMeta.seqNumb = mdl_txSar.ackd;
381  mdl_txeMeta.winSize = winSize;
382  mdl_txeMeta.ack = 1; // ACK is always set when session is established
383  mdl_txeMeta.rst = 0;
384  mdl_txeMeta.syn = 0;
385  mdl_txeMeta.fin = 0;
386  // Construct address before modifying 'mdl_txSar.ackd'
387  TxMemPtr memSegAddr; // 0x40000000
388  memSegAddr(31, 30) = 0x01;
389  memSegAddr(29, 16) = mdl_curEvent.sessionID(13, 0);
390  memSegAddr(15, 0) = mdl_txSar.ackd(15, 0); // mdl_curEvent.address;
391  // Decrease Slow Start Threshold, only on first RT from retransmitTimer
392  if (!mdl_sarLoaded and (mdl_curEvent.rt_count == 1)) {
393  if (currDatLen > (4*ZYC2_MSS)) { // max(FlightSize/2, 2*MSS) RFC:5681
394  slowstart_threshold = currDatLen/2;
395  }
396  else {
397  slowstart_threshold = (2 * ZYC2_MSS);
398  }
399  soTSt_TxSarQry.write(TXeTxSarRtQuery(mdl_curEvent.sessionID, slowstart_threshold));
400  }
401  // Since we are retransmitting from 'txSar.ackd' to 'txSar.not_ackd',
402  // this data is already inside the usableWindow => No check is required
403  // Only check if length is bigger than MSS
404  if (currDatLen+TCP_HEADER_LEN > ZYC2_MSS) {
405  // We stay in this state and sent immediately another packet
406  mdl_txeMeta.length = ZYC2_MSS-TCP_HEADER_LEN;
407  mdl_txSar.ackd += ZYC2_MSS-TCP_HEADER_LEN;
408  // [TODO - replace with dynamic count, remove this]
409  if (mdl_segmentCount == 3) {
410  // Should set a probe or sth??
411  //txEng2txSar_upd_req.write(txTxSarQuery(ml_curEvent.sessionID, mdl_txSar.not_ackd, 1));
412  mdl_fsmState = MDL_WAIT_EVENT;
413  }
414  mdl_segmentCount++;
415  }
416  else {
417  mdl_txeMeta.length = currDatLen;
418  if (mdl_txSar.finSent) {
419  mdl_curEvent.type = FIN_EVENT;
420  }
421  else {
422  mdl_fsmState = MDL_WAIT_EVENT;
423  }
424  }
425 
426  // Only send a packet if there is data
427  if (mdl_txeMeta.length != 0) {
428  soMrd_BufferRdCmd.write(DmCmd(memSegAddr, mdl_txeMeta.length));
429  soIhc_TcpDatLen.write(mdl_txeMeta.length);
430  soPhc_TxeMeta.write(mdl_txeMeta);
431  soSps_IsLookup.write(true);
432 #if (TCP_NODELAY)
433  soTODO_isDDRbypass.write(false);
434 #endif
435  soSLc_ReverseLkpReq.write(mdl_curEvent.sessionID);
436  // Only set RT timer if we actually send sth
437  soTIm_ReTxTimerCmd.write(TXeReTransTimerCmd(mdl_curEvent.sessionID));
438  }
439  mdl_sarLoaded = true;
440  }
441  break;
442  case ACK_EVENT:
443  case ACK_NODELAY_EVENT:
444  if (DEBUG_LEVEL & TRACE_MDL) { printInfo(myName, "Entering the 'ACK' processing.\n"); }
445  if (!siRSt_RxSarRep.empty() and !siTSt_TxSarRep.empty()) {
446  siRSt_RxSarRep.read(mdl_rxSar);
447  siTSt_TxSarRep.read(mdl_txSar);
448 
449  //[FIXME-TODO: It is better to compute and maintain the window_size in the [Rst] module]
450  winSize = ((mdl_rxSar.appd - (RxBufPtr)mdl_rxSar.oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
451  mdl_txeMeta.ackNumb = mdl_rxSar.rcvd;
452  mdl_txeMeta.seqNumb = mdl_txSar.not_ackd; //Always send SEQ
453  mdl_txeMeta.winSize = winSize;
454  mdl_txeMeta.length = 0;
455  mdl_txeMeta.ack = 1;
456  mdl_txeMeta.rst = 0;
457  mdl_txeMeta.syn = 0;
458  mdl_txeMeta.fin = 0;
459  soIhc_TcpDatLen.write(mdl_txeMeta.length);
460  soPhc_TxeMeta.write(mdl_txeMeta);
461  soSps_IsLookup.write(true);
462  soSLc_ReverseLkpReq.write(mdl_curEvent.sessionID);
463  mdl_fsmState = MDL_WAIT_EVENT;
464  }
465  break;
466  case SYN_EVENT:
467  if (DEBUG_LEVEL & TRACE_MDL) { printInfo(myName, "Entering the 'SYN' processing.\n"); }
468  if (((mdl_curEvent.rt_count != 0) and !siTSt_TxSarRep.empty()) or (mdl_curEvent.rt_count == 0)) {
469  if (mdl_curEvent.rt_count != 0) {
470  siTSt_TxSarRep.read(mdl_txSar);
471  mdl_txeMeta.seqNumb = mdl_txSar.ackd;
472  }
473  else {
474  mdl_txSar.not_ackd = mdl_randomValue; // [FIXME - Use a register from EMIF]
475  mdl_randomValue = (mdl_randomValue* 8) xor mdl_randomValue;
476  // Initialize TxSar with the UnAcked byte pointer
477  mdl_txeMeta.seqNumb = mdl_txSar.not_ackd;
478  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID, mdl_txSar.not_ackd+1, QUERY_WR, QUERY_INIT));
479  }
480  mdl_txeMeta.ackNumb = 0;
481  //mdl_txeMeta.seqNumb = mdl_txSar.not_ackd;
482  mdl_txeMeta.winSize = 0xFFFF;
483  mdl_txeMeta.length = 4; // FYI - MSS adds 4 option bytes
484  mdl_txeMeta.ack = 0;
485  mdl_txeMeta.rst = 0;
486  mdl_txeMeta.syn = 1;
487  mdl_txeMeta.fin = 0;
488  soIhc_TcpDatLen.write(mdl_txeMeta.length);
489  soPhc_TxeMeta.write(mdl_txeMeta);
490  soSps_IsLookup.write(true);
491  soSLc_ReverseLkpReq.write(mdl_curEvent.sessionID);
492  // Set retransmission timer
493  soTIm_ReTxTimerCmd.write(TXeReTransTimerCmd(mdl_curEvent.sessionID, SYN_EVENT));
494  mdl_fsmState = MDL_WAIT_EVENT;
495  }
496  break;
497  case SYN_ACK_EVENT:
498  if (DEBUG_LEVEL & TRACE_MDL) { printInfo(myName, "Entering the 'SYN_ACK' processing.\n"); }
499  if (!siRSt_RxSarRep.empty() and !siTSt_TxSarRep.empty()) {
500  siRSt_RxSarRep.read(mdl_rxSar);
501  siTSt_TxSarRep.read(mdl_txSar);
502 
503  // Construct SYN_ACK message
504  mdl_txeMeta.ackNumb = mdl_rxSar.rcvd;
505  mdl_txeMeta.winSize = MY_MSS * 12;
506  mdl_txeMeta.length = 4; // FYI - MSS adds 4 option bytes
507  mdl_txeMeta.ack = 1;
508  mdl_txeMeta.rst = 0;
509  mdl_txeMeta.syn = 1;
510  mdl_txeMeta.fin = 0;
511  if (mdl_curEvent.rt_count != 0) {
512  mdl_txeMeta.seqNumb = mdl_txSar.ackd;
513  }
514  else {
515  mdl_txSar.not_ackd = mdl_randomValue; // FIXME better rand();
516  mdl_randomValue = (mdl_randomValue* 8) xor mdl_randomValue;
517  // Initialize TxSar with the UnAcked byte pointer
518  mdl_txeMeta.seqNumb = mdl_txSar.not_ackd;
519  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID,
520  mdl_txSar.not_ackd+1, QUERY_WR, QUERY_INIT));
521  }
522  soIhc_TcpDatLen.write(mdl_txeMeta.length);
523  soPhc_TxeMeta.write(mdl_txeMeta);
524  soSps_IsLookup.write(true);
525  soSLc_ReverseLkpReq.write(mdl_curEvent.sessionID);
526  // Set retransmission timer
527  soTIm_ReTxTimerCmd.write(TXeReTransTimerCmd(mdl_curEvent.sessionID, SYN_ACK_EVENT));
528  mdl_fsmState = MDL_WAIT_EVENT;
529  }
530  break;
531  case FIN_EVENT:
532  if (DEBUG_LEVEL & TRACE_MDL) { printInfo(myName, "Entering the 'FIN' processing.\n"); }
533  if ((!siRSt_RxSarRep.empty() && !siTSt_TxSarRep.empty()) || mdl_sarLoaded) {
534  if (!mdl_sarLoaded) {
535  siRSt_RxSarRep.read(mdl_rxSar);
536  siTSt_TxSarRep.read(mdl_txSar);
537  }
538  // Construct FIN message
539  //[FIXME-TODO: It is better to compute and maintain the window_size in the [Rst] module]
540  winSize = ((mdl_rxSar.appd - (RxBufPtr)mdl_rxSar.oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
541  mdl_txeMeta.ackNumb = mdl_rxSar.rcvd;
542  //meta.seqNumb = mdl_txSar.not_ackd;
543  mdl_txeMeta.winSize = winSize;
544  mdl_txeMeta.length = 0;
545  mdl_txeMeta.ack = 1; // has to be set for FIN message as well
546  mdl_txeMeta.rst = 0;
547  mdl_txeMeta.syn = 0;
548  mdl_txeMeta.fin = 1;
549 
550  // Check if retransmission, in case of RT, we have to reuse 'not_ackd' number
551  if (mdl_curEvent.rt_count != 0)
552  mdl_txeMeta.seqNumb = mdl_txSar.not_ackd-1; // Special case, or use ackd?
553  else {
554  mdl_txeMeta.seqNumb = mdl_txSar.not_ackd;
555  // Check if all data is sent, otherwise we have to delay FIN message
556  // Set FIN flag, such that probeTimer is informed
557  if (mdl_txSar.app == mdl_txSar.not_ackd(15, 0))
558  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID, mdl_txSar.not_ackd+1,
559  QUERY_WR, ~QUERY_INIT, true, true));
560  else
561  soTSt_TxSarQry.write(TXeTxSarQuery(mdl_curEvent.sessionID, mdl_txSar.not_ackd,
562  QUERY_WR, ~QUERY_INIT, true, false));
563  }
564 
565  // Check if there is a FIN to be sent // [TODO - maybe restrict this]
566  if (mdl_txeMeta.seqNumb(15, 0) == mdl_txSar.app) {
567  soIhc_TcpDatLen.write(mdl_txeMeta.length);
568  soPhc_TxeMeta.write(mdl_txeMeta);
569  soSps_IsLookup.write(true);
570  soSLc_ReverseLkpReq.write(mdl_curEvent.sessionID);
571  // Set retransmission timer
572  soTIm_ReTxTimerCmd.write(TXeReTransTimerCmd(mdl_curEvent.sessionID));
573  }
574  mdl_fsmState = MDL_WAIT_EVENT;
575  }
576  break;
577  case RST_EVENT:
578  if (DEBUG_LEVEL & TRACE_MDL) { printInfo(myName, "Entering the 'RST' processing.\n"); }
579  // Assumption RST length == 0
580  resetEvent = mdl_curEvent;
581  if (!resetEvent.hasSessionID()) {
582  soIhc_TcpDatLen.write(0);
583  soPhc_TxeMeta.write(TXeMeta(0, resetEvent.getAckNumb(), 1, 1, 0, 0));
584  soSps_IsLookup.write(false);
585  soSps_RstSockPair.write(mdl_curEvent.tuple);
586  mdl_fsmState = MDL_WAIT_EVENT;
587  }
588  else if (!siTSt_TxSarRep.empty()) {
589  siTSt_TxSarRep.read(mdl_txSar);
590  soIhc_TcpDatLen.write(0);
591  soSps_IsLookup.write(true);
592  soSLc_ReverseLkpReq.write(resetEvent.sessionID); //there is no sessionID??
593  soPhc_TxeMeta.write(TXeMeta(mdl_txSar.not_ackd, resetEvent.getAckNumb(), 1, 1, 0, 0));
594 
595  mdl_fsmState = MDL_WAIT_EVENT;
596  }
597  break;
598  } // End of: switch(mdl_curEvent.type)
599  if (DEBUG_LEVEL & TRACE_MDL) {
600  printInfo(myName, "Event : [%s]\n", getEventName(mdl_curEvent.type));
601  printInfo(myName, "\t ackNumb = %lu\n", mdl_txeMeta.ackNumb.to_ulong());
602  printInfo(myName, "\t seqNumb = %lu\n", mdl_txeMeta.seqNumb.to_ulong());
603  printInfo(myName, "\t winSize = %d \n", mdl_txeMeta.winSize.to_uint());
604  printInfo(myName, "\t length = %d \n", mdl_txeMeta.length.to_uint());
605  }
606  break;
607  } // End of: switch
608 
609 } // End of: pMetaDataLoader
ap_uint< 3 > rt_count
Definition: toe.hpp:667
LE_SocketPair tuple
Definition: toe.hpp:685
ap_uint< 1 > ack
Definition: tx_engine.hpp:79
ap_uint< 1 > rst
Definition: tx_engine.hpp:80
TcpSegLen length
Definition: tx_engine.hpp:78
TcpWindow winSize
Definition: tx_engine.hpp:77
TcpSeqNum seqNumb
Definition: tx_engine.hpp:75
ap_uint< 1 > syn
Definition: tx_engine.hpp:81
TcpAckNum ackNumb
Definition: tx_engine.hpp:76
ap_uint< 1 > fin
Definition: tx_engine.hpp:82
TcpWindow min_window
Definition: toe.hpp:517
bool finReady
Definition: toe.hpp:519
TxAckNum not_ackd
Definition: toe.hpp:516
TxAckNum ackd
Definition: toe.hpp:515
bool finSent
Definition: toe.hpp:520
TxBufPtr app
Definition: toe.hpp:518
ap_uint< 32 > TxMemPtr
Definition: toe.hpp:296
const int cDepth_TXeToRSt_Req
Definition: toe.hpp:230
TcpBufAdr TxBufPtr
Definition: toe.hpp:299
#define TRACE_MDL
Definition: tx_engine.cpp:72
const int cDepth_TXeToTSt_Qry
Definition: toe.hpp:231
ap_uint< 16 > TcpWindow
Definition: AxisTcp.hpp:112
TxAckNum getAckNumb()
Definition: toe.hpp:707
bool hasSessionID()
Definition: toe.hpp:713
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pNotificationMux()

void pNotificationMux ( stream< TcpAppNotif > &  siRXe_Notif,
stream< TcpAppNotif > &  siTIm_Notif,
stream< TcpAppNotif > &  soTAIF_Notif,
stream< ap_uint< 8 > > &  soMMIO_NotifDropCnt 
)

Rx Notification Multiplexer (Nmx)

Parameters
[in]siRXe_NotifNotification from RxEngine (RXe).
[in]siTIm_NotifNotification from Timers (TIm).
[out]soTAIF_NotifNotification to TcpAppInterface (TAIF).
[out]soMMIO_NotifDropCntThe value of the notification drop counter.

This 2-to-1 stream multiplexer behaves like an arbiter. It takes two streams as inputs and forwards one of them to the output channel. Notice that the stream connected to the first input always takes precedence over the second one.

Warning
To avoid any blocking of [RAi], the current notification to be sent on the outgoing stream will be dropped if that stream is full. As a results, the application process must provision enough buffering to store all incoming notifications, or the application must drain the stream as fast as it fills up. An 8-bit notification drop counter register is provided in MMIO to help diagnose such issues.

Definition at line 103 of file rx_app_interface.cpp.

108 {
109  //-- DIRECTIVES FOR THIS PROCESS --------------------------------------------
110  #pragma HLS PIPELINE II=1 enable_flush
111  #pragma HLS INLINE off
112 
113  const char *myName = concat3(THIS_NAME, "/", "Nmx");
114 
115  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
116  static ap_uint<8 > nmx_notifDropCounter=0;
117  #pragma HLS reset variable=nmx_notifDropCounter
118 
119  TcpAppNotif currNotif;
120 
121  if (!siRXe_Notif.empty()) {
122  currNotif = siRXe_Notif.read();
123  if (!soTAIF_Notif.full()) {
124  soTAIF_Notif.write(currNotif);
125  }
126  else {
127  // Drop this notification and increment the Notif Drop Counter
128  nmx_notifDropCounter++;
129  printFatal(myName, "Cannot write 'soTAIF_Notif()'. Stream is full!");
130  }
131  }
132  else if (!siTIm_Notif.empty()) {
133  currNotif = siTIm_Notif.read();
134  if (!soTAIF_Notif.full()) {
135  soTAIF_Notif.write(currNotif);
136  }
137  else {
138  // Drop this notification
139  printFatal(myName, "Cannot write 'soTAIF_Notif()'. Stream is full!");
140  }
141  }
142 
143  //-- ALWAYS
144  if (!soMMIO_NotifDropCnt.full()) {
145  soMMIO_NotifDropCnt.write(nmx_notifDropCounter);
146  }
147  else {
148  printFatal(myName, "Cannot write soMMIO_NotifDropCnt stream...");
149  }
150 }
Here is the caller graph for this function:

◆ port_table()

void port_table ( StsBool poTOE_Ready,
stream< TcpPort > &  siRXe_GetPortStateReq,
stream< RepBit > &  soRXe_GetPortStateRep,
stream< TcpPort > &  siRAi_OpenLsnPortReq,
stream< AckBit > &  soRAi_OpenLsnPortAck,
stream< ReqBit > &  siTAi_GetFreePortReq,
stream< TcpPort > &  soTAi_GetFreePortRep,
stream< TcpPort > &  siSLc_CloseActPortCmd 
)

Port Table (PRt)

ENTITY - Port Table (PRt)

Parameters
[out]poTOE_ReadyThe ready logic signal of this process to [TOE].
[in]siRXe_GetPortStateReqPort state request from RxEngine (RXe).
[out]soRXe_GetPortStateRepPort state reply to [RXe].
[in]siRAi_OpenLsnPortReqOpen port request from RxAppInterface (RAi).
[out]soRAi_OpenLsnPortRepOpen port reply to [RAi].
[in]siTAi_GetFreePortReqFree port request from TxAppInterface (TAi).
[out]soTAi_GetFreePortRepFree port reply o [TAi].
[in]siSLc_CloseActPortCmdCommand to close an active port from SessionLookupController (SLc).

This process keeps track of the TCP port numbers which are in use and therefore opened. It maintains two port ranges based on two tables of 32768 x 1-bit:

  • One for static ports (0 to 32,767) which are used for listening ports,
  • One for dynamically assigned or ephemeral ports (32,768 to 65,535) which are used for active connections open by [TOE]. A port can be either closed, in listen, or in active state. The PortTable receives requests from 3 sources: 1) opening (listening) requests from the RxApplication Interface (RAi), 2) requests to check if a given port is open from the RxEngine (RXe), 3) requests for a free port from the TxApplicationInterface (TAi).

Definition at line 453 of file port_table.cpp.

462 {
463 
464  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
465  #pragma HLS INLINE
466 
467  //--------------------------------------------------------------------------
468  //-- LOCAL SIGNALS AND STREAMS
469  //-- (Sorted by the name of the modules which generate them)
470  //--------------------------------------------------------------------------
471 
472  //-- Input Request Router (Irr)
473  static stream<TcpStaPort> ssIrrToLpt_GetLsnPortStateCmd ("ssIrrToLpt_GetLsnPortStateCmd");
474  #pragma HLS STREAM variable=ssIrrToLpt_GetLsnPortStateCmd depth=2
475 
476  static stream<TcpDynPort> ssIrrToFpt_GetActPortStateCmd ("ssIrrToFpt_GetActPortStateCmd");
477  #pragma HLS STREAM variable=ssIrrToFpt_GetActPortStateCmd depth=2
478 
479  static stream<bool> ssIrrToOrm_QueryRange ("ssIrrToOrm_QueryRange");
480  #pragma HLS STREAM variable=ssIrrToOrm_QueryRange depth=4
481 
482  //-- Listening Port Table (Lpt)
483  StsBool sLptToAnd2_Ready;
484  static stream<RspBit> ssLptToOrm_GetLsnPortStateRsp ("ssLptToOrm_GetLsnPortStateRsp");
485  #pragma HLS STREAM variable=ssLptToOrm_GetLsnPortStateRsp depth=2
486 
487  //-- Free Port Table (Fpt)
488  StsBool sFptToAnd2_Ready;
489  static stream<RspBit> ssFptToOrm_GetActPortStateRsp ("ssFptToOrm_GetActPortStateRsp");
490  #pragma HLS STREAM variable=ssFptToOrm_GetActPortStateRsp depth=2
491 
492  //--------------------------------------------------------------------------
493  //-- PROCESS FUNCTIONS
494  //--------------------------------------------------------------------------
495 
497  sLptToAnd2_Ready,
498  siRAi_OpenLsnPortReq,
499  soRAi_OpenLsnPortAck,
500  ssIrrToLpt_GetLsnPortStateCmd,
501  ssLptToOrm_GetLsnPortStateRsp);
502 
504  sFptToAnd2_Ready,
505  siSLc_CloseActPortCmd,
506  ssIrrToFpt_GetActPortStateCmd,
507  ssFptToOrm_GetActPortStateRsp,
508  siTAi_GetFreePortReq,
509  soTAi_GetFreePortRep);
510 
511  // Routes the input requests
513  siRXe_GetPortStateReq,
514  ssIrrToLpt_GetLsnPortStateCmd,
515  ssIrrToFpt_GetActPortStateCmd,
516  ssIrrToOrm_QueryRange);
517 
519  ssIrrToOrm_QueryRange,
520  ssLptToOrm_GetLsnPortStateRsp,
521  ssFptToOrm_GetActPortStateRsp,
522  soRXe_GetPortStateRep);
523 
524  pReady(
525  sLptToAnd2_Ready,
526  sFptToAnd2_Ready,
527  poTOE_Ready);
528 
529 }
bool StsBool
Definition: nal.hpp:246
void pOutputReplyMultiplexer(stream< bool > &siIrr_QueryRange, stream< RspBit > &siLpt_GetLsnPortStateRsp, stream< RspBit > &siFpt_GetActPortStateRsp, stream< RspBit > &soRXe_GetPortStateRsp)
Output Reply Multiplexer (Orm)
Definition: port_table.cpp:387
void pListeningPortTable(StsBool &poRdy_Ready, stream< TcpPort > &siRAi_OpenLsnPortReq, stream< RepBit > &soRAi_OpenLsnPortRep, stream< TcpStaPort > &siIrr_GetPortStateCmd, stream< RspBit > &soOrm_GetPortStateRsp)
Listening Port Table (Lpt)
Definition: port_table.cpp:141
void pReady(StsBool &piLpt_Ready, StsBool &piFpt_Ready, StsBool &poTOE_Ready)
Ready Logic (Rdy)
Definition: port_table.cpp:106
void pInputRequestRouter(stream< TcpPort > &siRXe_GetPortStateCmd, stream< TcpStaPort > &soLpt_GetLsnPortStateCmd, stream< TcpDynPort > &soFpt_GetActPortStateCmd, stream< bool > &soOrm_QueryRange)
Input Request Router (Irr)
Definition: port_table.cpp:343
void pFreePortTable(StsBool &poRdy_Ready, stream< TcpPort > &siSLc_CloseActPortCmd, stream< TcpDynPort > &siIrr_GetPortStateCmd, stream< RspBit > &soOrm_GetPortStateRsp, stream< ReqBit > &siTAi_GetFreePortReq, stream< TcpPort > &soTAi_GetFreePortRep)
Free Port Table (Fpt)
Definition: port_table.cpp:232
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pOutputReplyMultiplexer()

void pOutputReplyMultiplexer ( stream< bool > &  siIrr_QueryRange,
stream< RspBit > &  siLpt_GetLsnPortStateRsp,
stream< RspBit > &  siFpt_GetActPortStateRsp,
stream< RspBit > &  soRXe_GetPortStateRsp 
)

Output Reply Multiplexer (Orm)

Parameters
[in]siIrr_QueryRangeRange of the query from InputRequestRouter (Irr).
[in]siLpt_GetLsnPortStateRspListen port state response from ListenPortTable (LPt).
[in]siFpt_GetActPortStateRspActive port state response from FreePortTable (Fpt).
[out]soRXe_GetPortStateRspPort state response to RxEngine (RXe).

This process orders the lookup replies before sending them back to the RxEngine (RXe).

Definition at line 387 of file port_table.cpp.

392 {
393  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
394  #pragma HLS PIPELINE II=1 enable_flush
395  #pragma HLS INLINE off
396 
397  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
398  static enum FsmStates { ORM_WAIT_FOR_QUERY_FROM_Irr=0,
399  ORM_FORWARD_LSN_PORT_STATE_RSP,
400  ORM_FORWARD_ACT_PORT_STATE_RSP } orm_fsmState=ORM_WAIT_FOR_QUERY_FROM_Irr;
401 
402  // Read out responses from tables in order and merge them
403  switch (orm_fsmState) {
404  case ORM_WAIT_FOR_QUERY_FROM_Irr:
405  if (!siIrr_QueryRange.empty()) {
406  PortRange qryType = siIrr_QueryRange.read();
407  if (qryType == LISTEN_PORT)
408  orm_fsmState = ORM_FORWARD_LSN_PORT_STATE_RSP;
409  else
410  orm_fsmState = ORM_FORWARD_ACT_PORT_STATE_RSP;
411  }
412  break;
413  case ORM_FORWARD_LSN_PORT_STATE_RSP:
414  if (!siLpt_GetLsnPortStateRsp.empty() and !soRXe_GetPortStateRsp.full()) {
415  soRXe_GetPortStateRsp.write(siLpt_GetLsnPortStateRsp.read());
416  orm_fsmState = ORM_WAIT_FOR_QUERY_FROM_Irr;
417  }
418  break;
419  case ORM_FORWARD_ACT_PORT_STATE_RSP:
420  if (!siFpt_GetActPortStateRsp.empty() and !soRXe_GetPortStateRsp.full()) {
421  soRXe_GetPortStateRsp.write(siFpt_GetActPortStateRsp.read());
422  orm_fsmState = ORM_WAIT_FOR_QUERY_FROM_Irr;
423  }
424  break;
425  }
426 }
Here is the caller graph for this function:

◆ pProbeTimer()

void pProbeTimer ( stream< SessionId > &  siRXe_ClrProbeTimer,
stream< SessionId > &  siTXe_SetProbeTimer,
stream< Event > &  soEmx_Event 
)

Probe Timer (Prb) process.

Parameters
[in]siRXe_ClrProbeTimerClear probe timer command from RxEngine (RXe).
[in]siTXe_SetProbeTimerSet probe timer from TxEngine (TXe).
[out]soEmx_EventEvent to EventMultiplexer (Emx).

This process reads in 'set-probe-timer' commands from [TXe] and 'clear-probe-timer' commands from [RXe]. Upon a set request, a timer is initialized with an interval of 10s. When the timer expires, an 'RT_EVENT' is fired to the TxEngine via the [Emx] and the EventEngine. In case of a zero-window (or too small window) an 'RT_EVENT' will generate a packet without payload which is the same as a probing packet.

Definition at line 327 of file timers.cpp.

331 {
332  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
333  #pragma HLS INLINE off
334  #pragma HLS PIPELINE II=1 enable_flush
335 
336  const char *myName = concat3(THIS_NAME, "/", "Pbt");
337 
338  //-- STATIC ARRAYS ---------------------------------------------------------
339  static ProbeTimerEntry PROBE_TIMER_TABLE[TOE_MAX_SESSIONS];
340  #pragma HLS RESOURCE variable=PROBE_TIMER_TABLE core=RAM_T2P_BRAM
341  #pragma HLS DATA_PACK variable=PROBE_TIMER_TABLE
342  #pragma HLS DEPENDENCE variable=PROBE_TIMER_TABLE inter false
343  #pragma HLS RESET variable=PROBE_TIMER_TABLE
344 
345  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
346  static bool pbt_WaitForWrite=false;
347  #pragma HLS RESET variable=pbt_WaitForWrite
348  static SessionId pbt_currSessId=0;
349  #pragma HLS RESET variable=pbt_currSessId
350  static SessionId pbt_updtSessId=0;
351  #pragma HLS RESET variable=pbt_updtSessId
352  static SessionId pbt_prevSessId=0;
353  #pragma HLS RESET variable=pbt_prevSessId
354 
355  //-- DYNAMIC VARIABLES -----------------------------------------------------
356  bool fastResume = false;
357 
358  if (pbt_WaitForWrite) {
359  //-- Update the table
360  if (pbt_updtSessId != pbt_prevSessId) {
361  PROBE_TIMER_TABLE[pbt_updtSessId].time = TIME_10s;
362  //****************************************************************
363  //** [FIXME - Disabling the KeepAlive process for the time being]
364  //****************************************************************
365  PROBE_TIMER_TABLE[pbt_updtSessId].active = false;
366  pbt_WaitForWrite = false;
367  }
368  pbt_prevSessId--;
369  }
370  else if (!siTXe_SetProbeTimer.empty()) {
371  //-- Read the Session-Id to set
372  siTXe_SetProbeTimer.read(pbt_updtSessId);
373  pbt_WaitForWrite = true;
374  }
375  else { // if (!soEmx_Event.full()) this leads to II=2
376  SessionId sessIdToProcess;
377 
378  if (!siRXe_ClrProbeTimer.empty()) {
379  //-- Read the Session-Id to clear
380  sessIdToProcess = siRXe_ClrProbeTimer.read();
381  fastResume = true;
382  }
383  else {
384  sessIdToProcess = pbt_currSessId;
385  pbt_currSessId++;
386  if (pbt_currSessId == TOE_MAX_SESSIONS) {
387  pbt_currSessId = 0;
388  }
389  }
390 
391  if (PROBE_TIMER_TABLE[sessIdToProcess].active) {
392  if (fastResume) {
393  //-- Clear (de-activate) the keepalive process for the current session-ID
394  PROBE_TIMER_TABLE[sessIdToProcess].time = 0;
395  PROBE_TIMER_TABLE[sessIdToProcess].active = false;
396  fastResume = false;
397  }
398  else if (PROBE_TIMER_TABLE[sessIdToProcess].time == 0 and !soEmx_Event.full()) {
399  //-- Request to send a keepalive probe
400  PROBE_TIMER_TABLE[sessIdToProcess].time = 0;
401  PROBE_TIMER_TABLE[sessIdToProcess].active = false;
402  #if !(TCP_NODELAY)
403  soEmx_Event.write(Event(TX_EVENT, sessIdToProcess));
404  #else
405  soEmx_Event.write(Event(RT_EVENT, sessIdToProcess));
406  #endif
407  }
408  else {
409  PROBE_TIMER_TABLE[sessIdToProcess].time -= 1;
410  }
411  }
412  pbt_prevSessId = sessIdToProcess;
413  }
414 }
ap_uint< 32 > time
Definition: timers.hpp:86
Here is the caller graph for this function:

◆ pPseudoHeaderConstructor()

void pPseudoHeaderConstructor ( stream< TXeMeta > &  siMdl_TxeMeta,
stream< SocketPair > &  siSps_SockPair,
stream< AxisPsd4 > &  soTss_PseudoHdr 
)

Pseudo Header Constructor (Phc)

Parameters
[in]siMdl_TxeMetaMeta data from MetaDataLoader (Mdl).
[in]siSps_SockPairSocket pair from SocketPairSplitter (Sps).
[out]soTss_PseudoHdrTCP pseudo header to TcpSegmentStitcher (Tss).

Reads the TCP header metadata and the IP tuples and generates a TCP pseudo header from it. Result is streamed out to the TcpSegmentStitcher (Tss).

@Warning The pseudo header is prepared as if it was to be transmitted over the Ethernet MAC. Therefore, remember that this 64-bits interface is logically divided into lane #0 (7:0) to lane #7 (63:56). The format of the outgoing pseudo header is then:

  6                   5                   4                   3                   2                   1                   0

3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DA (LL) | DA (L) | DA (H) | DA (HH) | SA (LL) | SA (L) | SA (H) | SA (HH) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DP (L) | DP (H) | SP (L) | SP (H) | Segment Len | 0x06 | 0x00 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Ack (LL) | Ack (L) | Ack (H) | Ack (HH) | Seq (LL) | Seq (L) | Seq (H) | Seq (HH) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | | | |C|E|U|A|P|R|S|F| Data | |N| | UrgPtr(L) | UrgPtr(H) | CSum (L) | CSum (H) | Win (L) | Win (H) |W|C|R|C|S|S|Y|I| Offset| Res |S| | | | | | | |R|E|G|K|H|T|N|N| | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data 3 | Data 2 | Data 1 | Data 0 | Opt-Data (.i.e MSS) | Opt-Length | Opt-Kind | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Definition at line 818 of file tx_engine.cpp.

822 {
823  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
824  #pragma HLS INLINE off
825  #pragma HLS PIPELINE II=1 enable_flush
826 
827  const char *myName = concat3(THIS_NAME, "/", "Phc");
828 
829  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
830  static ap_uint<3> phc_chunkCount=0;
831  #pragma HLS RESET variable=phc_chunkCount
832 
833  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
834  static TXeMeta phc_meta;
835  static SocketPair phc_socketPair;
836 
837  //-- DYNAMIC VARIABLES -----------------------------------------------------
838  AxisPsd4 currChunk(0, 0xFF, 0);
839  TcpSegLen pseudoHdrLen = 0;
840 
841  switch(phc_chunkCount) {
842  case CHUNK_0:
843  // Build and forward [ IP_DA | IP_SA ]
844  if (!siSps_SockPair.empty() && !siMdl_TxeMeta.empty()) {
845  siSps_SockPair.read(phc_socketPair);
846  siMdl_TxeMeta.read(phc_meta);
847  currChunk.setPsd4SrcAddr(phc_socketPair.src.addr);
848  currChunk.setPsd4DstAddr(phc_socketPair.dst.addr);
849  assessSize(myName, soTss_PseudoHdr, "soTss_PseudoHdr", 32); // [FIXME-Use constant for the length]
850  soTss_PseudoHdr.write(currChunk);
851  if (DEBUG_LEVEL & TRACE_PHC) { printAxisRaw(myName, "soTss_PseudoHdr =", currChunk); }
852  phc_chunkCount++;
853  }
854  break;
855  case CHUNK_1:
856  // Build and forward [ TCP_DP | TCP_SP | SegLen | 0x06 | 0x00 ]
857  currChunk.setPsd4ResBits(0x00);
858  currChunk.setPsd4Prot(IP4_PROT_TCP);
859  // Compute the length of the TCP segment. This includes both the header and the payload.
860  pseudoHdrLen = phc_meta.length + TCP_HEADER_LEN; // [FIXME]
861  currChunk.setPsd4Len(pseudoHdrLen);
862  currChunk.setTcpSrcPort(phc_socketPair.src.port);
863  currChunk.setTcpDstPort(phc_socketPair.dst.port);
864  assessSize(myName, soTss_PseudoHdr, "soTss_PseudoHdr", 32); // [FIXME-Use constant for the length]
865  soTss_PseudoHdr.write(currChunk);
866  if (DEBUG_LEVEL & TRACE_PHC) { printAxisRaw(myName, "soTss_PseudoHdr =", currChunk); }
867  phc_chunkCount++;
868  break;
869  case CHUNK_2:
870  // Build and forward [ AckNum | SeqNum ]
871  currChunk.setTcpSeqNum(phc_meta.seqNumb);
872  currChunk.setTcpAckNum(phc_meta.ackNumb);
873  assessSize(myName, soTss_PseudoHdr, "soTss_PseudoHdr", 32); // [FIXME-Use constant for the length]
874  soTss_PseudoHdr.write(currChunk);
875  if (DEBUG_LEVEL & TRACE_PHC) { printAxisRaw(myName, "soTss_PseudoHdr =", currChunk); }
876  phc_chunkCount++;
877  break;
878  case CHUNK_3:
879  // Build and forward [ UrgPtr | CSum | Win | Flags | DataOffset & Res & NS ]
880  currChunk.setTcpCtrlNs(0);
881  currChunk.setTcpResBits(0);
882  currChunk.setTcpDataOff(5 + (int)phc_meta.syn); // 5x32bits (+ 1x32bits for MSS)
883  currChunk.setTcpCtrlFin(phc_meta.fin);
884  currChunk.setTcpCtrlSyn(phc_meta.syn);
885  currChunk.setTcpCtrlRst(phc_meta.rst);
886  currChunk.setTcpCtrlPsh(0);
887  currChunk.setTcpCtrlAck(phc_meta.ack);
888  currChunk.setTcpCtrlUrg(0);
889  currChunk.setTcpCtrlEce(0);
890  currChunk.setTcpCtrlCwr(0);
891  currChunk.setTcpWindow(phc_meta.winSize);
892  currChunk.setTcpChecksum(0);
893  currChunk.setTcpUrgPtr(0);
894  currChunk.setTLast((phc_meta.length == 0) and (phc_meta.syn == 0));
895  assessSize(myName, soTss_PseudoHdr, "soTss_PseudoHdr", 32); // [FIXME-Use constant for the length]
896  soTss_PseudoHdr.write(currChunk);
897  if (DEBUG_LEVEL & TRACE_PHC) { printAxisRaw(myName, "soTss_PseudoHdr =", currChunk); }
898  if (!phc_meta.syn) {
899  phc_chunkCount = 0;
900  }
901  else {
902  phc_chunkCount++;
903  }
904  break;
905  case CHUNK_4:
906  // Only used for SYN and MSS negotiation
907  // Build and forward [ Data 3:0 | Opt-Data | Opt-Length | Opt-Kind ]
908  currChunk.setTcpOptKind(0x02); // Option Kind = Maximum Segment Size
909  currChunk.setTcpOptLen(0x04); // Option length = 4 bytes
910  currChunk.setTcpOptMss(MY_MSS); // Our Maximum Segment Size (1456)
911  currChunk.setLE_TKeep(0x0F);
912  currChunk.setLE_TLast(TLAST);
913  assessSize(myName, soTss_PseudoHdr, "soTss_PseudoHdr", 32); // [FIXME-Use constant for the length]
914  soTss_PseudoHdr.write(currChunk);
915  if (DEBUG_LEVEL & TRACE_PHC) { printAxisRaw(myName, "soTss_PseudoHdr =", currChunk); }
916  phc_chunkCount = 0;
917  break;
918  } // End of: switch
919 
920 } // End of: pPseudoHeaderConstructor (Phc)
#define TRACE_PHC
Definition: tx_engine.cpp:75
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pReady() [1/2]

void pReady ( StsBool piLpt_Ready,
StsBool piFpt_Ready,
StsBool poTOE_Ready 
)

Ready Logic (Rdy)

Parameters
[in]piLpt_ReadyThe ready signal from ListenPortTable (Lpt).
[in]piFpt_ReadyThe ready signal from FreePortTable (Fpt).
[out]poTOE_ReadyThe ready signal of PortTable (PRt) to [TOE].

This process generates a ready signal indicating that the logic of the PortTable (PRt) is ready.

Definition at line 106 of file port_table.cpp.

110 {
111  const char *myName = concat3(THIS_NAME, "/", "Rdy");
112 
113  poTOE_Ready = piLpt_Ready and piFpt_Ready;
114 
115  if (DEBUG_LEVEL & TRACE_RDY) {
116  if (poTOE_Ready)
117  printInfo(myName, "Process [PRt] is ready.\n");
118  }
119 }
#define TRACE_RDY
Definition: port_table.cpp:75
Here is the caller graph for this function:

◆ pReady() [2/2]

void pReady ( StsBool piPRt_Ready,
StsBit poNTS_Ready 
)

Ready (Rdy)

Parameters
[in]piPRt_ReadyThe ready signal from PortTable (PRt).
[in]piTBD_ReadyThe ready signal from TBD.
[out]poNTS_ReadyThe ready signal of the TOE.

[FIXME - Turn this IO into a stream] This process merges multiple ready signals into a single global ready signal for the TOE.

Definition at line 133 of file toe.cpp.

136 {
137  const char *myName = concat3(THIS_NAME, "/", "Rdy");
138 
139  poNTS_Ready = (piPRt_Ready == true) ? 1 : 0;
140 
141  if (DEBUG_LEVEL & TRACE_RDY) {
142  if (poNTS_Ready)
143  printInfo(myName, "Process [TOE] is ready.\n");
144  }
145 }
Here is the caller graph for this function:

◆ pRetransmitTimer()

void pRetransmitTimer ( stream< RXeReTransTimerCmd > &  siRXe_ReTxTimerCmd,
stream< TXeReTransTimerCmd > &  siTXe_ReTxTimerCmd,
stream< Event > &  soEmx_Event,
stream< SessionId > &  soSmx_SessCloseCmd,
stream< SessState > &  soTAi_Notif,
stream< TcpAppNotif > &  soRAi_Notif 
)

ReTransmit Timer (Rtt) process.

Parameters
[in]siRXe_ReTxTimerCmdRetransmit timer command from RxEngine (RXe).
[in]siTXe_ReTxTimerCmdRetransmit timer command from TxEngine (TXe).
[out]soEmx_EventEvent to EventMultiplexer (Emx).
[out]soSmx_SessCloseCmdClose command to StateTableMux (Smx).
[out]soTAi_NotifNotification to TxApplicationInterface (TAi).
[out]soRAi_NotifNotification to RxApplicationInterface (RAi).

This process implements the retransmission timers at the session level. This is slightly different from the software method used to detect lost segments and for retransmitting them. Instead of managing a retransmission timer per segment, the current implementation only keeps track of a single timer per session. Such a session timer is managed as follows: [START] The retransmit timer of a session is re-started with an initial retransmission timeout value (RTO) whenever the timer is not active and a new segment is transmitted by [TXe]. The RTO value is set between 3 and 24 seconds, depending on how often the session already timed-out in the recent past. [STOP] The retransmit timer of a session is stopped and deactivated whenever an ACK is received by [RXe] and its received AckNum equals to the previously transmitted bytes but not yet acknowledged. [LOAD] Otherwise, the retransmit timer of a session is loaded with a RTO value of 1 second. [TIMEOUT] Upon a time-out, an event is fired to [TXe]. If a session times-out more than 4 times in a row, it is aborted. A release command is sent to the StateTable (STt) and the application is notified.

Definition at line 135 of file timers.cpp.

142 {
143  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
144  #pragma HLS PIPELINE II=1 enable_flush
145  #pragma HLS INLINE off
146 
147  const char *myName = concat3(THIS_NAME, "/", "Rtt");
148 
149  //-- STATIC ARRAYs ---------------------------------------------------------
150  static ReTxTimerEntry RETRANSMIT_TIMER_TABLE[TOE_MAX_SESSIONS];
151  #pragma HLS RESOURCE variable=RETRANSMIT_TIMER_TABLE core=RAM_T2P_BRAM
152  #pragma HLS DEPENDENCE variable=RETRANSMIT_TIMER_TABLE inter false
153  #pragma HLS RESET variable=RETRANSMIT_TIMER_TABLE
154 
155  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
156  static bool rtt_waitForWrite=false;
157  #pragma HLS RESET variable=rtt_waitForWrite
158  static SessionId rtt_prevPosition=0;
159  #pragma HLS RESET variable=rtt_prevPosition
160  static SessionId rtt_position=0;
161  #pragma HLS RESET variable=rtt_position
162 
163  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
164  static RXeReTransTimerCmd rtt_rxeCmd;
165 
166  //-- DYNAMIC VARIABLES ----------------------------------------------------
167  ReTxTimerEntry currEntry;
168  TXeReTransTimerCmd txeCmd;
169  ValBool txeCmdVal;
170  SessionId currID;
171 
172  if (rtt_waitForWrite and (rtt_rxeCmd.sessionID != rtt_prevPosition)) {
173  //-------------------------------------------------------------
174  // Handle previously read command from [RXe] (i.e. RELOAD|STOP)
175  //-------------------------------------------------------------
176  if (rtt_rxeCmd.command == LOAD_TIMER) {
177  RETRANSMIT_TIMER_TABLE[rtt_rxeCmd.sessionID].time = TIME_1s;
178  if (DEBUG_LEVEL & TRACE_RTT) {
179  printInfo(myName, "Session #%d - Reloading RTO timer (value=%d i.e. %d clock cycles).\n",
180  rtt_rxeCmd.sessionID.to_int(), RETRANSMIT_TIMER_TABLE[rtt_rxeCmd.sessionID].time.to_uint(),
181  TOE_MAX_SESSIONS * RETRANSMIT_TIMER_TABLE[rtt_rxeCmd.sessionID].time.to_uint());
182  }
183  }
184  else { //-- STOP the timer
185  RETRANSMIT_TIMER_TABLE[rtt_rxeCmd.sessionID].time = 0;
186  RETRANSMIT_TIMER_TABLE[rtt_rxeCmd.sessionID].active = false;
187  if (DEBUG_LEVEL & TRACE_RTT) {
188  printInfo(myName, "Session #%d - Stopping RTO timer.\n",
189  rtt_rxeCmd.sessionID.to_int());
190  }
191  }
192  RETRANSMIT_TIMER_TABLE[rtt_rxeCmd.sessionID].retries = 0;
193  rtt_waitForWrite = false;
194  }
195  else if (!siRXe_ReTxTimerCmd.empty() and !rtt_waitForWrite) {
196  //------------------------------------------------
197  // Read input command from [RXe]
198  // INFO: Rx path has priority over Tx path
199  //------------------------------------------------
200  siRXe_ReTxTimerCmd.read(rtt_rxeCmd);
201  rtt_waitForWrite = true;
202  }
203  else {
204  if (!siTXe_ReTxTimerCmd.empty()) {
205  //------------------------------------------------
206  // Read input command from [TXe]
207  //------------------------------------------------
208  txeCmd = siTXe_ReTxTimerCmd.read();
209  txeCmdVal = true;
210  currID = txeCmd.sessionID;
211  if ( (txeCmd.sessionID-3 < rtt_position) and
212  (rtt_position <= txeCmd.sessionID) ) {
213  rtt_position += 5; // [FIXME - Why is this?]
214  }
215  }
216  else {
217  txeCmdVal = false;
218  currID = rtt_position;
219  // Increment position to be used in next loop
220  rtt_position++;
221  if (rtt_position >= TOE_MAX_SESSIONS) {
222  rtt_position = 0;
223  }
224  }
225 
226  // Get current entry from table
227  currEntry = RETRANSMIT_TIMER_TABLE[currID];
228 
229  if (txeCmdVal) {
230  // There is a pending set command from [TXe]. Go and process it.
231  currEntry.type = txeCmd.type;
232  if (not currEntry.active) {
233  switch(currEntry.retries) {
234  case 0:
235  currEntry.time = TIME_3s;
236  break;
237  case 1:
238  currEntry.time = TIME_6s;
239  break;
240  case 2:
241  currEntry.time = TIME_12s;
242  break;
243  default:
244  currEntry.time = TIME_30s;
245  break;
246  }
247  currEntry.active = true;
248  if (DEBUG_LEVEL & TRACE_RTT) {
249  printInfo(myName, "Session #%d - Starting RTO timer (value=%d i.e. %d clock cycles).\n",
250  currID.to_int(), currEntry.time.to_uint(),
251  currEntry.time.to_uint()*TOE_MAX_SESSIONS);
252  }
253  }
254  else {
255  if (DEBUG_LEVEL & TRACE_RTT) {
256  printInfo(myName, "Session #%d - Current RTO timer (value=%d i.e. %d clock cycles).\n",
257  currID.to_int(), currEntry.time.to_uint(),
258  currEntry.time.to_uint()*TOE_MAX_SESSIONS);
259  }
260  }
261  }
262  else {
263  // No [TXe] command. Manage RETRANSMIT_TIMER_TABLE entries
264  if (currEntry.active) {
265  if (currEntry.time > 0) {
266  currEntry.time--;
267  }
268  // We need to check if we can generate another event, otherwise we might
269  // end up in a Deadlock since the [TXe] will not be able to set new
270  // retransmit timers.
271  else if (!soEmx_Event.full()) {
272  currEntry.time = 0;
273  currEntry.active = false;
274  if (currEntry.retries < 4) {
275  currEntry.retries++;
276  //-- Send timeout event to [TXe]
277  soEmx_Event.write(Event((EventType)currEntry.type,
278  currID,
279  currEntry.retries));
280  printWarn(myName, "Session #%d - RTO Timeout (retries=%d).\n",
281  currID.to_int(), currEntry.retries.to_uint());
282  }
283  else {
284  currEntry.retries = 0;
285  soSmx_SessCloseCmd.write(currID);
286  if (currEntry.type == SYN_EVENT) {
287  soTAi_Notif.write(SessState(currID, CLOSED));
288  if (DEBUG_LEVEL & TRACE_RTT) {
289  printWarn(myName, "Notifying [TAi] - Failed to open session %d (event=\'%s\').\n",
290  currID.to_int(), getEventName(currEntry.type));
291  }
292  }
293  else {
294  soRAi_Notif.write(TcpAppNotif(currID, CLOSED));
295  if (DEBUG_LEVEL & TRACE_RTT) {
296  printWarn(myName, "Notifying [RAi] - Session %d timeout (event=\'%s\').\n",
297  currID.to_int(), getEventName(currEntry.type));
298  }
299  }
300  }
301  }
302  }
303  } // End of: txeCmdVal
304 
305  // Write the entry back into the table
306  RETRANSMIT_TIMER_TABLE[currID] = currEntry;
307  rtt_prevPosition = currID;
308  }
309 }
TimerCmd command
Definition: toe.hpp:631
SessionId sessionID
Definition: toe.hpp:630
ap_uint< 32 > time
Definition: timers.hpp:97
ap_uint< 3 > retries
Definition: timers.hpp:98
EventType type
Definition: timers.hpp:100
EventType type
Definition: toe.hpp:645
SessionId sessionID
Definition: toe.hpp:644
#define TRACE_RTT
Definition: timers.cpp:73
EventType
Definition: toe.hpp:273
bool ValBool
Definition: nts_types.hpp:131
Here is the caller graph for this function:

◆ pReverseLookupTable()

void pReverseLookupTable ( stream< SLcReverseLkp > &  siLrh_ReverseLkpRsp,
stream< SessionId > &  siSTt_SessReleaseCmd,
stream< SessionId > &  siTXe_ReverseLkpReq,
stream< fourTuple > &  soTXe_ReverseLkpRep,
stream< TcpPort > &  soPRt_ClosePortCmd,
stream< CamSessionUpdateRequest > &  soUrs_SessDeleteReq 
)

Reverse Lookup Table (Rlt)

Parameters
[in]sLrh_ReverseLkpRspReverse lookup response from LookupReplyHandler (Lrh).
[in]siSTt_SessReleaseCmdSession release command from StateTable (STt).
[in[siTXe_ReverseLkpReq Reverse lookup request from TxEngine (TXe).
[out]soTXe_ReverseLkpRepReverse lookup reply to TxEngine (TXe).
[out]soPRt_ClosePortCmdCommand to close a port for the PortTable (PRt).
[out]soUrs_SessDeleteReqRequest to delete a session to UpdateRequestSender (Urs).

The REVERSE_LOOKUP_TABLE stores a four-tuple piece of information at memory address indexed by the 'SessionId' of that 4-tuple. This table is used to retrieve the 4-tuple information corresponding to a SessionId upon request from [TXe].

Definition at line 334 of file session_lookup_controller.cpp.

341 {
342  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
343  #pragma HLS PIPELINE II=1 enable_flush
344  #pragma HLS INLINE off
345 
346  const char *myName = concat3(THIS_NAME, "/", "Rlt");
347 
348  //-- STATIC ARRAYS --------------------------------------------------------
349  static SLcFourTuple REVERSE_LOOKUP_TABLE[TOE_MAX_SESSIONS];
350  #pragma HLS RESOURCE variable=REVERSE_LOOKUP_TABLE core=RAM_T2P_BRAM
351  #pragma HLS DEPENDENCE variable=REVERSE_LOOKUP_TABLE inter false
352  static ValBool TUPLE_VALID_TABLE[TOE_MAX_SESSIONS];
353  #pragma HLS DEPENDENCE variable=TUPLE_VALID_TABLE inter false
354 
355  //-- STATIC CONTROL VARIABLES (with RESET) --------------------------------
356  static bool rlt_isInit=false;
357  #pragma HLS reset variable=rlt_isInit
358  static RtlSessId rlt_counter=0;
359  #pragma HLS reset variable=rlt_counter
360 
361  if (!rlt_isInit) {
362  // The two tables must be cleared upon reset
363  TUPLE_VALID_TABLE[rlt_counter] = false;
364  if (rlt_counter < TOE_MAX_SESSIONS) {
365  rlt_counter++;
366  }
367  else {
368  rlt_isInit = true;
369  }
370  }
371  else {
372  // Normal operation
373  if (!siLrh_ReverseLkpRsp.empty()) {
374  // Update the two TABLEs
375  SLcReverseLkp insert = siLrh_ReverseLkpRsp.read();
376  REVERSE_LOOKUP_TABLE[insert.key] = insert.value;
377  TUPLE_VALID_TABLE[insert.key] = true;
378  }
379  else if (!siSTt_SessReleaseCmd.empty()) {
380  // Release a session
381  SessionId sessionId = siSTt_SessReleaseCmd.read();
382  SLcFourTuple releaseTuple = REVERSE_LOOKUP_TABLE[sessionId];
383  if (TUPLE_VALID_TABLE[sessionId]) { // if valid
384  soPRt_ClosePortCmd.write(releaseTuple.myPort);
385  soUrs_SessDeleteReq.write(CamSessionUpdateRequest(releaseTuple, sessionId, DELETE, FROM_RXe));
386  }
387  TUPLE_VALID_TABLE[sessionId] = false;
388  }
389  else if (!siTXe_ReverseLkpReq.empty()) {
390  // Return 4-tuple corresponding to a given session Id
391  SessionId sessionId = siTXe_ReverseLkpReq.read();
392  soTXe_ReverseLkpRep.write(fourTuple(
393  REVERSE_LOOKUP_TABLE[sessionId].myIp,
394  REVERSE_LOOKUP_TABLE[sessionId].theirIp,
395  REVERSE_LOOKUP_TABLE[sessionId].myPort,
396  REVERSE_LOOKUP_TABLE[sessionId].theirPort));
397  }
398  }
399 }
LE_TcpPort myPort
Definition: nts_types.hpp:397
AppMeta sessionId
Definition: tb_nal.cpp:827
@ DELETE
Definition: nts_types.hpp:382
Here is the caller graph for this function:

◆ printFourTuple()

void printFourTuple ( const char *  callerName,
int  src,
FourTuple  fourTuple 
)

Print a socket pair association from an internal FourTuple encoding.

Parameters
[in]callerNameThe name of the caller process (e.g. "TAi").
[in]sourceThe source of the internal 4-tuple information.
[in]fourTupleThe internal 4-tuple encoding of the socket pair.

Definition at line 73 of file toe_utils.cpp.

73  {
74  SocketPair socketPair;
75  switch (src) {
76  case FROM_RXe:
77  socketPair.src.addr = byteSwap32(fourTuple.theirIp);
78  socketPair.src.port = byteSwap16(fourTuple.theirPort);
79  socketPair.dst.addr = byteSwap32(fourTuple.myIp);
80  socketPair.dst.port = byteSwap16(fourTuple.myPort);
81  break;
82  case FROM_TAi:
83  socketPair.src.addr = byteSwap32(fourTuple.myIp);
84  socketPair.src.port = byteSwap16(fourTuple.myPort);
85  socketPair.dst.addr = byteSwap32(fourTuple.theirIp);
86  socketPair.dst.port = byteSwap16(fourTuple.theirPort);
87  break;
88  default:
89  printFatal(callerName, "Unknown request source %d.\n", src);
90  break;
91  }
92  printSockPair(callerName, socketPair);
93 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pRxAppNotifier()

void pRxAppNotifier ( stream< DmSts > &  siMEM_WrSts,
stream< TcpAppNotif > &  siFsm_Notif,
stream< TcpAppNotif > &  soRAi_RxNotif,
stream< FlagBool > &  siMwr_SplitSeg,
stream< StsBit > &  soMMIO_MemWrErr 
)

Rx Application Notifier (Ran)

Parameters
[in]siMEM_WrStsThe memory write status from the AXI data mover [MEM].
[in]siFsm_NotifRx data notification from FiniteStateMachine (Fsm).
[out]soRAi_RxNotifRx data notification to RxApplicationInterface (RAi).
[in]siMwr_SplitSegSplit segment flag from MemoryWriter (Mwr).
[out]soMMIO_MemWrErrReports a memory write error to MMIO.

Delays the notifications to the application until the TCP segment is actually written into the physical DRAM memory. If the segment was split in two memory accesses, the current process will wait until both segments are written into memory before issuing the notification to the application. Any error reported by the AXI data mover (MEM) is forwarded to MIMO and remains set until [TOE] is reset.

Definition at line 1075 of file rx_engine.cpp.

1081 {
1082  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1083  #pragma HLS PIPELINE II=1 enable_flush
1084  #pragma HLS INLINE off
1085 
1086  const char *myName = concat3(THIS_NAME, "/", "Ran");
1087 
1088  //-- LOCAL STREAMS ---------------------------------------------------------
1089  static stream<TcpAppNotif> ssRxNotifFifo("ssRxNotifFifo");
1090  #pragma HLS STREAM variable=ssRxNotifFifo depth=32 // WARNING: [FIXME] Depends on the memory delay !!!
1091  #pragma HLS DATA_PACK variable=ssRxNotifFifo
1092 
1093  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1094  static FlagBool ran_doubleAccessFlag=FLAG_OFF;
1095  #pragma HLS RESET variable=ran_doubleAccessFlag
1096  static StsBit ran_dataMoverError=STS_NO_ERR;
1097  #pragma HLS RESET variable=ran_dataMoverError
1098 
1099  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
1100  static DmSts ran_dmStatus1;
1101  static DmSts ran_dmStatus2;
1102  static TcpAppNotif ran_appNotification;
1103 
1104  if (ran_doubleAccessFlag == FLAG_ON) {
1105  // The segment was splitted and notification will only go out now
1106  if(!siMEM_WrSts.empty()) {
1107  siMEM_WrSts.read(ran_dmStatus2);
1108  if (ran_dmStatus1.okay and ran_dmStatus2.okay) {
1109  soRAi_RxNotif.write(ran_appNotification);
1110  if (DEBUG_LEVEL & TRACE_RAN) {
1111  printInfo(myName, "Sending APP notification to [RAi]. This was a double access.\n");
1112  }
1113  }
1114  else {
1115  ran_dataMoverError = ran_dmStatus1.slverr | ran_dmStatus1.decerr | ran_dmStatus1.interr | \
1116  ran_dmStatus2.slverr | ran_dmStatus2.decerr | ran_dmStatus2.interr;;
1117  if (DEBUG_LEVEL & TRACE_RAN) {
1118  printError(myName, "The previous splitted mem-write command failed (OKAY=0).\n");
1119  }
1120  }
1121  ran_doubleAccessFlag = FLAG_OFF;
1122  }
1123  }
1124  else {
1125  //-- We don't know yet about a possible double memory access
1126  if (!siMEM_WrSts.empty() and !siMwr_SplitSeg.empty() and !ssRxNotifFifo.empty()) {
1127  siMEM_WrSts.read(ran_dmStatus1);
1128  siMwr_SplitSeg.read(ran_doubleAccessFlag);
1129  ssRxNotifFifo.read(ran_appNotification);
1130  if (ran_doubleAccessFlag == FLAG_OFF) {
1131  // This segment consists of a single memory access
1132  if (ran_dmStatus1.okay) {
1133  // Output the notification now
1134  soRAi_RxNotif.write(ran_appNotification);
1135  if (DEBUG_LEVEL & TRACE_RAN) {
1136  printInfo(myName, "Sending APP notification to [RAi].\n");
1137  }
1138  }
1139  else {
1140  ran_dataMoverError = ran_dmStatus1.slverr | ran_dmStatus1.decerr | ran_dmStatus1.interr;
1141  if (DEBUG_LEVEL & TRACE_RAN) {
1142  printError(myName, "The previous memory write command failed (OKAY=0).\n");
1143  }
1144  }
1145  }
1146  else {
1147  if (DEBUG_LEVEL & TRACE_RAN) {
1148  printInfo(myName, "The memory access was broken down in two parts.\n");
1149  }
1150  }
1151  }
1152  else if (!siFsm_Notif.empty() and !ssRxNotifFifo.full()) {
1153  siFsm_Notif.read(ran_appNotification);
1154  if (ran_appNotification.tcpDatLen != 0) {
1155  ssRxNotifFifo.write(ran_appNotification);
1156  }
1157  else {
1158  // Do not send forward the notification to [APP]
1159  printInfo(myName, "Received an RxNotif with LENGTH=0.\n");
1160  }
1161  }
1162  }
1163 
1164  //-- ALWAYS
1165  if (!soMMIO_MemWrErr.full()) {
1166  soMMIO_MemWrErr.write(ran_dataMoverError);
1167  }
1168  else {
1169  printFatal(myName, "Cannot write soMMIO_MemWrerr stream...");
1170  }
1171 }
ap_uint< 1 > okay
ap_uint< 1 > decerr
ap_uint< 1 > slverr
ap_uint< 1 > interr
TcpDatLen tcpDatLen
Definition: nts.hpp:90
#define TRACE_RAN
Definition: rx_engine.cpp:80
#define STS_NO_ERR
Definition: nts_types.hpp:84
#define FLAG_OFF
Definition: nts_types.hpp:70
#define FLAG_ON
Definition: nts_types.hpp:71
Here is the caller graph for this function:

◆ pRxAppStream()

void pRxAppStream ( stream< TcpAppRdReq > &  siTAIF_DataReq,
stream< TcpAppMeta > &  soTAIF_Meta,
stream< RAiRxSarQuery > &  soRSt_RxSarQry,
stream< RAiRxSarReply > &  siRSt_RxSarRep,
stream< DmCmd > &  soMrd_MemRdCmd,
stream< ap_uint< 8 > > &  soMMIO_MetaDropCnt 
)

Rx Application Stream (RAs)

Parameters
[in]siTAIF_DataReqData request from TcpApplicationInterface (TAIF).
[out]soTAIF_MetaMetadata to [TAIF].
[out]soRSt_RxSarQryQuery to RxSarTable (RSt).
[in]siRSt_RxSarRepReply from [RSt].
[out]soMrd_MemRdCmdRx memory read command to Rx MemoryReader (Mrd).
[out]soMMIO_MetaDropCntThe value of the metadata drop counter.

@detail This process waits for a valid data read request from the TcpAppInterface (TAIF) and generates a corresponding read command for the TCP Rx buffer memory via the Rx MemoryReader (Mrd) process. Next, a request to update the RxApp pointer of the session is forwarded to the RxSarTable (RSt) and a meta-data (.i.e the current session-id) is sent back to [TAIF] to signal that the request has been processed.

Warning
To avoid any blocking of [RAi], the current metadata to be sent on the outgoing stream 'soTAIF_Meta' will be dropped if that stream is full. This implies that the application process must provision enough buffering to store the metadata returned by this process upon a granted request to be read from the TCP Rx buffer. An 8-bit metadata drop counter register is provided in MMIO to help diagnose such issues.

Definition at line 178 of file rx_app_interface.cpp.

185 {
186  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
187  #pragma HLS PIPELINE II=1 enable_flush
188  #pragma HLS INLINE off
189 
190  const char *myName = concat3(THIS_NAME, "/", "Ras");
191 
192  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
193  static enum FsmStates { S0=0, S1 } \
194  ras_fsmState=S0;
195  #pragma HLS RESET variable=ras_fsmState
196  static ap_uint<8 > ras_metaDropCounter=0;
197  #pragma HLS reset variable=ras_metaDropCounter
198 
199  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
200  static TcpSegLen ras_readLength;
201 
202  switch (ras_fsmState) {
203  case S0:
204  if (!siTAIF_DataReq.empty() and !soRSt_RxSarQry.full()) {
205  TcpAppRdReq appReadRequest = siTAIF_DataReq.read();
206  if (appReadRequest.length != 0) {
207  // Make sure length is not 0, otherwise Data Mover will hang
208  soRSt_RxSarQry.write(RAiRxSarQuery(appReadRequest.sessionID));
209  ras_readLength = appReadRequest.length;
210  ras_fsmState = S1;
211  }
212  else {
213  // Do nothing but return the metadata to avoid blocking the APP
214  if (!soTAIF_Meta.full()) {
215  soTAIF_Meta.write(appReadRequest.sessionID);
216  }
217  else {
218  // Drop this metadata and increment the Meta Drop Counter
219  ras_metaDropCounter++;
220  printFatal(myName, "Cannot write 'soTAIF_Meta()'. Stream is full!");
221  }
222  }
223  }
224  break;
225  case S1:
226  if (!siRSt_RxSarRep.empty() and
227  !soMrd_MemRdCmd.full() and !soRSt_RxSarQry.full()) {
228  RAiRxSarReply rxSarRep = siRSt_RxSarRep.read();
229  // Signal that the data request has been processed by sending the SessId back to [TAIF]
230  if (!soTAIF_Meta.full()) {
231  soTAIF_Meta.write(rxSarRep.sessionID);
232  }
233  else {
234  // Drop this metadata and increment the Meta Drop Counter
235  ras_metaDropCounter++;
236  printFatal(myName, "Cannot write 'soTAIF_Meta()'. Stream is full!");
237  }
238  // Generate a memory buffer read command
239  RxMemPtr memSegAddr = TOE_RX_MEMORY_BASE;
240  memSegAddr(29, 16) = rxSarRep.sessionID(13, 0);
241  memSegAddr(15, 0) = rxSarRep.appd;
242  soMrd_MemRdCmd.write(DmCmd(memSegAddr, ras_readLength));
243  // Update the APP read pointer
244  soRSt_RxSarQry.write(RAiRxSarQuery(rxSarRep.sessionID, rxSarRep.appd+ras_readLength));
245  ras_fsmState = S0;
246  }
247  break;
248  }
249 
250  //-- ALWAYS
251  if (!soMMIO_MetaDropCnt.full()) {
252  soMMIO_MetaDropCnt.write(ras_metaDropCounter);
253  }
254  else {
255  printFatal(myName, "Cannot write soMMIO_MetaDropCnt stream...");
256  }
257 }
SessionId sessionID
Definition: toe.hpp:431
RxBufPtr appd
Definition: toe.hpp:432
TcpDatLen length
Definition: nts.hpp:117
SessionId sessionID
Definition: nts.hpp:116
Here is the caller graph for this function:

◆ pRxMemoryReader()

void pRxMemoryReader ( stream< DmCmd > &  siRas_MemRdCmd,
stream< DmCmd > &  soMEM_RxpRdCmd,
stream< FlagBool > &  soAss_SplitSeg 
)

Rx Memory Reader (Mrd)

Parameters
[in]siRas_MemRdCmdRx memory read command from RxAppStream (Ras).
[out]soMEM_RxpRdCmdRx memory read command to [MEM].
[out]soAss_SplitSegSplit segment to AppSegmentStitcher (Ass).

This process takes the memory read command assembled by RxAppStream (Ras) an forwards it to the memory sub-system (MEM). While doing so, it checks if the TCP Rx memory buffer wraps around and accordingly generates two memory read commands out of the initial command received from [Ras]. Because the AppSegmetStitcher (Ass) process needs to be aware of this split, a signal is sent to [Ass] telling whether a data segment was broken in two Rx memory buffers or is provided as a single buffer.

Definition at line 275 of file rx_app_interface.cpp.

279 {
280  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
281  #pragma HLS PIPELINE II=1 enable_flush
282  #pragma HLS INLINE off
283 
284  const char *myName = concat3(THIS_NAME, "/", "Mrd");
285 
286  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
287  static enum FsmState { MRD_1ST_ACCESS=0, MRD_2ND_ACCESS } \
288  mrd_fsmState=MRD_1ST_ACCESS;
289  #pragma HLS RESET variable=mrd_fsmState
290 
291  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
292  static DmCmd mrd_memRdCmd;
293  static RxBufPtr mrd_firstAccLen;
294  static uint16_t mrd_debugCounter=1;
295 
296  switch (mrd_fsmState) {
297  case MRD_1ST_ACCESS:
298  if (!siRas_MemRdCmd.empty() and !soAss_SplitSeg.full() and !soMEM_RxpRdCmd.full() ) {
299  siRas_MemRdCmd.read(mrd_memRdCmd);
300 
301  if ((mrd_memRdCmd.saddr.range(TOE_WINDOW_BITS-1, 0) + mrd_memRdCmd.btt) > TOE_RX_BUFFER_SIZE) {
302  // This segment was broken in two memory accesses because TCP Rx memory buffer wrapped around
303  mrd_firstAccLen = TOE_RX_BUFFER_SIZE - mrd_memRdCmd.saddr;
304  mrd_fsmState = MRD_2ND_ACCESS;
305 
306  soMEM_RxpRdCmd.write(DmCmd(mrd_memRdCmd.saddr, mrd_firstAccLen));
307  soAss_SplitSeg.write(true);
308 
309  if (DEBUG_LEVEL & TRACE_MRD) {
310  printInfo(myName, "TCP Rx memory buffer wraps around: This segment is broken in two memory accesses.\n");
311  printInfo(myName, "Issuing 1st memory read command #%d - SADDR=0x%9.9lx - BTT=%d\n",
312  mrd_debugCounter, mrd_memRdCmd.saddr.to_ulong(), mrd_firstAccLen.to_uint());
313  }
314  }
315  else {
316  soMEM_RxpRdCmd.write(mrd_memRdCmd);
317  soAss_SplitSeg.write(false);
318 
319  if (DEBUG_LEVEL & TRACE_MRD) {
320  printInfo(myName, "Issuing memory read command #%d - SADDR=0x%9.9lx - BTT=%d\n",
321  mrd_debugCounter, mrd_memRdCmd.saddr.to_ulong(), mrd_memRdCmd.btt.to_uint());
322  mrd_debugCounter++;
323  }
324  }
325  }
326  break;
327  case MRD_2ND_ACCESS:
328  if (!soMEM_RxpRdCmd.full()) {
329  // Update the command to account for the Rx buffer wrap around
330  mrd_memRdCmd.saddr(TOE_WINDOW_BITS-1, 0) = 0;
331  soMEM_RxpRdCmd.write(DmCmd(mrd_memRdCmd.saddr, mrd_memRdCmd.btt - mrd_firstAccLen));
332 
333  mrd_fsmState = MRD_1ST_ACCESS;
334 
335  if (DEBUG_LEVEL & TRACE_MRD) {
336  printInfo(myName, "Issuing 2nd memory read command #%d - SADDR=0x%9.9lx - BTT=%d\n",
337  mrd_debugCounter, mrd_memRdCmd.saddr.to_ulong(),
338  (mrd_memRdCmd.btt - mrd_firstAccLen).to_uint());
339  mrd_debugCounter++;
340  }
341  }
342  break;
343  }
344 }
ap_uint< 40 > saddr
ap_uint< 23 > btt
Definition: mem.hpp:85
#define TRACE_MRD
Here is the caller graph for this function:

◆ pRxMemoryWriter()

void pRxMemoryWriter ( stream< AxisApp > &  siTsd_Data,
stream< DmCmd > &  siFsm_MemWrCmd,
stream< DmCmd > &  soMEM_WrCmd,
stream< AxisApp > &  soMEM_WrData,
stream< FlagBool > &  soRan_SplitSeg 
)

Rx Memory Writer (Mwr)

Parameters
[in]siTsd_DataTcp data stream from the Tcp SegmentDropper (Tid).
[in]siFsm_MemWrCmdMemory write command from the FiniteStateMachine (Fsm).
[out]soMEM_WrCmdMemory write command to the data mover of Memory sub-system (MEM).
[out]soMEM_WrDataMemory data write stream to [MEM].
[out]soRan_SplitSegSplit segment flag to RxAppNotifier (Ran).

This is the front end memory controller process for writing the received TCP data segments into the external DRAM. Memory write commands are received from the FiniteStetMachine (Fsm) and are transferred to the data-mover of the memory sub-system (MEM). The Rx buffer memory is organized and managed as a circular buffer, and it may happen that the received segment does not fit into remain memory buffer space because the memory pointer needs to wrap around. In such a case, the incoming segment is broken down and written into physical DRAM as two memory buffers, and the follow-on RxAppNotifier (Ran) process is notified about this splitted segment

Definition at line 859 of file rx_engine.cpp.

865 {
866  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
867  #pragma HLS PIPELINE II=1 enable_flush
868  #pragma HLS INLINE off
869 
870  const char *myName = concat3(THIS_NAME, "/", "Mwr");
871 
872  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
873  static enum FsmStates { MWR_IDLE=0,
874  MWR_FWD_ALIGNED, MWR_SPLIT_1ST_CMD,
875  MWR_FWD_1ST_BUF, MWR_FWD_2ND_BUF, MWR_RESIDUE } \
876  mwr_fsmState=MWR_IDLE;
877  #pragma HLS RESET variable=mwr_fsmState
878  static ap_uint<3> mwr_residueLen=0;
879  #pragma HLS RESET variable=mwr_residueLen
880  static bool mwr_accessBreakdown=false;
881  #pragma HLS RESET variable=mwr_accessBreakdown
882 
883  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
884  static DmCmd mwr_memWrCmd;
885  static AxisApp mwr_currChunk;
886  static RxBufPtr mwr_firstAccLen;
887  static TcpSegLen mwr_nrBytesToWr;
888  static ap_uint<4> mwr_splitOffset;
889  static uint16_t mwr_debugCounter=3; // To align with # in the DAT file
890 
891  switch (mwr_fsmState) {
892  case MWR_IDLE:
893  if (!siFsm_MemWrCmd.empty() and !soRan_SplitSeg.full() and !soMEM_WrCmd.full()) {
894  siFsm_MemWrCmd.read(mwr_memWrCmd);
895  if ((mwr_memWrCmd.saddr.range(TOE_WINDOW_BITS-1, 0) + mwr_memWrCmd.btt) > TOE_RX_BUFFER_SIZE) {
896  //-- Break this segment in two memory accesses because TCP Rx memory buffer wraps around
897  soRan_SplitSeg.write(true);
898 
899  if (DEBUG_LEVEL & TRACE_MWR) {
900  printInfo(myName, "TCP Rx memory buffer wraps around: This segment will be broken in two memory buffers.\n");
901  }
902  mwr_fsmState = MWR_SPLIT_1ST_CMD;
903  }
904  else {
905  //-- Don't split and issue the write command
906  soRan_SplitSeg.write(false);
907  soMEM_WrCmd.write(mwr_memWrCmd);
908 
909  if (DEBUG_LEVEL & TRACE_MWR) {
910  printInfo(myName, "Issuing memory write command #%d - SADDR=0x%9.9x - BTT=%d\n",
911  mwr_debugCounter, mwr_memWrCmd.saddr.to_uint(), mwr_memWrCmd.btt.to_uint());
912  mwr_debugCounter++;
913  }
914  mwr_fsmState = MWR_FWD_ALIGNED;
915  }
916  }
917  break;
918  case MWR_SPLIT_1ST_CMD:
919  if (!soMEM_WrCmd.full()) {
920  mwr_firstAccLen = TOE_RX_BUFFER_SIZE - mwr_memWrCmd.saddr;
921  mwr_nrBytesToWr = mwr_firstAccLen;
922  soMEM_WrCmd.write(DmCmd(mwr_memWrCmd.saddr, mwr_firstAccLen));
923 
924  if (DEBUG_LEVEL & TRACE_MWR) {
925  printInfo(myName, "Issuing 1st memory write command #%d - SADDR=0x%9.9x - BTT=%d\n",
926  mwr_debugCounter, mwr_memWrCmd.saddr.to_uint(), mwr_firstAccLen.to_uint());
927  }
928  mwr_fsmState = MWR_FWD_1ST_BUF;
929  }
930  break;
931  case MWR_FWD_ALIGNED:
932  if (!siTsd_Data.empty() and !soMEM_WrData.full()) {
933  //-- Default streaming state used to forward segments or splitted buffers
934  //-- that are aligned with the Axis raw width
935  AxisApp memChunk = siTsd_Data.read();
936  soMEM_WrData.write(memChunk);
937  if (memChunk.getTLast()) {
938  mwr_fsmState = MWR_IDLE;
939  }
940 
941  if (DEBUG_LEVEL & TRACE_MWR) { printAxisRaw(myName, "FWD_ALIGNED: soMEM_WrData =", memChunk); }
942  }
943  break;
944  case MWR_FWD_1ST_BUF:
945  if (!siTsd_Data.empty() and !soMEM_WrData.full()) {
946  //-- Create 1st splitted data buffer and stream it to memory
947  siTsd_Data.read(mwr_currChunk);
948  AxisApp memChunk = mwr_currChunk;
949  if (mwr_nrBytesToWr > (ARW/8)) {
950  mwr_nrBytesToWr -= (ARW/8);
951  }
952  else if (!soMEM_WrCmd.full()) {
953  if (mwr_nrBytesToWr == (ARW/8)) {
954  //-- End of 1st segment and begin of 2nd segment are aligned
955  memChunk.setLE_TLast(TLAST);
956 
957  //-- Prepare and issue 2nd command
958  mwr_memWrCmd.saddr(TOE_WINDOW_BITS-1, 0) = 0;
959  mwr_memWrCmd.btt -= mwr_firstAccLen;
960  soMEM_WrCmd.write(mwr_memWrCmd);
961 
962  if (DEBUG_LEVEL & TRACE_MWR) {
963  printInfo(myName, "Issuing 2nd memory write command #%d - SADDR=0x%9.9x - BTT=%d\n",
964  mwr_debugCounter, mwr_memWrCmd.saddr.to_uint(), mwr_memWrCmd.btt.to_uint());
965  mwr_debugCounter++;
966  }
967  mwr_fsmState = MWR_FWD_ALIGNED;
968  }
969  else {
970  //-- End of 1st segment and begin of 2nd segment not aligned
971  memChunk.setLE_TLast(TLAST);
972  memChunk.setLE_TKeep(lenToLE_tKeep(mwr_nrBytesToWr));
973  #ifndef __SYNTHESIS__
974  memChunk.setLE_TData(0, (ARW-1), ((int)mwr_nrBytesToWr*8));
975  #endif
976 
977  //-- Prepare and issue 2nd command
978  mwr_memWrCmd.saddr(TOE_WINDOW_BITS-1, 0) = 0;
979  mwr_memWrCmd.btt -= mwr_firstAccLen;
980  soMEM_WrCmd.write(mwr_memWrCmd);
981 
982  if (DEBUG_LEVEL & TRACE_MWR) {
983  printInfo(myName, "Issuing 2nd memory write command #%d - SADDR=0x%9.9x - BTT=%d\n",
984  mwr_debugCounter, mwr_memWrCmd.saddr.to_uint(), mwr_memWrCmd.btt.to_uint());
985  mwr_debugCounter++;
986  }
987  mwr_splitOffset = (ARW/8) - mwr_nrBytesToWr;
988  if (mwr_currChunk.getLE_TLast()) {
989  mwr_fsmState = MWR_RESIDUE;
990  }
991  else {
992  mwr_fsmState = MWR_FWD_2ND_BUF;
993  }
994  }
995  }
996 
997  soMEM_WrData.write(memChunk);
998  if (DEBUG_LEVEL & TRACE_MWR) { printAxisRaw(myName, "FWD_1ST_BUF: soMEM_WrData =", memChunk); }
999  }
1000  break;
1001  case MWR_FWD_2ND_BUF:
1002  if (!siTsd_Data.empty() && !soMEM_WrData.full()) {
1003  //-- Alternate streaming state used to re-align a splitted second buffer
1004  AxisApp prevChunk = mwr_currChunk;
1005  mwr_currChunk = siTsd_Data.read();
1006 
1007  AxisApp joinedChunk(0,0,0); // [FIXME-Create a join method in AxisRaw]
1008  // Set lower-part of the joined chunk with the last bytes of the previous chunk
1009  joinedChunk.setLE_TData(prevChunk.getLE_TData((ARW )-1, ((ARW )-((int)mwr_splitOffset*8))),
1010  ((int)mwr_splitOffset*8)-1, 0);
1011  joinedChunk.setLE_TKeep(prevChunk.getLE_TKeep((ARW/8)-1, ((ARW/8)-((int)mwr_splitOffset ))),
1012  ((int)mwr_splitOffset )-1, 0);
1013  // Set higher part of the joined chunk with the first bytes of the current chunk
1014  joinedChunk.setLE_TData(mwr_currChunk.getLE_TData((ARW )-((int)mwr_splitOffset*8)-1, 0),
1015  (ARW ) -1, ((int)mwr_splitOffset*8));
1016  joinedChunk.setLE_TKeep(mwr_currChunk.getLE_TKeep((ARW/8)-((int)mwr_splitOffset )-1, 0),
1017  (ARW/8) -1, ((int)mwr_splitOffset ));
1018  if (mwr_currChunk.getLE_TLast()) {
1019  if (mwr_currChunk.getLen() > mwr_nrBytesToWr) {
1020  // This cannot be the last chunk because the current one plus
1021  // the remainder of the previous one do not fit into a single chunk.
1022  // Goto the 'MWR_RESIDUE' and handle the remainder of that chunk.
1023  mwr_fsmState = MWR_RESIDUE;
1024  }
1025  else {
1026  // The entire current chunk and the remainder of the previous chunk
1027  // fit into a single chunk. We are done with this 2nd memory buffer.
1028  joinedChunk.setLE_TLast(TLAST);
1029  mwr_fsmState = MWR_IDLE;
1030  }
1031  }
1032  soMEM_WrData.write(joinedChunk);
1033  if (DEBUG_LEVEL & TRACE_MWR) { printAxisRaw(myName, "FWD_2ND_BUF: soMEM_WrData =", joinedChunk); }
1034  }
1035  break;
1036  case MWR_RESIDUE:
1037  if (!soMEM_WrData.full()) {
1038  //-- Output the very last unaligned chunk
1039  AxisApp prevChunk = mwr_currChunk;
1040  AxisApp lastChunk(0,0,0);
1041 
1042  // Set lower-part of the last chunk with the last bytes of the previous chunk
1043  lastChunk.setLE_TData(prevChunk.getLE_TData((ARW )-1, ((ARW )-((int)mwr_splitOffset*8))),
1044  ((int)mwr_splitOffset*8)-1, 0);
1045  lastChunk.setLE_TKeep(prevChunk.getLE_TKeep((ARW/8)-1, ((ARW/8)-((int)mwr_splitOffset ))),
1046  ((int)mwr_splitOffset )-1, 0);
1047  lastChunk.setLE_TLast(TLAST);
1048  soMEM_WrData.write(lastChunk);
1049 
1050  if (DEBUG_LEVEL & TRACE_MWR) { printAxisRaw(myName, "RESIDUE : soMEM_WrData =", lastChunk); }
1051  mwr_fsmState = MWR_IDLE;
1052  }
1053  break;
1054  }
1055 }
#define TRACE_MWR
Definition: rx_engine.cpp:79
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
Here is the caller graph for this function:

◆ pSessionIdManager()

void pSessionIdManager ( stream< RtlSessId > &  siUrs_FreeId,
stream< RtlSessId > &  soLrh_FreeList 
)

Session Id Manager (Sim)

Parameters
[in]siUrs_FreeIdThe session ID to recycle from the UpdateRequestSender (Urs).
[out]soLrh_FreeListThe free list of session IDs to LookupReplyHandler (Lrh).

Implements the free list of session IDs as a FiFo stream.

Definition at line 89 of file session_lookup_controller.cpp.

92 {
93  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
94  #pragma HLS PIPELINE II=1 enable_flush
95  #pragma HLS INLINE off
96 
97  const char *myName = concat3(THIS_NAME, "/", "Sim");
98 
99  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
100  static RtlSessId sim_counter=0;
101  #pragma HLS reset variable=sim_counter
102 
103  if (sim_counter < TOE_MAX_SESSIONS) {
104  // Initialize the free list after a reset
105  soLrh_FreeList.write(sim_counter);
106  sim_counter++;
107  }
108  else if (!siUrs_FreeId.empty()) {
109  // Recycle the incoming session ID
110  RtlSessId rtlSessId;
111  siUrs_FreeId.read(rtlSessId);
112  soLrh_FreeList.write(rtlSessId);
113  }
114 }
Here is the caller graph for this function:

◆ pSocketPairSplitter()

void pSocketPairSplitter ( stream< fourTuple > &  siSLc_ReverseLkpRsp,
stream< LE_SocketPair > &  siMdl_RstSockPair,
stream< StsBool > &  siMdl_IsLookup,
stream< IpAddrPair > &  soIhc_IpAddrPair,
stream< SocketPair > &  soPhc_SocketPair 
)

Socket Pair Splitter (Sps)

Parameters
[in]siSLc_ReverseLkpRspReverse lookup response from SessionLookupController (SLc).
[in]siMdl_RstSockPairThe socket pair to reset from MetaDataLoader (Mdh).
[in]siMdl_IsLookupStatus from [Mdl] indicating that a reverse lookup is to be expected.
[out]soIhc_IpAddrPairIP_SA and IP_DA to IpHeaderConstructor (Ihc).
[out]soPhc_SocketPairThe socket pair to PseudoHeaderConstructor (Phc).

This process forwards the incoming socket-pair from the CAM or the RxEngine to both the IpHeaderConstructor (Ihc) and the PseudoHeaderConstructor (Phc).

Definition at line 624 of file tx_engine.cpp.

630 {
631  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
632  #pragma HLS PIPELINE II=1 enable_flush
633  #pragma HLS INLINE off
634 
635  const char *myName = concat3(THIS_NAME, "/", "Sps");
636 
637  //-- STATIC CONTROL VARIABLES (with RESET) --------------------------------
638  static bool sps_getMeta=false;
639  #pragma HLS RESET variable=sps_getMeta
640 
641  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
642  static StsBool sps_isLookUp;
643 
644  //-- DYNAMIC VARIABLES ----------------------------------------------------
645  fourTuple tuple;
646 
647  if (not sps_getMeta) {
648  if (!siMdl_IsLookup.empty()) {
649  siMdl_IsLookup.read(sps_isLookUp);
650  sps_getMeta = true;
651  }
652  }
653  else {
654  if (!siSLc_ReverseLkpRsp.empty() && sps_isLookUp) {
655  siSLc_ReverseLkpRsp.read(tuple);
656  SocketPair socketPair(SockAddr(byteSwap32(tuple.srcIp),
657  byteSwap16(tuple.srcPort)),
658  SockAddr(byteSwap32(tuple.dstIp),
659  byteSwap16(tuple.dstPort)));
660  if (DEBUG_LEVEL & TRACE_SPS) {
661  printInfo(myName, "Received the following socket-pair from [SLc]: \n");
662  printSockPair(myName, socketPair);
663  }
664  soIhc_IpAddrPair.write(IpAddrPair(socketPair.src.addr, socketPair.dst.addr));
665  soPhc_SocketPair.write(socketPair);
666  sps_getMeta = false;
667  }
668  else if(!siMdl_RstSockPair.empty() && !sps_isLookUp) {
669  LE_SocketPair leSocketPair;
670  siMdl_RstSockPair.read(leSocketPair);
671  SocketPair socketPair = SocketPair(SockAddr(byteSwap32(leSocketPair.src.addr),
672  byteSwap16(leSocketPair.src.port)),
673  SockAddr(byteSwap32(leSocketPair.dst.addr),
674  byteSwap16(leSocketPair.dst.port)));
675  if (DEBUG_LEVEL & TRACE_SPS) {
676  printInfo(myName, "Received the following socket-pair from [Mdl]: \n");
677  printSockPair(myName, socketPair);
678  }
679  soIhc_IpAddrPair.write(IpAddrPair(socketPair.src.addr, socketPair.dst.addr));
680  soPhc_SocketPair.write(socketPair);
681  sps_getMeta = false;
682  }
683  }
684 }
#define TRACE_SPS
Definition: tx_engine.cpp:74
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pStreamMetaLoader()

void pStreamMetaLoader ( stream< TcpAppSndReq > &  siTAIF_SndReq,
stream< TcpAppSndRep > &  soTAIF_SndRep,
stream< SessionId > &  soSTt_SessStateReq,
stream< TcpState > &  siSTt_SessStateRep,
stream< TxAppTableQuery > &  soTat_AccessReq,
stream< TxAppTableReply > &  siTat_AccessRep,
stream< AppMemMeta > &  soMwr_AppMeta,
stream< Event > &  soEmx_Event 
)

Stream Metadata Loader (Sml)

Parameters
[in]siTAIF_SndReqAPP request to send from [TAIF].
[out]soTAIF_SndRepAPP send reply to [TAIF].
[out]soSTt_SessStateReqSession state request to StateTable (STt).
[in]siSTt_SessStateRepSession state reply from StateTable (STt).
[out]soTat_AccessReqAccess request to TxAppTable (Tat).
[in]siTat_AccessRepAccess reply from [Tat]
[out]soMwr_AppMetaAPP memory metadata to MemoryWriter (Mwr).
[out]soEmx_EventEvent to EventMultiplexer (Emx).

The FSM of this process decides if the incoming application data is written to the TX buffer in DDR4 memory. The process reads the request to send from the application and loads the necessary metadata from the [Tat] for transmitting this data. A request to send consists of a session-id and a data-length information. Once this request is received from [TAIF], the state of the connection is checked as well as the available memory space, and a reply is sent back to [TAIF]. 1) If the return code is 'NO_ERROR', the application is allowed to send. In that case, the segment memory pointer is loaded into the TxAppTable and the segment's metadata is forwarded to MemoryWriter (Mwr) process which will use it to write the incoming data stream into DDR4 memory. 2) If there is not enough space available in the Tx buffer of the session, the application can either retry its request later or decide to abandon the transmission. 3) It the connection is not established, the application will be noticed it should act accordingly (e.g. by first opening the connection).

Warning
The outgoing stream 'soTAIF_SndRep is operated in non-blocking mode to avoid any stalling of this process. This means that the current reply to be sent on this stream will be dropped if the stream is full. As a result, the application process must provision enough buffering to store the reply returned by this process upon a request to send.

[TODO: Implement TCP_NODELAY]

Definition at line 456 of file tx_app_interface.cpp.

465 {
466  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
467  #pragma HLS pipeline II=1 enable_flush
468 
469  const char *myName = concat3(THIS_NAME, "/", "Mdl");
470 
471  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
472  static enum FsmStates { READ_REQUEST=0, READ_META } \
473  mdl_fsmState = READ_REQUEST;
474  #pragma HLS reset variable = mdl_fsmState
475 
476  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
477  static TcpAppSndReq mdl_appSndReq;
478 
479  //-- DYNAMIC VARIABLES -----------------------------------------------------
480  TxAppTableReply txAppTableReply;
481  TcpState sessState;
482 
483  switch(mdl_fsmState) {
484  case READ_REQUEST:
485  if (!siTAIF_SndReq.empty()) {
486  // Read the request to send
487  siTAIF_SndReq.read(mdl_appSndReq);
488  // Request state of the session
489  assessSize(myName, soSTt_SessStateReq, "soSTt_SessStateReq", 2); // [FIXME-Use constant for the length]
490  soSTt_SessStateReq.write(mdl_appSndReq.sessId);
491  // Request the value of ACK and MemPtr from TxAppTable
492  assessSize(myName, soTat_AccessReq, "soTat_AccessReq", 2); // [FIXME-Use constant for the length]
493  soTat_AccessReq.write(TxAppTableQuery(mdl_appSndReq.sessId));
494  if (DEBUG_LEVEL & TRACE_SML) {
495  printInfo(myName, "Received new Tx request for session %d.\n", mdl_appSndReq.sessId.to_int());
496  }
497  mdl_fsmState = READ_META;
498  }
499  break;
500  case READ_META:
501  if (!siTat_AccessRep.empty() and !siSTt_SessStateRep.empty()) {
502  siSTt_SessStateRep.read(sessState);
503  siTat_AccessRep.read(txAppTableReply);
504  TcpDatLen maxWriteLength = (txAppTableReply.ackd - txAppTableReply.mempt) - 1;
505 
514  if (!soTAIF_SndRep.full()) {
515  if (sessState != ESTABLISHED) {
516  // Notify APP about the none-established connection
517  soTAIF_SndRep.write(TcpAppSndRep(mdl_appSndReq.sessId, mdl_appSndReq.length, maxWriteLength, NO_CONNECTION));
518  printError(myName, "Session %d is not established. Current session state is \'%s\'.\n",
519  mdl_appSndReq.sessId.to_uint(), getTcpStateName(sessState));
520  }
521  else if (mdl_appSndReq.length > maxWriteLength) {
522  // Notify APP about the lack of space
523  soTAIF_SndRep.write(TcpAppSndRep(mdl_appSndReq.sessId, mdl_appSndReq.length, maxWriteLength, NO_SPACE));
524  printError(myName, "There is not enough TxBuf memory space available for session %d.\n",
525  mdl_appSndReq.sessId.to_uint());
526  }
527  else { //-- Session is ESTABLISHED and data-length <= maxWriteLength
528  // Forward the metadata to the SegmentMemoryWriter (Mwr)
529  soMwr_AppMeta.write(AppMemMeta(mdl_appSndReq.sessId, txAppTableReply.mempt, mdl_appSndReq.length));
530  // Notify APP about acceptance of the transmission
531  soTAIF_SndRep.write(TcpAppSndRep(mdl_appSndReq.sessId, mdl_appSndReq.length, maxWriteLength, NO_ERROR));
532  // Notify [TXe] about new data to be sent via an event to [EVe]
533  assessSize(myName, soEmx_Event, "soEmx_Event", 2); // [FIXME-Use constant for the length]
534  soEmx_Event.write(Event(TX_EVENT, mdl_appSndReq.sessId, txAppTableReply.mempt, mdl_appSndReq.length));
535  // Update the 'txMemPtr' in TxAppTable
536  soTat_AccessReq.write(TxAppTableQuery(mdl_appSndReq.sessId, txAppTableReply.mempt + mdl_appSndReq.length));
537  }
538  }
539  else {
540  // Drop this reply
541  printFatal(myName, "Cannot write 'soTAIF_SndRep()'. Stream is full!");
542  }
543  mdl_fsmState = READ_REQUEST;
544  }
545  break;
546  }
547 }
TcpDatLen length
Definition: nts.hpp:130
SessionId sessId
Definition: nts.hpp:129
ap_uint< 16 > ackd
Definition: toe.hpp:604
TxBufPtr mempt
Definition: toe.hpp:605
#define TRACE_SML
const char * getTcpStateName(TcpState tcpState)
Returns the name of an enum-based TCP-State as a user friendly string.
Definition: nts_utils.cpp:272
@ NO_ERROR
Definition: nts_types.hpp:304
@ NO_CONNECTION
Definition: nts_types.hpp:304
@ NO_SPACE
Definition: nts_types.hpp:304
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pStreamMux()

template<typename T >
void pStreamMux ( stream< T > &  si1,
stream< T > &  si2,
stream< T > &  so 
)

A 2-to-1 generic Stream Multiplexer.

Parameters
[in]si1The input stream #1.
[in]si2The input stream #2.
[out]soThe output stream.

This multiplexer behaves like an arbiter. It takes two streams as inputs and forwards one of them to the output channel. The stream connected to the first input always takes precedence over the second one.

Definition at line 90 of file timers.cpp.

94 {
95  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
96  #pragma HLS PIPELINE II=1 enable_flush
97  #pragma HLS INLINE off
98 
99  if (!si1.empty())
100  so.write(si1.read());
101  else if (!si2.empty())
102  so.write(si2.read());
103 }
Here is the caller graph for this function:

◆ pSubChecksumAccumulators()

void pSubChecksumAccumulators ( stream< AxisPsd4 > &  siTss_PseudoPkt,
stream< AxisPsd4 > &  soIps_PseudoPkt,
stream< SubCSums > &  soTca_4SubCsums 
)

Sub-Checksum Accumulator (Sca)

Parameters
[in]siTss_PseudoPktIncoming data stream from Tc pSegment Stitcher (Tss).
[out]soIps_PseudoPktOutgoing data stream to IP Packet Stitcher (Ips).
[out]soTca_4SubCsumsFour sub-checksums to Tcp Checksum Accumulator (Tca).

This process takes a TCP pseudo packet as input from the TcpSegmentStitcher (Tss) and forwards it to the IpPacketStitcher (Ips) while accumulating 4 sub-checksums on the fly. When the the end-of-packet is detected, these 4 sub-checksums are forwarded to the TcpChecksumAccumulator (Tca) for final checksum computation.

Definition at line 1206 of file tx_engine.cpp.

1210 {
1211  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1212  #pragma HLS INLINE off
1213  #pragma HLS PIPELINE II=1 enable_flush
1214 
1215  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1216  static bool sca_doForwardChunk=false;
1217  #pragma HLS RESET variable=sca_doForwardChunk
1218  static ap_uint<17> sca_4CSums[4]={0, 0, 0, 0};
1219  #pragma HLS RESET variable=sca_4CSums
1220  #pragma HLS ARRAY_PARTITION \
1221  variable=sca_4CSums complete dim=1
1222 
1223  //-- DYNAMIC VARIABLES -----------------------------------------------------
1224  AxisPsd4 currPktChunk;
1225 
1226  if (!siTss_PseudoPkt.empty()) {
1227  siTss_PseudoPkt.read(currPktChunk);
1228  if (sca_doForwardChunk) {
1229  // We do not forward the first chunk of the pseudo-header
1230  // [FIXME] Consider forwarding all chunks and drop the 1st in the next process.
1231  soIps_PseudoPkt.write(currPktChunk);
1232  }
1233  for (int i = 0; i < 4; i++) {
1234  #pragma HLS UNROLL
1235  TcpCsum temp;
1236  if (currPktChunk.getLE_TKeep(i*2+1, i*2) == 0x3) {
1237  temp( 7, 0) = currPktChunk.getLE_TData(i*16+15, i*16+8);
1238  temp(15, 8) = currPktChunk.getLE_TData(i*16+ 7, i*16);
1239  sca_4CSums[i] += temp;
1240  sca_4CSums[i] = (sca_4CSums[i] + (sca_4CSums[i] >> 16)) & 0xFFFF;
1241  }
1242  else if (currPktChunk.getLE_TKeep()[i*2] == 0x1) {
1243  temp( 7, 0) = 0;
1244  temp(15, 8) = currPktChunk.getLE_TData(i*16+7, i*16);
1245  sca_4CSums[i] += temp;
1246  sca_4CSums[i] = (sca_4CSums[i] + (sca_4CSums[i] >> 16)) & 0xFFFF;
1247  }
1248  }
1249 
1250  sca_doForwardChunk = true;
1251 
1252  if(currPktChunk.getTLast()) {
1253  soTca_4SubCsums.write(sca_4CSums);
1254  sca_doForwardChunk = false;
1255  sca_4CSums[0] = 0;
1256  sca_4CSums[1] = 0;
1257  sca_4CSums[2] = 0;
1258  sca_4CSums[3] = 0;
1259  }
1260  }
1261 } // End-of: Sca
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pTbSimCount()

void pTbSimCount ( volatile ap_uint< 32 > &  poSimCycCount)

Testbench Simulation Counter.

Parameters
[out]poSimCycCountThe incremented simulation counter.

This process is provided for debugging only. It allows to implement the simulation a counter of the testbench within the TOE itself.

Definition at line 156 of file toe.cpp.

158 {
159  //-- STATIC CONTROL VARIABLES (with RESET) --------------------------------
160  #ifdef __SYNTHESIS__
161  static ap_uint<32> sCounter = 0xFFFFFFF9;
162  #else
163  static ap_uint<32> sCounter = 0x00000000;
164  #endif
165  #pragma HLS reset variable=sCounter
166 
167  sCounter += 1;
168  // [Un-comment this line ]poSimCycCount = sCounter;
169 }
Here is the caller graph for this function:

◆ pTcpChecksumAccumulator()

void pTcpChecksumAccumulator ( stream< SubCSums > &  siSca_FourSubCsums,
stream< TcpChecksum > &  soIps_TcpCsum 
)

TCP Checksum Accumulator (Tca)

Parameters
[in]siSca_FourSubCsumsThe 4 sub-csums from the Sub-Checksum Accumulator (Sca).
[out]soIps_TcpCsumThe computed checksum to IP Packet Stitcher (Ips).

Computes the final TCP checksum from the 4 accumulated sub-checksums and forwards the results to the IP Packet Stitcher (Ips).

Definition at line 1274 of file tx_engine.cpp.

1277 {
1278  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1279  #pragma HLS INLINE off
1280  #pragma HLS PIPELINE II=1 enable_flush
1281 
1282  const char *myName = concat3(THIS_NAME, "/", "Tca");
1283 
1284  if (!siSca_FourSubCsums.empty()) {
1285  SubCSums tca_4CSums = siSca_FourSubCsums.read();
1286 
1287  tca_4CSums.sum0 += tca_4CSums.sum2;
1288  tca_4CSums.sum1 += tca_4CSums.sum3;
1289  tca_4CSums.sum0 = (tca_4CSums.sum0 + (tca_4CSums.sum0 >> 16)) & 0xFFFF;
1290  tca_4CSums.sum1 = (tca_4CSums.sum1 + (tca_4CSums.sum1 >> 16)) & 0xFFFF;
1291  tca_4CSums.sum0 += tca_4CSums.sum1;
1292  tca_4CSums.sum0 = (tca_4CSums.sum0 + (tca_4CSums.sum0 >> 16)) & 0xFFFF;
1293  tca_4CSums.sum0 = ~tca_4CSums.sum0;
1294 
1295  if (DEBUG_LEVEL & TRACE_TCA) {
1296  printInfo(myName, "Checksum =0x%4.4X\n", tca_4CSums.sum0.to_uint());
1297  }
1298  soIps_TcpCsum.write(tca_4CSums.sum0);
1299  }
1300 }
#define TRACE_TCA
Definition: tx_engine.cpp:79
ap_uint< 17 > sum3
Definition: tx_engine.hpp:101
ap_uint< 17 > sum0
Definition: tx_engine.hpp:98
ap_uint< 17 > sum1
Definition: tx_engine.hpp:99
ap_uint< 17 > sum2
Definition: tx_engine.hpp:100
Here is the caller graph for this function:

◆ pTcpInvalidDropper()

void pTcpInvalidDropper ( stream< AxisApp > &  siCsa_Data,
stream< ValBit > &  siCsa_DataVal,
stream< AxisApp > &  soTsd_Data,
stream< ap_uint< 8 > > &  soMMIO_CrcDropCnt 
)

TCP Invalid checksum Dropper (Tid)

Parameters
[in]siCsa_DataTCP data stream from CheckSumAccumulator (Csa).
[in]siCsa_DataValTCP data segment valid.
[out]soTsd_DataTCP data stream to TcpSegmentDropper (Tsd).
[out]soMMIO_CrcDropCntThe value of the CRC drop counter.

This process drops the incoming TCP segment when it is flagged with an invalid checksum. Otherwise, the TCP segment is passed on.

Definition at line 695 of file rx_engine.cpp.

700 {
701  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
702  #pragma HLS PIPELINE II=1 enable_flush
703  #pragma HLS INLINE off
704 
705  const char *myName = concat3(THIS_NAME, "/", "Tid");
706 
707  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
708  static enum FsmStates { TSD_IDLE=0, TSD_FWD, TSD_DROP } \
709  tid_fsmState=TSD_IDLE;
710  #pragma HLS RESET variable=tid_fsmState
711  static ap_uint<8 > tid_crcDropCounter=0;
712  #pragma HLS reset variable=tid_crcDropCounter
713 
714 
715  //-- DYNAMIC VARIABLES -----------------------------------------------------
716  AxisApp currChunk;
717  ValBit validBit;
718 
719  switch (tid_fsmState) {
720  case TSD_IDLE:
721  if (!siCsa_DataVal.empty()) {
722  siCsa_DataVal.read(validBit);
723  if (validBit == OK) {
724  tid_fsmState = TSD_FWD;
725  }
726  else {
727  tid_fsmState = TSD_DROP;
728  tid_crcDropCounter++;
729  printWarn(myName, "Bad checksum: Dropping payload for this packet!\n");
730  }
731  }
732  break;
733  case TSD_FWD:
734  if(!siCsa_Data.empty() && !soTsd_Data.full()) {
735  siCsa_Data.read(currChunk);
736  soTsd_Data.write(currChunk);
737  if (currChunk.getTLast()) {
738  tid_fsmState = TSD_IDLE;
739  }
740  if (DEBUG_LEVEL & TRACE_TID) { printAxisRaw(myName, "soTsd_Data =", currChunk); }
741  }
742  break;
743  case TSD_DROP:
744  if(!siCsa_Data.empty()) {
745  siCsa_Data.read(currChunk);
746  if (currChunk.getTLast()) {
747  tid_fsmState = TSD_IDLE;
748  }
749  }
750  break;
751  } // End of: switch
752 
753  //-- ALWAYS
754  if (!soMMIO_CrcDropCnt.full()) {
755  soMMIO_CrcDropCnt.write(tid_crcDropCounter);
756  }
757  else {
758  printFatal(myName, "Cannot write soMMIO_CrcDropCnt stream...");
759  }
760 
761 } // End of: pTcpInvalidDropper
#define TRACE_TID
Definition: rx_engine.cpp:75
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pTcpLengthExtractor()

void pTcpLengthExtractor ( stream< AxisIp4 > &  siIPRX_Data,
stream< AxisRaw > &  soIph_Data,
stream< TcpSegLen > &  soIph_TcpSegLen 
)

TCP Length Extraction (Tle)

Parameters
[in]siIPRX_DataIP4 packet stream from IpRxHandler (IPRX).
[out]soIph_DataA custom-made pseudo packet to InsertPseudoHeader (Iph).
[out]soIph_TcpSegLenThe length of the incoming TCP segment to [Iph].

This process receives the incoming IPv4 data stream from IpRxHandler (IPRX). It computes the TCP length field from the IP header, removes that IP header but keeps the IP source and destination addresses in front of the TCP segment in order for that output stream to be used by the next process to populate the rest of the TCP pseudo header. The length of the IPv4 data (.i.e. the TCP segment length) is computed from the IPv4 total length and the IPv4 header length.

The data received from [IPRX] are logically divided into lane #0 (7:0) to lane #7 (63:56). The format of an incoming IPv4 packet is defined in (

See also
AxisIp4.hpp) and is as follows:
  6                   5                   4                   3                   2                   1                   0
3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Frag Ofst (L) |Flags| FO(H) | Ident (L) | Ident (H) | Total Len (L) | Total Len (H) |Type of Service|Version| IHL | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | SA (LL) | SA (L) | SA (H) | SA (HH) | Hd Chksum (L) | Hd Chksum (H) | Protocol | Time to Live | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DP (L) | DP (H) | SP (L) | SP (H) | DA (LL) | DA (L) | DA (H) | DA (HH) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Ack (LL) | Ack (L) | Ack (H) | Ack (HH) | Seq (LL) | Seq (L) | Seq (H) | Seq (HH) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | | | | |U|A|P|R|S|F| Data | | | UrgPtr(L) | UrgPtr(H) | CSum (L) | CSum (H) | Win (L) | Win (H) |Res|R|C|S|S|Y|I| Offset| Res | | | | | | | | |G|K|H|T|N|N| | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data 7 | Data 6 | Data 5 | Data 4 | Data 3 | Data 2 | Data 1 | Data 0 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The format of the outgoing segment is custom-made as follows:

 6                   5                   4                   3                   2                   1                   0

3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DA (LL) | DA (L) | DA (H) | DA (HH) | SA (LL) | SA (L) | SA (H) | SA (HH) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Seq (LL) | Seq (L) | Seq (H) | Seq (HH) | DP (L) | DP (H) | SP (L) | SP (H) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | |U|A|P|R|S|F| Data | | | | | | | Win (L) | Win (H) |Res|R|C|S|S|Y|I| Offset| Res | Ack (LL) | Ack (L) | Ack (H) | Ack (HH) | | | | |G|K|H|T|N|N| | | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | | | | | | | Data 3 | Data 2 | Data 1 | Data 0 | UrgPtr(L) | UrgPtr(H) | CSum (L) | CSum (H) | | | | | | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | NU | Data 7 | Data 6 | Data 5 | Data 4 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Definition at line 145 of file rx_engine.cpp.

149 {
150  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
151  #pragma HLS PIPELINE II=1 enable_flush
152  #pragma HLS INLINE off
153 
154  const char *myName = concat3(THIS_NAME, "/", "Tle");
155 
156  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
157  static ap_uint<4> tle_chunkCount=0;
158  #pragma HLS RESET variable=tle_chunkCount
159  static bool tle_residue=false;
160  #pragma HLS RESET variable=tle_residue
161 
162  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
163  static bool tle_shift; // Keeps track of the chunk alignment
164  static Ip4HdrLen tle_ip4HdrLen;
165  static Ip4TotalLen tle_ip4TotLen;
166  static Ip4DatLen tle_ipDataLen;
167  static AxisIp4 tle_prevChunk;
168 
169  //-- DYNAMIC VARIABLES -----------------------------------------------------
170  AxisRaw sendChunk;
171 
172  //-- MAIN PROCESS
173  if (!siIPRX_Data.empty() and !soIph_Data.full() and !tle_residue) {
174  AxisIp4 currChunk = siIPRX_Data.read();
175  switch (tle_chunkCount) {
176  case CHUNK_0:
177  tle_ip4HdrLen = currChunk.getIp4HdrLen();
178  tle_ip4TotLen = currChunk.getIp4TotalLen();
179  // Compute length of IPv4 data (.i.e. the TCP segment length)
180  tle_ipDataLen = tle_ip4TotLen - (tle_ip4HdrLen * 4);
181  tle_ip4HdrLen -= 2; // We just processed 8 bytes
182  tle_chunkCount++;
183  break;
184  case CHUNK_1:
185  // Forward length of IPv4 data (.i.e. the TCP segment length)
186  soIph_TcpSegLen.write(tle_ipDataLen);
187  tle_ip4HdrLen -= 2; // We just processed 8 bytes
188  tle_chunkCount++;
189  break;
190  case CHUNK_2:
191  // Forward destination IP address
192  // Warning, half of this address is now in 'prevChunk'
193  sendChunk.setLE_TData(tle_prevChunk.getLE_TData(63, 32), 31, 0);
194  sendChunk.setLE_TKeep(tle_prevChunk.getLE_TKeep( 7, 4), 3, 0);
195  sendChunk.setLE_TData( currChunk.getLE_TData(31, 0), 63, 32);
196  sendChunk.setLE_TKeep( currChunk.getLE_TKeep( 3, 0), 7, 4);
197  sendChunk.setLE_TLast( currChunk.getLE_TKeep()[4] == 0);
198  soIph_Data.write(sendChunk);
199  tle_ip4HdrLen -= 1; // We just processed the last 4 bytes of a standard IP4 header
200  tle_chunkCount++;
201  if (DEBUG_LEVEL & TRACE_TLE) { printAxisRaw(myName, "soIph_Data =", sendChunk); }
202  break;
203  case CHUNK_3:
204  switch (tle_ip4HdrLen) {
205  case 0: // No or end of IP option(s) - Forward half of 'prevChunk' and half of 'currChunk'.
206  sendChunk.setLE_TData(tle_prevChunk.getLE_TData(63, 32), 31, 0);
207  sendChunk.setLE_TKeep(tle_prevChunk.getLE_TKeep( 7, 4), 3, 0);
208  sendChunk.setLE_TData( currChunk.getLE_TData(31, 0), 63, 32);
209  sendChunk.setLE_TKeep( currChunk.getLE_TKeep( 3, 0), 7, 4);
210  sendChunk.setLE_TLast( currChunk.getLE_TKeep()[4] == 0);
211  soIph_Data.write(sendChunk);
212  tle_shift = true;
213  tle_chunkCount++;
214  if (DEBUG_LEVEL & TRACE_TLE) { printAxisRaw(myName, "soIph_Data =", sendChunk); }
215  break;
216  case 1: // Drop IP option located in 'prevChunk' and forward entire 'currChunk'
217  sendChunk = AxisRaw(currChunk.getLE_TData(), currChunk.getLE_TKeep(), currChunk.getLE_TLast());
218  soIph_Data.write(sendChunk);
219  tle_shift = false;
220  tle_ip4HdrLen = 0;
221  tle_chunkCount++;
222  if (DEBUG_LEVEL & TRACE_TLE) { printAxisRaw(myName, "soIph_Data =", sendChunk); }
223  break;
224  default: // Drop two option chunks located in half of 'prevChunk' and half of 'currChunk'.
225  tle_ip4HdrLen -= 2;
226  break;
227  }
228  break;
229  default:
230  if (tle_shift) {
231  // The 'currChunk' is not aligned with the outgoing 'sendChunk'
232  sendChunk.setLE_TData(tle_prevChunk.getLE_TData(63, 32), 31, 0);
233  sendChunk.setLE_TKeep(tle_prevChunk.getLE_TKeep( 7, 4), 3, 0);
234  sendChunk.setLE_TData( currChunk.getLE_TData(31, 0), 63, 32);
235  sendChunk.setLE_TKeep( currChunk.getLE_TKeep( 3, 0), 7, 4);
236  sendChunk.setLE_TLast( currChunk.getLE_TKeep()[4] == 0);
237  soIph_Data.write(sendChunk);
238  if (DEBUG_LEVEL & TRACE_TLE) { printAxisRaw(myName, "soIph_Data =", sendChunk); }
239  if (currChunk.getTLast()) {
240  tle_chunkCount = 0;
241  tle_residue = (currChunk.getLE_TKeep()[4] != 0);
242  }
243  }
244  else {
245  // The 'currChunk' is aligned with the outgoing 'sendChunk'
246  sendChunk = AxisIp4(currChunk.getLE_TData(), currChunk.getLE_TKeep(), currChunk.getLE_TLast());
247  soIph_Data.write(sendChunk);
248  if (DEBUG_LEVEL & TRACE_TLE) { printAxisRaw(myName, "soIph_Data =", sendChunk); }
249  if (currChunk.getTLast()) {
250  tle_chunkCount = 0;
251  }
252  }
253  break;
254  } // End of: switch (tle_chunkCount)
255  // Always copy 'currChunk' into 'prevChunk'
256  tle_prevChunk = currChunk;
257  }
258  else if (tle_residue) {
259  // Send remaining data
260  AxisRaw sendChunk = AxisRaw(0, 0, TLAST);
261  sendChunk.setLE_TData(tle_prevChunk.getLE_TData(63, 32), 31, 0);
262  sendChunk.setLE_TKeep(tle_prevChunk.getLE_TKeep( 7, 4), 3, 0);
263  soIph_Data.write(sendChunk);
264  tle_residue = false;
265  if (DEBUG_LEVEL & TRACE_TLE) { printAxisRaw(myName, "soIph_Data =", sendChunk); }
266  }
267 }
Ip4TotalLen getIp4TotalLen()
Definition: AxisIp4.hpp:205
Ip4HdrLen getIp4HdrLen()
Definition: AxisIp4.hpp:199
#define TRACE_TLE
Definition: rx_engine.cpp:71
ap_uint< 16 > Ip4DatLen
Definition: AxisIp4.hpp:173
ap_uint< 4 > Ip4HdrLen
Definition: AxisIp4.hpp:157
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pTcpSegmentDropper()

void pTcpSegmentDropper ( stream< AxisApp > &  siTid_Data,
stream< CmdBit > &  siMdh_DropCmd,
stream< CmdBit > &  siFsm_DropCmd,
stream< AxisApp > &  soMwr_Data 
)

TCP Segment Dropper (Tsd)

Parameters
[in]siTid_DataTCP data stream from TcpInvalidDropper (Tid).
[in]siMdh_DropCmdDrop command from MetaDataHandler (Mdh).
[in]siFsm_DropCmdDrop command from FiniteStateMachine (Fsm).
[out]soMwr_DataTCP data stream to MemoryWriter (MWr).

This process drops the TCP segment which metadata did not match and/or which is invalid.

Definition at line 775 of file rx_engine.cpp.

780 {
781  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
782  #pragma HLS PIPELINE II=1 enable_flush
783  #pragma HLS INLINE off
784 
785  const char *myName = concat3(THIS_NAME, "/", "Tsd");
786 
787  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
788  static enum FsmStates { TSD_RD_DROP_CMD1=0, TSD_RD_DROP_CMD2, TSD_FWD, TSD_DROP } \
789  tsd_fsmState=TSD_RD_DROP_CMD1;
790  #pragma HLS RESET variable=tsd_fsmState
791 
792  switch (tsd_fsmState) {
793  case TSD_RD_DROP_CMD1:
794  if (!siMdh_DropCmd.empty()) {
795  CmdBit dropCmd = siMdh_DropCmd.read();
796  if (dropCmd) {
797  tsd_fsmState = TSD_DROP;
798  printWarn(myName, "[Mdh] is requesting to drop this packet.\n");
799  }
800  else {
801  tsd_fsmState = TSD_RD_DROP_CMD2;
802  }
803  }
804  break;
805  case TSD_RD_DROP_CMD2:
806  if (!siFsm_DropCmd.empty()) {
807  CmdBit dropCmd = siFsm_DropCmd.read();
808  if (dropCmd) {
809  tsd_fsmState = TSD_DROP;
810  printWarn(myName, "[Fsm] is requesting to drop this packet.\n");
811  }
812  else {
813  tsd_fsmState = TSD_FWD;
814  }
815  }
816  break;
817  case TSD_FWD:
818  if(!siTid_Data.empty() && !soMwr_Data.full()) {
819  AxisApp currChunk = siTid_Data.read();
820  if (currChunk.getTLast()) {
821  tsd_fsmState = TSD_RD_DROP_CMD1;
822  }
823  soMwr_Data.write(currChunk);
824  if (DEBUG_LEVEL & TRACE_TID) { printAxisRaw(myName, "soMwr_Data =", currChunk); }
825  }
826  break;
827  case TSD_DROP:
828  if(!siTid_Data.empty()) {
829  AxisApp currChunk = siTid_Data.read();
830  if (currChunk.getTLast()) {
831  tsd_fsmState = TSD_RD_DROP_CMD1;
832  }
833  }
834  break;
835  } // End of: switch
836 }
ap_uint< 1 > CmdBit
Definition: nts_types.hpp:108
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pTcpSegStitcher()

void pTcpSegStitcher ( stream< AxisPsd4 > &  siPhc_PseudoHdr,
stream< AxisApp > &  siMEM_TxP_Data,
stream< AxisPsd4 > &  soSca_PseudoPkt,
stream< FlagBool > &  siMrd_SplitSegFlag 
)

TCP Segment Stitcher (Tss)

Parameters
[in]siPhc_PseudoHdrIncoming chunk from PseudoHeaderConstructor (Phc).
[in]siMEM_TxP_DataTCP data payload from DRAM Memory (MEM).
[out]soSca_PseudoPktPseudo TCP/IP packet to SubChecksumAccumulator (Sca).
[in]siMrd_SplitSegStsIndicates that the current segment has been splitted and stored in 2 memory buffers.

Reads in the TCP pseudo header stream from PseudoHeaderConstructor (Phc) and appends the corresponding payload stream retrieved from the memory. Note that a TCP segment might have been splitted and stored as two memory segment units. This typically happens when the address of the physical memory buffer ring wraps around.

Definition at line 937 of file tx_engine.cpp.

946 {
947  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
948  #pragma HLS INLINE off
949  #pragma HLS PIPELINE II=1 enable_flush
950 
951  const char *myName = concat3(THIS_NAME, "/", "Tss");
952 
953  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
954  static enum FsmState { TSS_PSD_HDR=0, TSS_PSD_OPT, TSS_DATA,
955  TSS_FWD_1ST_BUF, TSS_FWD_2ND_BUF,
956  TSS_JOIN_2ND_BUF, TSS_RESIDUE } \
957  tss_fsmState=TSS_PSD_HDR;
958  #pragma HLS RESET variable=tss_fsmState
959  static ap_uint<3> tss_psdHdrChunkCount = 0;
960  #pragma HLS RESET variable=tss_psdHdrChunkCount
961 
962  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
963  static AxisApp tss_prevChunk;
964  static ap_uint<4> tss_memRdOffset;
965  static FlagBool tss_mustJoin;
966 
967  //-- DYNAMIC VARIABLES -----------------------------------------------------
968  bool isShortCutData = false;
969 
970  switch (tss_fsmState) {
971  case TSS_PSD_HDR:
972  //-- Read and forward the first 4 chunks from [Phc]
973  if (!siPhc_PseudoHdr.empty() and !soSca_PseudoPkt.full()) {
974  AxisPsd4 currHdrChunk = siPhc_PseudoHdr.read();
975  soSca_PseudoPkt.write(currHdrChunk);
976 
977  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currHdrChunk); }
978  if (tss_psdHdrChunkCount == 3) {
979  if (currHdrChunk.getTcpCtrlSyn()) {
980  tss_fsmState = TSS_PSD_OPT; // Segment is a SYN, handle MSS
981  }
982  else {
983  tss_fsmState = TSS_DATA;
984  }
985  tss_psdHdrChunkCount = 0;
986  }
987  else {
988  tss_psdHdrChunkCount++;
989  }
990  if (currHdrChunk.getTLast()) {
991  tss_fsmState = TSS_PSD_HDR;
992  tss_psdHdrChunkCount = 0;
993  }
994  }
995  break;
996  case TSS_PSD_OPT:
997  //-- Read fifth chunk from [Phc] because segment includes a TCP option (.i.e, MSS)
998  if (!siPhc_PseudoHdr.empty() and !soSca_PseudoPkt.full()) {
999  AxisPsd4 currHdrChunk = siPhc_PseudoHdr.read();
1000  soSca_PseudoPkt.write(currHdrChunk);
1001 
1002  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currHdrChunk); }
1003  if (not currHdrChunk.getTLast()) {
1004  printFatal(myName, "Pseudo Header is malformed...\n");
1005  }
1006  tss_fsmState = TSS_PSD_HDR;
1007  }
1008  break;
1009  case TSS_DATA:
1010  //-- Handle the very 1st data chunk from the 1st memory buffer
1011  if (!siMEM_TxP_Data.empty() and !siMrd_SplitSegFlag.empty() and !soSca_PseudoPkt.full()) {
1012  siMrd_SplitSegFlag.read(tss_mustJoin);
1013  AxisApp currAppChunk = siMEM_TxP_Data.read();
1014  if (currAppChunk.getTLast()) {
1015  // We are done with the 1st memory buffer
1016  if (tss_mustJoin == false) {
1017  // The TCP segment was not splitted.
1018  // We are done with this segment. Go back to 'TSS_PSD_HDR'.
1019  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1020  tss_fsmState = TSS_PSD_HDR;
1021  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1022  }
1023  else {
1024  // The TCP segment was splitted in two parts
1025  tss_memRdOffset = currAppChunk.getLen();
1026  if (tss_memRdOffset != 8) {
1027  // The last chunk of the 1st memory buffer is not fully populated.
1028  // Don't output anything here. Save the current chunk and goto 'TSS_JOIN_2ND'.
1029  // There, we will fetch more data to fill in the current chunk.
1030  tss_prevChunk = currAppChunk;
1031  tss_fsmState = TSS_JOIN_2ND_BUF;
1032  }
1033  else {
1034  // The last chunk of the 1st memory buffer is populated with
1035  // 8 valid bytes and is therefore also aligned.
1036  // Forward this chunk and goto 'TSS_FWD_2ND_BUF'.
1037  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1038  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1039  tss_fsmState = TSS_FWD_2ND_BUF;
1040  }
1041  }
1042  }
1043  else {
1044  // The 1st memory buffer contains more than one chunk
1045  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1046  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1047  tss_fsmState = TSS_FWD_1ST_BUF;
1048  }
1049  }
1050  break;
1051  case TSS_FWD_1ST_BUF:
1052  //-- Forward all the data chunks of the 1st memory buffer
1053  if (!siMEM_TxP_Data.empty() and !soSca_PseudoPkt.full()) {
1054  AxisApp currAppChunk = siMEM_TxP_Data.read();
1055  if (currAppChunk.getTLast()) {
1056  // We are done with the 1st memory buffer
1057  if (tss_mustJoin == false) {
1058  // The TCP segment was not splitted.
1059  // We are done with this segment. Go back to 'TSS_PSD_HDR'.
1060  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1061  tss_fsmState = TSS_PSD_HDR;
1062  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1063  }
1064  else {
1065  // The TCP segment was splitted in two parts
1066  tss_memRdOffset = currAppChunk.getLen();
1067  // Always clear the last bit of the last chunk of 1st part
1068  currAppChunk.setTLast(0);
1069  if (tss_memRdOffset != 8) {
1070  // The last chunk of the 1st memory buffer is not fully populated.
1071  // Don't output anything here. Save the current chunk and goto 'TSS_JOIN_2ND'.
1072  // There, we will fetch more data to fill in the current chunk.
1073  tss_prevChunk = currAppChunk;
1074  tss_fsmState = TSS_JOIN_2ND_BUF;
1075  }
1076  else {
1077  // The last chunk of the 1st memory buffer is populated with
1078  // 8 valid bytes and is therefore also aligned.
1079  // Forward this chunk and goto 'TSS_FWD_2ND_BUF'.
1080  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1081  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1082  tss_fsmState = TSS_FWD_2ND_BUF;
1083  }
1084  }
1085  }
1086  else {
1087  // Remain in this state and continue streaming the 1st memory buffer
1088  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1089  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1090  }
1091  }
1092  break;
1093  case TSS_FWD_2ND_BUF:
1094  //-- Forward all the data chunks of the 2nd memory buffer
1095  if (!siMEM_TxP_Data.empty() and !soSca_PseudoPkt.full()) {
1096  AxisApp currAppChunk = siMEM_TxP_Data.read();
1097 
1098  soSca_PseudoPkt.write((AxisPsd4)currAppChunk);
1099  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", currAppChunk); }
1100  if (currAppChunk.getTLast()) {
1101  // We are done with the 2nd memory buffer
1102  tss_fsmState = TSS_PSD_HDR;
1103  }
1104  }
1105  break;
1106  case TSS_JOIN_2ND_BUF:
1107  //-- Join the bytes from the 2nd memory buffer to the stream of bytes of
1108  //-- the 1st memory buffer when the 1st buffer was not fully populated.
1109  //-- The re-alignment occurs between the previously read chunk stored
1110  //-- in 'tss_prevChunk' and the latest chunk stored in 'currAppChunk',
1111  //-- and 'tss_memRdOffset' specifies the number of valid bytes in 'tss_prevChunk'.
1112  if (!siMEM_TxP_Data.empty() and !soSca_PseudoPkt.full()) {
1113  AxisApp currAppChunk = siMEM_TxP_Data.read();
1114 
1115  AxisApp joinedChunk(0,0,0); // [FIXME-Create a join method in AxisRaw]
1116  // Set lower-part of the joined chunk with the last bytes of the previous chunk
1117  joinedChunk.setLE_TData(tss_prevChunk.getLE_TData(((int)tss_memRdOffset*8)-1, 0),
1118  ((int)tss_memRdOffset*8)-1, 0);
1119  joinedChunk.setLE_TKeep(tss_prevChunk.getLE_TKeep( (int)tss_memRdOffset -1, 0),
1120  (int)tss_memRdOffset -1, 0);
1121  // Set higher part of the joined chunk with the first bytes of the current chunk
1122  joinedChunk.setLE_TData(currAppChunk.getLE_TData( ARW -1-((int)tss_memRdOffset*8), 0),
1123  ARW -1,((int)tss_memRdOffset*8));
1124  joinedChunk.setLE_TKeep(currAppChunk.getLE_TKeep((ARW/8)-1- (int)tss_memRdOffset, 0),
1125  (ARW/8)-1, (int)tss_memRdOffset);
1126  if (currAppChunk.getLE_TKeep()[8-(int)tss_memRdOffset] == 0) {
1127  // The entire current chunk fits into the remainder of the previous chunk.
1128  // We are done with this 2nd memory buffer.
1129  joinedChunk.setLE_TLast(TLAST);
1130  tss_fsmState = TSS_PSD_HDR;
1131  }
1132  else if (currAppChunk.getLE_TLast()) {
1133  // This cannot be the last chunk because it doesn't fit into the
1134  // available space of the previous chunk. Goto the 'TSS_RESIDUE'
1135  // and handle the remainder of this data chunk
1136  tss_fsmState = TSS_RESIDUE;
1137  }
1138 
1139  soSca_PseudoPkt.write(joinedChunk);
1140  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", joinedChunk); }
1141 
1142  // Move remainder of current chunk to previous chunk
1143  tss_prevChunk.setLE_TData(currAppChunk.getLE_TData(64-1, 64-(int)tss_memRdOffset*8),
1144  ((int)tss_memRdOffset*8)-1, 0);
1145  tss_prevChunk.setLE_TKeep(currAppChunk.getLE_TKeep(8-1, 8-(int)tss_memRdOffset),
1146  (int)tss_memRdOffset-1, 0);
1147  }
1148  break;
1149  case TSS_RESIDUE:
1150  //-- Output the very last unaligned chunk
1151  if (!soSca_PseudoPkt.full()) {
1152  AxisPsd4 lastChunk = AxisPsd4(0, 0, TLAST);
1153  lastChunk.setLE_TData(tss_prevChunk.getLE_TData(((int)tss_memRdOffset*8)-1, 0),
1154  ((int)tss_memRdOffset*8)-1, 0);
1155  lastChunk.setLE_TKeep(tss_prevChunk.getLE_TKeep((int)tss_memRdOffset-1, 0),
1156  (int)tss_memRdOffset-1, 0);
1157 
1158  soSca_PseudoPkt.write(lastChunk);
1159  if (DEBUG_LEVEL & TRACE_TSS) { printAxisRaw(myName, "soSca_PseudoPkt =", lastChunk); }
1160  tss_fsmState = TSS_PSD_HDR;
1161  }
1162  break;
1163 
1164  #if (TCP_NODELAY)
1165  case 6:
1166  if (!txApp2txEng_data_stream.empty() && !soSca_PseudoPkt.full()) {
1167  txApp2txEng_data_stream.read(currWord);
1168  soSca_PseudoPkt.write(currWord);
1169  if (currWord.last) {
1170  tps_state = 0;
1171  }
1172  }
1173  break;
1174  #endif
1175  #if (TCP_NODELAY)
1176  case 7:
1177  if (!txEng_isDDRbypass.empty()) {
1178  txEng_isDDRbypass.read(isShortCutData);
1179  if (isShortCutData) {
1180  tss_fsmState = 6;
1181  }
1182  else {
1183  TSS_1ST_BUF;
1184  }
1185  }
1186  break;
1187  #endif
1188  } // End of: switch
1189 
1190 } // End of: pTcpSegStitcher
TcpCtrlBit getTcpCtrlSyn()
Definition: AxisPsd4.hpp:169
#define TRACE_TSS
Definition: tx_engine.cpp:77
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pTxAppConnect()

void pTxAppConnect ( stream< TcpAppOpnReq > &  siTAIF_OpnReq,
stream< TcpAppOpnRep > &  soTAIF_OpnRep,
stream< TcpAppClsReq > &  siTAIF_ClsReq,
stream< SocketPair > &  soSLc_SessLookupReq,
stream< SessionLookupReply > &  siSLc_SessLookupRep,
stream< ReqBit > &  soPRt_GetFreePortReq,
stream< TcpPort > &  siPRt_GetFreePortRep,
stream< StateQuery > &  soSTt_ConnectStateQry,
stream< TcpState > &  siSTt_ConnectStateRep,
stream< SessState > &  siRXe_ActSessState,
stream< Event > &  soEVe_Event,
stream< SessState > &  siTIm_Notif,
Ip4Address  piMMIO_IpAddr 
)

Tx Application Connect (Tac)

Parameters
[in]siTAIF_OpnReqOpen connection request from TcpApplicationInterface (TAIF).
[out]soTAIF_OpnRepOpen connection reply to [TAIF].
[]siTAIF_ClsReq Close connection request from [TAIF].
[out]soSLc_SessLookupReqLookup request SessionLookupController (SLc).
[in]siSLc_SessLookupRepReply from [SLc]
[out]soPRt_GetFreePortReqFree port request to PortTable (PRt).
[out]siPRt_GetFreePortRepFree port reply from [PRt].
[in]siRXe_ActSessStateTCP state of an active session from [RXe].
[outsoSTt_AcceptStateQry Session state query to StateTable (STt). [FIXME - What about ConnectStateReply?]
[in]siSTt_AcceptStateRepSession state reply from [STt].
[out]soEVe_EventEvent to EventEngine (EVe).
[in]siTIm_NotifNotification from Timers (TIm).
[in]piMMIO_IpAddrIPv4 Address from MMIO.

This process performs the creation and tear down of the active connections. Active connections are the ones opened by the FPGA when operating in client mode. They make use of dynamically assigned or ephemeral ports which always fall in the range 32,768 to 65,535 (by TOE's convention). The operations performed here are somehow similar to the 'connect' and 'close' system calls. The IP tuple of the new connection to open is read from 'siTAIF_OpnReq'. Next, a free port number is requested from the PortTable (PRt) and a SYN event is forwarded to the TxeEngine (TXe) in order to initiate a 3-way handshake with the remote server. The [APP] is notified upon a connection establishment success or fail via a status message delivered over 'soTAIF_OpnRep'. Upon success, the message will provide the [APP] with the 'SessionId' of the new connection. Sending the 'SessionId' over the 'siTAIF_ClsReq' interface, will tear-down the connection.

Warning
The outgoing stream 'soTAIF_SndRep is operated in non-blocking mode to avoid any stalling of this process. This means that the current reply to be sent on this stream will be dropped if the stream is full. As a result, the application process must provision enough buffering to store the reply returned by this process upon a request to open an active connection.

Definition at line 150 of file tx_app_interface.cpp.

164 {
165  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
166  #pragma HLS pipeline II=1 enable_flush
167  #pragma HLS INLINE off
168 
169  const char *myName = concat3(THIS_NAME, "/", "Tac");
170 
171  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
172  static enum FsmStates {TAC_IDLE=0, TAC_GET_FREE_PORT, TAC_CLOSE_CONN } \
173  tac_fsmState=TAC_IDLE;
174  #pragma HLS RESET variable=tac_fsmState
175 
176  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
177  static SessionId tac_closeSessionID;
178 
179  //-- LOCAL STREAMS ---------------------------------------------------------
180  static stream<SockAddr> tac_localFifo ("tac_localFifo");
181  const int tac_localFifo_depth = 4;
182  #pragma HLS stream variable=tac_localFifo depth=tac_localFifo_depth
183 
184  SessState activeSessState;
185 
186  switch (tac_fsmState) {
187  case TAC_IDLE:
188  if (!siTAIF_OpnReq.empty() and !soPRt_GetFreePortReq.full()) {
189  assessSize(myName, tac_localFifo, "tac_localFifo", tac_localFifo_depth);
190  tac_localFifo.write(siTAIF_OpnReq.read());
191  soPRt_GetFreePortReq.write(1);
192  tac_fsmState = TAC_GET_FREE_PORT;
193  }
194  else if (!siSLc_SessLookupRep.empty()) {
195  // Read the session lookup reply and check its state
196  SessionLookupReply sessLkpRep = siSLc_SessLookupRep.read();
197  if (sessLkpRep.hit) {
198  soEVe_Event.write(Event(SYN_EVENT, sessLkpRep.sessionID));
199  soSTt_ConnectStateQry.write(StateQuery(sessLkpRep.sessionID, SYN_SENT, QUERY_WR));
200  }
201  else {
202  // Tell the [APP ]that opening of the active connection failed
203  if (!soTAIF_OpnRep.full()) {
204  soTAIF_OpnRep.write(TcpAppOpnRep(sessLkpRep.sessionID, CLOSED));
205  }
206  else {
207  // Drop this reply
208  printFatal(myName, "Cannot write 'soTAIF_OpnRep()'. Stream is full!");
209  }
210  }
211  }
212  else if (!siRXe_ActSessState.empty()) {
213  // If pending, read the state of the on-going active session (.i.e, initiated by [TOE])
214  siRXe_ActSessState.read(activeSessState);
215  // And forward it to [TAIF]
216  // [TODO-FIXME We should check if [TAIF] is actually waiting for such a status]
217  if (!soTAIF_OpnRep.full()) {
218  soTAIF_OpnRep.write(activeSessState);
219  }
220  else {
221  // Drop this reply
222  printFatal(myName, "Cannot write 'soTAIF_OpnRep()'. Stream is full!");
223  }
224  }
225  else if (!siTIm_Notif.empty()) {
226  if (!soTAIF_OpnRep.full()) {
227  soTAIF_OpnRep.write(siTIm_Notif.read());
228  }
229  else {
230  // Drop this reply
231  printFatal(myName, "Cannot write 'soTAIF_OpnRep()'. Stream is full!");
232  }
233  }
234  else if(!siTAIF_ClsReq.empty()) {
235  siTAIF_ClsReq.read(tac_closeSessionID);
236  soSTt_ConnectStateQry.write(StateQuery(tac_closeSessionID));
237  tac_fsmState = TAC_CLOSE_CONN;
238  }
239  break;
240  case TAC_GET_FREE_PORT:
241  if (!siPRt_GetFreePortRep.empty() and !soSLc_SessLookupReq.full()) {
242  TcpPort freePort = siPRt_GetFreePortRep.read();
243  SockAddr serverAddr = tac_localFifo.read();
244  // Request the [SLc] to create a new entry in its session table
245  soSLc_SessLookupReq.write(SocketPair(
246  SockAddr(piMMIO_IpAddr, freePort),
247  SockAddr(serverAddr.addr, serverAddr.port)));
248  tac_fsmState = TAC_IDLE;
249  }
250  break;
251  case TAC_CLOSE_CONN:
252  if (!siSTt_ConnectStateRep.empty()) {
253  TcpState tcpState = siSTt_ConnectStateRep.read();
254  // [FIXME-TODO Not yet tested]
255  if ((tcpState == ESTABLISHED) or (tcpState == FIN_WAIT_2) or (tcpState == FIN_WAIT_1)) {
256  // [TODO - Why if FIN already SENT]
257  soSTt_ConnectStateQry.write(StateQuery(tac_closeSessionID, FIN_WAIT_1, QUERY_WR));
258  soEVe_Event.write(Event(FIN_EVENT, tac_closeSessionID));
259  }
260  else {
261  soSTt_ConnectStateQry.write(StateQuery(tac_closeSessionID, tcpState, QUERY_WR));
262  }
263  tac_fsmState = TAC_IDLE;
264  }
265  break;
266  }
267 }
Here is the caller graph for this function:

◆ pTxAppStatusHandler()

void pTxAppStatusHandler ( stream< DmSts > &  siMEM_TxP_WrSts,
stream< Event > &  siEmx_Event,
stream< TAiTxSarPush > &  soTSt_PushCmd,
stream< Event > &  soEVe_Event 
)

Tx Application Status Handler (Tash)

Parameters
[in]siMEM_TxP_WrStsTx memory write status from [MEM].
[in]siEmx_EventEvent from the EventMultiplexer (Emx).
[out]soTSt_PushCmdPush command to TxSarTable (TSt).
[out]soEVe_EventEvent to EventEngine (EVe).

This process waits and reads events from [Emx]. If the incoming event is a 'TX_EVENT', the process will wait for one (or possibly two) memory status from [MEM] and will forward a command to update the 'TxApplicationPointer' of the [TSt]. Whatever the received event, it is always forwarded to [EVe].

Definition at line 284 of file tx_app_interface.cpp.

289 {
290  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
291  #pragma HLS pipeline II=1
292  #pragma HLS INLINE off
293 
294  const char *myName = concat3(THIS_NAME, "/", "Tash");
295 
296  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
297  static enum FsmStates { TASH_IDLE=0, TASH_RD_MEM_STATUS_1, TASH_RD_MEM_STATUS_2 } \
298  tash_fsmState=TASH_IDLE;
299  #pragma HLS reset variable=tash_fsmState
300 
301  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
302  static Event ev;
303 
304  switch (tash_fsmState) {
305  case TASH_IDLE: //-- Read the Event
306  if (!siEmx_Event.empty()) {
307  siEmx_Event.read(ev);
308  if (ev.type == TX_EVENT) {
309  tash_fsmState = TASH_RD_MEM_STATUS_1;
310  }
311  else {
312  soEVe_Event.write(ev);
313  }
314  if (DEBUG_LEVEL & TRACE_TASH) {
315  printInfo(myName, "Received event \'%s\' from [Emx].\n",
316  getEventName(ev.type));
317  }
318  }
319  break;
320  case TASH_RD_MEM_STATUS_1: //-- Read the Memory Write Status #1 (this might also be the last)
321  if (!siMEM_TxP_WrSts.empty()) {
322  DmSts status = siMEM_TxP_WrSts.read();
323  if (status.okay) {
324  ap_uint<TOE_WINDOW_BITS+1> txAppPtr = ev.address + ev.length;
325  if (txAppPtr[TOE_WINDOW_BITS] == 1) {
326  // The TCP buffer wrapped around
327  tash_fsmState = TASH_RD_MEM_STATUS_2;
328  }
329  else {
330  // Update the 'txAppPtr' of the TX_SAR_TABLE
331  soTSt_PushCmd.write(TAiTxSarPush(ev.sessionID, txAppPtr.range(TOE_WINDOW_BITS-1, 0)));
332  // Forward event to [EVe] which will signal [TXe]
333  soEVe_Event.write(ev);
334  if (DEBUG_LEVEL & TRACE_TASH) {
335  printInfo(myName, "Received TXMEM write status = %d.\n", status.okay.to_int());
336  }
337  tash_fsmState = TASH_IDLE;
338  }
339  }
340  }
341  break;
342  case TASH_RD_MEM_STATUS_2: //-- Read the Memory Write Status #2
343  if (!siMEM_TxP_WrSts.empty()) {
344  DmSts status = siMEM_TxP_WrSts.read();
345  TxBufPtr txAppPtr = (ev.address + ev.length);
346  if (status.okay) {
347  // Update the 'txAppPtr' of the TX_SAR_TABLE
348  soTSt_PushCmd.write(TAiTxSarPush(ev.sessionID, txAppPtr));
349  // Forward event to [EVe] which will signal [TXe]
350  soEVe_Event.write(ev);
351  if (DEBUG_LEVEL & TRACE_TASH) {
352  printInfo(myName, "Received TXMEM write status = %d (this was a split access).\n", status.okay.to_int());
353  }
354  }
355  tash_fsmState = TASH_IDLE;
356  }
357  break;
358  } // End of: switch
359 }
TcpBufAdr address
Definition: toe.hpp:665
TcpSegLen length
Definition: toe.hpp:666
#define TRACE_TASH
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pTxAppTable()

void pTxAppTable ( stream< TStTxSarPush > &  siTSt_PushCmd,
stream< TxAppTableQuery > &  siTas_AccessQry,
stream< TxAppTableReply > &  siTas_AccessRep 
)

Tx Application Table (Tat)

Parameters
[in]siTSt_PushCmdPush command from TxSarTable (TSt).
[in]siTas_AccessQryAccess query from TxAppStream (Tas).
[out]soTAs_AccessRepAccess reply to [Tas].

This table keeps tack of the Tx ACK numbers and Tx memory pointers.

Definition at line 372 of file tx_app_interface.cpp.

376 {
377  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
378  #pragma HLS PIPELINE II=1 enable_flush
379  #pragma HLS INLINE off
380 
381  const char *myName = concat3(THIS_NAME, "/", "Tat");
382 
383  //-- STATIC ARRAYS ---------------------------------------------------------
384  static TxAppTableEntry TX_APP_TABLE[TOE_MAX_SESSIONS];
385  #pragma HLS DEPENDENCE variable=TX_APP_TABLE inter false
386  #pragma HLS reset variable=TX_APP_TABLE
387 
388  //-- DYNAMIC VARIABLES -----------------------------------------------------
389  TStTxSarPush ackPush;
390  TxAppTableQuery txAppUpdate;
391 
392  if (!siTSt_PushCmd.empty()) {
393  siTSt_PushCmd.read(ackPush);
394  if (ackPush.init) {
395  // At init this is actually not_ackd
396  TX_APP_TABLE[ackPush.sessionID].ackd = ackPush.ackd-1;
397  TX_APP_TABLE[ackPush.sessionID].mempt = ackPush.ackd;
398  }
399  else {
400  TX_APP_TABLE[ackPush.sessionID].ackd = ackPush.ackd;
401  }
402  }
403  else if (!siTas_AccessQry.empty()) {
404  siTas_AccessQry.read(txAppUpdate);
405  if(txAppUpdate.write) {
406  TX_APP_TABLE[txAppUpdate.sessId].mempt = txAppUpdate.mempt;
407  }
408  else {
409  siTas_AccessRep.write(TxAppTableReply(txAppUpdate.sessId,
410  TX_APP_TABLE[txAppUpdate.sessId].ackd,
411  TX_APP_TABLE[txAppUpdate.sessId].mempt));
412  }
413  }
414 }
SessionId sessionID
Definition: toe.hpp:559
CmdBit init
Definition: toe.hpp:564
ap_uint< 16 > ackd
Definition: toe.hpp:560
bool write
Definition: toe.hpp:590
SessionId sessId
Definition: toe.hpp:588
TxBufPtr mempt
Definition: toe.hpp:589
Here is the caller graph for this function:

◆ pTxMemoryReader()

void pTxMemoryReader ( stream< DmCmd > &  siMdl_BufferRdCmd,
stream< DmCmd > &  soMEM_TxpRdCmd,
stream< FlagBool > &  soTss_SplitMemAcc 
)

Tx Memory Reader (Mrd)

Parameters
[in]siMdl_BufferRdCmdBuffer read command from Meta Data Loader (Mdl).
[out]soMEM_TxpRdCmdMemory read command to the DRAM Memory (MEM).
[out]soTss_SplitMemAccSplitted memory access to Tcp Segment Stitcher (Tss).

Front end memory controller for reading data from the external DRAM. This process receives a read command from the MetaDataLoader (Mdl) and forwards it to the AXI4 Data Mover. The incoming memory read command might end-up being split in two memory accesses if the address of the data buffer to read from wraps in the external memory. Such a split memory access is flagged by the signal 'soTss_SplitMemAcc'.

Definition at line 1419 of file tx_engine.cpp.

1423 {
1424  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1425  #pragma HLS INLINE off
1426  #pragma HLS PIPELINE II=1 enable_flush
1427 
1428  const char *myName = concat3(THIS_NAME, "/", "Mrd");
1429 
1430  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
1431  static enum FsmState { MRD_1ST_ACCESS=0, MRD_2ND_ACCESS } \
1432  mrd_fsmState=MRD_1ST_ACCESS;
1433  #pragma HLS RESET variable=mrd_fsmState
1434 
1435  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
1436  static DmCmd mrd_memRdCmd;
1437  static TxBufPtr mrd_firstAccLen;
1438  static uint16_t mrd_debugCounter=1;
1439 
1440  switch (mrd_fsmState) {
1441  case MRD_1ST_ACCESS:
1442  if (!siMdl_BufferRdCmd.empty() and !soTss_SplitMemAcc.full() and !soMEM_TxpRdCmd.full()) {
1443  siMdl_BufferRdCmd.read(mrd_memRdCmd);
1444 
1445  if ((mrd_memRdCmd.saddr(TOE_WINDOW_BITS-1, 0) + mrd_memRdCmd.btt) > TOE_TX_BUFFER_SIZE) {
1446  // This segment was broken in two memory accesses because TCP Tx memory buffer wrapped around
1447  mrd_firstAccLen = TOE_TX_BUFFER_SIZE - mrd_memRdCmd.saddr;
1448  mrd_fsmState = MRD_2ND_ACCESS;
1449 
1450  soMEM_TxpRdCmd.write(DmCmd(mrd_memRdCmd.saddr, mrd_firstAccLen));
1451  soTss_SplitMemAcc.write(true);
1452  mrd_fsmState = MRD_2ND_ACCESS;
1453 
1454  if (DEBUG_LEVEL & TRACE_MRD) {
1455  printInfo(myName, "TCP Tx memory buffer wraps around: This segment is broken in two memory accesses.\n");
1456  printInfo(myName, "Issuing 1st memory read command #%d - SADDR=0x%9.9x - BTT=%d\n",
1457  mrd_debugCounter, mrd_memRdCmd.saddr.to_uint(), mrd_firstAccLen.to_uint());
1458  }
1459  }
1460  else {
1461  soMEM_TxpRdCmd.write(mrd_memRdCmd);
1462  soTss_SplitMemAcc.write(false);
1463 
1464  if (DEBUG_LEVEL & TRACE_MRD) {
1465  printInfo(myName, "Issuing memory read command #%d - SADDR=0x%9.9x - BTT=%d\n",
1466  mrd_debugCounter, mrd_memRdCmd.saddr.to_uint(), mrd_memRdCmd.btt.to_uint());
1467  mrd_debugCounter++;
1468  }
1469  }
1470  }
1471  break;
1472  case MRD_2ND_ACCESS:
1473  if (!soMEM_TxpRdCmd.full()) {
1474  // Update the command to account for the Tx buffer wrap around
1475  mrd_memRdCmd.saddr(TOE_WINDOW_BITS-1, 0) = 0;
1476  soMEM_TxpRdCmd.write(DmCmd(mrd_memRdCmd.saddr, mrd_memRdCmd.btt - mrd_firstAccLen));
1477  mrd_fsmState = MRD_1ST_ACCESS;
1478 
1479  if (DEBUG_LEVEL & TRACE_MRD) {
1480  printInfo(myName, "Issuing 2nd memory read command #%d - SADDR=0x%9.9x - BTT=%d\n",
1481  mrd_debugCounter, mrd_memRdCmd.saddr.to_uint(),
1482  (mrd_memRdCmd.btt - mrd_firstAccLen).to_uint());
1483  mrd_debugCounter++;
1484  }
1485  }
1486  break;
1487  }
1488 }
Here is the caller graph for this function:

◆ pTxMemoryWriter()

void pTxMemoryWriter ( stream< TcpAppData > &  siTAIF_Data,
stream< AppMemMeta > &  siSml_AppMeta,
stream< DmCmd > &  soMEM_WrCmd,
stream< AxisApp > &  soMEM_WrData 
)

Tx Memory Writer (Mwr)

Parameters
[in]siTAIF_DataAPP data stream from [TAIF].
[in]siSml_AppMetaAPP memory metadata from StreamMetaLoader (Sml).
[out]soMEM_WrCmdTx memory write command to [MEM].
[out]soMEM_WrDataTx memory write data to [MEM].

This process writes the incoming APP data into the external DRAM upon a a request issued by the state machine of the MetaDataLoader (Sml). The Tx buffer memory is organized and managed as a circular buffer in the DRAM and it may happen that the APP data to be transmitted does not fit into the remaining memory buffer space because the memory pointer needs to wrap around. In such a case, the incoming APP data is broken down and is written into the physical DRAM as two memory buffers.

Definition at line 566 of file tx_app_interface.cpp.

571 {
572  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
573  #pragma HLS INLINE off
574  #pragma HLS pipeline II=1 enable_flush
575 
576  const char *myName = concat3(THIS_NAME, "/", "Mwr");
577 
578  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
579  static enum FsmStates { MWR_IDLE=0,
580  MWR_FWD_ALIGNED, MWR_SPLIT_1ST_CMD,
581  MWR_FWD_1ST_BUF, MWR_FWD_2ND_BUF, MWR_RESIDUE } \
582  mwr_fsmState=MWR_IDLE;
583  #pragma HLS RESET variable = mwr_fsmState
584 
585  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
586  static AppMemMeta mwr_appMemMeta;
587  static DmCmd mwr_memWrCmd;
588  static AxisApp mwr_currChunk;
589  static TxBufPtr mwr_firstAccLen;
590  static TcpDatLen mwr_nrBytesToWr;
591  static ap_uint<4> mwr_splitOffset;
592  static uint16_t mwr_debugCounter=1;
593 
594  //-- DYNAMIC VARIABLES -----------------------------------------------------
595  static uint8_t lengthBuffer;
596  static ap_uint<3> accessResidue;
597 
598  switch (mwr_fsmState) {
599  case MWR_IDLE:
600  if (!siSml_AppMeta.empty() and !soMEM_WrCmd.full()) {
601  siSml_AppMeta.read(mwr_appMemMeta);
602  //-- Build a memory address for this segment
603  TxMemPtr memSegAddr = TOE_TX_MEMORY_BASE; // 0x40000000
604  memSegAddr(29, 16) = mwr_appMemMeta.sessId(13, 0);
605  memSegAddr(15, 0) = mwr_appMemMeta.addr;
606  // Build a data mover command for this segment
607  mwr_memWrCmd = DmCmd(memSegAddr, mwr_appMemMeta.len);
608  if ((mwr_memWrCmd.saddr(TOE_WINDOW_BITS-1, 0) + mwr_memWrCmd.btt) > TOE_TX_BUFFER_SIZE) {
609  // This segment must be broken in two memory accesses because TCP Tx memory buffer wraps around
610  if (DEBUG_LEVEL & TRACE_MWR) {
611  printInfo(myName, "TCP Tx memory buffer wraps around: This segment must be broken in two memory accesses.\n");
612  }
613  mwr_fsmState = MWR_SPLIT_1ST_CMD;
614  }
615  else {
616  soMEM_WrCmd.write(mwr_memWrCmd);
617  mwr_firstAccLen = mwr_memWrCmd.btt;
618  mwr_nrBytesToWr = mwr_firstAccLen;
619  mwr_fsmState = MWR_FWD_ALIGNED;
620  if (DEBUG_LEVEL & TRACE_MWR) {
621  printInfo(myName, "Issuing memory write command #%d - SADDR=0x%9.9x - BTT=%d\n",
622  mwr_debugCounter, mwr_memWrCmd.saddr.to_uint(), mwr_memWrCmd.btt.to_uint());
623  mwr_debugCounter++;
624  }
625  }
626  }
627  break;
628  case MWR_SPLIT_1ST_CMD:
629  if (!soMEM_WrCmd.full()) {
630  mwr_firstAccLen = TOE_TX_BUFFER_SIZE - mwr_memWrCmd.saddr;
631  mwr_nrBytesToWr = mwr_firstAccLen;
632  soMEM_WrCmd.write(DmCmd(mwr_memWrCmd.saddr, mwr_firstAccLen));
633  if (DEBUG_LEVEL & TRACE_MWR) {
634  printInfo(myName, "Issuing 1st memory write command #%d - SADDR=0x%9.9x - BTT=%d\n",
635  mwr_debugCounter, mwr_memWrCmd.saddr.to_uint(), mwr_firstAccLen.to_uint());
636  }
637  mwr_fsmState = MWR_FWD_1ST_BUF;
638  }
639  break;
640  case MWR_FWD_ALIGNED:
641  if (!siTAIF_Data.empty() and !soMEM_WrData.full()) {
642  //-- Default streaming state used to forward APP data or splitted
643  //-- buffers that are aligned with to the Axis raw width.
644  AxisApp memChunk = siTAIF_Data.read();
645  soMEM_WrData.write(memChunk);
646  if (memChunk.getTLast()) {
647  mwr_fsmState = MWR_IDLE;
648  }
649  }
650  break;
651  case MWR_FWD_1ST_BUF:
652  if (!siTAIF_Data.empty() and !soMEM_WrData.full()) {
653  //-- Create 1st splitted data buffer and stream it to memory
654  siTAIF_Data.read(mwr_currChunk);
655  AxisApp memChunk = mwr_currChunk;
656  if (mwr_nrBytesToWr > (ARW/8)) {
657  mwr_nrBytesToWr -= (ARW/8);
658  }
659  else if (!soMEM_WrCmd.full()) {
660  if (mwr_nrBytesToWr == (ARW/8)) {
661  memChunk.setLE_TLast(TLAST);
662 
663  mwr_memWrCmd.saddr(TOE_WINDOW_BITS-1, 0) = 0;
664  mwr_memWrCmd.btt -= mwr_firstAccLen;
665  soMEM_WrCmd.write(mwr_memWrCmd);
666  if (DEBUG_LEVEL & TRACE_MWR) {
667  printInfo(myName, "Issuing 2nd memory write command #%d - SADDR=0x%9.9x - BTT=%d\n",
668  mwr_debugCounter, mwr_memWrCmd.saddr.to_uint(), mwr_memWrCmd.btt.to_uint());
669  mwr_debugCounter++;
670  }
671  mwr_fsmState = MWR_FWD_ALIGNED;
672  }
673  else {
674  memChunk.setLE_TLast(TLAST);
675  memChunk.setLE_TKeep(lenToLE_tKeep(mwr_nrBytesToWr));
676  #ifndef __SYNTHESIS__
677  memChunk.setLE_TData(0, (ARW-1), ((int)mwr_nrBytesToWr*8));
678  #endif
679 
680  mwr_memWrCmd.saddr(TOE_WINDOW_BITS-1, 0) = 0;
681  mwr_memWrCmd.btt -= mwr_firstAccLen;
682  soMEM_WrCmd.write(mwr_memWrCmd);
683  if (DEBUG_LEVEL & TRACE_MWR) {
684  printInfo(myName, "Issuing 2nd memory write command #%d - SADDR=0x%9.9x - BTT=%d\n",
685  mwr_debugCounter, mwr_memWrCmd.saddr.to_uint(), mwr_memWrCmd.btt.to_uint());
686  mwr_debugCounter++;
687  }
688  mwr_splitOffset = (ARW/8) - mwr_nrBytesToWr;
689  mwr_fsmState = MWR_FWD_2ND_BUF;
690  }
691  }
692  soMEM_WrData.write(memChunk);
693  if (DEBUG_LEVEL & TRACE_MWR) { printAxisRaw(myName, "soMEM_WrData =", memChunk); }
694  }
695  break;
696  case MWR_FWD_2ND_BUF:
697  if (!siTAIF_Data.empty() and !soMEM_WrData.full()) {
698  //-- Alternate streaming state used to re-align a splitted second buffer
699  AxisApp prevChunk = mwr_currChunk;
700  mwr_currChunk = siTAIF_Data.read();
701 
702  AxisApp joinedChunk(0,0,0); // [FIXME-Create a join method in AxisRaw]
703  // Set lower-part of the joined chunk with the last bytes of the previous chunk
704  joinedChunk.setLE_TData(prevChunk.getLE_TData((ARW )-1, ((ARW )-((int)mwr_splitOffset*8))),
705  ((int)mwr_splitOffset*8)-1, 0);
706  joinedChunk.setLE_TKeep(prevChunk.getLE_TKeep((ARW/8)-1, ((ARW/8)-((int)mwr_splitOffset ))),
707  ((int)mwr_splitOffset )-1, 0);
708  // Set higher part of the joined chunk with the first bytes of the current chunk
709  joinedChunk.setLE_TData(mwr_currChunk.getLE_TData((ARW )-((int)mwr_splitOffset*8)-1, 0),
710  (ARW ) -1, ((int)mwr_splitOffset*8));
711  joinedChunk.setLE_TKeep(mwr_currChunk.getLE_TKeep((ARW/8)-((int)mwr_splitOffset )-1, 0),
712  (ARW/8) -1, ((int)mwr_splitOffset ));
713  if (mwr_currChunk.getLE_TLast()) {
714  if (mwr_currChunk.getLen() > mwr_nrBytesToWr) {
715  // This cannot be the last chunk because the current one plus
716  // the remainder of the previous one do not fit into a single chunk.
717  // Goto the 'MWR_RESIDUE' and handle the remainder of that chunk.
718  mwr_fsmState = MWR_RESIDUE;
719  }
720  else {
721  // The entire current chunk and the remainder of the previous chunk
722  // fit into a single chunk. We are done with this 2nd memory buffer.
723  joinedChunk.setLE_TLast(TLAST);
724  mwr_fsmState = MWR_IDLE;
725  }
726  }
727  soMEM_WrData.write(joinedChunk);
728  if (DEBUG_LEVEL & TRACE_MWR) {
729  printAxisRaw(myName, "soMEM_WrData =", joinedChunk);
730  }
731  }
732  break;
733  case MWR_RESIDUE:
734  if (!soMEM_WrData.full()) {
735  //-- Output the very last unaligned chunk
736  AxisApp prevChunk = mwr_currChunk;
737  AxisApp lastChunk(0,0,0);
738 
739  // Set lower-part of the last chunk with the last bytes of the previous chunk
740  lastChunk.setLE_TData(prevChunk.getLE_TData((ARW )-1, ((ARW )-((int)mwr_splitOffset*8))),
741  ((int)mwr_splitOffset*8)-1, 0);
742  lastChunk.setLE_TKeep(prevChunk.getLE_TKeep((ARW/8)-1, ((ARW/8)-((int)mwr_splitOffset ))),
743  ((int)mwr_splitOffset )-1, 0);
744  lastChunk.setLE_TLast(TLAST);
745  soMEM_WrData.write(lastChunk);
746  if (DEBUG_LEVEL & TRACE_MWR) {
747  printAxisRaw(myName, "soMEM_TxP_Data =", lastChunk);
748  }
749  mwr_fsmState = MWR_IDLE;
750  }
751  break;
752  } // End-of switch
753 }
TcpSessId sessId
Here is the caller graph for this function:

◆ pUpdateReplyHandler()

void pUpdateReplyHandler ( stream< CamSessionUpdateReply > &  siCAM_SessUpdateRep,
stream< CamSessionUpdateReply > &  soLrh_SessUpdateRsp 
)

Update Reply Handler (Urh)

Parameters
[in]siCAM_SessUpdateRepSession update reply from [CAM].
[out]soLrh_SessUpdateRspSession update response to LookupReplyHandler (Lrh).*

Definition at line 300 of file session_lookup_controller.cpp.

303 {
304  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
305  #pragma HLS PIPELINE II=1 enable_flush
306  #pragma HLS INLINE off
307 
308  const char *myName = concat3(THIS_NAME, "/", "Urh");
309 
310  if (!siCAM_SessUpdateRep.empty()) {
311  CamSessionUpdateReply upReply;
312  siCAM_SessUpdateRep.read(upReply);
313  if (upReply.op == INSERT)
314  soLrh_SessUpdateRsp.write(upReply);
315  }
316 }
Here is the caller graph for this function:

◆ pUpdateRequestSender()

void pUpdateRequestSender ( stream< CamSessionUpdateRequest > &  siLrh_InsertSessReq,
stream< CamSessionUpdateRequest > &  siRlt_SessDeleteReq,
stream< CamSessionUpdateRequest > &  soCAM_SessUpdateReq,
stream< RtlSessId > &  soSim_FreeId,
stream< ap_uint< 16 > > &  soSssRelCnt,
stream< ap_uint< 16 > > &  soSssRegCnt 
)

Update Request Sender (Urs)

Parameters
[in]siLrh_InsertSessReqRequest to insert session from LookupReplyHandler (Lrh).
[in]siRlt_SessDeleteReqRequest to delete session from Reverse Lookup Table (Rlt).
[out]soCAM_SessUpdateReqUpdate request to [CAM].
[out]soSim_FreeIdThe SessId to recycle to the [SessionIdManager].
[out]soSssRelCntSession release count to DEBUG.
[out]soSssRegCntSession register count to DEBUG.

This process sends the insertion or deletion requests to the ternary content addressable memory (TCAM or CAM for short). If a session deletion is requested, the corresponding sessionId is collected from the request and is forwarded to the SessionIdManager for re-cycling.

Definition at line 253 of file session_lookup_controller.cpp.

260 {
261  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
262  #pragma HLS PIPELINE II=1 enable_flush
263  #pragma HLS INLINE off
264 
265  const char *myName = concat3(THIS_NAME, "/", "Urs");
266 
267  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
268  static ap_uint<16> urs_insertedSessions=0;
269  #pragma HLS RESET variable=urs_insertedSessions
270  static ap_uint<16> urs_releasedSessions=0;
271  #pragma HLS RESET variable=urs_releasedSessions
272 
273  if (!siLrh_InsertSessReq.empty()) {
274  soCAM_SessUpdateReq.write(siLrh_InsertSessReq.read());
275  urs_insertedSessions++;
276  }
277  else if (!siRlt_SessDeleteReq.empty()) {
278  CamSessionUpdateRequest request;
279  siRlt_SessDeleteReq.read(request);
280  soCAM_SessUpdateReq.write(request);
281  soSim_FreeId.write(request.value);
282  urs_releasedSessions++;
283  }
284  // Always
285  if (!soSssRegCnt.full()) {
286  soSssRegCnt.write(urs_insertedSessions);
287  }
288  if (!soSssRelCnt.full()) {
289  soSssRelCnt.write(urs_releasedSessions);
290  }
291 }
Here is the caller graph for this function:

◆ readChunk()

void DummyMemory::readChunk ( AxisApp chunk)

Definition at line 72 of file dummy_memory.cpp.

72  {
73  readStorageIt = storage.find(readId);
74  if (readStorageIt == storage.end()) {
75  readStorageIt = createBuffer(readId);
76  // check it?
77  }
78  int i = 0;
79  chunk.setLE_TKeep(0);
80  while (this->readLen > 0 and i < 8) {
81  chunk.setLE_TData((readStorageIt->second)[readAddr], (i*8)+7, i*8);
82  chunk.setLE_TKeep(chunk.getLE_TKeep() | (0x01 << i));
83  readLen--;
84  readAddr++;
85  i++;
86  }
87  if (this->readLen == 0) {
88  chunk.setTLast(TLAST);
89  }
90  else {
91  chunk.setTLast(0);
92  }
93 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rx_app_interface()

void rx_app_interface ( stream< TcpAppNotif > &  soTAIF_Notif,
stream< TcpAppRdReq > &  siTAIF_DataReq,
stream< TcpAppData > &  soTAIF_Data,
stream< TcpAppMeta > &  soTAIF_Meta,
stream< TcpAppLsnReq > &  siTAIF_LsnReq,
stream< TcpAppLsnRep > &  soTAIF_LsnRep,
stream< TcpPort > &  soPRt_LsnReq,
stream< AckBit > &  siPRt_LsnAck,
stream< TcpAppNotif > &  siRXe_Notif,
stream< TcpAppNotif > &  siTIm_Notif,
stream< RAiRxSarQuery > &  soRSt_RxSarReq,
stream< RAiRxSarReply > &  siRSt_RxSarRep,
stream< DmCmd > &  soMEM_RxP_RdCmd,
stream< AxisApp > &  siMEM_RxP_Data,
stream< ap_uint< 8 > > &  soMMIO_NotifDropCnt,
stream< ap_uint< 8 > > &  soMMIO_MetaDropCnt,
stream< ap_uint< 8 > > &  soMMIO_DataDropCnt 
)

Rx Application Interface (RAi)

ENTITY - Rx Application Interface (RAi)

Parameters
[out]soTAIF_NotifData availability notification to TcpAppInterface (TAIF).
[in]siTAIF_DataReqRequest to retrieve data from [TAIF].
[out]soTAIF_DataTCP data stream to [TAIF].
[out]soTAIF_MetaMetadata to [TAIF].
[in]siTAIF_LsnReqTCP listen port request from [TAIF].
[out]soTAIF_LsnRepTCP listen port reply to [TAIF].
[out]soPRt_LsnReqTCP listen port request to PortTable (PRt).
[in]siPRt_LsnAckTCP listen port acknowledge from [PRt].
[in]siRXe_NotifData availability notification from Rx Engine (RXe).
[in]siTIm_NotifData availability notification from Timers (TIm).
[out]soRSt_RxSarReqRx SAR request to RxSarTable (RSt).
[in]siRSt_RxSarRepRx SAR reply from [RSt].
[out]soMEM_RxP_RdCmdRx memory read command to Memory sub-system (MEM).
[in]siMEM_RxP_DataRx memory data stream from [MEM].
[out]soMMIO_NotifDropCntThe value of the notification drop counter.
[out]soMMIO_MetaDropCntThe value of the metadata drop counter.
[out]soMMIO_DataDropCntThe value of the data drop counter.

The Rx Application Interface (Rai) retrieves the data of an established connection from the TCP Rx buffer memory and forwards them to the application via the TcpAppInterface (TAIF). This process is also in charge of opening/closing TCP ports in listen mode for TOE to be ready for accepting passive incoming connections.

Warning
To avoid any blocking of this process, all the outgoing 'soTAIF_***' streams are checked for fullness and the current data to be sent out is dropped if the stream is full. This implies that the user application process connected to these streams must provision enough buffering to store the corresponding bytes exchanged on these request-reply interfaces. Alternatively, the user application must be able to drain the stream at its maximum rate (i.e. one data piece per clock cycle).

Definition at line 729 of file rx_app_interface.cpp.

756 {
757  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
758  #pragma HLS INLINE
759 
760  //--------------------------------------------------------------------------
761  //-- LOCAL STREAMS (Sorted by the name of the modules which generate them)
762  //--------------------------------------------------------------------------
763 
764  //-- Rx Application Stream (Ras) -------------------------------------------
765  static stream<DmCmd> ssRasToMrd_MemRdCmd ("ssRasToMrd_MemRdCmd");
766  #pragma HLS stream variable=ssRasToMrd_MemRdCmd depth=16
767 
768  //-- Rx Memory Reader (Mrd) ------------------------------------------------
769  static stream<FlagBool> ssMrdToAss_SplitSeg ("ssMrdToAss_SplitSeg");
770  #pragma HLS stream variable=ssMrdToAss_SplitSeg depth=16
771 
772  pRxAppStream(
773  siTAIF_DataReq,
774  soTAIF_Meta,
775  soRSt_RxSarReq,
776  siRSt_RxSarRep,
777  ssRasToMrd_MemRdCmd,
778  soMMIO_MetaDropCnt);
779 
781  ssRasToMrd_MemRdCmd,
782  soMEM_RxP_RdCmd,
783  ssMrdToAss_SplitSeg);
784 
786  siMEM_RxP_Data,
787  soTAIF_Data,
788  ssMrdToAss_SplitSeg,
789  soMMIO_DataDropCnt);
790 
792  siTAIF_LsnReq,
793  soTAIF_LsnRep,
794  soPRt_LsnReq,
795  siPRt_LsnAck);
796 
798  siRXe_Notif,
799  siTIm_Notif,
800  soTAIF_Notif,
801  soMMIO_NotifDropCnt);
802 
803 }
void pRxMemoryReader(stream< DmCmd > &siRas_MemRdCmd, stream< DmCmd > &soMEM_RxpRdCmd, stream< FlagBool > &soAss_SplitSeg)
Rx Memory Reader (Mrd)
void pNotificationMux(stream< TcpAppNotif > &siRXe_Notif, stream< TcpAppNotif > &siTIm_Notif, stream< TcpAppNotif > &soTAIF_Notif, stream< ap_uint< 8 > > &soMMIO_NotifDropCnt)
Rx Notification Multiplexer (Nmx)
void pLsnAppInterface(stream< TcpAppLsnReq > &siTAIF_LsnReq, stream< TcpAppLsnRep > &soTAIF_LsnRep, stream< TcpPort > &soPRt_LsnReq, stream< RepBit > &siPRt_LsnRep)
Listen Application Interface (Lai)
void pRxAppStream(stream< TcpAppRdReq > &siTAIF_DataReq, stream< TcpAppMeta > &soTAIF_Meta, stream< RAiRxSarQuery > &soRSt_RxSarQry, stream< RAiRxSarReply > &siRSt_RxSarRep, stream< DmCmd > &soMrd_MemRdCmd, stream< ap_uint< 8 > > &soMMIO_MetaDropCnt)
Rx Application Stream (RAs)
void pAppSegmentStitcher(stream< AxisApp > &siMEM_RxP_Data, stream< TcpAppData > &soTAIF_Data, stream< FlagBool > &siMrd_SplitSegFlag, stream< ap_uint< 8 > > &soMMIO_DataDropCnt)
Application Segment Stitcher (Ass)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rx_engine()

void rx_engine ( stream< AxisIp4 > &  siIPRX_Data,
stream< SessionLookupQuery > &  soSLc_SessLkReq,
stream< SessionLookupReply > &  siSLc_SessLkRep,
stream< StateQuery > &  soSTt_StateQry,
stream< TcpState > &  siSTt_StateRep,
stream< TcpPort > &  soPRt_PortStateReq,
stream< RepBit > &  siPRt_PortStateRep,
stream< RXeRxSarQuery > &  soRSt_RxSarQry,
stream< RxSarReply > &  siRSt_RxSarRep,
stream< RXeTxSarQuery > &  soTSt_TxSarQry,
stream< RXeTxSarReply > &  siTSt_TxSarRep,
stream< RXeReTransTimerCmd > &  soTIm_ReTxTimerCmd,
stream< SessionId > &  soTIm_ClearProbeTimer,
stream< SessionId > &  soTIm_CloseTimer,
stream< ExtendedEvent > &  soEVe_SetEvent,
stream< SessState > &  soTAi_SessOpnSts,
stream< TcpAppNotif > &  soRAi_RxNotif,
stream< DmCmd > &  soMEM_WrCmd,
stream< AxisApp > &  soMEM_WrData,
stream< DmSts > &  siMEM_WrSts,
stream< StsBit > &  soMMIO_RxMemWrErr,
stream< ap_uint< 8 > > &  soMMIO_CrcDropCnt,
stream< ap_uint< 8 > > &  soMMIO_SessDropCnt,
stream< ap_uint< 8 > > &  soMMIO_OooDropCnt,
stream< RxBufPtr > &  soDBG_RxFreeSpace,
stream< ap_uint< 32 > > &  soDBG_TcpIpRxByteCnt,
stream< ap_uint< 8 > > &  soDBG_OooDebug 
)

Receive Engine (RXe)

ENTITY - Rx Engine (RXe)

Parameters
[in]siIPRX_DataIP4 data stream form [IPRX].
[out]soSLc_SessLkReqSession lookup request to SessionLookupController (SLc).
[in]siSLc_SessLkRepSession lookup reply from [SLc].
[out]soSTt_StateQryState query to StateTable (STt).
[in]siSTt_StateRepState reply from [STt].
[out]soPRt_PortStateReqPort state request to PortTable (PRt).
[in]siPRt_PortStateRepPort state reply from [PRt].
[out]soRSt_RxSarQryQuery to RxSarTable (RSt).
[in]siRSt_RxSarRepReply from [RSt].
[out]soTSt_TxSarQryQuery to TxSarTable (TSt).
[in]siTSt_TxSarRepReply from [TSt].
[out]soTIm_ReTxTimerCmdCommand for a retransmit timer to Timers (TIm).
[out]soTIm_ClearProbeTimerClear the probe timer command to [TIm]..
[out]soTIm_CloseTimerClose session timer command to [TIm].
[out]soEVe_SetEventEvent forward to EventEngine (EVe).
[out]soTAi_SessOpnStsOpen status of the session to TxAppInterface (TAi).
[out]soRAi_RxNotifRx data notification to RxAppInterface (RAi).
[out]soMEM_WrCmdMemory write command to MemorySubSystem (MEM).
[out]soMEM_WrDataMemory data write stream to [MEM].
[in]siMEM_WrStsMemory write status from [MEM].
[out]soMMIO_RxMemWrErrReports an Rx memory write error.
[out]soMMIO_CrcDropCntThe value of the CRC drop counter.
[out]soMMIO_SessDropCntThe value of the session drop counter.
[out]soMMIO_OooDropCntThe value of the out-of-order drop counter.

The RxEngine (RXe) processes the TCP/IP packets received from the IpRxHandler (IPRX). When a new TCP/IP packet enters the RXe, its TCP checksum is tested, the TCP header is parsed and some more checks are done. Next, the TCP segment is evaluated by the TCP state machine which triggers events and updates the data structures according to the type of received packet. Finally, if the packet contains a valid data payload, the TCP segment is stored in external DDR4 memory and the application is notified about the arrival of new data.

Definition at line 2000 of file rx_engine.cpp.

2041 {
2042  //-- DIRECTIVES FOR THE INTERFACES ----------------------------------------
2043  #pragma HLS DATAFLOW
2044  #pragma HLS INTERFACE ap_ctrl_none port=return
2045 
2046  //-------------------------------------------------------------------------
2047  //-- LOCAL STREAMS (Sorted by the name of the modules which generate them)
2048  //-------------------------------------------------------------------------
2049 
2050  //-- Tcp Length Extract (Tle) ---------------------------------------------
2051  static stream<AxisRaw> ssTleToIph_Data ("ssTleToIph_Data");
2052  #pragma HLS stream variable=ssTleToIph_Data depth=8
2053  #pragma HLS DATA_PACK variable=ssTleToIph_Data
2054 
2055  static stream<TcpSegLen> ssTleToIph_TcpSegLen ("ssTleToIph_TcpSegLen");
2056  #pragma HLS stream variable=ssTleToIph_TcpSegLen depth=2
2057 
2058  //-- Insert Pseudo Header (Iph) -------------------------------------------
2059  static stream<AxisPsd4> ssIphToCsa_PseudoPkt ("ssIphToCsa_PseudoPkt");
2060  #pragma HLS stream variable=ssIphToCsa_PseudoPkt depth=8
2061  #pragma HLS DATA_PACK variable=ssIphToCsa_PseudoPkt
2062 
2063  //-- CheckSum Accumulator (Csa) -------------------------------------------
2064  static stream<AxisApp> ssCsaToTid_Data ("ssCsaToTid_Data");
2065  #pragma HLS stream variable=ssCsaToTid_Data depth=256 //critical, tcp checksum computation
2066  #pragma HLS DATA_PACK variable=ssCsaToTid_Data
2067 
2068  static stream<ValBit> ssCsaToTid_DataValid ("ssCsaToTid_DataValid");
2069  #pragma HLS stream variable=ssCsaToTid_DataValid depth=2
2070 
2071  static stream<RXeMeta> ssCsaToMdh_Meta ("ssCsaToMdh_Meta");
2072  #pragma HLS stream variable=ssCsaToMdh_Meta depth=2
2073  #pragma HLS DATA_PACK variable=ssCsaToMdh_Meta
2074 
2075  static stream<SocketPair> ssCsaToMdh_SockPair ("ssCsaToMdh_SockPair");
2076  #pragma HLS stream variable=ssCsaToMdh_SockPair depth=2
2077  #pragma HLS DATA_PACK variable=ssCsaToMdh_SockPair
2078 
2079  //-- Tcp Invalid dropper (Tid) --------------------------------------------
2080  static stream<AxisApp> ssTidToTsd_Data ("ssTidToTsd_Data");
2081  #pragma HLS stream variable=ssTidToTsd_Data depth=8
2082  #pragma HLS DATA_PACK variable=ssTidToTsd_Data
2083 
2084  //-- Tcp Tcp Segment Dropper (Tsd) -----------------------------------------
2085  static stream<AxisApp> ssTsdToMwr_Data ("ssTsdToMwr_Data");
2086  #pragma HLS stream variable=ssTsdToMwr_Data depth=16
2087  #pragma HLS DATA_PACK variable=ssTsdToMwr_Data
2088 
2089  //-- MetaData Handler (Mdh) -----------------------------------------------
2090  static stream<ExtendedEvent> ssMdhToEvm_Event ("ssMdhToEvm_Event");
2091  #pragma HLS stream variable=ssMdhToEvm_Event depth=cDepth_MdhToEvm_Event
2092  #pragma HLS DATA_PACK variable=ssMdhToEvm_Event
2093 
2094  static stream<CmdBit> ssMdhToTsd_DropCmd ("ssMdhToTsd_DropCmd");
2095  #pragma HLS stream variable=ssMdhToTsd_DropCmd depth=cDepth_MdhToTsd_DropCmd
2096 
2097  static stream<RXeFsmMeta> ssMdhToFsm_Meta ("ssMdhToFsm_Meta");
2098  #pragma HLS stream variable=ssMdhToFsm_Meta depth=2
2099  #pragma HLS DATA_PACK variable=ssMdhToFsm_Meta
2100 
2101  //-- Finite State Machine (Fsm) -------------------------------------------
2102  static stream<CmdBit> ssFsmToTsd_DropCmd ("ssFsmToTsd_DropCmd");
2103  #pragma HLS stream variable=ssFsmToTsd_DropCmd depth=cDepth_FsmToTsd_DropCmd
2104 
2105  static stream<TcpAppNotif> ssFsmToRan_Notif ("ssFsmToRan_Notif");
2106  #pragma HLS stream variable=ssFsmToRan_Notif depth=cDepth_FsmToRan_Notif
2107  #pragma HLS DATA_PACK variable=ssFsmToRan_Notif
2108 
2109  static stream<Event> ssFsmToEvm_Event ("ssFsmToEvm_Event");
2110  #pragma HLS stream variable=ssFsmToEvm_Event depth=cDepth_FsmToEve_Event
2111  #pragma HLS DATA_PACK variable=ssFsmToEvm_Event
2112 
2113  static stream<DmCmd> ssFsmToMwr_WrCmd ("ssFsmToMwr_WrCmd");
2114  #pragma HLS stream variable=ssFsmToMwr_WrCmd depth=cDepth_FsmToMwr_WrCmd
2115  #pragma HLS DATA_PACK variable=ssFsmToMwr_WrCmd
2116 
2117  //-- Memory Writer (Mwr) --------------------------------------------------
2118  static stream<FlagBool> ssMwrToRan_SplitSeg ("ssMwrToRan_SplitSeg");
2119  #pragma HLS stream variable=ssMwrToRan_SplitSeg depth=cDepth_MwrToRan_SplitSeg
2120 
2121  //-------------------------------------------------------------------------
2122  //-- PROCESS FUNCTIONS
2123  //-------------------------------------------------------------------------
2124 
2126  siIPRX_Data,
2127  ssTleToIph_Data,
2128  ssTleToIph_TcpSegLen);
2129 
2130 
2132  ssTleToIph_Data,
2133  ssTleToIph_TcpSegLen,
2134  ssIphToCsa_PseudoPkt);
2135 
2137  ssIphToCsa_PseudoPkt,
2138  ssCsaToTid_Data,
2139  ssCsaToTid_DataValid,
2140  ssCsaToMdh_Meta,
2141  ssCsaToMdh_SockPair,
2142  soPRt_PortStateReq);
2143 
2145  ssCsaToTid_Data,
2146  ssCsaToTid_DataValid,
2147  ssTidToTsd_Data,
2148  soMMIO_CrcDropCnt);
2149 
2151  ssCsaToMdh_Meta,
2152  ssCsaToMdh_SockPair,
2153  soSLc_SessLkReq,
2154  siSLc_SessLkRep,
2155  siPRt_PortStateRep,
2156  ssMdhToEvm_Event,
2157  ssMdhToTsd_DropCmd,
2158  ssMdhToFsm_Meta,
2159  soMMIO_SessDropCnt);
2160 
2162  ssMdhToFsm_Meta,
2163  soSTt_StateQry,
2164  siSTt_StateRep,
2165  soRSt_RxSarQry,
2166  siRSt_RxSarRep,
2167  soTSt_TxSarQry,
2168  siTSt_TxSarRep,
2169  soTIm_ReTxTimerCmd,
2170  soTIm_ClearProbeTimer,
2171  soTIm_CloseTimer,
2172  soTAi_SessOpnSts,
2173  ssFsmToEvm_Event,
2174  ssFsmToTsd_DropCmd,
2175  ssFsmToMwr_WrCmd,
2176  ssFsmToRan_Notif,
2177  soMMIO_OooDropCnt,
2178  soDBG_RxFreeSpace,
2179  soDBG_TcpIpRxByteCnt,
2180  soDBG_OooDebug);
2181 
2183  ssTidToTsd_Data,
2184  ssMdhToTsd_DropCmd,
2185  ssFsmToTsd_DropCmd,
2186  ssTsdToMwr_Data);
2187 
2189  ssTsdToMwr_Data,
2190  ssFsmToMwr_WrCmd,
2191  soMEM_WrCmd,
2192  soMEM_WrData,
2193  ssMwrToRan_SplitSeg);
2194 
2196  siMEM_WrSts,
2197  ssFsmToRan_Notif,
2198  soRAi_RxNotif,
2199  ssMwrToRan_SplitSeg,
2200  soMMIO_RxMemWrErr);
2201 
2203  ssMdhToEvm_Event,
2204  ssFsmToEvm_Event,
2205  soEVe_SetEvent);
2206 
2207 }
void pRxAppNotifier(stream< DmSts > &siMEM_WrSts, stream< TcpAppNotif > &siFsm_Notif, stream< TcpAppNotif > &soRAi_RxNotif, stream< FlagBool > &siMwr_SplitSeg, stream< StsBit > &soMMIO_MemWrErr)
Rx Application Notifier (Ran)
Definition: rx_engine.cpp:1075
void pRxMemoryWriter(stream< AxisApp > &siTsd_Data, stream< DmCmd > &siFsm_MemWrCmd, stream< DmCmd > &soMEM_WrCmd, stream< AxisApp > &soMEM_WrData, stream< FlagBool > &soRan_SplitSeg)
Rx Memory Writer (Mwr)
Definition: rx_engine.cpp:859
void pTcpSegmentDropper(stream< AxisApp > &siTid_Data, stream< CmdBit > &siMdh_DropCmd, stream< CmdBit > &siFsm_DropCmd, stream< AxisApp > &soMwr_Data)
TCP Segment Dropper (Tsd)
Definition: rx_engine.cpp:775
void pTcpLengthExtractor(stream< AxisIp4 > &siIPRX_Data, stream< AxisRaw > &soIph_Data, stream< TcpSegLen > &soIph_TcpSegLen)
TCP Length Extraction (Tle)
Definition: rx_engine.cpp:145
void pTcpInvalidDropper(stream< AxisApp > &siCsa_Data, stream< ValBit > &siCsa_DataVal, stream< AxisApp > &soTsd_Data, stream< ap_uint< 8 > > &soMMIO_CrcDropCnt)
TCP Invalid checksum Dropper (Tid)
Definition: rx_engine.cpp:695
void pMetaDataHandler(stream< RXeMeta > &siCsa_Meta, stream< SocketPair > &siCsa_SockPair, stream< SessionLookupQuery > &soSLc_SessLkpReq, stream< SessionLookupReply > &siSLc_SessLkpRep, stream< StsBit > &siPRt_PortSts, stream< ExtendedEvent > &soEVe_Event, stream< CmdBit > &soTsd_DropCmd, stream< RXeFsmMeta > &soFsm_Meta, stream< ap_uint< 8 > > &soMMIO_SessDropCnt)
MetaData Handler (Mdh)
Definition: rx_engine.cpp:1197
void pFiniteStateMachine(stream< RXeFsmMeta > &siMdh_FsmMeta, stream< StateQuery > &soSTt_StateQry, stream< TcpState > &siSTt_StateRep, stream< RXeRxSarQuery > &soRSt_RxSarQry, stream< RxSarReply > &siRSt_RxSarRep, stream< RXeTxSarQuery > &soTSt_TxSarQry, stream< RXeTxSarReply > &siTSt_TxSarRep, stream< RXeReTransTimerCmd > &soTIm_ReTxTimerCmd, stream< SessionId > &soTIm_ClearProbeTimer, stream< SessionId > &soTIm_CloseTimer, stream< SessState > &soTAi_SessOpnSts, stream< Event > &soEVe_Event, stream< CmdBit > &soTsd_DropCmd, stream< DmCmd > &soMwr_WrCmd, stream< TcpAppNotif > &soRan_RxNotif, stream< ap_uint< 8 > > &soMMIO_OooDropCnt, stream< RxBufPtr > &soDBG_RxFreeSpace, stream< ap_uint< 32 > > &soDBG_TcpIpRxByteCnt, stream< ap_uint< 8 > > &soDBG_OooDebug)
Finite State machine (Fsm)
Definition: rx_engine.cpp:1358
void pInsertPseudoHeader(stream< AxisRaw > &siTle_Data, stream< TcpSegLen > &siTle_TcpSegLen, stream< AxisPsd4 > &soCsa_PseudoPkt)
Insert pseudo header (Iph)
Definition: rx_engine.cpp:320
void pCheckSumAccumulator(stream< AxisPsd4 > &siIph_PseudoPkt, stream< AxisApp > &soTid_Data, stream< ValBit > &soTid_DataVal, stream< RXeMeta > &soMdh_Meta, stream< SocketPair > &soMdh_SockPair, stream< TcpPort > &soPRt_GetState)
TCP checksum accumulator (Csa)
Definition: rx_engine.cpp:444
void pEventMultiplexer(stream< ExtendedEvent > &siMdh_Event, stream< Event > &siFsm_Event, stream< ExtendedEvent > &soEVe_Event)
Event Multiplexer (Evm)
Definition: rx_engine.cpp:1943
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rx_sar_table()

void rx_sar_table ( stream< RXeRxSarQuery > &  siRXe_RxSarQry,
stream< RxSarReply > &  soRXe_RxSarRep,
stream< RAiRxSarQuery > &  siRAi_RxSarQry,
stream< RAiRxSarReply > &  soRAi_RxSarRep,
stream< SessionId > &  siTXe_RxSarReq,
stream< RxSarReply > &  soTxe_RxSarRep 
)

Rx SAR Table (RSt)

ENTITY - Rx SAR Table (RSt)

Parameters
[in]siRXe_RxSarQryQuery from RxEngine (RXe).
[out]soRXe_RxSarRepReply to RXe.
[in]siRAi_RxSarQryQuery from RxAppInterface (RAi).
[out]soRAi_RxSarRepReply to [RAi].
[in]siTXe_RxSarReqRead request from TxEngine (TXe).
[out]soTxe_RxSarRepRead reply to [TXe].

This process stores the structures for managing the received data stream in the TCP Rx buffer memory. An Rx buffer of 64KB is allocated to every session and the stream of bytes within every session is managed with two pointers:

  • 'rcvd' holds the sequence number of the last received and acknowledged byte from the network layer,
  • 'appd' holds a pointer to the next byte ready to be read (.i.e, consumed) by the application layer.

    appd rcvd oooTail oooHead | | | | |/ |/ |/ |/ –+—+—+—+—+—+—+—+—+—+—+—+—+—+—+—+—+– |269|270|271|272|273|274|275|276|277|278|279|280|281|282|283|284| –+—+—+—+—+—+—+—+—+—+—+—+—+—+—+—+—+–

This process is concurrently accessed by the RxEngine (RXe), the TxEngine (TXe) and the RxApplicationInterface (RAi), but TXe access is read-only.

Definition at line 105 of file rx_sar_table.cpp.

112 {
113  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
114  #pragma HLS PIPELINE II=1 enable_flush
115 
116  const char *myName = THIS_NAME;
117 
118  //-- STATIC ARRAYS ---------------------------------------------------------
119  static RxSarEntry RX_SAR_TABLE[TOE_MAX_SESSIONS];
120  #pragma HLS RESOURCE variable=RX_SAR_TABLE core=RAM_2P
121  #pragma HLS DEPENDENCE variable=RX_SAR_TABLE inter false
122 
123  if(!siTXe_RxSarReq.empty()) {
124  SessionId sessId;
125  //---------------------------------------
126  // [TXe] - Read only access
127  //---------------------------------------
128  siTXe_RxSarReq.read(sessId);
129  soTxe_RxSarRep.write(RxSarReply(RX_SAR_TABLE[sessId].appd,
130  RX_SAR_TABLE[sessId].rcvd,
131  RX_SAR_TABLE[sessId].ooo,
132  RX_SAR_TABLE[sessId].oooHead,
133  RX_SAR_TABLE[sessId].oooTail));
134  if (DEBUG_LEVEL & TRACE_RST) {
135  RxBufPtr free_space = ((RX_SAR_TABLE[sessId].appd -
136  (RxBufPtr)RX_SAR_TABLE[sessId].oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
137  printInfo(myName, "[TXe] Read S%d - FreeSpace=%d\n",
138  sessId.to_uint(), free_space.to_uint());
139  }
140  }
141  else if(!siRAi_RxSarQry.empty()) {
142  RAiRxSarQuery raiQry;
143  //----------------------------------------------------------------
144  // [RAi] - Read or write access to update the application pointer
145  //----------------------------------------------------------------
146  siRAi_RxSarQry.read(raiQry);
147  if(raiQry.write) {
148  RX_SAR_TABLE[raiQry.sessionID].appd = raiQry.appd;
149  if (DEBUG_LEVEL & TRACE_RST) {
150  RxBufPtr free_space = ((RX_SAR_TABLE[raiQry.sessionID].appd -
151  (RxBufPtr)RX_SAR_TABLE[raiQry.sessionID].oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
152  printInfo(myName, "[RAi] Write S%d - FreeSpace=%d\n",
153  raiQry.sessionID.to_uint(), free_space.to_uint());
154  }
155  }
156  else {
157  soRAi_RxSarRep.write(RAiRxSarReply(raiQry.sessionID,
158  RX_SAR_TABLE[raiQry.sessionID].appd));
159  if (DEBUG_LEVEL & TRACE_RST) {
160  RxBufPtr free_space = ((RX_SAR_TABLE[raiQry.sessionID].appd -
161  (RxBufPtr)RX_SAR_TABLE[raiQry.sessionID].oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
162  printInfo(myName, "[RAi] Read S%d - FreeSpace=%d\n",
163  raiQry.sessionID.to_uint(), free_space.to_uint());
164  }
165  }
166  }
167  else if(!siRXe_RxSarQry.empty()) {
168  RXeRxSarQuery rxeQry = siRXe_RxSarQry.read();
169  //---------------------------------------
170  // [RXe] - Write access
171  //---------------------------------------
172  if (rxeQry.write) {
173  RX_SAR_TABLE[rxeQry.sessionID].rcvd = rxeQry.rcvd;
174  if (rxeQry.init) {
175  RX_SAR_TABLE[rxeQry.sessionID].appd = rxeQry.rcvd;
176  }
177  if (rxeQry.ooo) {
178  RX_SAR_TABLE[rxeQry.sessionID].ooo = true;
179  RX_SAR_TABLE[rxeQry.sessionID].oooHead = rxeQry.oooHead;
180  RX_SAR_TABLE[rxeQry.sessionID].oooTail = rxeQry.oooTail;
181  }
182  else {
183  RX_SAR_TABLE[rxeQry.sessionID].ooo = false;
184  RX_SAR_TABLE[rxeQry.sessionID].oooHead = rxeQry.rcvd;
185  RX_SAR_TABLE[rxeQry.sessionID].oooTail = rxeQry.rcvd;
186  }
187  if (DEBUG_LEVEL & TRACE_RST) {
188  RxBufPtr free_space = ((RX_SAR_TABLE[rxeQry.sessionID].appd -
189  (RxBufPtr)RX_SAR_TABLE[rxeQry.sessionID].oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
190  printInfo(myName, "[RXe] Write S%d - FreeSpace=%d\n",
191  rxeQry.sessionID.to_uint(), free_space.to_uint());
192  }
193  }
194  else {
195  // Read access from [RXe]
196  soRXe_RxSarRep.write(RxSarReply(RX_SAR_TABLE[rxeQry.sessionID].appd,
197  RX_SAR_TABLE[rxeQry.sessionID].rcvd,
198  RX_SAR_TABLE[rxeQry.sessionID].ooo,
199  RX_SAR_TABLE[rxeQry.sessionID].oooHead,
200  RX_SAR_TABLE[rxeQry.sessionID].oooTail));
201  if (DEBUG_LEVEL & TRACE_RST) {
202  RxBufPtr free_space = ((RX_SAR_TABLE[rxeQry.sessionID].appd -
203  (RxBufPtr)RX_SAR_TABLE[rxeQry.sessionID].oooHead(TOE_WINDOW_BITS-1, 0)) - 1);
204  printInfo(myName, "[RXe] Read S%d - FreeSpace=%d\n",
205  rxeQry.sessionID.to_uint(), free_space.to_uint());
206  }
207  }
208  }
209 }
SessionId sessionID
Definition: toe.hpp:416
RxBufPtr appd
Definition: toe.hpp:417
RdWrBit write
Definition: toe.hpp:418
CmdBit init
Definition: toe.hpp:391
RdWrBit write
Definition: toe.hpp:390
RxSeqNum rcvd
Definition: toe.hpp:386
RxSeqNum oooTail
Definition: toe.hpp:388
FlagBool ooo
Definition: toe.hpp:389
SessionId sessionID
Definition: toe.hpp:385
RxSeqNum oooHead
Definition: toe.hpp:387
RxSeqNum oooHead
RxBufPtr appd
FlagBool ooo
RxSeqNum rcvd
RxSeqNum oooTail
#define TRACE_RST
Here is the caller graph for this function:

◆ session_lookup_controller()

void session_lookup_controller ( stream< SessionLookupQuery > &  siRXe_SessLookupReq,
stream< SessionLookupReply > &  soRXe_SessLookupRep,
stream< SessionId > &  siSTt_SessReleaseCmd,
stream< TcpPort > &  soPRt_ClosePortCmd,
stream< SocketPair > &  siTAi_SessLookupReq,
stream< SessionLookupReply > &  soTAi_SessLookupRep,
stream< SessionId > &  siTXe_ReverseLkpReq,
stream< fourTuple > &  soTXe_ReverseLkpRep,
stream< CamSessionLookupRequest > &  soCAM_SessLookupReq,
stream< CamSessionLookupReply > &  siCAM_SessLookupRep,
stream< CamSessionUpdateRequest > &  soCAM_SessUpdateReq,
stream< CamSessionUpdateReply > &  siCAM_SessUpdateRep,
stream< ap_uint< 16 > > &  soSssRelCnt,
stream< ap_uint< 16 > > &  soSssRegCnt 
)

Session Lookup Controller (SLc)

ENTITY - Session Lookup Controller (SLc)

Parameters
[in]siRXe_SessLookupReqSession lookup request from Rx Engine (RXe).
[out]soRXe_SessLookupRepSession lookup reply to [RXe].
[in]siSTt_SessReleaseCmdSession release command from State Table (STt).
[out]soPRt_ClosePortCmdCommand to close a port for the Port Table (PRt).
[in]siTAi_SessLookupReqSession lookup request from Tx App. I/F (TAi).
[out]soTAi_SessLookupReqSession lookup reply to [TAi].
[in]siTXe_ReverseLkpReqReverse lookup request from Tx Engine (TXe).
[out]soTXe_ReverseLkpRepReverse lookup reply to [TXe].
[out]soCAM_SessLookupReqLookup request to ternary CAM (CAM).
[in]siCAM_SessLookupRepLookup reply from [CAM].
[out]soCAM_SessUpdateReqUpdate request to [CAM].
[in]siCAM_SessUpdateRepUpdate reply from [CAM].
[out]soSssRelCntSession release count.
[out]soSssRegCntSession register count.

The SLc maps a four-tuple information {{IP4_SA,TCP_SA},{IP4_DA,TCP_DP}} of a socket pair to a so-called 'sessionID'. This session ID represents the TCP connection and is used as an index into the various data structures of the TOE. This module acts as a wrapper for the RTL implementation the TCAM which holds the session ID table. It also includes the wrapper for the sessionID free list which keeps track of the free SessionID.

Definition at line 430 of file session_lookup_controller.cpp.

445 {
446  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
447  #pragma HLS INLINE
448 
449  //--------------------------------------------------------------------------
450  //-- LOCAL SIGNALS AND STREAMS
451  //-- (Sorted by the name of the modules which generate them)
452  //--------------------------------------------------------------------------
453 
454  // Session Id Manager (Sim) ------------------------------------------------
455  static stream<RtlSessId> ssSimToLrh_FreeList ("ssSimToLrh_FreeList");
456  #pragma HLS stream variable=ssSimToLrh_FreeList depth=16384 // 0x4000 [FIXME - Can we replace 16384 with MAX_SESSIONS]
457 
458  // Lookup Reply Handler (Lrh) ----------------------------------------------
459  static stream<RtlSessId> ssUrsToSim_FreeId ("ssUrsToSim_FreeId");
460  #pragma HLS stream variable=ssUrsToSim_FreeId depth=2
461 
462  static stream<CamSessionUpdateRequest> ssLrhToUrs_InsertSessReq ("ssLrhToUrs_InsertSessReq");
463  #pragma HLS STREAM variable=ssLrhToUrs_InsertSessReq depth=4
464 
465  static stream<SLcReverseLkp> ssLrhToRlt_ReverseLkpRsp ("ssLrhToRlt_ReverseLkpRsp");
466  #pragma HLS STREAM variable=ssLrhToRlt_ReverseLkpRsp depth=4
467 
468  // Update Reply Handler
469  static stream<CamSessionUpdateReply> ssUrhToLrh_SessUpdateRsp ("ssUrhToLrh_SessUpdateRsp");
470  #pragma HLS STREAM variable=ssUrhToLrh_SessUpdateRsp depth=4
471 
472  // Reverse Lookup Table (Rlt) ----------------------------------------------
473  static stream<CamSessionUpdateRequest> ssRltToUrs_SessDeleteReq ("ssRltToUrs_SessDeleteReq");
474  #pragma HLS STREAM variable=ssRltToUrs_SessDeleteReq depth=4
475 
476  //--------------------------------------------------------------------------
477  //-- PROCESS FUNCTIONS
478  //--------------------------------------------------------------------------
479 
481  ssUrsToSim_FreeId,
482  ssSimToLrh_FreeList);
483 
485  soCAM_SessLookupReq,
486  siCAM_SessLookupRep,
487  ssUrhToLrh_SessUpdateRsp,
488  siRXe_SessLookupReq,
489  soRXe_SessLookupRep,
490  siTAi_SessLookupReq,
491  soTAi_SessLookupRep,
492  ssSimToLrh_FreeList,
493  ssLrhToUrs_InsertSessReq,
494  ssLrhToRlt_ReverseLkpRsp);
495 
497  ssLrhToUrs_InsertSessReq,
498  ssRltToUrs_SessDeleteReq,
499  soCAM_SessUpdateReq,
500  ssUrsToSim_FreeId,
501  soSssRelCnt,
502  soSssRegCnt);
503 
505  siCAM_SessUpdateRep,
506  ssUrhToLrh_SessUpdateRsp);
507 
509  ssLrhToRlt_ReverseLkpRsp,
510  siSTt_SessReleaseCmd,
511  siTXe_ReverseLkpReq,
512  soTXe_ReverseLkpRep,
513  soPRt_ClosePortCmd,
514  ssRltToUrs_SessDeleteReq);
515 }
void pReverseLookupTable(stream< SLcReverseLkp > &siLrh_ReverseLkpRsp, stream< SessionId > &siSTt_SessReleaseCmd, stream< SessionId > &siTXe_ReverseLkpReq, stream< fourTuple > &soTXe_ReverseLkpRep, stream< TcpPort > &soPRt_ClosePortCmd, stream< CamSessionUpdateRequest > &soUrs_SessDeleteReq)
Reverse Lookup Table (Rlt)
void pSessionIdManager(stream< RtlSessId > &siUrs_FreeId, stream< RtlSessId > &soLrh_FreeList)
Session Id Manager (Sim)
void pLookupReplyHandler(stream< CamSessionLookupRequest > &soCAM_SessLookupReq, stream< CamSessionLookupReply > &siCAM_SessLookupRep, stream< CamSessionUpdateReply > &siUrh_SessUpdateRsp, stream< SessionLookupQuery > &siRXe_SessLookupReq, stream< SessionLookupReply > &soRXe_SessLookupRep, stream< SocketPair > &siTAi_SessLookupReq, stream< SessionLookupReply > &soTAi_SessLookupRep, stream< RtlSessId > &siSim_FreeList, stream< CamSessionUpdateRequest > &soUrs_InsertSessReq, stream< SLcReverseLkp > &soRlt_ReverseLkpRsp)
Lookup Reply Handler (Lrh)
void pUpdateReplyHandler(stream< CamSessionUpdateReply > &siCAM_SessUpdateRep, stream< CamSessionUpdateReply > &soLrh_SessUpdateRsp)
Update Reply Handler (Urh)
void pUpdateRequestSender(stream< CamSessionUpdateRequest > &siLrh_InsertSessReq, stream< CamSessionUpdateRequest > &siRlt_SessDeleteReq, stream< CamSessionUpdateRequest > &soCAM_SessUpdateReq, stream< RtlSessId > &soSim_FreeId, stream< ap_uint< 16 > > &soSssRelCnt, stream< ap_uint< 16 > > &soSssRegCnt)
Update Request Sender (Urs)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setReadCmd()

void DummyMemory::setReadCmd ( DmCmd  cmd)

Definition at line 58 of file dummy_memory.cpp.

58  {
59  this->readAddr = cmd.saddr(15, 0); // Start address
60  this->readId = cmd.saddr(31, 16); // Buffer address
61  uint16_t tempLen = (uint16_t) cmd.btt(15, 0); // Byte to Transfer
62  this->readLen = (int) tempLen;
63 }
Here is the caller graph for this function:

◆ setWriteCmd()

void DummyMemory::setWriteCmd ( DmCmd  cmd)

Definition at line 66 of file dummy_memory.cpp.

66  {
67  this->writeAddr = cmd.saddr(15, 0); // Start address
68  this->writeId = cmd.saddr(31, 16); // Buffer address
69 }
Here is the caller graph for this function:

◆ state_table()

void state_table ( stream< StateQuery > &  siRXe_SessStateQry,
stream< TcpState > &  soRXe_SessStateRep,
stream< StateQuery > &  siTAi_ConnectStateQry,
stream< TcpState > &  soTAi_ConnectStateRep,
stream< SessionId > &  siTAi_StreamStateReq,
stream< TcpState > &  soTAi_StreamStateRep,
stream< SessionId > &  siTIm_SessCloseCmd,
stream< SessionId > &  soSLc_SessReleaseCmd 
)

State Table (STt)

ENTITY - State Table (STt)

Parameters
[in]siRXe_SessStateQrySession state query from RxEngine (RXe).
[out]soRXe_SessStateRepSession state reply to [RXe].
[in]siTAi_ConnectStateQrySession state query from [TxAppInterface/TxAppConnect(TAi/Tac).
[out]soTAi_ConnectStateRepSession state reply to [TAi/Tac].
[in]siTAi_StreamStateReqSession state request from TxAppInterface/TxAppStream (TAi/Tas).
[out]soTAi_StreamStateRepSession state reply to [TAi/Tas].
[in]siTIm_SessCloseCmdSession close command from Timers (TIm).
[out]soSLc_SessReleaseCmdRelease session command to SessionLookupController (SLc).

The StateTable (STt) stores the connection state of each session during its lifetime. The states are defined in RFC793 as: LISTEN, SYN-SENT, SYN-RECEIVED, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT and CLOSED. The StateTable is accessed by the RxEngine (RXe), the TxAppInterface (TAi) and by the TxEngine (TXe). The process also receives session close commands from the Timers (TIm) and it sends session release commands to the SessionLookupController (SLc).

Definition at line 99 of file state_table.cpp.

108 {
109  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
110  #pragma HLS PIPELINE II=1 enable_flush
111  #pragma HLS INLINE off
112 
113  //-- STATIC ARRAYS ---------------------------------------------------------
114  static TcpState SESS_STATE_TABLE[TOE_MAX_SESSIONS];
115  #pragma HLS RESOURCE variable=SESS_STATE_TABLE core=RAM_2P_BRAM
116  #pragma HLS DEPENDENCE variable=SESS_STATE_TABLE inter false
117 
118  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
119  static bool stt_rxWait=false;
120  #pragma HLS RESET variable=stt_rxWait
121  static bool stt_txWait=false;
122  #pragma HLS RESET variable=stt_txWait
123  static bool stt_rxSessionLocked=false;
124  #pragma HLS RESET variable=stt_rxSessionLocked
125  static bool stt_txSessionLocked=false;
126  #pragma HLS RESET variable=stt_txSessionLocked
127  static bool stt_closeWait=false;
128  #pragma HLS RESET variable=stt_closeWait
129 
130  //-- STATIC DATAFLOW VARIABLES ---------------------------------------------
131  static StateQuery stt_txAccess;
132  static StateQuery stt_rxAccess;
133  static SessionId stt_txSessionID;
134  static SessionId stt_rxSessionID;
135  static SessionId stt_closeSessionID;
136 
137  if(!siTAi_ConnectStateQry.empty() && !stt_txWait) {
138  //-------------------------------------------------
139  //-- Request from TAi/Connect
140  //-------------------------------------------------
141  siTAi_ConnectStateQry.read(stt_txAccess);
142  if ((stt_txAccess.sessionID == stt_rxSessionID) && stt_rxSessionLocked) {
143  stt_txWait = true;
144  }
145  else {
146  if (stt_txAccess.write) {
147  SESS_STATE_TABLE[stt_txAccess.sessionID] = stt_txAccess.state;
148  stt_txSessionLocked = false;
149  if (DEBUG_LEVEL & TRACE_STT) {
150  printInfo(THIS_NAME, "TAi is requesting to set SESS_STATE_TABLE[%d] = %s.\n", \
151  stt_txAccess.sessionID.to_uint(), \
152  getTcpStateName(stt_txAccess.state));
153  }
154  }
155  else {
156  soTAi_ConnectStateRep.write(SESS_STATE_TABLE[stt_txAccess.sessionID]);
157  // Lock on every read
158  stt_txSessionID = stt_txAccess.sessionID;
159  stt_txSessionLocked = true;
160  }
161  }
162  }
163  else if (!siTAi_StreamStateReq.empty()) {
164  //-------------------------------------------------
165  //-- Request from TAi/Stream
166  //-------------------------------------------------
167  SessionId sessionID;
168  siTAi_StreamStateReq.read(sessionID);
169  soTAi_StreamStateRep.write(SESS_STATE_TABLE[sessionID]);
170  }
171  else if(!siRXe_SessStateQry.empty() && !stt_rxWait) {
172  //-------------------------------------------------
173  //-- Request from RxEngine
174  //-------------------------------------------------
175  siRXe_SessStateQry.read(stt_rxAccess);
176  if ((stt_rxAccess.sessionID == stt_txSessionID) && stt_txSessionLocked) {
177  stt_rxWait = true;
178  }
179  else {
180  if (stt_rxAccess.write) {
181  if (stt_rxAccess.state == CLOSED) {
182  // [TODO] Do we need to check if already closed?
183  // [TODO] && state_table[stt_rxAccess.sessionID] != CLOSED)
184  soSLc_SessReleaseCmd.write(stt_rxAccess.sessionID);
185  }
186  SESS_STATE_TABLE[stt_rxAccess.sessionID] = stt_rxAccess.state;
187  stt_rxSessionLocked = false;
188  if (DEBUG_LEVEL & TRACE_STT) {
189  printInfo(THIS_NAME, "RXe is requesting to set SESS_STATE_TABLE[%d] = %s.\n", \
190  stt_rxAccess.sessionID.to_uint(), \
191  getTcpStateName(stt_rxAccess.state));
192  }
193  }
194  else {
195  soRXe_SessStateRep.write(SESS_STATE_TABLE[stt_rxAccess.sessionID]);
196  stt_rxSessionID = stt_rxAccess.sessionID;
197  stt_rxSessionLocked = true;
198  }
199  }
200  }
201  else if (!siTIm_SessCloseCmd.empty() && !stt_closeWait) {
202  //-------------------------------------------------
203  //-- Request to close connection from Timers
204  //-------------------------------------------------
205  siTIm_SessCloseCmd.read(stt_closeSessionID);
206  if (((stt_closeSessionID == stt_rxSessionID) && stt_rxSessionLocked) || \
207  ((stt_closeSessionID == stt_txSessionID) && stt_txSessionLocked)) {
208  // The session is currently locked
209  stt_closeWait = true;
210  }
211  else {
212  SESS_STATE_TABLE[stt_closeSessionID] = CLOSED;
213  soSLc_SessReleaseCmd.write(stt_closeSessionID);
214  if (DEBUG_LEVEL & TRACE_STT) {
215  printWarn(THIS_NAME, "TIm is requesting to close connection with SessId=%d.\n",
216  stt_closeSessionID.to_uint());
217  }
218  }
219  }
220  else if (stt_txWait) {
221  //-------------------------------------------------
222  //-- Tx Wait
223  //-------------------------------------------------
224  if ((stt_txAccess.sessionID != stt_rxSessionID) || !stt_rxSessionLocked) {
225  if (stt_txAccess.write) {
226  SESS_STATE_TABLE[stt_txAccess.sessionID] = stt_txAccess.state;
227  stt_txSessionLocked = false;
228  }
229  else {
230  soTAi_ConnectStateRep.write(SESS_STATE_TABLE[stt_txAccess.sessionID]);
231  stt_txSessionID = stt_txAccess.sessionID;
232  stt_txSessionLocked = true;
233  }
234  stt_txWait = false;
235  }
236  }
237  else if (stt_rxWait) {
238  //-------------------------------------------------
239  //-- Rx Wait
240  //-------------------------------------------------
241  if ((stt_rxAccess.sessionID != stt_txSessionID) || !stt_txSessionLocked) {
242  if (stt_rxAccess.write) {
243  if (stt_rxAccess.state == CLOSED) {
244  soSLc_SessReleaseCmd.write(stt_rxAccess.sessionID);
245  }
246  SESS_STATE_TABLE[stt_rxAccess.sessionID] = stt_rxAccess.state;
247  stt_rxSessionLocked = false;
248  }
249  else {
250  soRXe_SessStateRep.write(SESS_STATE_TABLE[stt_rxAccess.sessionID]);
251  stt_rxSessionID = stt_rxAccess.sessionID;
252  stt_rxSessionLocked = true;
253  }
254  stt_rxWait = false;
255  }
256  }
257  else if (stt_closeWait) {
258  //-------------------------------------------------
259  //-- Close Wait
260  //-------------------------------------------------
261  if (((stt_closeSessionID != stt_rxSessionID) || !stt_rxSessionLocked) && \
262  ((stt_closeSessionID != stt_txSessionID) || !stt_txSessionLocked)) {
263  SESS_STATE_TABLE[stt_closeSessionID] = CLOSED;
264  soSLc_SessReleaseCmd.write(stt_closeSessionID);
265  stt_closeWait = false;
266  }
267  }
268 }
RdWrBit write
Definition: toe.hpp:352
TcpState state
Definition: toe.hpp:351
SessionId sessionID
Definition: toe.hpp:350
#define TRACE_STT
Definition: state_table.cpp:71
Here is the caller graph for this function:

◆ timers()

void timers ( stream< RXeReTransTimerCmd > &  siRXe_ReTxTimerCmd,
stream< SessionId > &  siRXe_ClrProbeTimer,
stream< SessionId > &  siRXe_CloseTimer,
stream< TXeReTransTimerCmd > &  siTXe_ReTxTimerCmd,
stream< SessionId > &  siTXe_SetProbeTimer,
stream< SessionId > &  soSTt_SessCloseCmd,
stream< Event > &  soEVe_Event,
stream< SessState > &  soTAi_Notif,
stream< TcpAppNotif > &  soRAi_Notif 
)

The Timers (TIm)

ENTITY - Timers (TIm)

Parameters
[in]siRXe_ReTxTimerCmdRetransmission timer command from Rx Engine (RXe).
[in]siRXe_ClrProbeTimerClear probe timer from [RXe].
[in]siRXe_CloseTimerClose timer from [RXe].
[in]siTXe_ReTxTimerCmdRetransmission timer command from Tx Engine (TXe).
[in]siTXe_SetProbeTimerSet probe timer from [TXe].
[out]soEVe_EventEvent to EventEngine (EVe).
[out]soSTt_SessCloseCmdClose session command to State Table (STt).
[out]soTAi_NotifNotification to Tx Application Interface (TAi).
[out]soRAi_NotifNotification to Rx Application Interface (RAi).

@detail This process includes all the timer-based processes of the [TOE].

Definition at line 505 of file timers.cpp.

515 {
516  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
517  #pragma HLS INLINE
518 
519  //==========================================================================
520  //== LOCAL STREAMS (Sorted by the name of the modules which generate them)
521  //==========================================================================
522  static stream<SessionId> ssClsToSmx_SessCloseCmd ("ssClsToSmx_SessCloseCmd");
523  #pragma HLS stream variable=ssClsToSmx_SessCloseCmd depth=2
524 
525  static stream<SessionId> ssRttToSmx_SessCloseCmd ("ssRttToSmx_SessCloseCmd");
526  #pragma HLS stream variable=ssRttToSmx_SessCloseCmd depth=2
527 
528  static stream<Event> ssRttToEmx_Event ("ssRttToEmx_Event");
529  #pragma HLS stream variable=ssRttToEmx_Event depth=2
530  #pragma HLS DATA_PACK variable=ssRttToEmx_Event
531 
532  static stream<Event> ssPbtToEmx_Event ("ssPbtToEmx_Event");
533  #pragma HLS stream variable=ssPbtToEmx_Event depth=2
534  #pragma HLS DATA_PACK variable=ssPbtToEmx_Event
535 
536  // Event Mux (Emx) based on template stream Mux
537  // Notice order --> RetransmitTimer comes before ProbeTimer
538  pStreamMux(
539  ssRttToEmx_Event,
540  ssPbtToEmx_Event,
541  soEVe_Event);
542 
543  // ReTransmit Timer (Rtt)
545  siRXe_ReTxTimerCmd,
546  siTXe_ReTxTimerCmd,
547  ssRttToEmx_Event,
548  ssRttToSmx_SessCloseCmd,
549  soTAi_Notif,
550  soRAi_Notif);
551 
552  // Probe Timer (Pbt)
553  pProbeTimer(
554  siRXe_ClrProbeTimer,
555  siTXe_SetProbeTimer,
556  ssPbtToEmx_Event);
557 
558  pCloseTimer(
559  siRXe_CloseTimer,
560  ssClsToSmx_SessCloseCmd);
561 
562  // State table release Mux (Smx) based on template stream Mux
563  pStreamMux(
564  ssClsToSmx_SessCloseCmd,
565  ssRttToSmx_SessCloseCmd,
566  soSTt_SessCloseCmd);
567 
568 }
void pStreamMux(stream< T > &si1, stream< T > &si2, stream< T > &so)
A 2-to-1 generic Stream Multiplexer.
Definition: timers.cpp:90
void pRetransmitTimer(stream< RXeReTransTimerCmd > &siRXe_ReTxTimerCmd, stream< TXeReTransTimerCmd > &siTXe_ReTxTimerCmd, stream< Event > &soEmx_Event, stream< SessionId > &soSmx_SessCloseCmd, stream< SessState > &soTAi_Notif, stream< TcpAppNotif > &soRAi_Notif)
ReTransmit Timer (Rtt) process.
Definition: timers.cpp:135
void pCloseTimer(stream< SessionId > &siRXe_CloseTimer, stream< SessionId > &soSmx_SessCloseCmd)
Close Timer (Clt) process.
Definition: timers.cpp:426
void pProbeTimer(stream< SessionId > &siRXe_ClrProbeTimer, stream< SessionId > &siTXe_SetProbeTimer, stream< Event > &soEmx_Event)
Probe Timer (Prb) process.
Definition: timers.cpp:327
Here is the call graph for this function:
Here is the caller graph for this function:

◆ toe()

void toe ( Ip4Addr  piMMIO_IpAddr,
stream< StsBit > &  soMMIO_RxMemWrErr,
stream< ap_uint< 8 > > &  soMMIO_NotifDropCnt,
stream< ap_uint< 8 > > &  soMMIO_MetaDropCnt,
stream< ap_uint< 8 > > &  soMMIO_DataDropCnt,
stream< ap_uint< 8 > > &  soMMIO_CrcDropCnt,
stream< ap_uint< 8 > > &  soMMIO_SessDropCnt,
stream< ap_uint< 8 > > &  soMMIO_OooDropCnt,
StsBit poNTS_Ready,
stream< AxisIp4 > &  siIPRX_Data,
stream< AxisIp4 > &  soIPTX_Data,
stream< TcpAppNotif > &  soTAIF_Notif,
stream< TcpAppRdReq > &  siTAIF_DReq,
stream< TcpAppData > &  soTAIF_Data,
stream< TcpAppMeta > &  soTAIF_Meta,
stream< TcpAppLsnReq > &  siTAIF_LsnReq,
stream< TcpAppLsnRep > &  soTAIF_LsnRep,
stream< TcpAppData > &  siTAIF_Data,
stream< TcpAppSndReq > &  siTAIF_SndReq,
stream< TcpAppSndRep > &  soTAIF_SndRep,
stream< TcpAppOpnReq > &  siTAIF_OpnReq,
stream< TcpAppOpnRep > &  soTAIF_OpnRep,
stream< TcpAppClsReq > &  siTAIF_ClsReq,
stream< DmCmd > &  soMEM_RxP_RdCmd,
stream< AxisApp > &  siMEM_RxP_Data,
stream< DmSts > &  siMEM_RxP_WrSts,
stream< DmCmd > &  soMEM_RxP_WrCmd,
stream< AxisApp > &  soMEM_RxP_Data,
stream< DmCmd > &  soMEM_TxP_RdCmd,
stream< AxisApp > &  siMEM_TxP_Data,
stream< DmSts > &  siMEM_TxP_WrSts,
stream< DmCmd > &  soMEM_TxP_WrCmd,
stream< AxisApp > &  soMEM_TxP_Data,
stream< CamSessionLookupRequest > &  soCAM_SssLkpReq,
stream< CamSessionLookupReply > &  siCAM_SssLkpRep,
stream< CamSessionUpdateRequest > &  soCAM_SssUpdReq,
stream< CamSessionUpdateReply > &  siCAM_SssUpdRep,
stream< ap_uint< 16 > > &  soDBG_SssRelCnt,
stream< ap_uint< 16 > > &  soDBG_SssRegCnt,
stream< RxBufPtr > &  soDBG_RxFreeSpace,
stream< ap_uint< 32 > > &  soDBG_TcpIpRxByteCnt,
stream< ap_uint< 8 > > &  soDBG_OooDebug 
)

Main process of the TCP Offload Engine (TOE0.

– MMIO Interfaces

Parameters
[in]piMMIO_IpAddrIP4 Address from [MMIO].
[out]soMMIO_RxMemWrErrReports a Rx memory write error.
[out]soMMIO_NotifDropThe value of the notification drop counter.
[out]soMMIO_MetaDropThe value of the metadata drop counter.
[out]soMMIO_DataDropThe value of the data drop counter.
[out]soMMIO_CrcDropThe value of the CRC drop counter.
[out]soMMIO_SessDropThe value of the session drop counter.
[out]soMMIO_OooDropThe value of the out-of-order drop counter. – NTS Interfaces
[out]poNTS_ReadyReady signal of TOE. – IPRX / IP Rx / Data Interface
[in]siIPRX_DataIP4 data stream from [IPRX]. – IPTX / IP Tx / Data Interface
[out]soIPTX_DataIP4 data stream to [IPTX]. – TAIF / Rx Data Interfaces
[out]soTAIF_NotifAPP data notification to [TAIF].
[in]siTAIF_DReqAPP data request from [TAIF].
[out]soTAIF_DataAPP data stream to [TAIF].
[out]soTAIF_MetaAPP metadata stream to [TAIF]. – TAIF / Listen Port Interfaces
[in]siTAIF_LsnReqAPP listen port request from [TAIF].
[out]soTAIF_LsnRepAPP listen port reply to [TAIF]. – TAIF / Tx Data Interfaces
[in]siTAIF_DataAPP data stream from [TAIF].
[in]siTAIF_SndReqAPP request to send from [TAIF].
[out]soTAIF_SndRepAPP send reply to [TAIF]. – TAIF / Open Interfaces
[in]siTAIF_OpnReqAPP open port request from [TAIF].
[out]soTAIF_OpnRepAPP open port reply to [TAIF]. – TAIF / Close Interfaces
[in]siTAIF_ClsReqAPP close connection request from [TAIF].
Warning
: Not-Used APP close connection status to [TAIF]. – MEM / Rx PATH / S2MM Interface
: Not-Used Rx memory read status from [MEM].
Parameters
[out]soMEM_RxP_RdCmdRx memory read command to [MEM].
[in]siMEM_RxP_DataRx memory data from [MEM].
[in]siMEM_RxP_WrStsRx memory write status from [MEM].
[out]soMEM_RxP_WrCmdRx memory write command to [MEM].
[out]soMEM_RxP_DataRx memory data to [MEM]. – MEM / Tx PATH / S2MM Interface
Warning
: Not-Used Tx memory read status from [MEM].
Parameters
[out]soMEM_TxP_RdCmdTx memory read command to [MEM].
[in]siMEM_TxP_DataTx memory data from [MEM].
[in]siMEM_TxP_WrStsTx memory write status from [MEM].
[out]soMEM_TxP_WrCmdTx memory write command to [MEM].
[out]soMEM_TxP_DataTx memory data to [MEM]. – CAM / Session Lookup & Update Interfaces
[in]siCAM_SssLkpRepSession lookup reply from [CAM].
[in]siCAM_SssUpdRepSession update reply from [CAM].
[out]soCAM_SssLkpReqSession lookup request to [CAM].
[out]soCAM_SssUpdReqSession update request to [CAM]. – DEBUG / Session Statistics Interfaces
[out]soDBG_SssRelCntSession release count to DEBUG.
[out]soDBG_SssRegCntSession register count to DEBUG.

PROCESS FUNCTIONS: TCP STATE-KEEPING DATA STRUCTURES

PROCESS FUNCTIONS: RX & TX ENGINES

PROCESSS FUNCTIONS: APPLICATION INTERFACES

PROCESS FUNCTIONS: CONTROL AND DEBUG INTERFACES

Definition at line 231 of file toe.cpp.

333 {
334  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
335  #pragma HLS DATAFLOW
336  #pragma HLS INLINE
337  #pragma HLS INTERFACE ap_ctrl_none port=return
338 
339  //-------------------------------------------------------------------------
340  //-- LOCAL STREAMS AND SIGNALS
341  //-- (Sorted by the name of the modules which generate them)
342  //-------------------------------------------------------------------------
343 
344  //-------------------------------------------------------------------------
345  //-- ACK Delayer (AKd)
346  //-------------------------------------------------------------------------
347  static stream<ExtendedEvent> ssAKdToTXe_Event ("ssAKdToTXe_Event");
348  #pragma HLS stream variable=ssAKdToTXe_Event depth=cDepth_AKdToTXe_Event
349  #pragma HLS DATA_PACK variable=ssAKdToTXe_Event
350 
351  static stream<SigBit> ssAKdToEVe_RxEventSig ("ssAKdToEVe_RxEventSig");
352  #pragma HLS stream variable=ssAKdToEVe_RxEventSig depth=cDepth_AKdToEVe_Event
353 
354  static stream<SigBit> ssAKdToEVe_TxEventSig ("ssAKdToEVe_TxEventSig");
355  #pragma HLS stream variable=ssAKdToEVe_TxEventSig depth=cDepth_AKdToEVe_Event
356 
357  //-------------------------------------------------------------------------
358  //-- Event Engine (EVe)
359  //-------------------------------------------------------------------------
360  static stream<ExtendedEvent> ssEVeToAKd_Event ("ssEVeToAKd_Event");
361  #pragma HLS stream variable=ssEVeToAKd_Event depth=cDepth_EVeToAKd_Event
362  #pragma HLS DATA_PACK variable=ssEVeToAKd_Event
363 
364  //-------------------------------------------------------------------------
365  //-- Port Table (PRt)
366  //-------------------------------------------------------------------------
367  StsBool sPRtToRdy_Ready;
368 
369  static stream<RepBit> ssPRtToRXe_PortStateRep ("ssPRtToRXe_PortStateRep");
370  #pragma HLS stream variable=ssPRtToRXe_PortStateRep depth=4
371 
372  static stream<AckBit> ssPRtToRAi_OpnLsnPortRep ("ssPRtToRAi_OpnLsnPortRep");
373  #pragma HLS stream variable=ssPRtToRAi_OpnLsnPortRep depth=4
374 
375  static stream<TcpPort> ssPRtToTAi_GetFreePortRep ("ssPRtToTAi_GetFreePortRep");
376  #pragma HLS stream variable=ssPRtToTAi_GetFreePortRep depth=4
377 
378  //-- Rx Application Interface (RAi) ---------------------------------------
379  static stream<TcpPort> ssRAiToPRt_OpnLsnPortReq ("ssRAiToPRt_OpnLsnPortReq");
380  #pragma HLS stream variable=ssRAiToPRt_OpnLsnPortReq depth=4
381 
382  static stream<RAiRxSarQuery> ssRAiToRSt_RxSarQry ("ssRAiToRSt_RxSarQry");
383  #pragma HLS stream variable=ssRAiToRSt_RxSarQry depth=cDepth_RAiToRSt_Qry
384  #pragma HLS DATA_PACK variable=ssRAiToRSt_RxSarQry
385 
386  //-------------------------------------------------------------------------
387  //-- Rx Engine (RXe)
388  //-------------------------------------------------------------------------
389  static stream<SessionLookupQuery> ssRXeToSLc_SessLkpReq ("ssRXeToSLc_SessLkpReq");
390  #pragma HLS stream variable=ssRXeToSLc_SessLkpReq depth=4
391  #pragma HLS DATA_PACK variable=ssRXeToSLc_SessLkpReq
392 
393  static stream<TcpPort> ssRXeToPRt_PortStateReq ("ssRXeToPRt_PortStateReq");
394  #pragma HLS stream variable=ssRXeToPRt_PortStateReq depth=4
395 
396  static stream<StateQuery> ssRXeToSTt_SessStateQry ("ssRXeToSTt_SessStateQry");
397  #pragma HLS stream variable=ssRXeToSTt_SessStateQry depth=2
398  #pragma HLS DATA_PACK variable=ssRXeToSTt_SessStateQry
399 
400  static stream<RXeRxSarQuery> ssRXeToRSt_RxSarQry ("ssRXeToRSt_RxSarQry");
401  #pragma HLS stream variable=ssRXeToRSt_RxSarQry depth=cDepth_RXeToRSt_Qry
402  #pragma HLS DATA_PACK variable=ssRXeToRSt_RxSarQry
403 
404  static stream<RXeTxSarQuery> ssRXeToTSt_TxSarQry ("ssRXeToTSt_TxSarQry");
405  #pragma HLS stream variable=ssRXeToTSt_TxSarQry depth=cDepth_RXeToTSt_Qry
406  #pragma HLS DATA_PACK variable=ssRXeToTSt_TxSarQry
407 
408  static stream<RXeReTransTimerCmd> ssRXeToTIm_ReTxTimerCmd ("ssRXeToTIm_ReTxTimerCmd");
409  #pragma HLS stream variable=ssRXeToTIm_ReTxTimerCmd depth=2
410  #pragma HLS DATA_PACK variable=ssRXeToTIm_ReTxTimerCmd
411 
412  static stream<SessionId> ssRXeToTIm_CloseTimer ("ssRXeToTIm_CloseTimer");
413  #pragma HLS stream variable=ssRXeToTIm_CloseTimer depth=2
414 
415  static stream<SessionId> ssRXeToTIm_ClrProbeTimer ("ssRXeToTIm_ClrProbeTimer");
416  #pragma HLS stream variable=ssRXeToTIm_ClrProbeTimer depth=2
417 
418  static stream<TcpAppNotif> ssRXeToRAi_Notif ("ssRXeToRAi_Notif");
419  #pragma HLS stream variable=ssRXeToRAi_Notif depth=4
420  #pragma HLS DATA_PACK variable=ssRXeToRAi_Notif
421 
422  static stream<SessState> ssRXeToTAi_SessOpnSts ("ssRXeToTAi_SessOpnSts");
423  #pragma HLS stream variable=ssRXeToTAi_SessOpnSts depth=4
424  #pragma HLS DATA_PACK variable=ssRXeToTAi_SessOpnSts
425 
426  static stream<ExtendedEvent> ssRXeToEVe_Event ("ssRXeToEVe_Event");
427  #pragma HLS stream variable=ssRXeToEVe_Event depth=cDepth_RXeToEVe_Event
428  #pragma HLS DATA_PACK variable=ssRXeToEVe_Event
429 
430  //-- Rx SAR Table (RSt) ---------------------------------------------------
431  static stream<RxSarReply> ssRStToRXe_RxSarRep ("ssRStToRXe_RxSarRep");
432  #pragma HLS stream variable=ssRStToRXe_RxSarRep depth=2
433  #pragma HLS DATA_PACK variable=ssRStToRXe_RxSarRep
434 
435  static stream<RAiRxSarReply> ssRStToRAi_RxSarRep ("ssRStToRAi_RxSarRep");
436  #pragma HLS stream variable=ssRStToRAi_RxSarRep depth=2
437  #pragma HLS DATA_PACK variable=ssRStToRAi_RxSarRep
438 
439  static stream<RxSarReply> ssRStToTXe_RxSarRep ("ssRStToTXe_RxSarRep");
440  #pragma HLS stream variable=ssRStToTXe_RxSarRep depth=2
441  #pragma HLS DATA_PACK variable=ssRStToTXe_RxSarRep
442 
443  //-------------------------------------------------------------------------
444  //-- Session Lookup Controller (SLc)
445  //-------------------------------------------------------------------------
446  static stream<SessionLookupReply> ssSLcToRXe_SessLkpRep ("ssSLcToRXe_SessLkpRep");
447  #pragma HLS stream variable=ssSLcToRXe_SessLkpRep depth=4
448  #pragma HLS DATA_PACK variable=ssSLcToRXe_SessLkpRep
449 
450  static stream<SessionLookupReply> ssSLcToTAi_SessLookupRep ("ssSLcToTAi_SessLookupRep");
451  #pragma HLS stream variable=ssSLcToTAi_SessLookupRep depth=4
452  #pragma HLS DATA_PACK variable=ssSLcToTAi_SessLookupRep
453 
454  static stream<TcpPort> ssSLcToPRt_ReleasePort ("ssSLcToPRt_ReleasePort");
455  #pragma HLS stream variable=ssSLcToPRt_ReleasePort depth=4
456 
457  static stream<fourTuple> ssSLcToTXe_ReverseLkpRep ("ssSLcToTXe_ReverseLkpRep");
458  #pragma HLS stream variable=ssSLcToTXe_ReverseLkpRep depth=4
459  #pragma HLS DATA_PACK variable=ssSLcToTXe_ReverseLkpRep
460 
461  //-------------------------------------------------------------------------
462  //-- State Table (STt)
463  //-------------------------------------------------------------------------
464  static stream<TcpState> ssSTtToRXe_SessStateRep ("ssSTtToRXe_SessStateRep");
465  #pragma HLS stream variable=ssSTtToRXe_SessStateRep depth=cDepth_STtToRXe_Rep
466 
467  static stream<TcpState> ssSTtToTAi_AcceptStateRep ("ssSTtToTAi_AcceptStateRep");
468  #pragma HLS stream variable=ssSTtToTAi_AcceptStateRep depth=cDepth_STtToTAi_Rep
469 
470  static stream<TcpState> ssSTtToTAi_SessStateRep ("ssSTtToTAi_SessStateRep");
471  #pragma HLS stream variable=ssSTtToTAi_SessStateRep depth=2
472 
473  static stream<SessionId> ssSTtToSLc_SessReleaseCmd ("ssSTtToSLc_SessReleaseCmd");
474  #pragma HLS stream variable=ssSTtToSLc_SessReleaseCmd depth=2
475 
476  //-------------------------------------------------------------------------
477  //-- Tx Application Interface (TAi)
478  //-------------------------------------------------------------------------
479  static stream<ReqBit> ssTAiToPRt_GetFeePortReq ("ssTAiToPRt_GetFeePortReq");
480  #pragma HLS stream variable=ssTAiToPRt_GetFeePortReq depth=4
481 
482  static stream<SocketPair> ssTAiToSLc_SessLookupReq ("ssTAiToSLc_SessLookupReq");
483  #pragma HLS DATA_PACK variable=ssTAiToSLc_SessLookupReq
484  #pragma HLS stream variable=ssTAiToSLc_SessLookupReq depth=4
485 
486  static stream<Event> ssTAiToEVe_Event ("ssTAiToEVe_Event");
487  #pragma HLS stream variable=ssTAiToEVe_Event depth=cDepth_TAiToEVe_Event
488  #pragma HLS DATA_PACK variable=ssTAiToEVe_Event
489 
490  static stream<TAiTxSarPush> ssTAiToTSt_PushCmd ("ssTAiToTSt_PushCmd");
491  #pragma HLS stream variable=ssTAiToTSt_PushCmd depth=cDepth_TAiToTSt_Cmd
492  #pragma HLS DATA_PACK variable=ssTAiToTSt_PushCmd
493 
494  static stream<StateQuery> ssTAiToSTt_AcceptStateQry ("ssTAiToSTt_AcceptStateQry");
495  #pragma HLS stream variable=ssTAiToSTt_AcceptStateQry depth=2
496  #pragma HLS DATA_PACK variable=ssTAiToSTt_AcceptStateQry
497 
498  static stream<TcpSessId> ssTAiToSTt_SessStateReq ("ssTAiToSTt_SessStateReq");
499  #pragma HLS stream variable=ssTAiToSTt_SessStateReq depth=2
500 
501  //-------------------------------------------------------------------------
502  //-- Timers (TIm)
503  //-------------------------------------------------------------------------
504  static stream<Event> ssTImToEVe_Event ("ssTImToEVe_Event");
505  #pragma HLS stream variable=ssTImToEVe_Event depth=cDepth_TImToEVe_Event
506  #pragma HLS DATA_PACK variable=ssTImToEVe_Event
507 
508  static stream<SessionId> ssTImToSTt_SessCloseCmd ("ssTImToSTt_SessCloseCmd");
509  #pragma HLS stream variable=ssTImToSTt_SessCloseCmd depth=2
510 
511  static stream<SessState> ssTImToTAi_Notif ("ssTImToTAi_Notif");
512  #pragma HLS stream variable=ssTImToTAi_Notif depth=4
513  #pragma HLS DATA_PACK variable=ssTImToTAi_Notif
514 
515  static stream<TcpAppNotif> ssTImToRAi_Notif ("ssTImToRAi_Notif");
516  #pragma HLS stream variable=ssTImToRAi_Notif depth=4
517  #pragma HLS DATA_PACK variable=ssTImToRAi_Notif
518 
519  //-------------------------------------------------------------------------
520  //-- Tx Engine (TXe)
521  //-------------------------------------------------------------------------
522  static stream<SigBit> ssTXeToEVe_RxEventSig ("ssTXeToEVe_RxEventSig");
523  #pragma HLS stream variable=ssTXeToEVe_RxEventSig depth=cDepth_TXeToEVe_Event
524 
525  static stream<SessionId> ssTXeToRSt_RxSarReq ("ssTXeToRSt_RxSarReq");
526  #pragma HLS stream variable=ssTXeToRSt_RxSarReq depth=cDepth_TXeToRSt_Req
527 
528  static stream<TXeTxSarQuery> ssTXeToTSt_TxSarQry ("ssTXeToTSt_TxSarQry");
529  #pragma HLS stream variable=ssTXeToTSt_TxSarQry depth=cDepth_TXeToTSt_Qry
530  #pragma HLS DATA_PACK variable=ssTXeToTSt_TxSarQry
531 
532  static stream<SessionId> ssTXeToSLc_ReverseLkpReq ("ssTXeToSLc_ReverseLkpReq");
533  #pragma HLS stream variable=ssTXeToSLc_ReverseLkpReq depth=4
534 
535  static stream<TXeReTransTimerCmd> ssTXeToTIm_SetReTxTimer ("ssTXeToTIm_SetReTxTimer");
536  #pragma HLS stream variable=ssTXeToTIm_SetReTxTimer depth=2
537  #pragma HLS DATA_PACK variable=ssTXeToTIm_SetReTxTimer
538 
539  static stream<SessionId> ssTXeToTIm_SetProbeTimer ("ssTXeToTIm_SetProbeTimer");
540  #pragma HLS stream variable=ssTXeToTIm_SetProbeTimer depth=2
541 
542  //-------------------------------------------------------------------------
543  //-- Tx SAR Table (TSt)
544  //-------------------------------------------------------------------------
545  static stream<RXeTxSarReply> ssTStToRXe_TxSarRep ("ssTStToRXe_TxSarRep");
546  #pragma HLS stream variable=ssTStToRXe_TxSarRep depth=cDepth_TStToRXe_Rep
547  #pragma HLS DATA_PACK variable=ssTStToRXe_TxSarRep
548 
549  static stream<TXeTxSarReply> ssTStToTXe_TxSarRep ("ssTStToTXe_TxSarRep");
550  #pragma HLS stream variable=ssTStToTXe_TxSarRep depth=cDepth_TStToTXe_Rep
551  #pragma HLS DATA_PACK variable=ssTStToTXe_TxSarRep
552 
553  static stream<TStTxSarPush> ssTStToTAi_PushCmd ("ssTStToTAi_PushCmd");
554  #pragma HLS stream variable=ssTStToTAi_PushCmd depth=cDepth_TStToTAi_Cmd
555  #pragma HLS DATA_PACK variable=ssTStToTAi_PushCmd
556 
557 
561  //-- Session Lookup Controller (SLc) -----------------------------------
563  ssRXeToSLc_SessLkpReq,
564  ssSLcToRXe_SessLkpRep,
565  ssSTtToSLc_SessReleaseCmd,
566  ssSLcToPRt_ReleasePort,
567  ssTAiToSLc_SessLookupReq,
568  ssSLcToTAi_SessLookupRep,
569  ssTXeToSLc_ReverseLkpReq,
570  ssSLcToTXe_ReverseLkpRep,
571  soCAM_SssLkpReq,
572  siCAM_SssLkpRep,
573  soCAM_SssUpdReq,
574  siCAM_SssUpdRep,
575  soDBG_SssRelCnt,
576  soDBG_SssRegCnt);
577 
578  //-- State Table (STt) -------------------------------------------------
579  state_table(
580  ssRXeToSTt_SessStateQry,
581  ssSTtToRXe_SessStateRep,
582  ssTAiToSTt_AcceptStateQry,
583  ssSTtToTAi_AcceptStateRep,
584  ssTAiToSTt_SessStateReq,
585  ssSTtToTAi_SessStateRep,
586  ssTImToSTt_SessCloseCmd,
587  ssSTtToSLc_SessReleaseCmd);
588 
589  //-- RX SAR Table (RSt) ------------------------------------------------
590  rx_sar_table(
591  ssRXeToRSt_RxSarQry,
592  ssRStToRXe_RxSarRep,
593  ssRAiToRSt_RxSarQry,
594  ssRStToRAi_RxSarRep,
595  ssTXeToRSt_RxSarReq,
596  ssRStToTXe_RxSarRep);
597 
598  //-- TX SAR Table (TSt) ------------------------------------------------
599  tx_sar_table(
600  ssRXeToTSt_TxSarQry,
601  ssTStToRXe_TxSarRep,
602  ssTXeToTSt_TxSarQry,
603  ssTStToTXe_TxSarRep,
604  ssTAiToTSt_PushCmd,
605  ssTStToTAi_PushCmd);
606 
607  //-- Port Table (PRt) --------------------------------------------------
608  port_table(
609  sPRtToRdy_Ready,
610  ssRXeToPRt_PortStateReq,
611  ssPRtToRXe_PortStateRep,
612  ssRAiToPRt_OpnLsnPortReq,
613  ssPRtToRAi_OpnLsnPortRep,
614  ssTAiToPRt_GetFeePortReq,
615  ssPRtToTAi_GetFreePortRep,
616  ssSLcToPRt_ReleasePort);
617 
618  //-- Timers (TIm) ------------------------------------------------------
619  timers(
620  ssRXeToTIm_ReTxTimerCmd,
621  ssRXeToTIm_ClrProbeTimer,
622  ssRXeToTIm_CloseTimer,
623  ssTXeToTIm_SetReTxTimer,
624  ssTXeToTIm_SetProbeTimer,
625  ssTImToSTt_SessCloseCmd,
626  ssTImToEVe_Event,
627  ssTImToTAi_Notif,
628  ssTImToRAi_Notif);
629 
630  //-- Event Engine (EVe) ------------------------------------------------
631  event_engine(
632  ssTAiToEVe_Event,
633  ssRXeToEVe_Event,
634  ssTImToEVe_Event,
635  ssEVeToAKd_Event,
636  ssAKdToEVe_RxEventSig,
637  ssAKdToEVe_TxEventSig,
638  ssTXeToEVe_RxEventSig);
639 
640  //-- Ack Delayer (AKd)) ----------------------------------------------
641  ack_delay(
642  ssEVeToAKd_Event,
643  ssAKdToEVe_RxEventSig,
644  ssAKdToEVe_TxEventSig,
645  ssAKdToTXe_Event);
646 
647 
648 
652  //-- RX Engine (RXe) --------------------------------------------------
653  rx_engine(
654  siIPRX_Data,
655  ssRXeToSLc_SessLkpReq,
656  ssSLcToRXe_SessLkpRep,
657  ssRXeToSTt_SessStateQry,
658  ssSTtToRXe_SessStateRep,
659  ssRXeToPRt_PortStateReq,
660  ssPRtToRXe_PortStateRep,
661  ssRXeToRSt_RxSarQry,
662  ssRStToRXe_RxSarRep,
663  ssRXeToTSt_TxSarQry,
664  ssTStToRXe_TxSarRep,
665  ssRXeToTIm_ReTxTimerCmd,
666  ssRXeToTIm_ClrProbeTimer,
667  ssRXeToTIm_CloseTimer,
668  ssRXeToEVe_Event,
669  ssRXeToTAi_SessOpnSts,
670  ssRXeToRAi_Notif,
671  soMEM_RxP_WrCmd,
672  soMEM_RxP_Data,
673  siMEM_RxP_WrSts,
674  soMMIO_RxMemWrErr,
675  soMMIO_CrcDropCnt,
676  soMMIO_SessDropCnt,
677  soMMIO_OooDropCnt,
678  soDBG_RxFreeSpace,
679  soDBG_TcpIpRxByteCnt,
680  soDBG_OooDebug);
681 
682  //-- TX Engine (TXe) --------------------------------------------------
683  tx_engine(
684  ssAKdToTXe_Event,
685  ssTXeToEVe_RxEventSig,
686  ssTXeToRSt_RxSarReq,
687  ssRStToTXe_RxSarRep,
688  ssTXeToTSt_TxSarQry,
689  ssTStToTXe_TxSarRep,
690  soMEM_TxP_RdCmd,
691  siMEM_TxP_Data,
692  ssTXeToTIm_SetReTxTimer,
693  ssTXeToTIm_SetProbeTimer,
694  ssTXeToSLc_ReverseLkpReq,
695  ssSLcToTXe_ReverseLkpRep,
696  soIPTX_Data);
697 
698 
699 
703  //-- Rx Application Interface (RAi) -----------------------------------
705  soTAIF_Notif,
706  siTAIF_DReq,
707  soTAIF_Data,
708  soTAIF_Meta,
709  siTAIF_LsnReq,
710  soTAIF_LsnRep,
711  ssRAiToPRt_OpnLsnPortReq,
712  ssPRtToRAi_OpnLsnPortRep,
713  ssRXeToRAi_Notif,
714  ssTImToRAi_Notif,
715  ssRAiToRSt_RxSarQry,
716  ssRStToRAi_RxSarRep,
717  soMEM_RxP_RdCmd,
718  siMEM_RxP_Data,
719  soMMIO_NotifDropCnt,
720  soMMIO_MetaDropCnt,
721  soMMIO_DataDropCnt);
722 
723  //-- Tx Application Interface (TAi) ------------------------------------
725  siTAIF_OpnReq,
726  soTAIF_OpnRep,
727  siTAIF_ClsReq,
728  siTAIF_Data,
729  siTAIF_SndReq,
730  soTAIF_SndRep,
731  soMEM_TxP_WrCmd,
732  soMEM_TxP_Data,
733  siMEM_TxP_WrSts,
734  ssTAiToSTt_SessStateReq,
735  ssSTtToTAi_SessStateRep,
736  ssTAiToSTt_AcceptStateQry, // [FIXME- ReEname ConnectStateQry]
737  ssSTtToTAi_AcceptStateRep,
738  ssTAiToSLc_SessLookupReq,
739  ssSLcToTAi_SessLookupRep,
740  ssTAiToPRt_GetFeePortReq,
741  ssPRtToTAi_GetFreePortRep,
742  ssTStToTAi_PushCmd,
743  ssTAiToTSt_PushCmd,
744  ssRXeToTAi_SessOpnSts,
745  ssTAiToEVe_Event,
746  ssTImToTAi_Notif,
747  piMMIO_IpAddr);
748 
749 
753  //-- Ready signal generator -------------------------------------------
754  pReady(
755  sPRtToRdy_Ready,
756  poNTS_Ready);
757 
758  #if TOE_FEATURE_USED_FOR_DEBUGGING
759  //-- Testbench counter incrementer (for debugging) --------------------
760  pTbSimCount(
761  poSimCycCount);
762  #endif
763 
764 }
void rx_engine(stream< AxisIp4 > &siIPRX_Data, stream< SessionLookupQuery > &soSLc_SessLkReq, stream< SessionLookupReply > &siSLc_SessLkRep, stream< StateQuery > &soSTt_StateQry, stream< TcpState > &siSTt_StateRep, stream< TcpPort > &soPRt_PortStateReq, stream< RepBit > &siPRt_PortStateRep, stream< RXeRxSarQuery > &soRSt_RxSarQry, stream< RxSarReply > &siRSt_RxSarRep, stream< RXeTxSarQuery > &soTSt_TxSarQry, stream< RXeTxSarReply > &siTSt_TxSarRep, stream< RXeReTransTimerCmd > &soTIm_ReTxTimerCmd, stream< SessionId > &soTIm_ClearProbeTimer, stream< SessionId > &soTIm_CloseTimer, stream< ExtendedEvent > &soEVe_SetEvent, stream< SessState > &soTAi_SessOpnSts, stream< TcpAppNotif > &soRAi_RxNotif, stream< DmCmd > &soMEM_WrCmd, stream< AxisApp > &soMEM_WrData, stream< DmSts > &siMEM_WrSts, stream< StsBit > &soMMIO_RxMemWrErr, stream< ap_uint< 8 > > &soMMIO_CrcDropCnt, stream< ap_uint< 8 > > &soMMIO_SessDropCnt, stream< ap_uint< 8 > > &soMMIO_OooDropCnt, stream< RxBufPtr > &soDBG_RxFreeSpace, stream< ap_uint< 32 > > &soDBG_TcpIpRxByteCnt, stream< ap_uint< 8 > > &soDBG_OooDebug)
Receive Engine (RXe)
Definition: rx_engine.cpp:2000
void rx_sar_table(stream< RXeRxSarQuery > &siRXe_RxSarQry, stream< RxSarReply > &soRXe_RxSarRep, stream< RAiRxSarQuery > &siRAi_RxSarQry, stream< RAiRxSarReply > &soRAi_RxSarRep, stream< SessionId > &siTXe_RxSarReq, stream< RxSarReply > &soTxe_RxSarRep)
Rx SAR Table (RSt)
void ack_delay(stream< ExtendedEvent > &siEVe_Event, stream< SigBit > &soEVe_RxEventSig, stream< SigBit > &soEVe_TxEventSig, stream< ExtendedEvent > &soTXe_Event)
ACK Delayer (AKd)
Definition: ack_delay.cpp:95
void session_lookup_controller(stream< SessionLookupQuery > &siRXe_SessLookupReq, stream< SessionLookupReply > &soRXe_SessLookupRep, stream< SessionId > &siSTt_SessReleaseCmd, stream< TcpPort > &soPRt_ClosePortCmd, stream< SocketPair > &siTAi_SessLookupReq, stream< SessionLookupReply > &soTAi_SessLookupRep, stream< SessionId > &siTXe_ReverseLkpReq, stream< fourTuple > &soTXe_ReverseLkpRep, stream< CamSessionLookupRequest > &soCAM_SessLookupReq, stream< CamSessionLookupReply > &siCAM_SessLookupRep, stream< CamSessionUpdateRequest > &soCAM_SessUpdateReq, stream< CamSessionUpdateReply > &siCAM_SessUpdateRep, stream< ap_uint< 16 > > &soSssRelCnt, stream< ap_uint< 16 > > &soSssRegCnt)
Session Lookup Controller (SLc)
void timers(stream< RXeReTransTimerCmd > &siRXe_ReTxTimerCmd, stream< SessionId > &siRXe_ClrProbeTimer, stream< SessionId > &siRXe_CloseTimer, stream< TXeReTransTimerCmd > &siTXe_ReTxTimerCmd, stream< SessionId > &siTXe_SetProbeTimer, stream< SessionId > &soSTt_SessCloseCmd, stream< Event > &soEVe_Event, stream< SessState > &soTAi_Notif, stream< TcpAppNotif > &soRAi_Notif)
The Timers (TIm)
Definition: timers.cpp:505
void tx_sar_table(stream< RXeTxSarQuery > &siRXe_TxSarQry, stream< RXeTxSarReply > &soRXe_TxSarRep, stream< TXeTxSarQuery > &siTXe_TxSarQry, stream< TXeTxSarReply > &soTXe_TxSarRep, stream< TAiTxSarPush > &siTAi_PushCmd, stream< TStTxSarPush > &soTAi_PushCmd)
Tx Sar Table (TSt). Stores the data structures for managing the TCP Tx buffer and Tx sliding window.
void tx_app_interface(stream< TcpAppOpnReq > &siTAIF_OpnReq, stream< TcpAppOpnRep > &soTAIF_OpnRep, stream< TcpAppClsReq > &siTAIF_ClsReq, stream< TcpAppData > &siTAIF_Data, stream< TcpAppSndReq > &siTAIF_SndReq, stream< TcpAppSndRep > &soTAIF_SndRep, stream< DmCmd > &soMEM_TxP_WrCmd, stream< AxisApp > &soMEM_TxP_Data, stream< DmSts > &siMEM_TxP_WrSts, stream< SessionId > &soSTt_SessStateReq, stream< TcpState > &siSTt_SessStateRep, stream< StateQuery > &soSTt_ConnectStateQry, stream< TcpState > &siSTt_ConnectStateRep, stream< SocketPair > &soSLc_SessLookupReq, stream< SessionLookupReply > &siSLc_SessLookupRep, stream< ReqBit > &soPRt_GetFreePortReq, stream< TcpPort > &siPRt_GetFreePortRep, stream< TStTxSarPush > &siTSt_PushCmd, stream< TAiTxSarPush > &soTSt_PushCmd, stream< SessState > &siRXe_ActSessState, stream< Event > &soEVe_Event, stream< SessState > &siTIm_Notif, Ip4Addr piMMIO_IpAddr)
Tx Application Interface (TAi)
void port_table(StsBool &poTOE_Ready, stream< TcpPort > &siRXe_GetPortStateReq, stream< RepBit > &soRXe_GetPortStateRep, stream< TcpPort > &siRAi_OpenLsnPortReq, stream< AckBit > &soRAi_OpenLsnPortAck, stream< ReqBit > &siTAi_GetFreePortReq, stream< TcpPort > &soTAi_GetFreePortRep, stream< TcpPort > &siSLc_CloseActPortCmd)
Port Table (PRt)
Definition: port_table.cpp:453
void state_table(stream< StateQuery > &siRXe_SessStateQry, stream< TcpState > &soRXe_SessStateRep, stream< StateQuery > &siTAi_ConnectStateQry, stream< TcpState > &soTAi_ConnectStateRep, stream< SessionId > &siTAi_StreamStateReq, stream< TcpState > &soTAi_StreamStateRep, stream< SessionId > &siTIm_SessCloseCmd, stream< SessionId > &soSLc_SessReleaseCmd)
State Table (STt)
Definition: state_table.cpp:99
void event_engine(stream< Event > &siTAi_Event, stream< ExtendedEvent > &siRXe_Event, stream< Event > &siTIm_Event, stream< ExtendedEvent > &soAKd_Event, stream< SigBit > &siAKd_RxEventSig, stream< SigBit > &siAKd_TxEventSig, stream< SigBit > &siTXe_RxEventSig)
The Event Engine (EVe) arbitrates the incoming events and forwards them to the Tx Engine (TXe) via th...
void pReady(StsBool &piPRt_Ready, StsBit &poNTS_Ready)
Ready (Rdy)
Definition: toe.cpp:133
void rx_app_interface(stream< TcpAppNotif > &soTAIF_Notif, stream< TcpAppRdReq > &siTAIF_DataReq, stream< TcpAppData > &soTAIF_Data, stream< TcpAppMeta > &soTAIF_Meta, stream< TcpAppLsnReq > &siTAIF_LsnReq, stream< TcpAppLsnRep > &soTAIF_LsnRep, stream< TcpPort > &soPRt_LsnReq, stream< AckBit > &siPRt_LsnAck, stream< TcpAppNotif > &siRXe_Notif, stream< TcpAppNotif > &siTIm_Notif, stream< RAiRxSarQuery > &soRSt_RxSarReq, stream< RAiRxSarReply > &siRSt_RxSarRep, stream< DmCmd > &soMEM_RxP_RdCmd, stream< AxisApp > &siMEM_RxP_Data, stream< ap_uint< 8 > > &soMMIO_NotifDropCnt, stream< ap_uint< 8 > > &soMMIO_MetaDropCnt, stream< ap_uint< 8 > > &soMMIO_DataDropCnt)
Rx Application Interface (RAi)
void tx_engine(stream< ExtendedEvent > &siAKd_Event, stream< SigBit > &soEVe_RxEventSig, stream< SessionId > &soRSt_RxSarReq, stream< RxSarReply > &siRSt_RxSarRep, stream< TXeTxSarQuery > &soTSt_TxSarQry, stream< TXeTxSarReply > &siTSt_TxSarRep, stream< DmCmd > &soMEM_Txp_RdCmd, stream< AxisApp > &siMEM_TxP_Data, stream< TXeReTransTimerCmd > &soTIm_ReTxTimerCmd, stream< SessionId > &soTIm_SetProbeTimer, stream< SessionId > &soSLc_ReverseLkpReq, stream< fourTuple > &siSLc_ReverseLkpRep, stream< AxisIp4 > &soIPTX_Data)
Transmit Engine (TXe)
Definition: tx_engine.cpp:1517
void pTbSimCount(volatile ap_uint< 32 > &poSimCycCount)
Testbench Simulation Counter.
Definition: toe.cpp:156
Here is the call graph for this function:
Here is the caller graph for this function:

◆ toe_top()

void toe_top ( Ip4Addr  piMMIO_IpAddr,
stream< StsBit > &  soMMIO_RxMemWrErr,
stream< ap_uint< 8 > > &  soMMIO_NotifDropCnt,
stream< ap_uint< 8 > > &  soMMIO_MetaDropCnt,
stream< ap_uint< 8 > > &  soMMIO_DataDropCnt,
stream< ap_uint< 8 > > &  soMMIO_CrcDropCnt,
stream< ap_uint< 8 > > &  soMMIO_SessDropCnt,
stream< ap_uint< 8 > > &  soMMIO_OooDropCnt,
StsBit poNTS_Ready,
stream< AxisRaw > &  siIPRX_Data,
stream< AxisRaw > &  soIPTX_Data,
stream< TcpAppNotif > &  soTAIF_Notif,
stream< TcpAppRdReq > &  siTAIF_DReq,
stream< TcpAppData > &  soTAIF_Data,
stream< TcpAppMeta > &  soTAIF_Meta,
stream< TcpAppLsnReq > &  siTAIF_LsnReq,
stream< TcpAppLsnRep > &  soTAIF_LsnRep,
stream< TcpAppData > &  siTAIF_Data,
stream< TcpAppSndReq > &  siTAIF_SndReq,
stream< TcpAppSndRep > &  soTAIF_SndRep,
stream< TcpAppOpnReq > &  siTAIF_OpnReq,
stream< TcpAppOpnRep > &  soTAIF_OpnRep,
stream< TcpAppClsReq > &  siTAIF_ClsReq,
stream< DmCmd > &  soMEM_RxP_RdCmd,
stream< AxisApp > &  siMEM_RxP_Data,
stream< DmSts > &  siMEM_RxP_WrSts,
stream< DmCmd > &  soMEM_RxP_WrCmd,
stream< AxisApp > &  soMEM_RxP_Data,
stream< DmCmd > &  soMEM_TxP_RdCmd,
stream< AxisApp > &  siMEM_TxP_Data,
stream< DmSts > &  siMEM_TxP_WrSts,
stream< DmCmd > &  soMEM_TxP_WrCmd,
stream< AxisApp > &  soMEM_TxP_Data,
stream< CamSessionLookupRequest > &  soCAM_SssLkpReq,
stream< CamSessionLookupReply > &  siCAM_SssLkpRep,
stream< CamSessionUpdateRequest > &  soCAM_SssUpdReq,
stream< CamSessionUpdateReply > &  siCAM_SssUpdRep,
stream< ap_uint< 16 > > &  soDBG_SssRelCnt,
stream< ap_uint< 16 > > &  soDBG_SssRegCnt,
stream< RxBufPtr > &  soDBG_RxFreeSpace,
stream< ap_uint< 32 > > &  soDBG_TcpIpRxByteCnt,
stream< ap_uint< 8 > > &  soDBG_OooDebug 
)

Top of TCP Offload Engine (TOE)

Parameters
[in]piMMIO_IpAddrIP4 Address from [MMIO].
[out]soMMIO_RxMemWrErrReports a Rx memory write error.
[out]soMMIO_NotifDropThe value of the notification drop counter.
[out]soMMIO_MetaDropThe value of the metadata drop counter.
[out]soMMIO_DataDropThe value of the data drop counter.
[out]soMMIO_CrcDropThe value of the CRC drop counter.
[out]soMMIO_SessDropThe value of the session drop counter.
[out]soMMIO_OooDropThe value of the out-of-order drop counter.
[out]poNTS_ReadyReady signal of TOE.
[in]siIPRX_DataIP4 data stream from [IPRX].
[out]soIPTX_DataIP4 data stream to [IPTX].
[out]soTAIF_NotifAPP data notification to [TAIF].
[in]siTAIF_DReqAPP data request from [TAIF].
[out]soTAIF_DataAPP data stream to [TAIF].
[out]soTAIF_MetaAPP metadata stream to [TAIF].
[in]siTAIF_LsnReqAPP listen port request from [TAIF].
[out]soTAIF_LsnRepAPP listen port reply to [TAIF].
[in]siTAIF_DataAPP data stream from [TAIF].
[in]siTAIF_SndReqAPP request to send from [TAIF].
[out]soTAIF_SndRepAPP send reply to [TAIF].
[in]siTAIF_OpnReqAPP open port request from [TAIF].
[out]soTAIF_OpnRepAPP open port reply to [TAIF].
[in]siTAIF_ClsReqAPP close connection request from [TAIF].
Warning
: Not-Used APP close connection status to [TAIF].
: Not-Used Rx memory read status from [MEM].
Parameters
[out]soMEM_RxP_RdCmdRx memory read command to [MEM].
[in]siMEM_RxP_DataRx memory data from [MEM].
[in]siMEM_RxP_WrStsRx memory write status from [MEM].
[out]soMEM_RxP_WrCmdRx memory write command to [MEM].
[out]soMEM_RxP_DataRx memory data to [MEM].
Warning
: Not-Used Tx memory read status from [MEM].
Parameters
[out]soMEM_TxP_RdCmdTx memory read command to [MEM].
[in]siMEM_TxP_DataTx memory data from [MEM].
[in]siMEM_TxP_WrStsTx memory write status from [MEM].
[out]soMEM_TxP_WrCmdTx memory write command to [MEM].
[out]soMEM_TxP_DataTx memory data to [MEM].
[out]soCAM_SssLkpReqSession lookup request to [CAM].
[in]siCAM_SssLkpRepSession lookup reply from [CAM].
[out]soCAM_SssUpdReqSession update request to [CAM].
[in]siCAM_SssUpdRepSession update reply from [CAM].
[out]soDBG_SssRelCntSession release count (for DEBUG).
[out]soDBG_SssRegCntSession register count (foe DEBUG).

ENTITY - TCP OFFLOAD ENGINE (TOE)

Definition at line 1056 of file toe.cpp.

1145 {
1146 
1147  //-- DIRECTIVES FOR THE INTERFACES -----------------------------------------
1148  #pragma HLS INTERFACE ap_ctrl_none port=return
1149 
1150  //-- MMIO Interfaces
1151  #pragma HLS INTERFACE ap_stable port=piMMIO_IpAddr name=piMMIO_IpAddr
1152  #pragma HLS INTERFACE axis register both port=soMMIO_RxMemWrErr name=soMMIO_RxMemWrErr
1153  #pragma HLS INTERFACE axis register both port=soMMIO_NotifDropCnt name=soMMIO_NotifDropCnt
1154  #pragma HLS INTERFACE axis register both port=soMMIO_MetaDropCnt name=soMMIO_MetaDropCnt
1155  #pragma HLS INTERFACE axis register both port=soMMIO_DataDropCnt name=soMMIO_DataDropCnt
1156  #pragma HLS INTERFACE axis register both port=soMMIO_CrcDropCnt name=soMMIO_CrcDropCnt
1157  #pragma HLS INTERFACE axis register both port=soMMIO_SessDropCnt name=soMMIO_SessDropCnt
1158  #pragma HLS INTERFACE axis register both port=soMMIO_OooDropCnt name=soMMIO_OooDropCnt
1159  //-- NTS Interfaces
1160  #pragma HLS INTERFACE ap_none register port=poNTS_Ready name=poNTS_Ready
1161  //-- IPRX / IP Rx Data Interface -------------------------------------------
1162  #pragma HLS INTERFACE axis off port=siIPRX_Data name=siIPRX_Data
1163  //-- IPTX / IP Tx Data Interface -------------------------------------------
1164  #pragma HLS INTERFACE axis off port=soIPTX_Data name=soIPTX_Data
1165  //-- TAIF / ROLE Rx Data Interfaces ----------------------------------------
1166  #pragma HLS INTERFACE axis off port=siTAIF_DReq name=siTAIF_DReq
1167  #pragma HLS DATA_PACK variable=siTAIF_DReq
1168  #pragma HLS INTERFACE axis off port=soTAIF_Notif name=soTAIF_Notif
1169  #pragma HLS DATA_PACK variable=soTAIF_Notif
1170  #pragma HLS INTERFACE axis off port=soTAIF_Data name=soTAIF_Data
1171  #pragma HLS INTERFACE axis off port=soTAIF_Meta name=soTAIF_Meta
1172  //-- TAIF / ROLE Rx Listen Interface ---------------------------------------
1173  #pragma HLS INTERFACE axis off port=siTAIF_LsnReq name=siTAIF_LsnReq
1174  #pragma HLS INTERFACE axis off port=soTAIF_LsnRep name=soTAIF_LsnRep
1175  //-- TAIF / ROLE Tx Data Interfaces ----------------------------------------
1176  #pragma HLS INTERFACE axis off port=siTAIF_Data name=siTAIF_Data
1177  #pragma HLS INTERFACE axis off port=siTAIF_SndReq name=siTAIF_SndReq
1178  #pragma HLS DATA_PACK variable=siTAIF_SndReq
1179  #pragma HLS INTERFACE axis off port=soTAIF_SndRep name=soTAIF_SndRep
1180  #pragma HLS DATA_PACK variable=soTAIF_SndRep
1181  //-- TAIF / ROLE Tx Ctrl Interfaces ----------------------------------------
1182  #pragma HLS INTERFACE axis off port=siTAIF_OpnReq name=siTAIF_OpnReq
1183  #pragma HLS DATA_PACK variable=siTAIF_OpnReq
1184  #pragma HLS INTERFACE axis off port=soTAIF_OpnRep name=soTAIF_OpnRep
1185  #pragma HLS DATA_PACK variable=soTAIF_OpnRep
1186  #pragma HLS INTERFACE axis off port=siTAIF_ClsReq name=siTAIF_ClsReq
1187  //-- MEM / Nts0 / RxP Interface --------------------------------------------
1188  #pragma HLS INTERFACE axis off port=soMEM_RxP_RdCmd name=soMEM_RxP_RdCmd
1189  #pragma HLS DATA_PACK variable=soMEM_RxP_RdCmd
1190  #pragma HLS INTERFACE axis off port=siMEM_RxP_Data name=siMEM_RxP_Data
1191  #pragma HLS INTERFACE axis off port=siMEM_RxP_WrSts name=siMEM_RxP_WrSts
1192  #pragma HLS DATA_PACK variable=siMEM_RxP_WrSts
1193  #pragma HLS INTERFACE axis off port=soMEM_RxP_WrCmd name=soMEM_RxP_WrCmd
1194  #pragma HLS DATA_PACK variable=soMEM_RxP_WrCmd
1195  #pragma HLS INTERFACE axis off port=soMEM_RxP_Data name=soMEM_RxP_Data
1196  //-- MEM / Nts0 / TxP Interface --------------------------------------------
1197  #pragma HLS INTERFACE axis off port=soMEM_TxP_RdCmd name=soMEM_TxP_RdCmd
1198  #pragma HLS DATA_PACK variable=soMEM_TxP_RdCmd
1199  #pragma HLS INTERFACE axis off port=siMEM_TxP_Data name=siMEM_TxP_Data
1200  #pragma HLS INTERFACE axis off port=siMEM_TxP_WrSts name=siMEM_TxP_WrSts
1201  #pragma HLS DATA_PACK variable=siMEM_TxP_WrSts
1202  #pragma HLS INTERFACE axis off port=soMEM_TxP_WrCmd name=soMEM_TxP_WrCmd
1203  #pragma HLS DATA_PACK variable=soMEM_TxP_WrCmd
1204  #pragma HLS INTERFACE axis off port=soMEM_TxP_Data name=soMEM_TxP_Data
1205  //-- CAM / Session Lookup & Update Interfaces ------------------------------
1206  #pragma HLS INTERFACE axis register both port=soCAM_SssLkpReq name=soCAM_SssLkpReq
1207  #pragma HLS DATA_PACK variable=soCAM_SssLkpReq
1208  #pragma HLS INTERFACE axis off port=siCAM_SssLkpRep name=siCAM_SssLkpRep
1209  #pragma HLS DATA_PACK variable=siCAM_SssLkpRep
1210  #pragma HLS INTERFACE axis register both port=soCAM_SssUpdReq name=soCAM_SssUpdReq
1211  #pragma HLS DATA_PACK variable=soCAM_SssUpdReq
1212  #pragma HLS INTERFACE axis off port=siCAM_SssUpdRep name=siCAM_SssUpdRep
1213  #pragma HLS DATA_PACK variable=siCAM_SssUpdRep
1214  //-- DEBUG Interfaces
1215  #pragma HLS INTERFACE axis register both port=soDBG_SssRelCnt name=soDBG_SssRelCnt
1216  #pragma HLS INTERFACE axis register both port=soDBG_SssRegCnt name=soDBG_SssRegCnt
1217  #pragma HLS INTERFACE axis register both port=soDBG_RxFreeSpace name=soDBG_RxFreeSpace
1218  #pragma HLS INTERFACE axis register both port=soDBG_TcpIpRxByteCnt name=soDBG_TcpIpRxByteCnt
1219  #pragma HLS INTERFACE axis register both port=soDBG_OooDebug name=soDBG_OooDebug
1220  //-- DEBUG / Simulation Counter Interfaces
1221  #if TOE_FEATURE_USED_FOR_DEBUGGING
1222  #pragma HLS INTERFACE ap_ovld register port=poSimCycCount name=poSimCycCount
1223  #endif
1224 
1225  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1226  #pragma HLS DATAFLOW disable_start_propagation
1227 
1228  //-- LOCAL INPUT and OUTPUT STREAMS ----------------------------------------
1229  static stream<AxisIp4> ssiIPRX_Data ("ssiIPRX_Data");
1230  static stream<AxisIp4> ssoIPTX_Data ("ssoIPTX_Data");
1231 
1232  //-- INPUT STREAM CASTING --------------------------------------------------
1233  pAxisRawCast(siIPRX_Data, ssiIPRX_Data);
1234 
1235  //-- MAIN TOE PROCESS ------------------------------------------------------
1236  toe(
1237  //-- MMIO Interfaces
1238  piMMIO_IpAddr,
1239  soMMIO_RxMemWrErr,
1240  soMMIO_NotifDropCnt,
1241  soMMIO_MetaDropCnt,
1242  soMMIO_DataDropCnt,
1243  soMMIO_CrcDropCnt,
1244  soMMIO_SessDropCnt,
1245  soMMIO_OooDropCnt,
1246  //-- NTS Interfaces
1247  poNTS_Ready,
1248  //-- IPRX / IP Rx / Data Interface
1249  ssiIPRX_Data,
1250  //-- IPTX / IP Tx / Data Interface
1251  ssoIPTX_Data,
1252  //-- TAIF / Rx Data Interfaces
1253  soTAIF_Notif,
1254  siTAIF_DReq,
1255  soTAIF_Data,
1256  soTAIF_Meta,
1257  //-- TAIF / Listen Port Interfaces
1258  siTAIF_LsnReq,
1259  soTAIF_LsnRep,
1260  //-- TAIF / Tx Data Interfaces
1261  siTAIF_Data,
1262  siTAIF_SndReq,
1263  soTAIF_SndRep,
1264  //-- TAIF / Open connection Interfaces
1265  siTAIF_OpnReq,
1266  soTAIF_OpnRep,
1267  //-- TAIF / Close Interfaces
1268  siTAIF_ClsReq,
1269  //-- Not Used soTAIF_ClsSts,
1270  //-- MEM / Rx PATH / S2MM Interface
1271  //-- Not Used siMEM_RxP_RdSts,
1272  soMEM_RxP_RdCmd,
1273  siMEM_RxP_Data,
1274  siMEM_RxP_WrSts,
1275  soMEM_RxP_WrCmd,
1276  soMEM_RxP_Data,
1277  //-- MEM / Tx PATH / S2MM Interface
1278  //-- Not Used siMEM_TxP_RdSts,
1279  soMEM_TxP_RdCmd,
1280  siMEM_TxP_Data,
1281  siMEM_TxP_WrSts,
1282  soMEM_TxP_WrCmd,
1283  soMEM_TxP_Data,
1284  //-- CAM / Session Lookup & Update Interfaces
1285  soCAM_SssLkpReq,
1286  siCAM_SssLkpRep,
1287  soCAM_SssUpdReq,
1288  siCAM_SssUpdRep,
1289  //-- DEBUG Interfaces
1290  soDBG_SssRelCnt,
1291  soDBG_SssRegCnt,
1292  soDBG_RxFreeSpace,
1293  soDBG_TcpIpRxByteCnt,
1294  soDBG_OooDebug
1296  poSimCycCount
1297  #endif
1298  );
1299 
1300  //-- OUTPUT STREAM CASTING -------------------------------------------------
1301  pAxisRawCast(ssoIPTX_Data, soIPTX_Data);
1302 
1303 }
void toe(Ip4Addr piMMIO_IpAddr, stream< StsBit > &soMMIO_RxMemWrErr, stream< ap_uint< 8 > > &soMMIO_NotifDropCnt, stream< ap_uint< 8 > > &soMMIO_MetaDropCnt, stream< ap_uint< 8 > > &soMMIO_DataDropCnt, stream< ap_uint< 8 > > &soMMIO_CrcDropCnt, stream< ap_uint< 8 > > &soMMIO_SessDropCnt, stream< ap_uint< 8 > > &soMMIO_OooDropCnt, StsBit &poNTS_Ready, stream< AxisIp4 > &siIPRX_Data, stream< AxisIp4 > &soIPTX_Data, stream< TcpAppNotif > &soTAIF_Notif, stream< TcpAppRdReq > &siTAIF_DReq, stream< TcpAppData > &soTAIF_Data, stream< TcpAppMeta > &soTAIF_Meta, stream< TcpAppLsnReq > &siTAIF_LsnReq, stream< TcpAppLsnRep > &soTAIF_LsnRep, stream< TcpAppData > &siTAIF_Data, stream< TcpAppSndReq > &siTAIF_SndReq, stream< TcpAppSndRep > &soTAIF_SndRep, stream< TcpAppOpnReq > &siTAIF_OpnReq, stream< TcpAppOpnRep > &soTAIF_OpnRep, stream< TcpAppClsReq > &siTAIF_ClsReq, stream< DmCmd > &soMEM_RxP_RdCmd, stream< AxisApp > &siMEM_RxP_Data, stream< DmSts > &siMEM_RxP_WrSts, stream< DmCmd > &soMEM_RxP_WrCmd, stream< AxisApp > &soMEM_RxP_Data, stream< DmCmd > &soMEM_TxP_RdCmd, stream< AxisApp > &siMEM_TxP_Data, stream< DmSts > &siMEM_TxP_WrSts, stream< DmCmd > &soMEM_TxP_WrCmd, stream< AxisApp > &soMEM_TxP_Data, stream< CamSessionLookupRequest > &soCAM_SssLkpReq, stream< CamSessionLookupReply > &siCAM_SssLkpRep, stream< CamSessionUpdateRequest > &soCAM_SssUpdReq, stream< CamSessionUpdateReply > &siCAM_SssUpdRep, stream< ap_uint< 16 > > &soDBG_SssRelCnt, stream< ap_uint< 16 > > &soDBG_SssRegCnt, stream< RxBufPtr > &soDBG_RxFreeSpace, stream< ap_uint< 32 > > &soDBG_TcpIpRxByteCnt, stream< ap_uint< 8 > > &soDBG_OooDebug)
Main process of the TCP Offload Engine (TOE0.
Definition: toe.cpp:231
#define TOE_FEATURE_USED_FOR_DEBUGGING
Definition: toe.hpp:103
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:

◆ tx_app_interface()

void tx_app_interface ( stream< TcpAppOpnReq > &  siTAIF_OpnReq,
stream< TcpAppOpnRep > &  soTAIF_OpnRep,
stream< TcpAppClsReq > &  siTAIF_ClsReq,
stream< TcpAppData > &  siTAIF_Data,
stream< TcpAppSndReq > &  siTAIF_SndReq,
stream< TcpAppSndRep > &  soTAIF_SndRep,
stream< DmCmd > &  soMEM_TxP_WrCmd,
stream< AxisApp > &  soMEM_TxP_Data,
stream< DmSts > &  siMEM_TxP_WrSts,
stream< SessionId > &  soSTt_SessStateReq,
stream< TcpState > &  siSTt_SessStateRep,
stream< StateQuery > &  soSTt_ConnectStateQry,
stream< TcpState > &  siSTt_ConnectStateRep,
stream< SocketPair > &  soSLc_SessLookupReq,
stream< SessionLookupReply > &  siSLc_SessLookupRep,
stream< ReqBit > &  soPRt_GetFreePortReq,
stream< TcpPort > &  siPRt_GetFreePortRep,
stream< TStTxSarPush > &  siTSt_PushCmd,
stream< TAiTxSarPush > &  soTSt_PushCmd,
stream< SessState > &  siRXe_ActSessState,
stream< Event > &  soEVe_Event,
stream< SessState > &  siTIm_Notif,
Ip4Addr  piMMIO_IpAddr 
)

Tx Application Interface (TAi)

ENTITY - Tx Application Interface (TAi)

Parameters
[in]siTAIF_OpnReqOpen connection request from TCP Role I/F (TAIF).
[out]soTAIF_OpnRepOpen connection reply to [TAIF].
[in]siTAIF_ClsReqClose connection request from [TAIF]
[in]siTAIF_DataAPP data stream from [TAIF].
[in]siTAIF_SndReqAPP request to send from [TAIF].
[out]soTAIF_SndRepAPP send reply to [TAIF].
[out]soMEM_TxP_WrCmdTx memory write command to MEM.
[out]soMEM_TxP_DataTx memory data to MEM.
[in]siMEM_TxP_WrStsTx memory write status from MEM.
[out]soSTt_SessStateReqSession sate request to StateTable (STt).
[in]siSTt_SessStateRepSession state reply from [STt].
[out]soSTt_AcceptStateQrySession state query to [STt].
[in]siSTt_AcceptStateRepSession state reply from [STt].
[out]soSLc_SessLookupReqSession lookup request to SessionLookupController(SLc).
[in]siSLc_SessLookupRepSession lookup reply from [SLc].
[out]soPRt_GetFreePortReqFree port request to PortTable (PRt).
[in]siPRt_GetFreePortRepFree port reply from [PRt].
[in]siTSt_PushCmdPush command for an AckNum from TxSarTable (TSt).
[out]soTSt_PushCmdPush command for an AppPtr to [TSt].
[in]siRXe_ActSessStateTCP state of active session from [RXe].
[out]soEVe_EventEvent to EventEngine (EVe).
[in]siTIm_NotifNotification from Timers (TIm).
[in]piMMIO_IpAddrIPv4 address from [MMIO].

This process is the front-end interface to the TCP application layer.

Warning
To avoid any stalling of this process, the outgoing streams 'soTAIF_OpnRep and 'soTAIF_Sndrep' are operated in non-blocking mode. This implies that the user application process connected to these streams must provision enough buffering to store the corresponding bytes exchanged on these interfaces.

Definition at line 791 of file tx_app_interface.cpp.

826 {
827  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
828  #pragma HLS DATAFLOW
829  #pragma HLS INTERFACE ap_ctrl_none port=return
830 
831  //--------------------------------------------------------------------------
832  //-- LOCAL STREAMS (Sorted by the name of the modules which generate them)
833  //--------------------------------------------------------------------------
834 
835  //-- Event Multiplexer (Emx) ----------------------------------------------
836  static stream<Event> ssEmxToTash_Event ("ssEmxToTash_Event");
837  #pragma HLS stream variable=ssEmxToTash_Event depth=2
838  #pragma HLS DATA_PACK variable=ssEmxToTash_Event
839 
840  //-- Tx App Connect (Tac) --------------------------------------------------
841  static stream<Event> ssTacToEmx_Event ("ssTacToEmx_Event");
842  #pragma HLS stream variable=ssTacToEmx_Event depth=2
843  #pragma HLS DATA_PACK variable=ssTacToEmx_Event
844 
845  //-- Tx App Table (Tat)----------------------------------------------------
846  static stream<TxAppTableReply> ssTatToSml_AccessRep ("ssTatToSml_AccessRep");
847  #pragma HLS stream variable=ssTatToSml_AccessRep depth=2
848  #pragma HLS DATA_PACK variable=ssTatToSml_AccessRep
849 
850  //-- StreamMetaLoader (Sml)------------------------------------------------
851  static stream<TxAppTableQuery> ssSmlToTat_AccessQry ("ssSmlToTat_AccessQry");
852  #pragma HLS stream variable=ssSmlToTat_AccessQry depth=2
853  #pragma HLS DATA_PACK variable=ssSmlToTat_AccessQry
854 
855  static stream<AppMemMeta> ssSmlToMwr_AppMeta ("ssSmlToMwr_AppMeta");
856  #pragma HLS stream variable=ssSmlToMwr_AppMeta depth=32
857  #pragma HLS DATA_PACK variable=ssSmlToMwr_AppMeta
858 
859  static stream<Event> ssSmlToEmx_Event ("ssSmlToEmx_Event");
860  #pragma HLS stream variable=ssSmlToEmx_Event depth=2
861  #pragma HLS DATA_PACK variable=ssSmlToEmx_Event
862 
863  //-------------------------------------------------------------------------
864  //-- PROCESS FUNCTIONS
865  //-------------------------------------------------------------------------
866 
867  // Event Multiplexer (Emx)
868  pStreamMux(
869  ssTacToEmx_Event,
870  ssSmlToEmx_Event,
871  ssEmxToTash_Event);
872 
873  // Tx Application Status Handler (Tash)
875  siMEM_TxP_WrSts,
876  ssEmxToTash_Event,
877  soTSt_PushCmd,
878  soEVe_Event);
879 
881  siTAIF_SndReq,
882  soTAIF_SndRep,
883  soSTt_SessStateReq,
884  siSTt_SessStateRep,
885  ssSmlToTat_AccessQry,
886  ssTatToSml_AccessRep,
887  ssSmlToMwr_AppMeta,
888  ssSmlToEmx_Event);
889 
891  siTAIF_Data,
892  ssSmlToMwr_AppMeta,
893  soMEM_TxP_WrCmd,
894  soMEM_TxP_Data);
895 
896  // Tx Application Connect (Tac)
898  siTAIF_OpnReq,
899  soTAIF_OpnRep,
900  siTAIF_ClsReq,
901  soSLc_SessLookupReq,
902  siSLc_SessLookupRep,
903  soPRt_GetFreePortReq,
904  siPRt_GetFreePortRep,
905  soSTt_ConnectStateQry,
906  siSTt_ConnectStateRep,
907  siRXe_ActSessState,
908  ssTacToEmx_Event,
909  siTIm_Notif,
910  piMMIO_IpAddr);
911 
912  // Tx Application Table (Tat)
913  pTxAppTable(
914  siTSt_PushCmd,
915  ssSmlToTat_AccessQry,
916  ssTatToSml_AccessRep);
917 }
void pStreamMetaLoader(stream< TcpAppSndReq > &siTAIF_SndReq, stream< TcpAppSndRep > &soTAIF_SndRep, stream< SessionId > &soSTt_SessStateReq, stream< TcpState > &siSTt_SessStateRep, stream< TxAppTableQuery > &soTat_AccessReq, stream< TxAppTableReply > &siTat_AccessRep, stream< AppMemMeta > &soMwr_AppMeta, stream< Event > &soEmx_Event)
Stream Metadata Loader (Sml)
void pTxAppConnect(stream< TcpAppOpnReq > &siTAIF_OpnReq, stream< TcpAppOpnRep > &soTAIF_OpnRep, stream< TcpAppClsReq > &siTAIF_ClsReq, stream< SocketPair > &soSLc_SessLookupReq, stream< SessionLookupReply > &siSLc_SessLookupRep, stream< ReqBit > &soPRt_GetFreePortReq, stream< TcpPort > &siPRt_GetFreePortRep, stream< StateQuery > &soSTt_ConnectStateQry, stream< TcpState > &siSTt_ConnectStateRep, stream< SessState > &siRXe_ActSessState, stream< Event > &soEVe_Event, stream< SessState > &siTIm_Notif, Ip4Address piMMIO_IpAddr)
Tx Application Connect (Tac)
void pTxAppStatusHandler(stream< DmSts > &siMEM_TxP_WrSts, stream< Event > &siEmx_Event, stream< TAiTxSarPush > &soTSt_PushCmd, stream< Event > &soEVe_Event)
Tx Application Status Handler (Tash)
void pTxMemoryWriter(stream< TcpAppData > &siTAIF_Data, stream< AppMemMeta > &siSml_AppMeta, stream< DmCmd > &soMEM_WrCmd, stream< AxisApp > &soMEM_WrData)
Tx Memory Writer (Mwr)
void pTxAppTable(stream< TStTxSarPush > &siTSt_PushCmd, stream< TxAppTableQuery > &siTas_AccessQry, stream< TxAppTableReply > &siTas_AccessRep)
Tx Application Table (Tat)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tx_engine()

void tx_engine ( stream< ExtendedEvent > &  siAKd_Event,
stream< SigBit > &  soEVe_RxEventSig,
stream< SessionId > &  soRSt_RxSarReq,
stream< RxSarReply > &  siRSt_RxSarRep,
stream< TXeTxSarQuery > &  soTSt_TxSarQry,
stream< TXeTxSarReply > &  siTSt_TxSarRep,
stream< DmCmd > &  soMEM_Txp_RdCmd,
stream< AxisApp > &  siMEM_TxP_Data,
stream< TXeReTransTimerCmd > &  soTIm_ReTxTimerCmd,
stream< SessionId > &  soTIm_SetProbeTimer,
stream< SessionId > &  soSLc_ReverseLkpReq,
stream< fourTuple > &  siSLc_ReverseLkpRep,
stream< AxisIp4 > &  soIPTX_Data 
)

Transmit Engine (TXe)

ENTITY - Tx Engine (TXe)

Parameters
[in]siAKd_EventEvent from Ack Delayer (AKd).
[out]soEVe_RxEventSigSignals the reception of an event to [EventEngine].
[out]soRSt_RxSarReqRead request to RxSarTable (RSt).
[in]siRSt_RxSarRepRead reply from [RSt].
[out]soTSt_TxSarQryTxSar query to TxSarTable (TSt).
[in]siTSt_TxSarRepTxSar reply from [TSt].
[out]soMEM_Txp_RdCmdMemory read command to the DRAM Memory (MEM).
[in]siMEM_TxP_DataData payload from the DRAM Memory (MEM).
[out]soTIm_ReTxTimerCmdSend retransmit timer command to [Timers].
[out]soTIm_SetProbeTimerSet probe timer to Timers (TIm).
[out]soSLc_ReverseLkpReqReverse lookup request to Session Lookup Controller (SLc).
[in]siSLc_ReverseLkpRepReverse lookup reply from SLc.
[out]soIPTX_DataOutgoing data stream to IP Tx Handler (IPTX).

The Tx Engine (TXe) is responsible for the generation and transmission of IPv4 packets with embedded TCP payload. It contains a state machine with a state for each Event Type. Upon reception of an event, it loads and generates the necessary metadata to construct an IPv4 packet. If that packet contains any payload, the data are retrieved from the DDR4 memory and are put as a TCP segment into the IPv4 packet. The complete packet is then streamed out over the IPv4 Tx interface of the TOE (.i.e, soIPTX).

Definition at line 1517 of file tx_engine.cpp.

1538 {
1539  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
1540  #pragma HLS DATAFLOW
1541  #pragma HLS INTERFACE ap_ctrl_none port=return
1542 
1543  //==========================================================================
1544  //== LOCAL STREAMS (Sorted by the name of the modules which generate them)
1545  //==========================================================================
1546 
1547  //--------------------------------------------------------------------------
1548  //-- Meta Data Loader (Mdl)
1549  //--------------------------------------------------------------------------
1550  static stream<TcpDatLen> ssMdlToIhc_TcpDatLen ("ssMdlToIhc_TcpDatLen");
1551  #pragma HLS stream variable=ssMdlToIhc_TcpDatLen depth=16
1552 
1553  static stream<TXeMeta> ssMdlToPhc_TxeMeta ("ssMdlToPhc_TxeMeta");
1554  #pragma HLS stream variable=ssMdlToPhc_TxeMeta depth=16
1555  #pragma HLS DATA_PACK variable=ssMdlToPhc_TxeMeta
1556 
1557  static stream<bool> ssMdlToSpS_IsLookup ("ssMdlToSpS_IsLookup");
1558  #pragma HLS stream variable=ssMdlToSpS_IsLookup depth=4
1559 
1560  static stream<DmCmd> ssMdlToMrd_BufferRdCmd ("ssMdlToMrd_BufferRdCmd");
1561  #pragma HLS stream variable=ssMdlToMrd_BufferRdCmd depth=32
1562  #pragma HLS DATA_PACK variable=ssMdlToMrd_BufferRdCmd
1563 
1564  static stream<LE_SocketPair> ssMdlToSps_RstSockPair ("ssMdlToSps_RstSockPair");
1565  #pragma HLS stream variable=ssMdlToSps_RstSockPair depth=2
1566  #pragma HLS DATA_PACK variable=ssMdlToSps_RstSockPair
1567 
1568  //--------------------------------------------------------------------------
1569  //-- Ip Header Construction (Ihc)
1570  //--------------------------------------------------------------------------
1571  static stream<AxisIp4> ssIhcToIps_IpHeader ("ssIhcToIps_IpHeader");
1572  #pragma HLS stream variable=ssIhcToIps_IpHeader depth=32
1573  #pragma HLS DATA_PACK variable=ssIhcToIps_IpHeader
1574 
1575  //-------------------------------------------------------------------------
1576  //-- Pseudo Header Construction (Phc)
1577  //-------------------------------------------------------------------------
1578  static stream<AxisPsd4> ssPhcToTss_PseudoHdr ("ssPhcToTss_PseudoHdr");
1579  #pragma HLS stream variable=ssPhcToTss_PseudoHdr depth=32
1580  #pragma HLS DATA_PACK variable=ssPhcToTss_PseudoHdr
1581 
1582  //-------------------------------------------------------------------------
1583  //-- Socket Pair Splitter (Sps)
1584  //-------------------------------------------------------------------------
1585  static stream<IpAddrPair> ssSpsToIhc_IpAddrPair ("ssSpsToIhc_IpAddrPair");
1586  #pragma HLS stream variable=ssSpsToIhc_IpAddrPair depth=4
1587  #pragma HLS DATA_PACK variable=ssSpsToIhc_IpAddrPair
1588 
1589  static stream<SocketPair> ssSpsToPhc_SockPair ("ssSpsToPhc_SockPair");
1590  #pragma HLS stream variable=ssSpsToPhc_SockPair depth=4
1591  #pragma HLS DATA_PACK variable=ssSpsToPhc_SockPair
1592 
1593  //-------------------------------------------------------------------------
1594  //-- TCP Segment Stitcher (Tss)
1595  //-------------------------------------------------------------------------
1596  static stream<AxisPsd4> ssTssToSca_PseudoPkt ("ssTssToSca_PseudoPkt");
1597  #pragma HLS stream variable=ssTssToSca_PseudoPkt depth=16
1598  #pragma HLS DATA_PACK variable=ssTssToSca_PseudoPkt
1599 
1600  //-------------------------------------------------------------------------
1601  //-- TCP Checksum Accumulator (Tca)
1602  //-------------------------------------------------------------------------
1603  static stream<TcpChecksum> ssTcaToIps_TcpCsum ("ssTcaToIps_TcpCsum");
1604  #pragma HLS stream variable=ssTcaToIps_TcpCsum depth=4
1605 
1606  //-------------------------------------------------------------------------
1607  //-- Sub-Checksum Accumulator (Sca)
1608  //-------------------------------------------------------------------------
1609  static stream<AxisPsd4> ssScaToIps_PseudoPkt ("ssScaToIps_PseudoPkt");
1610  #pragma HLS stream variable=ssScaToIps_PseudoPkt depth=256 // WARNING: Critical; has to keep complete packet for checksum computation
1611  #pragma HLS DATA_PACK variable=ssScaToIps_PseudoPkt
1612 
1613  static stream<SubCSums> ssScaToTca_FourSubCsums ("ssScaToTca_FourSubCsums");
1614  #pragma HLS stream variable=ssScaToTca_FourSubCsums depth=2
1615  #pragma HLS DATA_PACK variable=ssScaToTca_FourSubCsums
1616 
1617  //------------------------------------------------------------------------
1618  //-- Memory Reader (Mrd)
1619  //------------------------------------------------------------------------
1620  static stream<FlagBool> ssMrdToTss_SplitMemAcc ("ssMrdToTss_SplitMemAcc");
1621  #pragma HLS stream variable=ssMrdToTss_SplitMemAcc depth=32
1622 
1623  //-------------------------------------------------------------------------
1624  //-- PROCESS FUNCTIONS
1625  //-------------------------------------------------------------------------
1626 
1628  siAKd_Event,
1629  soRSt_RxSarReq,
1630  siRSt_RxSarRep,
1631  soTSt_TxSarQry,
1632  siTSt_TxSarRep,
1633  soTIm_ReTxTimerCmd,
1634  soTIm_SetProbeTimer,
1635  ssMdlToIhc_TcpDatLen,
1636  ssMdlToPhc_TxeMeta,
1637  ssMdlToMrd_BufferRdCmd,
1638  soSLc_ReverseLkpReq,
1639  ssMdlToSpS_IsLookup,
1640  ssMdlToSps_RstSockPair,
1641  soEVe_RxEventSig);
1642 
1644  ssMdlToMrd_BufferRdCmd,
1645  soMEM_Txp_RdCmd,
1646  ssMrdToTss_SplitMemAcc);
1647 
1649  siSLc_ReverseLkpRep,
1650  ssMdlToSps_RstSockPair,
1651  ssMdlToSpS_IsLookup,
1652  ssSpsToIhc_IpAddrPair,
1653  ssSpsToPhc_SockPair);
1654 
1656  ssMdlToIhc_TcpDatLen,
1657  ssSpsToIhc_IpAddrPair,
1658  ssIhcToIps_IpHeader);
1659 
1661  ssIhcToIps_IpHeader,
1662  ssScaToIps_PseudoPkt,
1663  ssTcaToIps_TcpCsum,
1664  soIPTX_Data);
1665 
1667  ssMdlToPhc_TxeMeta,
1668  ssSpsToPhc_SockPair,
1669  ssPhcToTss_PseudoHdr);
1670 
1672  ssPhcToTss_PseudoHdr,
1673  siMEM_TxP_Data,
1674  ssTssToSca_PseudoPkt,
1675  ssMrdToTss_SplitMemAcc);
1676 
1678  ssTssToSca_PseudoPkt,
1679  ssScaToIps_PseudoPkt,
1680  ssScaToTca_FourSubCsums);
1681 
1683  ssScaToTca_FourSubCsums,
1684  ssTcaToIps_TcpCsum);
1685 
1686 }
void pTcpSegStitcher(stream< AxisPsd4 > &siPhc_PseudoHdr, stream< AxisApp > &siMEM_TxP_Data, stream< AxisPsd4 > &soSca_PseudoPkt, stream< FlagBool > &siMrd_SplitSegFlag)
Definition: tx_engine.cpp:937
void pTcpChecksumAccumulator(stream< SubCSums > &siSca_FourSubCsums, stream< TcpChecksum > &soIps_TcpCsum)
TCP Checksum Accumulator (Tca)
Definition: tx_engine.cpp:1274
void pSubChecksumAccumulators(stream< AxisPsd4 > &siTss_PseudoPkt, stream< AxisPsd4 > &soIps_PseudoPkt, stream< SubCSums > &soTca_4SubCsums)
Sub-Checksum Accumulator (Sca)
Definition: tx_engine.cpp:1206
void pMetaDataLoader(stream< ExtendedEvent > &siAKd_Event, stream< SessionId > &soRSt_RxSarReq, stream< RxSarReply > &siRSt_RxSarRep, stream< TXeTxSarQuery > &soTSt_TxSarQry, stream< TXeTxSarReply > &siTSt_TxSarRep, stream< TXeReTransTimerCmd > &soTIm_ReTxTimerCmd, stream< SessionId > &soTIm_SetProbeTimer, stream< TcpDatLen > &soIhc_TcpDatLen, stream< TXeMeta > &soPhc_TxeMeta, stream< DmCmd > &soMrd_BufferRdCmd, stream< SessionId > &soSLc_ReverseLkpReq, stream< StsBool > &soSps_IsLookup, stream< LE_SocketPair > &soSps_RstSockPair, stream< SigBit > &soEVe_RxEventSig)
Meta Data Loader (Mdl)
Definition: tx_engine.cpp:117
void pIpHeaderConstructor(stream< TcpDatLen > &siMdl_TcpDatLen, stream< IpAddrPair > &siSps_IpAddrPair, stream< AxisIp4 > &soIPs_IpHeader)
IPv4 Header Constructor (Ihc)
Definition: tx_engine.cpp:710
void pIpPktStitcher(stream< AxisIp4 > &siIhc_IpHeader, stream< AxisPsd4 > &siSca_PseudoPkt, stream< TcpChecksum > &siTca_TcpCsum, stream< AxisIp4 > &soIPTX_Data)
IPv4 Packet Stitcher (Ips)
Definition: tx_engine.cpp:1316
void pPseudoHeaderConstructor(stream< TXeMeta > &siMdl_TxeMeta, stream< SocketPair > &siSps_SockPair, stream< AxisPsd4 > &soTss_PseudoHdr)
Pseudo Header Constructor (Phc)
Definition: tx_engine.cpp:818
void pTxMemoryReader(stream< DmCmd > &siMdl_BufferRdCmd, stream< DmCmd > &soMEM_TxpRdCmd, stream< FlagBool > &soTss_SplitMemAcc)
Tx Memory Reader (Mrd)
Definition: tx_engine.cpp:1419
void pSocketPairSplitter(stream< fourTuple > &siSLc_ReverseLkpRsp, stream< LE_SocketPair > &siMdl_RstSockPair, stream< StsBool > &siMdl_IsLookup, stream< IpAddrPair > &soIhc_IpAddrPair, stream< SocketPair > &soPhc_SocketPair)
Definition: tx_engine.cpp:624
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tx_sar_table()

void tx_sar_table ( stream< RXeTxSarQuery > &  siRXe_TxSarQry,
stream< RXeTxSarReply > &  soRXe_TxSarRep,
stream< TXeTxSarQuery > &  siTXe_TxSarQry,
stream< TXeTxSarReply > &  soTXe_TxSarRep,
stream< TAiTxSarPush > &  siTAi_PushCmd,
stream< TStTxSarPush > &  soTAi_PushCmd 
)

Tx Sar Table (TSt). Stores the data structures for managing the TCP Tx buffer and Tx sliding window.

ENTITY - Tx SAR Table (TSt)

Parameters
[in]siRXe_TxSarQryQuery from RxEngine (RXe).
[out]soRXe_TxSarRepReply to [RXe].
[in]siTXe_TxSarQryTx SAR query from TxEngine (TXe).
[out]soTXe_TxSarRepTx SAR reply to [TXe].
[in]siTAi_PushCmdPush command from TxAppInterface (TAi).
[out]soTAi_PushCmdPush command to [TAi].

This process is accessed by the RxEngine (RXe), the TxEngine (TXe) and the TxAppInterface (TAi).

Definition at line 91 of file tx_sar_table.cpp.

98 {
99  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
100  #pragma HLS PIPELINE II=1 enable_flush
101 
102  const char *myName = THIS_NAME;
103 
104  //-- STATIC ARRAYS ---------------------------------------------------------
105  static TxSarEntry TX_SAR_TABLE[TOE_MAX_SESSIONS];
106  #pragma HLS DEPENDENCE variable=TX_SAR_TABLE inter false
107  #pragma HLS RESOURCE variable=TX_SAR_TABLE core=RAM_2P
108 
109  if (!siTXe_TxSarQry.empty()) {
110  TXeTxSarQuery sTXeQry;
111  //----------------------------------------
112  //-- Rd/Wr Query from TX Engine
113  //----------------------------------------
114  siTXe_TxSarQry.read(sTXeQry);
115  if (sTXeQry.write) {
116  //-- TXe Write Query
117  if (not sTXeQry.isRtQuery) {
118  TX_SAR_TABLE[sTXeQry.sessionID].unak = sTXeQry.not_ackd;
119  if (sTXeQry.init) {
120  TX_SAR_TABLE[sTXeQry.sessionID].appw = sTXeQry.not_ackd;
121  TX_SAR_TABLE[sTXeQry.sessionID].ackd = sTXeQry.not_ackd-1;
122  TX_SAR_TABLE[sTXeQry.sessionID].cong_window = 0x3908; // 10 x 1460(MSS)
123  TX_SAR_TABLE[sTXeQry.sessionID].slowstart_threshold = 0xFFFF;
124  // Avoid initializing 'finReady' and 'finSent' at two different
125  // places because it will translate into II=2 and DRC message:
126  // 'Unable to schedule store operation on array due to limited memory ports'.
127 
128  // Init ACK on the TxAppInterface side
129  soTAi_PushCmd.write(TStTxSarPush(sTXeQry.sessionID,
130  sTXeQry.not_ackd, CMD_INIT));
131  }
132  if (sTXeQry.finReady or sTXeQry.init) {
133  TX_SAR_TABLE[sTXeQry.sessionID].finReady = sTXeQry.finReady;
134  }
135  if (sTXeQry.finSent or sTXeQry.init) {
136  TX_SAR_TABLE[sTXeQry.sessionID].finSent = sTXeQry.finSent;
137  }
138  }
139  else {
140  //-- TXe Write RtQuery
141  TXeTxSarRtQuery sTXeRtQry = sTXeQry;
142  TX_SAR_TABLE[sTXeQry.sessionID].slowstart_threshold = sTXeRtQry.getThreshold();
143  TX_SAR_TABLE[sTXeQry.sessionID].cong_window = 0x3908; // 10 x 1460(MSS) TODO is this correct or less, eg. 1/2 * MSS
144  if (DEBUG_LEVEL & TRACE_TST) {
145  printInfo(myName, "Received a Retry-Write query from TXe for session #%d.\n",
146  sTXeQry.sessionID.to_int());
147  }
148  }
149  }
150  else {
151  //-- TXe Read Query
152  TxSarEntry txSarEntry = TX_SAR_TABLE[sTXeQry.sessionID];
153 
154  TcpWindow minWindow;
155  if (txSarEntry.cong_window < txSarEntry.recv_window) {
156  minWindow = txSarEntry.cong_window;
157  }
158  else {
159  minWindow = TX_SAR_TABLE[sTXeQry.sessionID].recv_window;
160  }
161  soTXe_TxSarRep.write(TXeTxSarReply(TX_SAR_TABLE[sTXeQry.sessionID].ackd,
162  TX_SAR_TABLE[sTXeQry.sessionID].unak,
163  minWindow,
164  TX_SAR_TABLE[sTXeQry.sessionID].appw,
165  TX_SAR_TABLE[sTXeQry.sessionID].finReady,
166  TX_SAR_TABLE[sTXeQry.sessionID].finSent));
167  }
168  }
169  else if (!siTAi_PushCmd.empty()) {
170  TAiTxSarPush sTAiCmd;
171  //---------------------------------------
172  //-- Wr Command from TX APP Interface
173  //---------------------------------------
174  siTAi_PushCmd.read(sTAiCmd);
175  //-- Update the 'txAppWrPtr'
176  TX_SAR_TABLE[sTAiCmd.sessionID].appw = sTAiCmd.app;
177  }
178  else if (!siRXe_TxSarQry.empty()) {
179  RXeTxSarQuery sRXeQry;
180  //---------------------------------------
181  //-- Rd/Wr Query from RX Engine
182  //---------------------------------------
183  siRXe_TxSarQry.read(sRXeQry);
184  if (sRXeQry.write == QUERY_WR) {
185  TX_SAR_TABLE[sRXeQry.sessionID].ackd = sRXeQry.ackd;
186  TX_SAR_TABLE[sRXeQry.sessionID].recv_window = sRXeQry.recv_window;
187  TX_SAR_TABLE[sRXeQry.sessionID].cong_window = sRXeQry.cong_window;
188  TX_SAR_TABLE[sRXeQry.sessionID].count = sRXeQry.count;
189  TX_SAR_TABLE[sRXeQry.sessionID].fastRetransmitted = sRXeQry.fastRetransmitted;
190  // Push ACK to txAppInterface
191  soTAi_PushCmd.write(TStTxSarPush(sRXeQry.sessionID, sRXeQry.ackd));
192  }
193  else {
194  //-- Read Query
195  soRXe_TxSarRep.write(RXeTxSarReply(TX_SAR_TABLE[sRXeQry.sessionID].ackd,
196  TX_SAR_TABLE[sRXeQry.sessionID].unak,
197  TX_SAR_TABLE[sRXeQry.sessionID].cong_window,
198  TX_SAR_TABLE[sRXeQry.sessionID].slowstart_threshold,
199  TX_SAR_TABLE[sRXeQry.sessionID].count,
200  TX_SAR_TABLE[sRXeQry.sessionID].fastRetransmitted));
201  }
202  }
203 }
RemotWinSize recv_window
Definition: toe.hpp:449
CmdBool fastRetransmitted
Definition: toe.hpp:452
TxAckNum ackd
Definition: toe.hpp:448
RdWrBit write
Definition: toe.hpp:453
ap_uint< 2 > count
Definition: toe.hpp:451
LocalWinSize cong_window
Definition: toe.hpp:450
SessionId sessionID
Definition: toe.hpp:447
SessionId sessionID
Definition: toe.hpp:547
TxBufPtr app
Definition: toe.hpp:548
bool finReady
Definition: toe.hpp:490
bool isRtQuery
Definition: toe.hpp:492
bool finSent
Definition: toe.hpp:491
SessionId sessionID
Definition: toe.hpp:486
TxAckNum not_ackd
Definition: toe.hpp:487
RdWrBit write
Definition: toe.hpp:488
CmdBit init
Definition: toe.hpp:489
ap_uint< TOE_WINDOW_BITS > getThreshold()
Definition: toe.hpp:537
bool fastRetransmitted
TxAckNum unak
TxBufPtr appw
TcpWindow slowstart_threshold
LocalWinSize cong_window
ap_uint< 2 > count
RemotWinSize recv_window
TxAckNum ackd
#define TRACE_TST
#define CMD_INIT
Definition: nts_types.hpp:60
Here is the caller graph for this function:

◆ writeChunk()

void DummyMemory::writeChunk ( AxisApp chunk)

Definition at line 96 of file dummy_memory.cpp.

96  {
97  writeStorageIt = storage.find(writeId);
98  if (writeStorageIt == storage.end()) {
99  writeStorageIt = createBuffer(writeId);
100  // check it?
101  }
102  // shuffleWord(word.data);
103  for (int i = 0; i < 8; i++) {
104  if (chunk.getLE_TKeep()[i]) {
105  (writeStorageIt->second)[writeAddr] = chunk.getLE_TData((i*8)+7, i*8);
106  writeAddr++;
107  }
108  else {
109  break;
110  }
111  }
112 }
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ cDepth_AKdToEVe_Event

const int cDepth_AKdToEVe_Event = 8

CONSTANTS FOR THE INTERNAL STREAM DEPTHS

Definition at line 206 of file toe.hpp.

◆ cDepth_AKdToTXe_Event

const int cDepth_AKdToTXe_Event = 16

Definition at line 207 of file toe.hpp.

◆ cDepth_EVeToAKd_Event

const int cDepth_EVeToAKd_Event = 8

Definition at line 209 of file toe.hpp.

◆ cDepth_FsmToEve_Event

const int cDepth_FsmToEve_Event = 4

CONSTANTS FOR THE INTERNAL STREAM DEPTHS

Definition at line 103 of file rx_engine.hpp.

◆ cDepth_FsmToMwr_WrCmd

const int cDepth_FsmToMwr_WrCmd = 16

Definition at line 104 of file rx_engine.hpp.

◆ cDepth_FsmToRan_Notif

const int cDepth_FsmToRan_Notif = 16

Definition at line 105 of file rx_engine.hpp.

◆ cDepth_FsmToTsd_DropCmd

const int cDepth_FsmToTsd_DropCmd = 16

Definition at line 106 of file rx_engine.hpp.

◆ cDepth_MdhToEvm_Event

const int cDepth_MdhToEvm_Event = 4

Definition at line 108 of file rx_engine.hpp.

◆ cDepth_MdhToTsd_DropCmd

const int cDepth_MdhToTsd_DropCmd = 16

Definition at line 109 of file rx_engine.hpp.

◆ cDepth_MwrToRan_SplitSeg

const int cDepth_MwrToRan_SplitSeg = 16

Definition at line 111 of file rx_engine.hpp.

◆ cDepth_RAiToRSt_Qry

const int cDepth_RAiToRSt_Qry = 4

Definition at line 211 of file toe.hpp.

◆ cDepth_RXeToEVe_Event

const int cDepth_RXeToEVe_Event = 64

Definition at line 213 of file toe.hpp.

◆ cDepth_RXeToRSt_Qry

const int cDepth_RXeToRSt_Qry = 4

Definition at line 214 of file toe.hpp.

◆ cDepth_RXeToTSt_Qry

const int cDepth_RXeToTSt_Qry = 4

Definition at line 215 of file toe.hpp.

◆ cDepth_STtToRXe_Rep

const int cDepth_STtToRXe_Rep = 2

Definition at line 217 of file toe.hpp.

◆ cDepth_STtToTAi_Rep

const int cDepth_STtToTAi_Rep = 2

Definition at line 218 of file toe.hpp.

◆ cDepth_TAiToEVe_Event

const int cDepth_TAiToEVe_Event = 8

Definition at line 220 of file toe.hpp.

◆ cDepth_TAiToTSt_Cmd

const int cDepth_TAiToTSt_Cmd = 4

Definition at line 221 of file toe.hpp.

◆ cDepth_TImToEVe_Event

const int cDepth_TImToEVe_Event = 4

Definition at line 227 of file toe.hpp.

◆ cDepth_TStToRXe_Rep

const int cDepth_TStToRXe_Rep = 2

Definition at line 223 of file toe.hpp.

◆ cDepth_TStToTAi_Cmd

const int cDepth_TStToTAi_Cmd = 4

Definition at line 224 of file toe.hpp.

◆ cDepth_TStToTXe_Rep

const int cDepth_TStToTXe_Rep = 2

Definition at line 225 of file toe.hpp.

◆ cDepth_TXeToEVe_Event

const int cDepth_TXeToEVe_Event = 8

Definition at line 229 of file toe.hpp.

◆ cDepth_TXeToRSt_Req

const int cDepth_TXeToRSt_Req = 4

Definition at line 230 of file toe.hpp.

◆ cDepth_TXeToTSt_Qry

const int cDepth_TXeToTSt_Qry = 4

Definition at line 231 of file toe.hpp.

◆ gSimCycCnt

unsigned int gSimCycCnt
extern

Definition at line 150 of file tb_nal.cpp.

◆ gTraceEvent [1/13]

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (TRACE_AKD)

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

Definition at line 151 of file tb_nal.cpp.

◆ gTraceEvent [2/13]

bool gTraceEvent
extern

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

Definition at line 151 of file tb_nal.cpp.

◆ gTraceEvent [3/13]

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (TRACE_ORM | TRACE_FPT)

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

Definition at line 151 of file tb_nal.cpp.

◆ gTraceEvent [4/13]

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (RAA_TRACE | RAD_TRACE)

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

Definition at line 151 of file tb_nal.cpp.

◆ gTraceEvent [5/13]

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (TRACE_CSA | TRACE_IPH)

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

Definition at line 151 of file tb_nal.cpp.

◆ gTraceEvent [6/13]

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (TRACE_RST)

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

Definition at line 151 of file tb_nal.cpp.

◆ gTraceEvent [7/13]

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (TRACE_LRH | TRACE_URH)

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

Definition at line 151 of file tb_nal.cpp.

◆ gTraceEvent [8/13]

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (STT_TRACE)

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

Definition at line 151 of file tb_nal.cpp.

◆ gTraceEvent [9/13]

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (PBT_TRACE | RTT_TRACE)

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

Definition at line 151 of file tb_nal.cpp.

◆ gTraceEvent [10/13]

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (TRACE_OFF | TRACE_RDY)

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

Definition at line 151 of file tb_nal.cpp.

◆ gTraceEvent [11/13]

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (TAC_TRACE | TAS_TRACE)

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

Definition at line 151 of file tb_nal.cpp.

◆ gTraceEvent [12/13]

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (TRACE_PHC | TRACE_MDL)

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

Definition at line 151 of file tb_nal.cpp.

◆ gTraceEvent [13/13]

bool gTraceEvent
extern

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (TRACE_TST)

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

Definition at line 151 of file tb_nal.cpp.

◆ idleCycCnt

uint32_t idleCycCnt
extern

◆ packetCounter

uint32_t packetCounter
extern