68 #define THIS_NAME "IPTX"
70 #define TRACE_OFF 0x0000
71 #define TRACE_ICA 1 << 1
72 #define TRACE_ICI 1 << 2
73 #define TRACE_IAE 1 << 3
74 #define TRACE_MAI 1 << 4
75 #define TRACE_ALL 0xFFFF
77 #define DEBUG_LEVEL (TRACE_OFF)
108 stream<AxisIp4> &siL3MUX_Data,
109 stream<AxisIp4> &soICi_Data,
110 stream<Ip4HdrCsum> &soICi_Csum)
113 #pragma HLS INLINE off
114 #pragma HLS PIPELINE II=1 enable_flush
119 static bool hca_csumWritten=
true;
120 #pragma HLS RESET variable=hca_csumWritten
121 static enum FsmState {S0=0, S1, S2, S3} hca_fsmState=S0;
122 #pragma HLS RESET variable=hca_fsmState
123 static ap_uint<17> hca_ipHdrCsum[4]={0, 0, 0, 0};
124 #pragma HLS RESET variable=hca_ipHdrCsum
125 #pragma HLS ARRAY_PARTITION variable=hca_ipHdrCsum complete dim=1
126 static ap_uint<3> hca_chunkCount=0;
127 #pragma HLS RESET variable=hca_chunkCount
130 static ap_uint<4> hca_ipHdrLen;
137 if(!hca_csumWritten) {
138 switch (hca_fsmState) {
140 hca_ipHdrCsum[0] += hca_ipHdrCsum[2];
141 hca_ipHdrCsum[1] += hca_ipHdrCsum[3];
142 hca_ipHdrCsum[0] = (hca_ipHdrCsum[0] + (hca_ipHdrCsum[0] >> 16)) & 0xFFFF;
143 hca_ipHdrCsum[1] = (hca_ipHdrCsum[1] + (hca_ipHdrCsum[1] >> 16)) & 0xFFFF;
147 hca_ipHdrCsum[0] += hca_ipHdrCsum[1];
148 hca_ipHdrCsum[0] = (hca_ipHdrCsum[0] + (hca_ipHdrCsum[0] >> 16)) & 0xFFFF;
152 hca_ipHdrCsum[0] = ~hca_ipHdrCsum[0];
153 soICi_Csum.write(hca_ipHdrCsum[0](15, 0));
157 hca_ipHdrCsum[0] = 0;
158 hca_ipHdrCsum[1] = 0;
159 hca_ipHdrCsum[2] = 0;
160 hca_ipHdrCsum[3] = 0;
161 hca_csumWritten =
true;
166 else if (!siL3MUX_Data.empty() and !soICi_Data.full() and hca_csumWritten) {
167 siL3MUX_Data.read(currChunk);
172 switch (hca_chunkCount) {
176 for (
int i=0; i<4; i++) {
178 tempHdrCsum( 7, 0) = currChunk.
getLE_TData().range(i*16+15, i*16+8);
179 tempHdrCsum(15, 8) = currChunk.
getLE_TData().range(i*16+7, i*16);
180 hca_ipHdrCsum[i] += tempHdrCsum;
181 hca_ipHdrCsum[i] = (hca_ipHdrCsum[i] + (hca_ipHdrCsum[i] >> 16)) & 0xFFFF;
188 for (
int i=0; i<4; i++) {
192 tempHdrCsum( 7, 0) = currChunk.
getLE_TData().range(i*16+15, i*16+8);
193 tempHdrCsum(15, 8) = currChunk.
getLE_TData().range(i*16+7, i*16);
194 hca_ipHdrCsum[i] += tempHdrCsum;
195 hca_ipHdrCsum[i] = (hca_ipHdrCsum[i] + (hca_ipHdrCsum[i] >> 16)) & 0xFFFF;
202 switch (hca_ipHdrLen) {
209 for (
int i = 0; i < 2; i++) {
211 tempHdrCsum( 7, 0) = currChunk.
getLE_TData().range(i*16+15, i*16+8);
212 tempHdrCsum(15, 8) = currChunk.
getLE_TData().range(i*16+7, i*16);
213 hca_ipHdrCsum[i] += tempHdrCsum;
214 hca_ipHdrCsum[i] = (hca_ipHdrCsum[i] + (hca_ipHdrCsum[i] >> 16)) & 0xFFFF;
217 hca_csumWritten =
false;
221 for (
int i = 0; i < 4; i++) {
223 tempHdrCsum( 7, 0) = currChunk.
getLE_TData().range(i*16+15, i*16+8);
224 tempHdrCsum(15, 8) = currChunk.
getLE_TData().range(i*16+7, i*16);
225 hca_ipHdrCsum[i] += tempHdrCsum;
226 hca_ipHdrCsum[i] = (hca_ipHdrCsum[i] + (hca_ipHdrCsum[i] >> 16)) & 0xFFFF;
229 if (hca_ipHdrLen == 0) {
230 hca_csumWritten =
false;
236 soICi_Data.write(currChunk);
256 stream<AxisIp4> &siHCa_Data,
257 stream<Ip4HdrCsum> &siHCa_Csum,
258 stream<AxisIp4> &soIAe_Data)
261 #pragma HLS INLINE off
262 #pragma HLS PIPELINE II=1 enable_flush
267 static enum FsmStates { S0=0, S1, S2 } ici_fsmState=S0;
268 #pragma HLS RESET variable=ici_fsmState
275 switch (ici_fsmState) {
277 if (!siHCa_Data.empty() and !soIAe_Data.full()) {
278 siHCa_Data.read(currChunk);
279 soIAe_Data.write(currChunk);
284 if (!siHCa_Data.empty() and !siHCa_Csum.empty() and !soIAe_Data.full()) {
285 siHCa_Data.read(currChunk);
286 siHCa_Csum.read(ipHdrChecksum);
289 soIAe_Data.write(currChunk);
294 if (!siHCa_Data.empty() and !soIAe_Data.full()) {
295 siHCa_Data.read(currChunk);
296 soIAe_Data.write(currChunk);
323 stream<AxisIp4> &siICi_Data,
324 stream<AxisIp4> &soMAi_Data,
325 stream<Ip4Addr> &soARP_LookupReq)
328 #pragma HLS INLINE off
329 #pragma HLS PIPELINE II=1 enable_flush
334 static ap_uint<2> iae_chunkCount=0;
335 #pragma HLS RESET variable=iae_chunkCount
340 if (!siICi_Data.empty() and !soMAi_Data.full()) {
341 AxisIp4 currChunk = siICi_Data.read();
342 switch (iae_chunkCount) {
345 if ((ipDestAddr & piMMIO_SubNetMask) == (piMMIO_GatewayAddr & piMMIO_SubNetMask)
346 || (ipDestAddr == 0xFFFFFFFF)) {
347 soARP_LookupReq.write(ipDestAddr);
350 soARP_LookupReq.write(piMMIO_GatewayAddr);
358 else if (iae_chunkCount < 3) {
363 soMAi_Data.write(currChunk);
381 stream<AxisIp4> &siIAe_Data,
382 stream<ArpLkpReply> &siARP_LookupRsp,
383 stream<AxisEth> &soL2MUX_Data)
386 #pragma HLS INLINE off
387 #pragma HLS PIPELINE II=1 enable_flush
392 static enum FsmStates {FSM_MAI_WAIT_LOOKUP=0, FSM_MAI_DROP, FSM_MAI_WRITE,
393 FSM_MAI_WRITE_FIRST, FSM_MAI_WRITE_LAST} \
394 mai_fsmState=FSM_MAI_WAIT_LOOKUP;
395 #pragma HLS RESET variable=mai_fsmState
407 switch (mai_fsmState) {
408 case FSM_MAI_WAIT_LOOKUP:
409 if (!siARP_LookupRsp.empty() and !soL2MUX_Data.full()) {
410 siARP_LookupRsp.read(arpResponse);
412 if (arpResponse.
hit) {
417 soL2MUX_Data.write(sendChunk);
418 mai_fsmState = FSM_MAI_WRITE_FIRST;
420 printInfo(myName,
"FSM_MAI_WAIT_LOOKUP - Lookup=HIT - Received MAC = 0x%12.12lX\n",
422 printAxisRaw(myName,
"Forwarding AxisChunk to [L2MUX]: ", sendChunk);
426 mai_fsmState = FSM_MAI_DROP;
428 printInfo(myName,
"FSM_MAI_WAIT_LOOKUP - Lookup=NO-HIT. \n");
433 case FSM_MAI_WRITE_FIRST:
435 if (!siIAe_Data.empty() and !soL2MUX_Data.full()) {
436 siIAe_Data.read(currChunk);
444 soL2MUX_Data.write(sendChunk);
445 mai_prevChunk = currChunk;
446 mai_fsmState = FSM_MAI_WRITE;
451 if (!siIAe_Data.empty() and !soL2MUX_Data.full()) {
452 siIAe_Data.read(currChunk);
463 soL2MUX_Data.write(sendChunk);
465 printAxisRaw(myName,
"Forwarding AxisChunk to [L2MUX]: ", sendChunk);
467 mai_prevChunk = currChunk;
470 mai_fsmState = FSM_MAI_WAIT_LOOKUP;
473 mai_fsmState = FSM_MAI_WRITE_LAST;
477 mai_fsmState = FSM_MAI_WRITE;
481 case FSM_MAI_WRITE_LAST:
483 if (!soL2MUX_Data.full()) {
489 soL2MUX_Data.write(sendChunk);
491 printAxisRaw(myName,
"Forwarding AxisChunk to [L2MUX]: ", sendChunk);
493 mai_fsmState = FSM_MAI_WAIT_LOOKUP;
498 if (!siIAe_Data.empty() and !soL2MUX_Data.full()) {
499 siIAe_Data.read(currChunk);
501 mai_fsmState = FSM_MAI_WAIT_LOOKUP;
540 stream<AxisIp4> &siL3MUX_Data,
544 stream<AxisEth> &soL2MUX_Data,
548 stream<Ip4Addr> &soARP_LookupReq,
549 stream<ArpLkpReply> &siARP_LookupRep)
554 #pragma HLS INTERFACE ap_ctrl_none port=return
561 static stream<AxisIp4> ssHCaToICi_Data (
"ssHCaToICi_Data");
562 #pragma HLS STREAM variable=ssHCaToICi_Data depth=1024
563 #pragma HLS DATA_PACK variable=ssHCaToICi_Data
565 static stream<Ip4HdrCsum> ssHCaToICi_Csum (
"ssHCaToICi_Csum");
566 #pragma HLS STREAM variable=ssHCaToICi_Csum depth=16
569 static stream<AxisIp4> ssICiToIAe_Data (
"ssICiToIAe_Data");
570 #pragma HLS STREAM variable=ssICiToIAe_Data depth=16
571 #pragma HLS DATA_PACK variable=ssICiToIAe_Data
574 static stream<AxisIp4> ssIAeToMAi_Data (
"ssIAeToMAi_Data");
575 #pragma HLS STREAM variable=ssIAeToMAi_Data depth=16
576 #pragma HLS DATA_PACK variable=ssIAeToMAi_Data
616 #if HLS_VERSION == 2017
627 stream<AxisIp4> &siL3MUX_Data,
631 stream<AxisEth> &soL2MUX_Data,
635 stream<Ip4Addr> &soARP_LookupReq,
636 stream<ArpLkpReply> &siARP_LookupRep)
639 #pragma HLS INTERFACE ap_ctrl_none port=return
646 #pragma HLS INTERFACE ap_stable port=piMMIO_MacAddress
647 #pragma HLS INTERFACE ap_stable port=piMMIO_SubNetMask
648 #pragma HLS INTERFACE ap_stable port=piMMIO_GatewayAddr
650 #pragma HLS resource core=AXI4Stream variable=siL3MUX_Data metadata="-bus_bundle siL3MUX_Data"
651 #pragma HLS resource core=AXI4Stream variable=soL2MUX_Data metadata="-bus_bundle soL2MUX_Data"
653 #pragma HLS resource core=AXI4Stream variable=soARP_LookupReq metadata="-bus_bundle soARP_LookupReq"
654 #pragma HLS resource core=AXI4Stream variable=siARP_LookupRep metadata="-bus_bundle siARP_LookupRep"
655 #pragma HLS DATA_PACK variable=siARP_LookupRep
686 stream<AxisRaw> &siL3MUX_Data,
690 stream<AxisRaw> &soL2MUX_Data,
694 stream<Ip4Addr> &soARP_LookupReq,
695 stream<ArpLkpReply> &siARP_LookupRep)
698 #pragma HLS INTERFACE ap_ctrl_none port=return
700 #pragma HLS INTERFACE ap_stable port=piMMIO_MacAddress
701 #pragma HLS INTERFACE ap_stable port=piMMIO_SubNetMask
702 #pragma HLS INTERFACE ap_stable port=piMMIO_GatewayAddr
704 #pragma HLS INTERFACE axis off port=siL3MUX_Data
705 #pragma HLS INTERFACE axis register both port=soL2MUX_Data
707 #pragma HLS INTERFACE axis off port=soARP_LookupReq
708 #pragma HLS INTERFACE axis off port=siARP_LookupRep
709 #pragma HLS DATA_PACK variable=siARP_LookupRep
712 #pragma HLS DATAFLOW disable_start_propagation
715 static stream<AxisIp4> ssiL3MUX_Data (
"ssiL3MUX_Data");
716 #pragma HLS STREAM variable=ssiL3MUX_Data depth=8
717 static stream<AxisEth> ssoL2MUX_Data (
"ssoL2MUX_Data");
void setEthDstAddr(EthAddr addr)
void setIp4Version(Ip4Version ver)
void setEthSrcAddrHi(EthAddr addr)
void setEthSrcAddrLo(EthAddr addr)
void setEthTypeLen(EthTypeLen eTyLe)
void setIp4ToS(Ip4ToS tos)
void setIp4HdrLen(Ip4HdrLen ihl)
void setIp4HdrCsum(Ip4HdrCsum csum)
Ip4Version getIp4Version()
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 pHeaderChecksumAccumulator(stream< AxisIp4 > &siL3MUX_Data, stream< AxisIp4 > &soICi_Data, stream< Ip4HdrCsum > &soICi_Csum)
void pIpChecksumInsert(stream< AxisIp4 > &siHCa_Data, stream< Ip4HdrCsum > &siHCa_Csum, stream< AxisIp4 > &soIAe_Data)
void iptx(EthAddr piMMIO_MacAddress, Ip4Addr piMMIO_SubNetMask, Ip4Addr piMMIO_GatewayAddr, stream< AxisIp4 > &siL3MUX_Data, stream< AxisEth > &soL2MUX_Data, stream< Ip4Addr > &soARP_LookupReq, stream< ArpLkpReply > &siARP_LookupRep)
Main process of the IP Transmitter Handler (IPTX).
void pIp4AddressExtractor(Ip4Addr piMMIO_SubNetMask, Ip4Addr piMMIO_GatewayAddr, stream< AxisIp4 > &siICi_Data, stream< AxisIp4 > &soMAi_Data, stream< Ip4Addr > &soARP_LookupReq)
void iptx_top(EthAddr piMMIO_MacAddress, Ip4Addr piMMIO_SubNetMask, Ip4Addr piMMIO_GatewayAddr, stream< AxisRaw > &siL3MUX_Data, stream< AxisRaw > &soL2MUX_Data, stream< Ip4Addr > &soARP_LookupReq, stream< ArpLkpReply > &siARP_LookupRep)
Top of IP Transmitter Handler (IPTX)
void pMacAddressInserter(EthAddr piMMIO_MacAddress, stream< AxisIp4 > &siIAe_Data, stream< ArpLkpReply > &siARP_LookupRsp, stream< AxisEth > &soL2MUX_Data)
void printAxisRaw(const char *callerName, AxisRaw chunk)
Prints an Axis raw data chunk (used for debugging).
void pAxisRawCast(hls::stream< TypeIn > &si, hls::stream< TypeOut > &so)
AxisRaw cast - Casts an AxisRaw stream to/from an AxisRaw derived class.
#define printInfo(callerName, format,...)
A macro to print an information message.
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
: IP Transmitter packet handler (IPTX)