68 #define THIS_NAME "TOE/TAi"
70 #define TRACE_OFF 0x0000
71 #define TRACE_SML 1 << 1
72 #define TRACE_SLG 1 << 2
73 #define TRACE_MWR 1 << 3
74 #define TRACE_TAC 1 << 4
75 #define TRACE_TAS 1 << 5
76 #define TRACE_TAT 1 << 6
77 #define TRACE_TASH 1 << 7
78 #define TRACE_ALL 0xFFFF
80 #define DEBUG_LEVEL (TRACE_OFF)
101 #pragma HLS PIPELINE II=1 enable_flush
102 #pragma HLS INLINE off
105 so.write(si1.read());
106 else if (!si2.empty())
107 so.write(si2.read());
151 stream<TcpAppOpnReq> &siTAIF_OpnReq,
152 stream<TcpAppOpnRep> &soTAIF_OpnRep,
153 stream<TcpAppClsReq> &siTAIF_ClsReq,
154 stream<SocketPair> &soSLc_SessLookupReq,
155 stream<SessionLookupReply> &siSLc_SessLookupRep,
156 stream<ReqBit> &soPRt_GetFreePortReq,
157 stream<TcpPort> &siPRt_GetFreePortRep,
158 stream<StateQuery> &soSTt_ConnectStateQry,
159 stream<TcpState> &siSTt_ConnectStateRep,
160 stream<SessState> &siRXe_ActSessState,
161 stream<Event> &soEVe_Event,
162 stream<SessState> &siTIm_Notif,
166 #pragma HLS pipeline II=1 enable_flush
167 #pragma HLS INLINE off
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
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
186 switch (tac_fsmState) {
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;
194 else if (!siSLc_SessLookupRep.empty()) {
197 if (sessLkpRep.
hit) {
203 if (!soTAIF_OpnRep.full()) {
208 printFatal(myName,
"Cannot write 'soTAIF_OpnRep()'. Stream is full!");
212 else if (!siRXe_ActSessState.empty()) {
214 siRXe_ActSessState.read(activeSessState);
217 if (!soTAIF_OpnRep.full()) {
218 soTAIF_OpnRep.write(activeSessState);
222 printFatal(myName,
"Cannot write 'soTAIF_OpnRep()'. Stream is full!");
225 else if (!siTIm_Notif.empty()) {
226 if (!soTAIF_OpnRep.full()) {
227 soTAIF_OpnRep.write(siTIm_Notif.read());
231 printFatal(myName,
"Cannot write 'soTAIF_OpnRep()'. Stream is full!");
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;
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();
248 tac_fsmState = TAC_IDLE;
252 if (!siSTt_ConnectStateRep.empty()) {
253 TcpState tcpState = siSTt_ConnectStateRep.read();
263 tac_fsmState = TAC_IDLE;
285 stream<DmSts> &siMEM_TxP_WrSts,
286 stream<Event> &siEmx_Event,
287 stream<TAiTxSarPush> &soTSt_PushCmd,
288 stream<Event> &soEVe_Event)
291 #pragma HLS pipeline II=1
292 #pragma HLS INLINE off
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
304 switch (tash_fsmState) {
306 if (!siEmx_Event.empty()) {
307 siEmx_Event.read(ev);
309 tash_fsmState = TASH_RD_MEM_STATUS_1;
312 soEVe_Event.write(ev);
315 printInfo(myName,
"Received event \'%s\' from [Emx].\n",
320 case TASH_RD_MEM_STATUS_1:
321 if (!siMEM_TxP_WrSts.empty()) {
322 DmSts status = siMEM_TxP_WrSts.read();
324 ap_uint<TOE_WINDOW_BITS+1> txAppPtr = ev.
address + ev.
length;
325 if (txAppPtr[TOE_WINDOW_BITS] == 1) {
327 tash_fsmState = TASH_RD_MEM_STATUS_2;
333 soEVe_Event.write(ev);
335 printInfo(myName,
"Received TXMEM write status = %d.\n", status.
okay.to_int());
337 tash_fsmState = TASH_IDLE;
342 case TASH_RD_MEM_STATUS_2:
343 if (!siMEM_TxP_WrSts.empty()) {
344 DmSts status = siMEM_TxP_WrSts.read();
350 soEVe_Event.write(ev);
352 printInfo(myName,
"Received TXMEM write status = %d (this was a split access).\n", status.
okay.to_int());
355 tash_fsmState = TASH_IDLE;
373 stream<TStTxSarPush> &siTSt_PushCmd,
374 stream<TxAppTableQuery> &siTas_AccessQry,
375 stream<TxAppTableReply> &siTas_AccessRep)
378 #pragma HLS PIPELINE II=1 enable_flush
379 #pragma HLS INLINE off
385 #pragma HLS DEPENDENCE variable=TX_APP_TABLE inter false
386 #pragma HLS reset variable=TX_APP_TABLE
392 if (!siTSt_PushCmd.empty()) {
393 siTSt_PushCmd.read(ackPush);
403 else if (!siTas_AccessQry.empty()) {
404 siTas_AccessQry.read(txAppUpdate);
405 if(txAppUpdate.
write) {
457 stream<TcpAppSndReq> &siTAIF_SndReq,
458 stream<TcpAppSndRep> &soTAIF_SndRep,
459 stream<SessionId> &soSTt_SessStateReq,
460 stream<TcpState> &siSTt_SessStateRep,
461 stream<TxAppTableQuery> &soTat_AccessReq,
462 stream<TxAppTableReply> &siTat_AccessRep,
463 stream<AppMemMeta> &soMwr_AppMeta,
464 stream<Event> &soEmx_Event)
467 #pragma HLS pipeline II=1 enable_flush
472 static enum FsmStates { READ_REQUEST=0, READ_META } \
473 mdl_fsmState = READ_REQUEST;
474 #pragma HLS reset variable = mdl_fsmState
483 switch(mdl_fsmState) {
485 if (!siTAIF_SndReq.empty()) {
487 siTAIF_SndReq.read(mdl_appSndReq);
489 assessSize(myName, soSTt_SessStateReq,
"soSTt_SessStateReq", 2);
490 soSTt_SessStateReq.write(mdl_appSndReq.
sessId);
492 assessSize(myName, soTat_AccessReq,
"soTat_AccessReq", 2);
495 printInfo(myName,
"Received new Tx request for session %d.\n", mdl_appSndReq.
sessId.to_int());
497 mdl_fsmState = READ_META;
501 if (!siTat_AccessRep.empty() and !siSTt_SessStateRep.empty()) {
502 siSTt_SessStateRep.read(sessState);
503 siTat_AccessRep.read(txAppTableReply);
514 if (!soTAIF_SndRep.full()) {
518 printError(myName,
"Session %d is not established. Current session state is \'%s\'.\n",
521 else if (mdl_appSndReq.
length > maxWriteLength) {
524 printError(myName,
"There is not enough TxBuf memory space available for session %d.\n",
525 mdl_appSndReq.
sessId.to_uint());
533 assessSize(myName, soEmx_Event,
"soEmx_Event", 2);
541 printFatal(myName,
"Cannot write 'soTAIF_SndRep()'. Stream is full!");
543 mdl_fsmState = READ_REQUEST;
567 stream<TcpAppData> &siTAIF_Data,
568 stream<AppMemMeta> &siSml_AppMeta,
569 stream<DmCmd> &soMEM_WrCmd,
570 stream<AxisApp> &soMEM_WrData)
573 #pragma HLS INLINE off
574 #pragma HLS pipeline II=1 enable_flush
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
587 static DmCmd mwr_memWrCmd;
591 static ap_uint<4> mwr_splitOffset;
592 static uint16_t mwr_debugCounter=1;
595 static uint8_t lengthBuffer;
596 static ap_uint<3> accessResidue;
598 switch (mwr_fsmState) {
600 if (!siSml_AppMeta.empty() and !soMEM_WrCmd.full()) {
601 siSml_AppMeta.read(mwr_appMemMeta);
603 TxMemPtr memSegAddr = TOE_TX_MEMORY_BASE;
604 memSegAddr(29, 16) = mwr_appMemMeta.
sessId(13, 0);
605 memSegAddr(15, 0) = mwr_appMemMeta.
addr;
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) {
611 printInfo(myName,
"TCP Tx memory buffer wraps around: This segment must be broken in two memory accesses.\n");
613 mwr_fsmState = MWR_SPLIT_1ST_CMD;
616 soMEM_WrCmd.write(mwr_memWrCmd);
617 mwr_firstAccLen = mwr_memWrCmd.
btt;
618 mwr_nrBytesToWr = mwr_firstAccLen;
619 mwr_fsmState = MWR_FWD_ALIGNED;
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());
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));
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());
637 mwr_fsmState = MWR_FWD_1ST_BUF;
640 case MWR_FWD_ALIGNED:
641 if (!siTAIF_Data.empty() and !soMEM_WrData.full()) {
644 AxisApp memChunk = siTAIF_Data.read();
645 soMEM_WrData.write(memChunk);
647 mwr_fsmState = MWR_IDLE;
651 case MWR_FWD_1ST_BUF:
652 if (!siTAIF_Data.empty() and !soMEM_WrData.full()) {
654 siTAIF_Data.read(mwr_currChunk);
655 AxisApp memChunk = mwr_currChunk;
656 if (mwr_nrBytesToWr > (
ARW/8)) {
657 mwr_nrBytesToWr -= (
ARW/8);
659 else if (!soMEM_WrCmd.full()) {
660 if (mwr_nrBytesToWr == (
ARW/8)) {
663 mwr_memWrCmd.
saddr(TOE_WINDOW_BITS-1, 0) = 0;
664 mwr_memWrCmd.
btt -= mwr_firstAccLen;
665 soMEM_WrCmd.write(mwr_memWrCmd);
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());
671 mwr_fsmState = MWR_FWD_ALIGNED;
676 #ifndef __SYNTHESIS__
680 mwr_memWrCmd.
saddr(TOE_WINDOW_BITS-1, 0) = 0;
681 mwr_memWrCmd.
btt -= mwr_firstAccLen;
682 soMEM_WrCmd.write(mwr_memWrCmd);
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());
688 mwr_splitOffset = (
ARW/8) - mwr_nrBytesToWr;
689 mwr_fsmState = MWR_FWD_2ND_BUF;
692 soMEM_WrData.write(memChunk);
696 case MWR_FWD_2ND_BUF:
697 if (!siTAIF_Data.empty() and !soMEM_WrData.full()) {
699 AxisApp prevChunk = mwr_currChunk;
700 mwr_currChunk = siTAIF_Data.read();
705 ((
int)mwr_splitOffset*8)-1, 0);
707 ((
int)mwr_splitOffset )-1, 0);
710 (
ARW ) -1, ((
int)mwr_splitOffset*8));
712 (
ARW/8) -1, ((
int)mwr_splitOffset ));
714 if (mwr_currChunk.
getLen() > mwr_nrBytesToWr) {
718 mwr_fsmState = MWR_RESIDUE;
724 mwr_fsmState = MWR_IDLE;
727 soMEM_WrData.write(joinedChunk);
734 if (!soMEM_WrData.full()) {
736 AxisApp prevChunk = mwr_currChunk;
741 ((
int)mwr_splitOffset*8)-1, 0);
743 ((
int)mwr_splitOffset )-1, 0);
745 soMEM_WrData.write(lastChunk);
749 mwr_fsmState = MWR_IDLE;
793 stream<TcpAppOpnReq> &siTAIF_OpnReq,
794 stream<TcpAppOpnRep> &soTAIF_OpnRep,
795 stream<TcpAppClsReq> &siTAIF_ClsReq,
797 stream<TcpAppData> &siTAIF_Data,
798 stream<TcpAppSndReq> &siTAIF_SndReq,
799 stream<TcpAppSndRep> &soTAIF_SndRep,
801 stream<DmCmd> &soMEM_TxP_WrCmd,
802 stream<AxisApp> &soMEM_TxP_Data,
803 stream<DmSts> &siMEM_TxP_WrSts,
805 stream<SessionId> &soSTt_SessStateReq,
806 stream<TcpState> &siSTt_SessStateRep,
807 stream<StateQuery> &soSTt_ConnectStateQry,
808 stream<TcpState> &siSTt_ConnectStateRep,
810 stream<SocketPair> &soSLc_SessLookupReq,
811 stream<SessionLookupReply> &siSLc_SessLookupRep,
813 stream<ReqBit> &soPRt_GetFreePortReq,
814 stream<TcpPort> &siPRt_GetFreePortRep,
816 stream<TStTxSarPush> &siTSt_PushCmd,
817 stream<TAiTxSarPush> &soTSt_PushCmd,
819 stream<SessState> &siRXe_ActSessState,
821 stream<Event> &soEVe_Event,
823 stream<SessState> &siTIm_Notif,
829 #pragma HLS INTERFACE ap_ctrl_none port=return
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
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
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
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
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
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
885 ssSmlToTat_AccessQry,
886 ssTatToSml_AccessRep,
903 soPRt_GetFreePortReq,
904 siPRt_GetFreePortRep,
905 soSTt_ConnectStateQry,
906 siSTt_ConnectStateRep,
915 ssSmlToTat_AccessQry,
916 ssTatToSml_AccessRep);
LE_tKeep getLE_TKeep(int leHi=64/8-1, int leLo=0) const
LE_tData getLE_TData(int leHi=64 -1, int leLo=0) const
void setLE_TLast(LE_tLast last)
void setLE_TData(LE_tData data, int leHi=64 -1, int leLo=0)
void setLE_TKeep(LE_tKeep keep, int leHi=64/8-1, int leLo=0)
LE_tLast getLE_TLast() const
void pStreamMux(stream< T > &si1, stream< T > &si2, stream< T > &so)
A 2-to-1 generic Stream Multiplexer.
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)
const char * getEventName(EventType evType)
Returns the name of an enum-based event as a user friendly string.
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 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)
#define assessSize(callerName, stream, streamName, depth)
A macro that checks if a stream is full.
#define printError(callerName, format,...)
A macro to print an error message.
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...
void printAxisRaw(const char *callerName, AxisRaw chunk)
Prints an Axis raw data chunk (used for debugging).
const char * getTcpStateName(TcpState tcpState)
Returns the name of an enum-based TCP-State as a user friendly string.
#define printInfo(callerName, format,...)
A macro to print an information message.
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
#define printFatal(callerName, format,...)
A macro to print a fatal error message and exit.
: Tx Application Interface (TAi)