diff --git a/hls/toe/port_table/port_table.cpp b/hls/toe/port_table/port_table.cpp index 45fbe0b..d3efe4d 100755 --- a/hls/toe/port_table/port_table.cpp +++ b/hls/toe/port_table/port_table.cpp @@ -137,16 +137,18 @@ void free_port_table( stream >& sLookup2portTable_releasePort, } else { - if (!freePortTable[pt_cursor] && !portTable2txApp_port_rsp.full()) //This is not perfect, but yeah - { - freePort(14, 0) = pt_cursor; - freePort[15] = 1; + bool used = freePortTable[pt_cursor]; + if (used) { + pt_cursor++; + } else if (!portTable2txApp_port_rsp.full()) { + ap_uint<16> freePort; + freePort(14,0) = pt_cursor; + freePort[15] = 1; freePortTable[pt_cursor] = true; portTable2txApp_port_rsp.write(freePort); + pt_cursor++; } } - pt_cursor++; - /*if (!txApp2portTable_port_req.empty()) //Fixme this!!! { txApp2portTable_port_req.read(); diff --git a/hls/toe/rx_engine/rx_engine.cpp b/hls/toe/rx_engine/rx_engine.cpp index 50b8d27..cbfd7fd 100755 --- a/hls/toe/rx_engine/rx_engine.cpp +++ b/hls/toe/rx_engine/rx_engine.cpp @@ -638,21 +638,25 @@ void drop_optional_header_fields( hls::stream& metaIn, * kind | length | description * 0 | 1B | End of options list * 1 | 1B | NOP/Padding - * 2 | 4B | MSS (Maximum segment size) + * 2 | 4B | MSS (Maximum segment size) - If omitted, 536B for IPv4 * 3 | 3B | Window scale * 4 | 2B | SACK permitted (Selective Acknowledgment) */ void parse_optional_header_fields( hls::stream >& dataOffsetIn, hls::stream >& optionalHeaderFieldsIn, - hls::stream >& windowScaleOut) + hls::stream >& windowScaleOut, + hls::stream >& mssOut) { #pragma HLS PIPELINE II=1 #pragma HLS INLINE off enum fsmStateType {IDLE, PARSE}; static fsmStateType state = IDLE; - static ap_uint<4> dataOffset; + static ap_uint<4> dataOffsetDword; + static ap_uint<6> dataOffsetByte; static ap_uint<320> fields; + static bool got_ws = false; + static bool got_mss = false; switch (state) { @@ -660,8 +664,11 @@ void parse_optional_header_fields( hls::stream >& dataOffsetIn, if (!dataOffsetIn.empty() && !optionalHeaderFieldsIn.empty()) { // std::cout << "PARSE IDLE" << std::endl; - dataOffsetIn.read(dataOffset); + dataOffsetIn.read(dataOffsetDword); + dataOffsetByte = 4 * (ap_int<6>)dataOffsetDword; optionalHeaderFieldsIn.read(fields); + got_ws = false; + got_mss = false; state = PARSE; } break; @@ -671,35 +678,64 @@ void parse_optional_header_fields( hls::stream >& dataOffsetIn, switch (optionKind) { - case 0: //End of option list - windowScaleOut.write(0); + case 0:{//End of option list + if(!got_mss) mssOut.write(536); + if(!got_ws) windowScaleOut.write(0); // std::cout << "PARSE EOL" << std::endl; state = IDLE; break; - case 1: - optionLength = 1; + } + case 1:{ // NOP + if(dataOffsetByte == 1){ + if(!got_mss) mssOut.write(536); + if(!got_ws) windowScaleOut.write(0); + state = IDLE; + } + else optionLength = 1; break; - case 3: + } + case 2:{ + ap_uint<16> mss; + mss(15,8) = fields(23,16); + mss( 7,0) = fields(31,24); + mssOut.write(mss); + if (dataOffsetByte == 4 || got_ws){ + if(!got_ws) windowScaleOut.write(0); + state = IDLE; + } + got_mss = true; + optionLength = 4; + break; + } + case 3:{ // std::cout << "PARSE WS: " << (uint16_t)fields(19, 16) << std::endl; windowScaleOut.write(fields(19, 16)); - state = IDLE; + if (dataOffsetByte == 3 || got_mss){ + if(!got_mss) mssOut.write((ap_uint<16>)536); + state = IDLE; + } + optionLength = 3; + got_ws = true; break; - default: - if (dataOffset == optionLength) - { - windowScaleOut.write(0); + } + default:{ + if(dataOffsetByte == optionLength){ + if(!got_mss) mssOut.write((ap_uint<16>)536); + if(!got_ws) windowScaleOut.write(0); // std::cout << "PARSE DONE" << std::endl; state = IDLE; } break; + } }//switch - dataOffset -= optionLength; + dataOffsetByte -= optionLength; fields = (fields >> (optionLength*8)); break; }//switch } void merge_header_meta(hls::stream >& rxEng_winScaleFifo, + hls::stream >& rxEng_mssFifo, hls::stream& rxEng_headerMetaFifo, hls::stream& rxEng_metaDataFifo) { @@ -723,15 +759,17 @@ void merge_header_meta(hls::stream >& rxEng_winScaleFifo, else { meta.winScale = 0; + meta.mss = 536; rxEng_metaDataFifo.write(meta); } } break; case 1: - if (!rxEng_winScaleFifo.empty()) + if (!rxEng_winScaleFifo.empty() && !rxEng_mssFifo.empty()) { // std::cout << "META MERGE 1" << std::endl; meta.winScale = rxEng_winScaleFifo.read(); + meta.mss = rxEng_mssFifo.read(); rxEng_metaDataFifo.write(meta); state = 0; } @@ -1368,7 +1406,7 @@ void rxTcpFSM( stream& fsmMetaDataFifo, // Initialize rxSar, SEQ + phantom byte for recvd and head pointer, offset to 0, gap set to false rxEng2rxSar_upd_req.write(rxSarRecvd(fsm_meta.sessionID, fsm_meta.meta.seqNumb+1, fsm_meta.meta.seqNumb+1, 0, false, rx_win_shift)); // Initialize receive window - rxEng2txSar_upd_req.write((rxTxSarQuery(fsm_meta.sessionID, 0, fsm_meta.meta.winSize, txSar.cong_window, 0, false, tx_win_shift))); //TODO maybe include count check + rxEng2txSar_upd_req.write((rxTxSarQuery(fsm_meta.sessionID, 0, fsm_meta.meta.winSize, txSar.cong_window, 0, false, tx_win_shift, fsm_meta.meta.mss))); //TODO maybe include count check #else // Initialize rxSar, SEQ + phantom byte, last '1' for makes sure appd is initialized rxEng2rxSar_upd_req.write(rxSarRecvd(fsm_meta.sessionID, fsm_meta.meta.seqNumb+1, fsm_meta.meta.seqNumb+1, 0, false, 1)); @@ -1432,7 +1470,7 @@ void rxTcpFSM( stream& fsmMetaDataFifo, ap_uint<4> rx_win_shift = (fsm_meta.meta.winScale == 0) ? 0 : WINDOW_SCALE_BITS; ap_uint<4> tx_win_shift = fsm_meta.meta.winScale; rxEng2rxSar_upd_req.write(rxSarRecvd(fsm_meta.sessionID, fsm_meta.meta.seqNumb+1, fsm_meta.meta.seqNumb+1, 0, false, rx_win_shift)); - rxEng2txSar_upd_req.write((rxTxSarQuery(fsm_meta.sessionID, fsm_meta.meta.ackNumb, fsm_meta.meta.winSize, txSar.cong_window, 0, false, tx_win_shift))); //TODO maybe include count check + rxEng2txSar_upd_req.write((rxTxSarQuery(fsm_meta.sessionID, fsm_meta.meta.ackNumb, fsm_meta.meta.winSize, txSar.cong_window, 0, false, tx_win_shift, fsm_meta.meta.mss))); //TODO maybe include count check #else //initialize rx_sar, SEQ + phantom byte, last '1' for appd init rxEng2rxSar_upd_req.write(rxSarRecvd(fsm_meta.sessionID, fsm_meta.meta.seqNumb+1, fsm_meta.meta.seqNumb+1, 0, false, 1)); @@ -2103,10 +2141,12 @@ void rx_engine( stream >& ipRxData, static hls::stream > rxEng_dataOffsetFifo("rxEng_dataOffsetFifo"); static hls::stream > rxEng_optionalFieldsFifo("rxEng_optionalFieldsFifo"); static hls::stream > rxEng_winScaleFifo("rxEng_winScaleFifo"); + static hls::stream > rxEng_mssFifo("rxEng_mssFifo"); #pragma HLS stream variable=rxEng_headerMetaFifo depth=16 #pragma HLS stream variable=rxEng_dataOffsetFifo depth=2 #pragma HLS stream variable=rxEng_optionalFieldsFifo depth=2 #pragma HLS stream variable=rxEng_winScaleFifo depth=2 + #pragma HLS stream variable=rxEng_mssFifo depth=2 //TODO data pack #endif @@ -2136,8 +2176,8 @@ void rx_engine( stream >& ipRxData, //rxTcpInvalidDropper(rxEng_dataBuffer3b, rxEng_tcpValidFifo, rxEng_dataBuffer3); #if (WINDOW_SCALE) - parse_optional_header_fields(rxEng_dataOffsetFifo, rxEng_optionalFieldsFifo, rxEng_winScaleFifo); - merge_header_meta(rxEng_winScaleFifo, rxEng_headerMetaFifo, rxEng_metaDataFifo); + parse_optional_header_fields(rxEng_dataOffsetFifo, rxEng_optionalFieldsFifo, rxEng_winScaleFifo, rxEng_mssFifo); + merge_header_meta(rxEng_winScaleFifo, rxEng_mssFifo, rxEng_headerMetaFifo, rxEng_metaDataFifo); #endif rxMetadataHandler( rxEng_metaDataFifo, diff --git a/hls/toe/rx_engine/rx_engine.hpp b/hls/toe/rx_engine/rx_engine.hpp index 64bf670..052b58e 100755 --- a/hls/toe/rx_engine/rx_engine.hpp +++ b/hls/toe/rx_engine/rx_engine.hpp @@ -66,6 +66,7 @@ struct rxEngineMetaData ap_uint<1> fin; ap_uint<4> dataOffset; //ap_uint<16> dstPort; + ap_uint<16> mss; // peer MSS }; /** @ingroup rx_engine diff --git a/hls/toe/toe_internals.hpp b/hls/toe/toe_internals.hpp index 603cfd3..ff8546b 100755 --- a/hls/toe/toe_internals.hpp +++ b/hls/toe/toe_internals.hpp @@ -185,6 +185,7 @@ struct txSarEntry ap_uint<16> recv_window; #if (WINDOW_SCALE) ap_uint<4> win_shift; + ap_uint<16> peer_mss; #endif ap_uint cong_window; ap_uint slowstart_threshold; @@ -205,6 +206,7 @@ struct rxTxSarQuery bool fastRetransmitted; #if (WINDOW_SCALE) ap_uint<4> win_shift; + ap_uint<16> peer_mss; #endif ap_uint<1> write; ap_uint<1> init; @@ -215,7 +217,9 @@ struct rxTxSarQuery :sessionID(id), ackd(ackd), recv_window(recv_win), cong_window(cong_win), count(count), fastRetransmitted(fastRetransmitted), write(1), init(0) {} #if (WINDOW_SCALE) rxTxSarQuery(ap_uint<16> id, ap_uint<32> ackd, ap_uint<16> recv_win, ap_uint cong_win, ap_uint<2> count, bool fastRetransmitted, ap_uint<4> win_shift) - :sessionID(id), ackd(ackd), recv_window(recv_win), cong_window(cong_win), count(count), fastRetransmitted(fastRetransmitted), win_shift(win_shift), write(1), init(1) {} + :sessionID(id), ackd(ackd), recv_window(recv_win), cong_window(cong_win), count(count), fastRetransmitted(fastRetransmitted), win_shift(win_shift), write(1), init(1), peer_mss(0) {} + rxTxSarQuery(ap_uint<16> id, ap_uint<32> ackd, ap_uint<16> recv_win, ap_uint cong_win, ap_uint<2> count, bool fastRetransmitted, ap_uint<4> win_shift, ap_uint<16> peer_mss) + :sessionID(id), ackd(ackd), recv_window(recv_win), cong_window(cong_win), count(count), fastRetransmitted(fastRetransmitted), win_shift(win_shift), write(1), init(1), peer_mss(peer_mss) {} #endif }; @@ -241,6 +245,17 @@ struct txTxSarQuery :sessionID(id), not_ackd(not_ackd), write(write), init(init), finReady(finReady), finSent(finSent), isRtQuery(isRt) {} }; +struct txDDRbypassPush +{ + bool isBypass; + ap_uint<16> session_mss; + txDDRbypassPush() {} + txDDRbypassPush(bool en) + :isBypass(en),session_mss(576) {} + txDDRbypassPush(bool en, ap_uint<16> mss) + :isBypass(en),session_mss(mss) {} +}; + struct txTxSarRtQuery : public txTxSarQuery { txTxSarRtQuery() {} @@ -338,12 +353,21 @@ struct txTxSarReply ap_uint usedLength; bool finReady; bool finSent; -//#if (WINDOW_SCALE) ap_uint<4> win_shift; -//#endif +#if (WINDOW_SCALE) + ap_uint<16> peer_mss; +#endif txTxSarReply() {} +#if (WINDOW_SCALE) + txTxSarReply(ap_uint<32> ack, ap_uint<32> nack, ap_uint usableWindow, ap_uint app, ap_uint usedLength, bool finReady, bool finSent) + :ackd(ack), not_ackd(nack), usableWindow(usableWindow), app(app), usedLength(usedLength), finReady(finReady), finSent(finSent), peer_mss(0) {} + txTxSarReply(ap_uint<32> ack, ap_uint<32> nack, ap_uint usableWindow, ap_uint app, ap_uint usedLength, bool finReady, bool finSent, ap_uint<16> peer_mss) + :ackd(ack), not_ackd(nack), usableWindow(usableWindow), app(app), usedLength(usedLength), finReady(finReady), finSent(finSent), peer_mss(peer_mss) {} +#else txTxSarReply(ap_uint<32> ack, ap_uint<32> nack, ap_uint usableWindow, ap_uint app, ap_uint usedLength, bool finReady, bool finSent) :ackd(ack), not_ackd(nack), usableWindow(usableWindow), app(app), usedLength(usedLength), finReady(finReady), finSent(finSent) {} +#endif + }; struct rxRetransmitTimerUpdate { diff --git a/hls/toe/tx_engine/tx_engine.cpp b/hls/toe/tx_engine/tx_engine.cpp index c4cb8b8..1b08076 100755 --- a/hls/toe/tx_engine/tx_engine.cpp +++ b/hls/toe/tx_engine/tx_engine.cpp @@ -55,6 +55,8 @@ * @param[out] txEng_isLookUpFifoOut * @param[out] txEng_tupleShortCutFifoOut */ + +template void metaLoader(hls::stream& eventEng2txEng_event, hls::stream& rxSar2txEng_rsp, hls::stream& txSar2txEng_upd_rsp, @@ -68,7 +70,7 @@ void metaLoader(hls::stream& eventEng2txEng_event, hls::stream >& txEng2sLookup_rev_req, hls::stream& txEng_isLookUpFifoOut, #if (TCP_NODELAY) - hls::stream& txEng_isDDRbypass, + hls::stream& txEng_isDDRbypass, #endif hls::stream& txEng_tupleShortCutFifoOut, hls::stream >& readCountFifo) @@ -88,6 +90,13 @@ void metaLoader(hls::stream& eventEng2txEng_event, static tx_engine_meta meta; rstEvent resetEvent; +#if (TCP_NODELAY) + static txTxSarReply txSar_TX; + static ap_uint<16> tx_remaining; + static ap_uint<16> mss_rounddown; +#endif + const ap_uint<16> MASK = ~((ap_uint<16>)(WIDTH/8) - 1); + switch (ml_FsmState) { case 0: @@ -104,6 +113,7 @@ void metaLoader(hls::stream& eventEng2txEng_event, txEng2txSar_upd_req.write(txTxSarQuery(ml_curEvent.sessionID)); break; case TX: + tx_remaining = 0; txEng2rxSar_req.write(ml_curEvent.sessionID); txEng2txSar_upd_req.write(txTxSarQuery(ml_curEvent.sessionID)); break; @@ -149,19 +159,44 @@ void metaLoader(hls::stream& eventEng2txEng_event, // Can bypass DDR #if (TCP_NODELAY) case TX: - if ((!rxSar2txEng_rsp.empty() && !txSar2txEng_upd_rsp.empty()))// || ml_sarLoaded) + if(tx_remaining != 0){ + if ((!rxSar2txEng_rsp.empty())){ + rxSar2txEng_rsp.read(rxSar); + if(tx_remaining > mss_rounddown){ + meta.length = mss_rounddown; + tx_remaining -= mss_rounddown; + txEng2rxSar_req.write(ml_curEvent.sessionID); + } + else{ + meta.length = tx_remaining; + tx_remaining = 0; + ml_FsmState = 0; + txEng2txSar_upd_req.write(txTxSarQuery(ml_curEvent.sessionID, txSar_TX.not_ackd + meta.length, 1)); + txEng2timer_setRetransmitTimer.write(txRetransmitTimerSet(ml_curEvent.sessionID)); + } + meta.ackNumb = rxSar.recvd; + meta.seqNumb = txSar_TX.not_ackd; + meta.window_size = rxSar.windowSize; //Precalcualted in rx_sar_table ((rxSar.appd - rxSar.recvd) - 1) + // Send single packet + txEng_ipMetaFifoOut.write(meta.length); + txEng_tcpMetaFifoOut.write(meta); + txEng_isLookUpFifoOut.write(true); + txEng2sLookup_rev_req.write(ml_curEvent.sessionID); + txSar_TX.not_ackd += meta.length; + } + } + else if ((!rxSar2txEng_rsp.empty() && !txSar2txEng_upd_rsp.empty()))// || ml_sarLoaded) { rxSar2txEng_rsp.read(rxSar); - txTxSarReply txSar = txSar2txEng_upd_rsp.read(); + txSar_TX = txSar2txEng_upd_rsp.read(); meta.ackNumb = rxSar.recvd; - meta.seqNumb = txSar.not_ackd; + meta.seqNumb = txSar_TX.not_ackd; meta.window_size = rxSar.windowSize; //Precalcualted in rx_sar_table ((rxSar.appd - rxSar.recvd) - 1) meta.ack = 1; // ACK is always set when established meta.rst = 0; meta.syn = 0; meta.fin = 0; - meta.length = ml_curEvent.length; //this is hack, makes sure that probeTimer is never set. //ProbeTimer is not used, since application checks space before transmitting @@ -170,30 +205,43 @@ void metaLoader(hls::stream& eventEng2txEng_event, txEng2timer_setProbeTimer.write(ml_curEvent.sessionID); } - //TODO some checking - txSar.not_ackd += ml_curEvent.length; - - txEng2txSar_upd_req.write(txTxSarQuery(ml_curEvent.sessionID, txSar.not_ackd, 1)); - //This state is always left - ml_FsmState = 0; - - - // Send a packet only if there is data or we want to send an empty probing message - if (meta.length != 0)// || ml_curEvent.retransmit) //TODO retransmit boolean currently not set, should be removed - { + if(ml_curEvent.length != 0){// Send a packet only if there is data +#if(WINDOW_SCALE) + mss_rounddown = txSar_TX.peer_mss & MASK; + // mss_rounddown = (txSar_TX.peer_mss != 0) ? (txSar_TX.peer_mss & MASK) : (ap_uint<16>)512; +#else + mss_rounddown = MSS; +#endif + if(ml_curEvent.length > txSar_TX.peer_mss){ + meta.length = mss_rounddown; + tx_remaining = ml_curEvent.length - mss_rounddown; + txSar_TX.not_ackd += mss_rounddown; + txEng2rxSar_req.write(ml_curEvent.sessionID); + txEng_isDDRbypass.write(txDDRbypassPush(true, mss_rounddown)); + } + else{ + meta.length = ml_curEvent.length; + tx_remaining = 0; + ml_FsmState = 0; + txSar_TX.not_ackd += ml_curEvent.length; + txEng2txSar_upd_req.write(txTxSarQuery(ml_curEvent.sessionID, txSar_TX.not_ackd, 1)); + txEng2timer_setRetransmitTimer.write(txRetransmitTimerSet(ml_curEvent.sessionID)); + txEng_isDDRbypass.write(txDDRbypassPush(true, txSar_TX.peer_mss)); + } txEng_ipMetaFifoOut.write(meta.length); txEng_tcpMetaFifoOut.write(meta); txEng_isLookUpFifoOut.write(true); - txEng_isDDRbypass.write(true); txEng2sLookup_rev_req.write(ml_curEvent.sessionID); - - // Only set RT timer if we actually send sth, TODO only set if we change state and sent sth - txEng2timer_setRetransmitTimer.write(txRetransmitTimerSet(ml_curEvent.sessionID)); } + else{ + txEng2txSar_upd_req.write(txTxSarQuery(ml_curEvent.sessionID, txSar_TX.not_ackd, 1)); + ml_FsmState = 0; + } + //This state is always left std::cout<<"TX"; std::cout<& eventEng2txEng_event, // Sends everyting between txSar.not_ackd and txSar.app if ((!rxSar2txEng_rsp.empty() && !txSar2txEng_upd_rsp.empty()) || ml_sarLoaded) { + txTxSarReply txSar; if (!ml_sarLoaded) { rxSar2txEng_rsp.read(rxSar); @@ -225,7 +274,7 @@ void metaLoader(hls::stream& eventEng2txEng_event, meta.fin = 0; meta.length = 0; - currLength = (txSar.app - ((ap_uint)txSar.not_ackd)); + ap_uint currLength = (txSar.app - ((ap_uint)txSar.not_ackd)); // Construct address before modifying txSar.not_ackd ap_uint<32> pkgAddr; @@ -375,16 +424,15 @@ void metaLoader(hls::stream& eventEng2txEng_event, txEng2txSar_upd_req.write(txTxSarRtQuery(ml_curEvent.sessionID, slowstart_threshold)); } - // Since we are retransmitting from txSar.ackd to txSar.not_ackd, this data is already inside the usableWindow // => no check is required // Only check if length is bigger than MMS - if (currLength > MSS) + if (currLength > txSar.peer_mss) { // We stay in this state and sent immediately another packet - meta.length = MSS; - txSar.ackd += MSS; - txSar.usedLength -= MSS; + meta.length = txSar.peer_mss; + txSar.ackd += txSar.peer_mss; + txSar.usedLength -= txSar.peer_mss; // TODO replace with dynamic count, remove this if (ml_segmentCount == 3) { @@ -416,7 +464,7 @@ void metaLoader(hls::stream& eventEng2txEng_event, txEng_tcpMetaFifoOut.write(meta); txEng_isLookUpFifoOut.write(true); #if (TCP_NODELAY) - txEng_isDDRbypass.write(false); + txEng_isDDRbypass.write(txDDRbypassPush(false)); #endif txEng2sLookup_rev_req.write(ml_curEvent.sessionID); @@ -1034,6 +1082,7 @@ void generate_ipv4( //stream& txEng_ipMetaDataFifoIn, //} //else }*/ + template void pseudoHeaderConstructionNew(stream& tcpMetaDataFifoIn, stream& tcpTupleFifoIn, @@ -1230,6 +1279,7 @@ void pseudoHeaderConstructionNew(stream& tcpMetaDataFifoIn, } + /** @ingroup tx_engine * In case of the payload had to bread using two DDR commands, it it concatened by this module */ @@ -1396,7 +1446,7 @@ void read_data_stitching( hls::stream& memAccessBreakdown2readPkgStitche template void read_data_arbiter(stream >& txBufferReadData, #if (TCP_NODELAY) - stream& txEng_isDDRbypass, + stream& txEng_isDDRbypass, stream >& txApp2txEng_data_stream, #endif stream >& txEng_tcpSegOut) @@ -1405,6 +1455,8 @@ void read_data_arbiter(stream >& txBufferReadData, #pragma HLS INLINE off static ap_uint<2> tps_state = 0; //TODO rename + static ap_uint<16> mss; + static ap_uint<16> left_len; switch (tps_state) { @@ -1412,9 +1464,11 @@ void read_data_arbiter(stream >& txBufferReadData, #if (TCP_NODELAY) if (!txEng_isDDRbypass.empty()) { - bool isBypass = txEng_isDDRbypass.read(); - if (isBypass) + txDDRbypassPush isDDRbypass = txEng_isDDRbypass.read(); + if (isDDRbypass.isBypass) { + mss = isDDRbypass.session_mss; + left_len = mss; tps_state = 2; } else @@ -1424,7 +1478,7 @@ void read_data_arbiter(stream >& txBufferReadData, } #else - tps_state = 1 + tps_state = 1; #endif break; case 1: @@ -1443,12 +1497,21 @@ void read_data_arbiter(stream >& txBufferReadData, if (!txApp2txEng_data_stream.empty()) { net_axis currWord = txApp2txEng_data_stream.read(); + bool lastWord = currWord.last; + if(left_len <= (WIDTH / 8)){ + currWord.last = 1; + left_len = mss; + } + else{ + left_len -= (WIDTH / 8); + } // std::cout << "ARBITER: "; // printLE(std::cout, currWord); // std::cout << std::endl; txEng_tcpSegOut.write(currWord); - if (currWord.last) + if (lastWord) { + left_len = 0; tps_state = 0; } } @@ -1662,7 +1725,7 @@ void tx_engine( stream& eventEng2txEng_event, static hls::stream > txEng_tcpPkgBuffer6("txEng_tcpPkgBuffer6"); #pragma HLS stream variable=txBufferReadDataStitched depth=2 - #pragma HLS stream variable=txEng_shift2pseudoFifo depth=2 + #pragma HLS stream variable=txEng_shift2pseudoFifo depth=8 #pragma HLS stream variable=txEng_tcpPkgBuffer0 depth=2 #pragma HLS stream variable=txEng_tcpPkgBuffer1 depth=16 // is forwarded immediately, size is not critical #pragma HLS stream variable=txEng_tcpPkgBuffer2 depth=256 // critical, has to keep complete packet for checksum computation @@ -1706,7 +1769,7 @@ void tx_engine( stream& eventEng2txEng_event, static stream memAccessBreakdown2txPkgStitcher("memAccessBreakdown2txPkgStitcher"); #pragma HLS stream variable=memAccessBreakdown2txPkgStitcher depth=32 - static stream txEng_isDDRbypass("txEng_isDDRbypass"); + static stream txEng_isDDRbypass("txEng_isDDRbypass"); #pragma HLS stream variable=txEng_isDDRbypass depth=32 #else #pragma HLS DATA_PACK variable=txBufferReadDataStitched @@ -1730,7 +1793,7 @@ void tx_engine( stream& eventEng2txEng_event, static stream txEng_ipTupleFifo("txEng_ipTupleFifo"); static stream txEng_tcpTupleFifo("txEng_tcpTupleFifo"); #pragma HLS stream variable=txEng_tupleShortCutFifo depth=2 - #pragma HLS stream variable=txEng_isLookUpFifo depth=4 + #pragma HLS stream variable=txEng_isLookUpFifo depth=32 #pragma HLS stream variable=txEng_ipTupleFifo depth=32 #pragma HLS stream variable=txEng_tcpTupleFifo depth=32 #pragma HLS DATA_PACK variable=txEng_tupleShortCutFifo @@ -1743,11 +1806,11 @@ void tx_engine( stream& eventEng2txEng_event, static stream memAccessBreakdown2txPkgStitcher("memAccessBreakdown2txPkgStitcher"); #pragma HLS stream variable=memAccessBreakdown2txPkgStitcher depth=32 - static stream txEng_isDDRbypass("txEng_isDDRbypass"); + static stream txEng_isDDRbypass("txEng_isDDRbypass"); #pragma HLS stream variable=txEng_isDDRbypass depth=32 #endif - metaLoader( eventEng2txEng_event, + metaLoader( eventEng2txEng_event, rxSar2txEng_rsp, txSar2txEng_upd_rsp, txEng2rxSar_req, diff --git a/hls/toe/tx_sar_table/tx_sar_table.cpp b/hls/toe/tx_sar_table/tx_sar_table.cpp index 4a3e945..f4fea3d 100755 --- a/hls/toe/tx_sar_table/tx_sar_table.cpp +++ b/hls/toe/tx_sar_table/tx_sar_table.cpp @@ -72,7 +72,11 @@ void tx_sar_table( stream& rxEng2txSar_upd_req, { tx_table[tst_txEngUpdate.sessionID].app = tst_txEngUpdate.not_ackd; tx_table[tst_txEngUpdate.sessionID].ackd = tst_txEngUpdate.not_ackd-1; +#if !(TCP_NODELAY) tx_table[tst_txEngUpdate.sessionID].cong_window = 0x3908; // 10 x 1460(MSS) +#else + tx_table[tst_txEngUpdate.sessionID].cong_window = 0x8000; // 8 x 4096(MSS) +#endif tx_table[tst_txEngUpdate.sessionID].slowstart_threshold = 0xFFFF; tx_table[tst_txEngUpdate.sessionID].finReady = tst_txEngUpdate.finReady; tx_table[tst_txEngUpdate.sessionID].finSent = tst_txEngUpdate.finSent; @@ -80,7 +84,7 @@ void tx_sar_table( stream& rxEng2txSar_upd_req, #if !(TCP_NODELAY) txSar2txApp_ack_push.write(txSarAckPush(tst_txEngUpdate.sessionID, tst_txEngUpdate.not_ackd, 1)); #else - txSar2txApp_ack_push.write(txSarAckPush(tst_txEngUpdate.sessionID, tst_txEngUpdate.not_ackd, 0x3908 /* 10 x 1460(MSS) */, 1)); + txSar2txApp_ack_push.write(txSarAckPush(tst_txEngUpdate.sessionID, tst_txEngUpdate.not_ackd, 0x8000 /* 8 x 4096(MSS) */, 1)); #endif } if (tst_txEngUpdate.finReady) @@ -96,8 +100,12 @@ void tx_sar_table( stream& rxEng2txSar_upd_req, { txTxSarRtQuery txEngRtUpdate = tst_txEngUpdate; tx_table[tst_txEngUpdate.sessionID].slowstart_threshold = txEngRtUpdate.getThreshold(); - tx_table[tst_txEngUpdate.sessionID].cong_window = 0x3908; // 10 x 1460(MSS) TODO is this correct or less, eg. 1/2 * MSS - } +#if !(TCP_NODELAY) + tx_table[tst_txEngUpdate.sessionID].cong_window = 0x3908; // 10 x 1460(MSS) +#else + tx_table[tst_txEngUpdate.sessionID].cong_window = 0x8000; // 10 x 1460(MSS) +#endif + } } else // Read { @@ -138,13 +146,15 @@ void tx_sar_table( stream& rxEng2txSar_upd_req, { usableWindow = minWindow - usedLength; } + txSar2txEng_upd_rsp.write(txTxSarReply( entry.ackd, entry.not_ackd, usableWindow, //minWindow, entry.app, usedLength, entry.finReady, - entry.finSent)); + entry.finSent, + entry.peer_mss)); } } // TX App Stream If @@ -170,6 +180,7 @@ void tx_sar_table( stream& rxEng2txSar_upd_req, { win_shift = tst_rxEngUpdate.win_shift; tx_table[tst_rxEngUpdate.sessionID].win_shift = tst_rxEngUpdate.win_shift; + tx_table[tst_rxEngUpdate.sessionID].peer_mss = tst_rxEngUpdate.peer_mss; } else {