diff --git a/README.md b/README.md new file mode 100644 index 0000000..e86f167 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Readme at: https://github.com/pomsi/Coyote/tree/tutorial/examples/Congestion_Control_Test diff --git a/hls/ib_transport_protocol/ib_transport_protocol.cpp b/hls/ib_transport_protocol/ib_transport_protocol.cpp index 81bfcb5..9f47e64 100644 --- a/hls/ib_transport_protocol/ib_transport_protocol.cpp +++ b/hls/ib_transport_protocol/ib_transport_protocol.cpp @@ -480,6 +480,7 @@ void rx_ibh_fsm( * RDMA READ RESPONSE LAST: AETH, PayLd * ACK: AETH */ +//MT added ipEcnFifo input template void rx_exh_fsm( #ifdef DBG_IBV @@ -487,6 +488,7 @@ void rx_exh_fsm( #endif stream& metaIn, stream >& udpLengthFifo, + stream >& ipEcnFifo, stream& msnTable2rxExh_rsp, #ifdef RETRANS_EN //stream& readReqTable_upd_req, @@ -515,6 +517,9 @@ void rx_exh_fsm( static ExHeader exHeader; static dmaState dmaMeta; static ap_uint<16> udpLength; + //MT added + static ap_uint<2> ecn; + ap_uint<32> payLoadLength; static bool consumeReadInit; //static rxReadReqRsp readReqMeta; @@ -546,12 +551,13 @@ void rx_exh_fsm( pe_fsmState = DMA_META; } break; + //MT added ecn case DMA_META: - if (!msnTable2rxExh_rsp.empty() && !udpLengthFifo.empty() && (!consumeReadInit || !retrans2rx_init.empty())) + if (!msnTable2rxExh_rsp.empty() && !udpLengthFifo.empty() && !ipEcnFifo.empty() && (!consumeReadInit || !retrans2rx_init.empty())) { - msnTable2rxExh_rsp.read(dmaMeta); udpLengthFifo.read(udpLength); + ipEcnFifo.read(ecn); #ifdef RETRANS_EN /*if (meta.op_code == RC_ACK) { @@ -583,7 +589,12 @@ void rx_exh_fsm( // Update state rxExh2msnTable_upd_req.write(rxMsnReq(meta.dest_qp, dmaMeta.msn+1)); // Trigger ACK - rx_exhEventMetaFifo.write(ackEvent(meta.dest_qp, meta.psn, false)); + //MT_pomsarc + if(ecn ==3){ + rx_exhEventMetaFifo.write(ackEvent(meta.dest_qp, meta.psn, false, true)); + } else{ + rx_exhEventMetaFifo.write(ackEvent(meta.dest_qp, meta.psn, false)); + } rx_pkgSplitTypeFifo.write(pkgSplit(meta.op_code)); rx_pkgShiftTypeFifo.write(pkgShift(SHIFT_NONE, meta.dest_qp)); @@ -601,7 +612,12 @@ void rx_exh_fsm( // Update state rxExh2msnTable_upd_req.write(rxMsnReq(meta.dest_qp, dmaMeta.msn+1)); // Trigger ACK - rx_exhEventMetaFifo.write(ackEvent(meta.dest_qp, meta.psn, false)); + //MT_pomsarc + if(ecn ==3){ + rx_exhEventMetaFifo.write(ackEvent(meta.dest_qp, meta.psn, false, true)); + } else{ + rx_exhEventMetaFifo.write(ackEvent(meta.dest_qp, meta.psn, false)); + } rx_pkgSplitTypeFifo.write(pkgSplit(meta.op_code)); rx_pkgShiftTypeFifo.write(pkgShift(SHIFT_NONE, meta.dest_qp)); @@ -636,7 +652,12 @@ void rx_exh_fsm( //TODO msn, only for ONLY?? rxExh2msnTable_upd_req.write(rxMsnReq(meta.dest_qp, dmaMeta.msn+1, rdmaHeader.getVirtualAddress()+payLoadLength, remainingLength, 1)); // Trigger ACK - rx_exhEventMetaFifo.write(ackEvent(meta.dest_qp, meta.psn, false)); + //MT_pomsarc + if(ecn ==3){ + rx_exhEventMetaFifo.write(ackEvent(meta.dest_qp, meta.psn, false, true)); + } else{ + rx_exhEventMetaFifo.write(ackEvent(meta.dest_qp, meta.psn, false)); + } rx_pkgSplitTypeFifo.write(pkgSplit(meta.op_code)); rx_pkgShiftTypeFifo.write(pkgShift(SHIFT_RETH, meta.dest_qp)); pe_fsmState = META; @@ -664,7 +685,12 @@ void rx_exh_fsm( //TODO msn only on LAST?? rxExh2msnTable_upd_req.write(rxMsnReq(meta.dest_qp, dmaMeta.msn+1, dmaMeta.vaddr+payLoadLength, remainingLength, 1)); // Trigger ACK - rx_exhEventMetaFifo.write(ackEvent(meta.dest_qp, meta.psn, false)); + //MT_pomsarc + if(ecn ==3){ + rx_exhEventMetaFifo.write(ackEvent(meta.dest_qp, meta.psn, false, true)); + } else{ + rx_exhEventMetaFifo.write(ackEvent(meta.dest_qp, meta.psn, false)); + } rx_pkgSplitTypeFifo.write(pkgSplit(meta.op_code)); rx_pkgShiftTypeFifo.write(pkgShift(SHIFT_NONE, meta.dest_qp)); pe_fsmState = META; @@ -691,9 +717,10 @@ void rx_exh_fsm( AckExHeader ackHeader = exHeader.getAckHeader(); if(meta.op_code == RC_RDMA_READ_RESP_ONLY || meta.op_code == RC_RDMA_READ_RESP_LAST) { + //MT_pomsarc added ecn m_axis_rx_ack_meta.write(ackMeta(meta.op_code, meta.dest_qp(15,0), readReqInit.host, readReqInit.host ? readReqInit.laddr(51,48) : 0, readReqInit.host ? readReqInit.laddr(53,52) : 0, - readReqInit.lst)); + readReqInit.lst, ecn)); } if (ackHeader.isNAK()) @@ -750,10 +777,10 @@ void rx_exh_fsm( { // [BTH][AETH] AckExHeader ackHeader = exHeader.getAckHeader(); - + //MT_pomsarc added ecn m_axis_rx_ack_meta.write(ackMeta(meta.op_code, meta.dest_qp(19,0), readReqInit.host, readReqInit.host ? readReqInit.laddr(51,48) : 0, readReqInit.host ? readReqInit.laddr(53,52) : 0, - readReqInit.lst)); + readReqInit.lst, ecn)); std::cout << "[RX EXH FSM " << INSTID << "]: syndrome: " << std::hex << ackHeader.getSyndrome() << std::endl; #ifdef RETRANS_EN @@ -1345,6 +1372,7 @@ void meta_merger( rx_ackEventFifo.read(aev); tx_connTable_req.write(aev.qpn(15, 0)); + // PSN used for read response tx_ibhMetaFifo.write(ibhMeta(RC_ACK, key, aev.qpn, aev.psn, aev.validPsn)); tx_exhMetaFifo.write(event(aev)); @@ -1502,6 +1530,8 @@ void generate_exh( stream >& txExh2msnTable_req, //stream& tx_readReqTable_upd, stream >& lengthFifo, + //MT_pomsarc + stream >& isMarkedAckFifo, stream& packetInfoFifo, #ifdef RETRANS_EN stream >& txSetTimer_req, @@ -1603,6 +1633,8 @@ void generate_exh( } udpLen = 12+16+payloadLen+4; //TODO dma_len can be much larger, for multiple packets we need to split this into multiple packets lengthFifo.write(udpLen); + //MT_pomsarc + isMarkedAckFifo.write(0); //Store meta for retransmit metaWritten = true; } @@ -1622,6 +1654,8 @@ void generate_exh( //BTH: 12, PayLd: x, ICRC: 4 udpLen = 12+meta.length+4; lengthFifo.write(udpLen); + //MT_pomsarc + isMarkedAckFifo.write(0); //Store meta for retransmit ge_state = META; break; @@ -1650,6 +1684,9 @@ void generate_exh( //BTH: 12, RETH: 16, PayLd: x, ICRC: 4 udpLen = 12+16+0+4; //TODO dma_len can be much larger, for multiple packets we need to split this into multiple packets lengthFifo.write(udpLen); + //MT_pomsarc + isMarkedAckFifo.write(0); + //Update Read Req max FWD header, TODO it is not exacly clear if meta.psn or meta.psn+numPkgs should be used //TODO i think psn is only used here!! //tx_readReqTable_upd.write(txReadReqUpdate(meta.qpn, meta.psn)); @@ -1688,6 +1725,8 @@ void generate_exh( //BTH: 12, AETH: 4, PayLd: x, ICRC: 4 udpLen = 12+4+meta.length+4; lengthFifo.write(udpLen); + //MT_pomsarc + isMarkedAckFifo.write(0); } break; } @@ -1700,6 +1739,8 @@ void generate_exh( //BTH: 12, PayLd: x, ICRC: 4 udpLen = 12+meta.length+4; lengthFifo.write(udpLen); + //MT_pomsarc + isMarkedAckFifo.write(0); ge_state = META; break; case RC_ACK: @@ -1735,6 +1776,12 @@ void generate_exh( output.write(sendWord); //BTH: 12, AETH: 4, ICRC: 4 lengthFifo.write(12+4+4); + //MT_pomsarc + if(meta.is_marked_ack_ecn){ + isMarkedAckFifo.write(1); + } else{ + isMarkedAckFifo.write(0); + } } break; } @@ -2016,6 +2063,7 @@ void prepend_ibh_header( */ //TODO maybe all ACKS should be triggered by ibhFSM?? what is the guarantee we should/have to give //TODO this should become a BRAM, storage type of thing +//MT_pomsarc added ecn output fifo template void ipUdpMetaHandler( stream& input, @@ -2024,7 +2072,9 @@ void ipUdpMetaHandler( //stream& output, //stream >& remcrc_lengthFifo, stream >& exh_lengthFifo, - stream >& exHeaderOutput + stream >& exHeaderOutput, + + stream>& ecn_Fifo ) { #pragma HLS inline off #pragma HLS pipeline II=1 @@ -2047,6 +2097,8 @@ void ipUdpMetaHandler( exh_lengthFifo.write(meta.length); exHeaderOutput.write(header); + ecn_Fifo.write(meta.ecn); + } //output.write(dstTuple(meta.their_address, meta.their_port)); } @@ -2060,6 +2112,8 @@ template void tx_ipUdpMetaMerger( stream& tx_connTable2ibh_rsp, stream >& tx_lengthFifo, + //MT_pomsarc + stream >& tx_isMarkedAckFifo, stream& m_axis_tx_meta, stream >& tx_dstQpFifo ) { @@ -2068,13 +2122,15 @@ void tx_ipUdpMetaMerger( connTableEntry connMeta; ap_uint<16> len; + ap_uint<1> is_ecn_marked; - if (!tx_connTable2ibh_rsp.empty() && !tx_lengthFifo.empty()) + if (!tx_connTable2ibh_rsp.empty() && !tx_lengthFifo.empty() && !tx_isMarkedAckFifo.empty()) { tx_connTable2ibh_rsp.read(connMeta); tx_lengthFifo.read(len); + tx_isMarkedAckFifo.read(is_ecn_marked); std::cout << "[TX IP UDP META MERGER " << INSTID << "]: port " << connMeta.remote_udp_port << std::endl; - m_axis_tx_meta.write(ipUdpMeta(connMeta.remote_ip_address, RDMA_DEFAULT_PORT, connMeta.remote_udp_port, len)); + m_axis_tx_meta.write(ipUdpMeta(connMeta.remote_ip_address, RDMA_DEFAULT_PORT, connMeta.remote_udp_port, len, 0, is_ecn_marked)); tx_dstQpFifo.write(connMeta.remote_qpn); } } @@ -2195,6 +2251,7 @@ void ib_transport_protocol( stream >& m_axis_mem_write_data, stream >& s_axis_mem_read_data, + // QP stream& s_axis_qp_interface, stream& s_axis_qp_conn_interface, @@ -2264,7 +2321,8 @@ void ib_transport_protocol( #pragma HLS DATA_PACK variable=rx_exhEventMetaFifo #pragma HLS DATA_PACK variable=rx_remoteMemCmd #endif - + //remove + //ecn_FiFo static stream tx_ibhMetaFifo("tx_ibhMetaFifo"); static stream tx_appMetaFifo("tx_appMetaFifo"); //static stream tx_localMetaFifo("tx_localMetaFifo"); @@ -2304,8 +2362,17 @@ void ib_transport_protocol( static stream tx_packetInfoFifo("tx_packetInfoFifo"); static stream > tx_lengthFifo("tx_lengthFifo"); + + //MT_pomsarc + static stream > tx_isMarkedAckFifo("tx_isMarkedAckFifo"); + + #pragma HLS STREAM depth=2 variable=tx_packetInfoFifo #pragma HLS STREAM depth=4 variable=tx_lengthFifo + + //MT_pomsarc + #pragma HLS STREAM depth=4 variable=tx_isMarkedAckFifo + #if defined( __VITIS_HLS__) #pragma HLS aggregate variable=tx_packetInfoFifo compact=bit #else @@ -2388,10 +2455,16 @@ void ib_transport_protocol( #endif static stream > exh_lengthFifo("exh_lengthFifo"); + //MT_pomsarc added ecn + static stream> ecn_Fifo("ecn_Fifo"); + static stream rx_readRequestFifo("rx_readRequestFifo"); static stream rx_readEvenFifo("rx_readEvenFifo"); static stream rx_ackEventFifo("rx_ackEventFifo"); #pragma HLS STREAM depth=4 variable=exh_lengthFifo + //MT_pomsarc added ecn + #pragma HLS STREAM depth=4 variable=ecn_Fifo + #pragma HLS STREAM depth=8 variable=rx_readRequestFifo #pragma HLS STREAM depth=512 variable=rx_readEvenFifo #pragma HLS STREAM depth=32 variable=rx_ackEventFifo @@ -2545,15 +2618,19 @@ void ib_transport_protocol( rx_exh2dropFifo, rx_ibhDropFifo, rx_ibhDrop2exhFifo); //some hack TODO, make this nicer.. not sure what this is still for - ipUdpMetaHandler(s_axis_rx_meta, rx_exh2drop_MetaFifo, rx_ibhDropMetaFifo, exh_lengthFifo, rx_drop2exhFsm_MetaFifo); + //MT added ecn output signal + ipUdpMetaHandler(s_axis_rx_meta, rx_exh2drop_MetaFifo, rx_ibhDropMetaFifo, exh_lengthFifo, rx_drop2exhFsm_MetaFifo, ecn_Fifo); + //MT added ecn input rx_exh_fsm( #ifdef DBG_IBV m_axis_dbg_2, #endif rx_fsm2exh_MetaFifo, exh_lengthFifo, + ecn_Fifo, msnTable2rxExh_rsp, + #ifdef RETRANS_EN //rx_readReqTable_upd_req, //rx_readReqTable_upd_rsp, @@ -2661,6 +2738,8 @@ void ib_transport_protocol( txExh2msnTable_req, //tx_readReqTable_upd, tx_lengthFifo, + //Mt_pomsarc + tx_isMarkedAckFifo, tx_packetInfoFifo, #ifdef RETRANS_EN txSetTimer_req, @@ -2688,7 +2767,8 @@ void ib_transport_protocol( prepend_ibh_header(tx_ibhHeaderFifo, tx_shift2ibhFifo, m_axis_tx_data, regIbvCountTx); //Get Meta data for UDP & IP layer - tx_ipUdpMetaMerger(tx_connTable2ibh_rsp, tx_lengthFifo, m_axis_tx_meta, tx_dstQpFifo); + //MT_pomsarc added tx_isMarkedAckFifo + tx_ipUdpMetaMerger(tx_connTable2ibh_rsp, tx_lengthFifo, tx_isMarkedAckFifo, m_axis_tx_meta, tx_dstQpFifo); //merge read requests mem_cmd_merger(rx_remoteMemCmd, tx_localMemCmdFifo, m_axis_mem_read_cmd, tx_pkgInfoFifo); diff --git a/hls/ib_transport_protocol/ib_transport_protocol.hpp b/hls/ib_transport_protocol/ib_transport_protocol.hpp index ca8bc08..746fe85 100644 --- a/hls/ib_transport_protocol/ib_transport_protocol.hpp +++ b/hls/ib_transport_protocol/ib_transport_protocol.hpp @@ -236,6 +236,7 @@ struct txMeta }; /* ACK meta */ +//MT changed this struct to also include 2 bit for the ecn marking struct ackMeta { ibOpCode op_code; // 32 @@ -244,30 +245,39 @@ struct ackMeta ap_uint<4> dst; ap_uint<2> strm; ap_uint<1> lst; + ap_uint<2> ecn; ackMeta() {} ackMeta(ibOpCode op_code, ap_uint<16> qpn, ap_uint<1> host, ap_uint<4> dst, ap_uint<2> strm, ap_uint<1> lst) - : op_code(op_code), qpn(qpn), host(host), dst(dst), strm(strm), lst(lst) {} + : op_code(op_code), qpn(qpn), host(host), dst(dst), strm(strm), lst(lst), ecn(0) {} + ackMeta(ibOpCode op_code, ap_uint<16> qpn, ap_uint<1> host, ap_uint<4> dst, ap_uint<2> strm, ap_uint<1> lst, ap_uint<2> e) + : op_code(op_code), qpn(qpn), host(host), dst(dst), strm(strm), lst(lst), ecn(e) {} }; /* Event */ +//MT_pomsarc added ecn struct ackEvent { ap_uint<24> qpn; ap_uint<24> psn; bool validPsn; bool isNak; + bool is_marked_ecn; + ackEvent() {} ackEvent(ap_uint<24> qpn) - :qpn(qpn), psn(0), validPsn(false), isNak(false) {} + :qpn(qpn), psn(0), validPsn(false), isNak(false), is_marked_ecn(false) {} ackEvent(ap_uint<24> qpn, bool nak) - :qpn(qpn), psn(0), validPsn(false), isNak(nak) {} + :qpn(qpn), psn(0), validPsn(false), isNak(nak), is_marked_ecn(false) {} ackEvent(ap_uint<24> qp, ap_uint<24> psn, bool nak) - :qpn(qp), psn(psn), validPsn(true), isNak(nak) {} + :qpn(qp), psn(psn), validPsn(true), isNak(nak), is_marked_ecn(false) {} + ackEvent(ap_uint<24> qp, ap_uint<24> psn, bool nak, bool ecn_mark) + :qpn(qp), psn(psn), validPsn(true), isNak(nak), is_marked_ecn(ecn_mark) {} }; //TODO create readEvent //TODO event for writes addr + len, no psn + struct event { ibOpCode op_code; @@ -277,22 +287,24 @@ struct event ap_uint<24> psn; bool validPsn; bool isNak; + bool is_marked_ack_ecn; + event() - :op_code(RC_ACK), validPsn(false), isNak(false) {} + :op_code(RC_ACK), validPsn(false), isNak(false), is_marked_ack_ecn(false) {} event(ibOpCode op, ap_uint<24> qp) - :op_code(op), qpn(qp), validPsn(false), isNak(false) {} + :op_code(op), qpn(qp), validPsn(false), isNak(false), is_marked_ack_ecn(false) {} event(ackEvent& aev) - :op_code(RC_ACK), qpn(aev.qpn), psn(aev.psn), validPsn(aev.validPsn), isNak(aev.isNak) {} + :op_code(RC_ACK), qpn(aev.qpn), psn(aev.psn), validPsn(aev.validPsn), isNak(aev.isNak), is_marked_ack_ecn(aev.is_marked_ecn) {} /*event(ibOpCode op, ap_uint<24> qp, ap_uint<24> psn, bool nak) :op_code(op), qpn(qp), psn(psn), validPsn(true), isNak(nak) {}*/ event(ibOpCode op, ap_uint<24> qp, ap_uint<32> len) - :op_code(op), qpn(qp), addr(0), length(len), psn(0), validPsn(false), isNak(false) {} + :op_code(op), qpn(qp), addr(0), length(len), psn(0), validPsn(false), isNak(false), is_marked_ack_ecn(false) {} event(ibOpCode op, ap_uint<24> qp, ap_uint<64> addr, ap_uint<32> len) - :op_code(op), qpn(qp), addr(addr), length(len), psn(0), validPsn(false), isNak(false) {} + :op_code(op), qpn(qp), addr(addr), length(len), psn(0), validPsn(false), isNak(false), is_marked_ack_ecn(false) {} event(ibOpCode op, ap_uint<24> qp, ap_uint<32> len, ap_uint<24> psn) - :op_code(op), qpn(qp), addr(0), length(len), psn(psn), validPsn(true), isNak(false) {} + :op_code(op), qpn(qp), addr(0), length(len), psn(psn), validPsn(true), isNak(false), is_marked_ack_ecn(false) {} event(ibOpCode op, ap_uint<24> qp, ap_uint<64> addr, ap_uint<32> len, ap_uint<24> psn) - :op_code(op), qpn(qp), addr(addr), length(len), psn(psn), validPsn(true), isNak(false) {} + :op_code(op), qpn(qp), addr(addr), length(len), psn(psn), validPsn(true), isNak(false), is_marked_ack_ecn(false) {} }; /* Pakage info */ diff --git a/hls/ipv4/ipv4.cpp b/hls/ipv4/ipv4.cpp index b7cf4ac..7fb0314 100644 --- a/hls/ipv4/ipv4.cpp +++ b/hls/ipv4/ipv4.cpp @@ -27,6 +27,7 @@ #include "ipv4_config.hpp" #include "ipv4.hpp" +//MT added ECN marking to the ipv4Meta struct written to MetaOut template void process_ipv4( stream >& dataIn, stream >& process2dropLengthFifo, @@ -54,7 +55,9 @@ void process_ipv4( stream >& dataIn, { std::cout << "IP HEADER: src address: " << header.getSrcAddr() << ", length: " << header.getLength() << std::endl; process2dropLengthFifo.write(header.getHeaderLength() - headerWordsDropped); - MetaOut.write(ipv4Meta(header.getSrcAddr(), header.getLength())); + + MetaOut.write(ipv4Meta(header.getSrcAddr(), header.getLength(), header.getECN())); + //MetaOut.write(ipv4Meta(header.getSrcAddr(), header.getLength(), 3)); metaWritten = true; } } @@ -69,6 +72,7 @@ void process_ipv4( stream >& dataIn, } } + template void generate_ipv4( stream& txEng_ipMetaDataFifoIn, stream >& tx_shift2ipv4Fifo, @@ -86,6 +90,7 @@ void generate_ipv4( stream& txEng_ipMetaDataFifoIn, ipv4Meta meta; net_axis currWord; ap_uint<16> length; + ap_uint<2> ecn; switch (gi_state) { @@ -102,7 +107,17 @@ void generate_ipv4( stream& txEng_ipMetaDataFifoIn, header.setProtocol(protocol); // Set ECN and flags accordingly - header.setECN(2); + + if(meta.is_marked_ack == 1){ + ecn = 3; + }else{ + ecn = 2; + } + + header.setECN(ecn); + + + header.setFlags(2); if (IPV4_HEADER_SIZE >= WIDTH) @@ -176,6 +191,7 @@ void ipv4_generate_ipv4( stream& txEng_ipMetaDataFifoIn, ipv4Meta meta; net_axis currWord; ap_uint<16> length; + ap_uint<2> ecn; switch (gi_state) { @@ -192,7 +208,15 @@ void ipv4_generate_ipv4( stream& txEng_ipMetaDataFifoIn, header.setProtocol(protocol); // Set ECN and flags accordingly - header.setECN(1); + //MT_pomsarc changed outgoing ecn if its ack + if(meta.is_marked_ack == 1){ + //header.setECN(meta.ecn) + ecn = 3; + }else{ + ecn = 1; + } + + header.setECN(ecn); header.setFlags(1); if (IPV4_HEADER_SIZE >= WIDTH) @@ -378,7 +402,7 @@ void ipv4( hls::stream >& s_axis_rx_data, generate_ipv4(s_axis_tx_meta, tx_shift2ipv4Fifo, m_axis_tx_data, local_ipv4_address, protocol); } -void ipv4_top( hls::stream >& s_axis_rx_data, +void ipv4_top( hls::stream >& s_axis_rx_data, hls::stream& m_axis_rx_meta, hls::stream >& m_axis_rx_data, hls::stream& s_axis_tx_meta, diff --git a/hls/ipv4/ipv4.hpp b/hls/ipv4/ipv4.hpp index efabe99..19f4912 100644 --- a/hls/ipv4/ipv4.hpp +++ b/hls/ipv4/ipv4.hpp @@ -31,17 +31,26 @@ const uint32_t IPV4_HEADER_SIZE = 160; + +//MT changed this struct to also include 2 bit for the ecn marking + is_outgoing... struct ipv4Meta { ap_uint<32> their_address; ap_uint<16> length; + ap_uint<2> ecn; + ap_uint<1> is_marked_ack; + //TODO what aobut my address?? ipv4Meta() {} ipv4Meta(ap_uint<32> addr, ap_uint<16> len) - :their_address(addr), length(len) {} + :their_address(addr), length(len), ecn(3), is_marked_ack(0) {} + ipv4Meta(ap_uint<32> addr, ap_uint<16> len, ap_uint<2> e) + :their_address(addr), length(len), ecn(e), is_marked_ack(0) {} + ipv4Meta(ap_uint<32> addr, ap_uint<16> len, ap_uint<2> e, ap_uint<1> is_ack) + :their_address(addr), length(len), ecn(e), is_marked_ack(is_ack) {} //for IPv6 TODO fix this in the future ipv4Meta(ap_uint<128> addr, ap_uint<16> len) - :their_address(addr(127,96)), length(len) {} + :their_address(addr(127,96)), length(len), ecn(0), is_marked_ack(0) {} }; template @@ -610,7 +619,7 @@ class ipv4Header : public packetHeader { ipv4Header() { header(7, 0) = 0x45; // version & IHL - header(71, 64) = 0x64; // TTL + header(71, 64) = 0x32; // TTL } void setSrcAddr(const ap_uint<32>& addr) @@ -645,11 +654,18 @@ class ipv4Header : public packetHeader { } // New function to set ECN - void setECN(const ap_uint<1> ECN) + void setECN(const ap_uint<2> ECN) { - header[9] = ECN; + header(9,8) = ECN; } + //MT added function to return the 2-bit ecn field + ap_uint<2> getECN() + { + return (ap_uint<2>)header(9,8); + } + + void setProtocol(const ap_uint<8>& protocol) { header(79, 72) = protocol; diff --git a/hls/rocev2/CMakeLists.txt b/hls/rocev2/CMakeLists.txt index 1828c8b..2df53e7 100644 --- a/hls/rocev2/CMakeLists.txt +++ b/hls/rocev2/CMakeLists.txt @@ -27,7 +27,7 @@ set(DATA_WIDTH 64 CACHE STRING "Width of data path in bytes") set(PMTU_BYTES 4096 CACHE STRING "PMTU size.") set(CLOCK_PERIOD 6.4 CACHE STRING "Target clock period in nanoseconds") # RoCE parameters -set(ROCE_STACK_MAX_QPS 500 CACHE STRING "Maximum number of queue pairs the RoCE stack can support") +set(ROCE_STACK_MAX_QPS 16 CACHE STRING "Maximum number of queue pairs the RoCE stack can support") find_package(VitisHLS REQUIRED) if (NOT VITIS_HLS_FOUND) diff --git a/hls/udp/udp.cpp b/hls/udp/udp.cpp index 3dd8a2c..0f4ebab 100644 --- a/hls/udp/udp.cpp +++ b/hls/udp/udp.cpp @@ -169,11 +169,13 @@ void split_tx_meta( stream& metaIn, metaIn.read(meta); //Add 8 bytes for UDP header ap_uint<16> tempLen = meta.length+8; - metaOut0.write(ipMeta(meta.their_address, tempLen)); + //MT_pomsarc added ecn and ack mark to be handed down the stack too + metaOut0.write(ipMeta(meta.their_address, tempLen, meta.ecn, meta.is_outgoing_ack)); metaOut1.write(udpMeta(meta.their_port, meta.my_port, tempLen)); } } +//MT added ECN marking from ipMeta to also be merged and written to MetaOut void merge_rx_meta( stream& ipMetaIn, stream& udpMetaIn, stream& metaOut) @@ -190,7 +192,7 @@ void merge_rx_meta( stream& ipMetaIn, udpMetaIn.read(meta1); if (meta1.valid) { - metaOut.write(ipUdpMeta(meta0.their_address, meta1.their_port, meta1.my_port, meta1.length)); + metaOut.write(ipUdpMeta(meta0.their_address, meta1.their_port, meta1.my_port, meta1.length, meta0.ecn)); } } } diff --git a/hls/udp/udp.hpp b/hls/udp/udp.hpp index 8fe12e8..07c370d 100644 --- a/hls/udp/udp.hpp +++ b/hls/udp/udp.hpp @@ -43,15 +43,24 @@ typedef ipv4Meta ipMeta; const uint32_t UDP_HEADER_SIZE = 64; const uint16_t UDP_PROTOCOL = 0x11; +//MT_pomsarc changed this struct to also include 2 bit for the ecn marking struct ipUdpMeta { ap_uint<128> their_address; ap_uint<16> their_port; ap_uint<16> my_port; ap_uint<16> length; + ap_uint<2> ecn; + ap_uint<1> is_outgoing_ack; ipUdpMeta() {} ipUdpMeta(ap_uint<128> addr, ap_uint<16> tport, ap_uint<16> mport, ap_uint<16> len) - :their_address(addr), their_port(tport), my_port(mport), length(len) {} + :their_address(addr), their_port(tport), my_port(mport), length(len), ecn(0), is_outgoing_ack(0) {} + ipUdpMeta(ap_uint<128> addr, ap_uint<16> tport, ap_uint<16> mport, ap_uint<16> len, ap_uint<2> e) + :their_address(addr), their_port(tport), my_port(mport), length(len), ecn(e), is_outgoing_ack(0) {} + ipUdpMeta(ap_uint<128> addr, ap_uint<16> tport, ap_uint<16> mport, ap_uint<16> len, ap_uint<2> e, ap_uint<1> is_ack) + :their_address(addr), their_port(tport), my_port(mport), length(len), ecn(e), is_outgoing_ack(is_ack) {} + + }; struct udpMeta