67 #define THIS_NAME "IPRX"
69 #define TRACE_OFF 0x0000
70 #define TRACE_IBUF 1 << 1
71 #define TRACE_MPD 1 << 2
72 #define TRACE_ILC 1 << 3
73 #define TRACE_ICA 1 << 4
74 #define TRACE_ICC 1 << 5
75 #define TRACE_IID 1 << 6
76 #define TRACE_ICL 1 << 7
77 #define TRACE_IPR 1 << 8
78 #define TRACE_ALL 0xFFFF
80 #define DEBUG_LEVEL (TRACE_OFF)
95 stream<AxisEth> &siETH_Data,
96 stream<AxisEth> &soMPd_Data)
99 #pragma HLS INLINE off
100 #pragma HLS PIPELINE II=1 enable_flush
104 if (!siETH_Data.empty() && !soMPd_Data.full()) {
106 siETH_Data.read(axisEth);
109 printWarn(myName,
"Received an AxisChunk with an unexpected \'tkeep\' or \'tlast\' value.\n");
115 soMPd_Data.write(axisEth);
135 stream<AxisEth> &siIBuf_Data,
136 stream<AxisArp> &soARP_Data,
137 stream<AxisEth> &soILc_Data)
140 #pragma HLS INLINE off
141 #pragma HLS PIPELINE II=1 enable_flush
146 static enum FsmStates { S0=0, S1 } mpd_fsmState=S0;
147 #pragma HLS RESET variable=mpd_fsmState
148 static ap_uint<2> mpd_chunkCount=0;
149 #pragma HLS RESET variable=mpd_chunkCount
158 switch (mpd_fsmState) {
160 if (!siIBuf_Data.empty() && !soARP_Data.full() && !soILc_Data.full()) {
161 siIBuf_Data.read(currChunk);
162 switch (mpd_chunkCount) {
169 printInfo(myName,
"Requesting current frame with MAC destination address = 0x%16.16lX (0x%16.16lX) to be dropped\n",
178 if (mpd_chunkCount == 1) {
185 soARP_Data.write(mpd_prevChunk);
188 soILc_Data.write(mpd_prevChunk);
192 mpd_prevChunk = currChunk;
200 if( !soARP_Data.full() && !soILc_Data.full()){
202 soARP_Data.write(mpd_prevChunk);
205 soILc_Data.write(mpd_prevChunk);
227 stream<AxisEth> &siMPd_Data,
228 stream<AxisEth> &soICa_Data)
231 #pragma HLS INLINE off
232 #pragma HLS PIPELINE II=1 enable_flush
237 static ap_uint<2> ilc_leftToWrite=0;
238 #pragma HLS RESET variable=ilc_leftToWrite
239 static enum FsmStates {
FSM_IDLE=0, FSM_SIZECHECK, FSM_STREAM} ilc_fsmState=
FSM_IDLE;
240 #pragma HLS RESET variable=ilc_fsmState
241 static ap_uint<2> ilc_chunkCount=0;
242 #pragma HLS RESET variable=ilc_chunkCount
243 static ap_uint<1> ilc_filterPacket=0;
244 #pragma HLS RESET variable=ilc_filterPacket
247 static ap_shift_reg<AxisEth, 2> chunkBuffer;
253 if (ilc_leftToWrite == 0) {
254 if (!siMPd_Data.empty() && !soICa_Data.full()) {
255 AxisEth currChunk = siMPd_Data.read();
256 switch (ilc_fsmState) {
259 chunkBuffer.shift(currChunk);
260 if (ilc_chunkCount == 1) {
261 ilc_fsmState = FSM_SIZECHECK;
269 ilc_filterPacket = 1;
270 printWarn(myName,
"Current frame will be discarded because frame is too long!\n");
273 ilc_filterPacket = 0;
275 printInfo(myName,
"Start of IPv4 packet - Total length = %d bytes.\n", ip4TotLen.to_int());
279 tempChunk = chunkBuffer.shift(currChunk);
280 if (ilc_filterPacket == 0) {
281 soICa_Data.write(tempChunk);
283 ilc_fsmState = FSM_STREAM;
286 tempChunk = chunkBuffer.shift(currChunk);
287 if (ilc_filterPacket == 0) {
288 soICa_Data.write(tempChunk);
300 else if (ilc_leftToWrite != 0 && !soICa_Data.full() ) {
301 tempChunk = chunkBuffer.shift(
AxisEth(0, 0, 0));
302 if (ilc_filterPacket == 0) {
303 soICa_Data.write(tempChunk);
325 stream<AxisEth> &siILc_Data,
326 stream<AxisIp4> &soIId_Data,
327 stream<Ip4Version> &soIId_IpVer,
328 stream<CmdBit> &soIId_DropCmd,
329 stream<SubSums> &soICc_SubSums)
332 #pragma HLS INLINE off
333 #pragma HLS PIPELINE II=1 enable_flush
338 static bool ica_wasLastChunk=
false;
339 #pragma HLS RESET variable=ica_wasLastChunk
340 static ap_uint<3> ica_chunkCount=0;
341 #pragma HLS RESET variable=ica_chunkCount
344 static ap_uint<17> ica_ipHdrSums[4];
345 static ap_uint<8> ica_ipHdrLen;
352 ap_uint<16> ip4FlagsAndFragOff;
356 if (!siILc_Data.empty() && !ica_wasLastChunk && !soIId_IpVer.full() &&
357 !soIId_DropCmd.full() && !soICc_SubSums.full() && !soIId_Data.full()) {
358 siILc_Data.read(currChunk);
360 switch (ica_chunkCount) {
363 for (
int i=0; i<4 ;++i) {
364 ica_ipHdrSums[i] = 0;
375 ica_ipHdrSums[3].range(11, 8) = currChunk.
getIp4HdrLen();
376 ica_ipHdrSums[3].range( 7, 0) = currChunk.
getIp4ToS();
384 if (ip4FlagsAndFragOff.range(12, 0) != 0 || ip4FlagsAndFragOff.bit(13) != 0) {
386 if (ip4FlagsAndFragOff.bit(13) != 0) {
387 printWarn(myName,
"The More Fragments (MF) is set but IP fragmentation is not supported (yet).\n");
389 if (ip4FlagsAndFragOff.range(12, 0) != 0) {
390 printWarn(myName,
"Fragment offset is set but not supported (yet) !!!\n");
396 for (
int i = 0; i < 4; i++) {
399 ica_ipHdrSums[i] = (ica_ipHdrSums[i] + (ica_ipHdrSums[i] >> 16)) & 0xFFFF;
406 for (
int i = 0; i < 4; i++) {
409 ica_ipHdrSums[i] = (ica_ipHdrSums[i] + (ica_ipHdrSums[i] >> 16)) & 0xFFFF;
416 if (ica_chunkCount == 4) {
419 switch (ica_ipHdrLen) {
425 ica_ipHdrSums[0] = (ica_ipHdrSums[0] + (ica_ipHdrSums[0] >> 16)) & 0xFFFF;
428 if (ica_dstIpAddress == piMMIO_Ip4Address) {
434 soICc_SubSums.write(
SubSums(ica_ipHdrSums, ipAddrMatch));
438 for (
int i = 0; i < 4; i++) {
441 ica_ipHdrSums[i] = (ica_ipHdrSums[i] + (ica_ipHdrSums[i] >> 16)) & 0xFFFF;
445 if (ica_dstIpAddress == piMMIO_Ip4Address) {
452 soICc_SubSums.write(
SubSums(ica_ipHdrSums, ipAddrMatch));
456 for (
int i = 0; i < 4; i++) {
459 ica_ipHdrSums[i] = (ica_ipHdrSums[i] + (ica_ipHdrSums[i] >> 16)) & 0xFFFF;
467 if (ica_chunkCount > 2) {
472 soIId_Data.write(sendChunk);
474 ica_prevChunk = currChunk;
480 else if(ica_wasLastChunk && !soIId_Data.full()) {
485 soIId_Data.write(sendChunk);
486 ica_wasLastChunk =
false;
505 stream<AxisIp4> &siICa_Data,
506 stream<Ip4Version> &siICa_IpVer,
507 stream<ValBit> &siICa_DropFrag,
508 stream<ValBit> &siICc_CsumValid,
509 stream<AxisIp4> &soICl_Data)
512 #pragma HLS INLINE off
513 #pragma HLS PIPELINE II=1 enable_flush
518 static enum FsmStates {
FSM_IDLE=0, FSM_FWD, FSM_DROP} iid_fsmState=
FSM_IDLE;
519 #pragma HLS RESET variable=iid_fsmState
524 switch(iid_fsmState) {
526 if (!siICc_CsumValid.empty() && !siICa_IpVer.empty() && !siICa_DropFrag.empty() &&
527 !siICa_Data.empty() && !soICl_Data.full()) {
528 siICa_Data.read(currChunk);
530 ValBit csumValid = (siICc_CsumValid.read() == 1);
531 ValBit isIpv4Pkt = (siICa_IpVer.read() == 4);
533 ap_uint<2> valid = (csumValid + isIpv4Pkt + doKeepPkt);
535 iid_fsmState = FSM_DROP;
536 printWarn(myName,
"The current IP packet will be dropped because:\n");
537 printWarn(myName,
" csumValid=%d | isIpv4Pkt=%d | doKeepPkt=%d\n",
538 csumValid.to_int(), isIpv4Pkt.to_int(), doKeepPkt.to_int());
541 soICl_Data.write(currChunk);
542 iid_fsmState = FSM_FWD;
547 if(!siICa_Data.empty() && !soICl_Data.full()) {
548 siICa_Data.read(currChunk);
549 soICl_Data.write(currChunk);
556 if(!siICa_Data.empty()){
557 siICa_Data.read(currChunk);
577 stream<AxisIp4> &siIId_Data,
578 stream<AxisIp4> &soIPr_Data)
581 #pragma HLS INLINE off
582 #pragma HLS PIPELINE II=1 enable_flush
587 static enum FsmStates {FSM_FWD=0, FSM_DROP} icl_fsmState=FSM_FWD;
588 #pragma HLS RESET variable=icl_fsmState
589 static ap_uint<13> icl_chunkCount=0;
590 #pragma HLS RESET variable=icl_chunkCount
595 switch(icl_fsmState){
597 if (!siIId_Data.empty() && !soIPr_Data.full()) {
598 AxisIp4 currChunk = siIId_Data.read();
599 switch (icl_chunkCount) {
604 if (((icl_chunkCount+1)*8) >= icl_ip4TotalLength) {
606 icl_fsmState = FSM_DROP;
609 ap_uint<4> leftLength = icl_ip4TotalLength - (icl_chunkCount*8);
614 soIPr_Data.write(currChunk);
622 if (!siIId_Data.empty()) {
623 AxisIp4 currChunk = siIId_Data.read();
625 icl_fsmState = FSM_FWD;
644 stream<SubSums> &siICa_SubSums,
645 stream<ValBit> &soIId_CsumValid)
648 #pragma HlS INLINE off
649 #pragma HLS PIPELINE II=1 enable_flush
653 if (!siICa_SubSums.empty() && !soIId_CsumValid.full()) {
654 SubSums ipHdrSums = siICa_SubSums.read();
658 ipHdrSums.
sum0 = (ipHdrSums.
sum0 + (ipHdrSums.
sum0 >> 16)) & 0xFFFF;
659 ipHdrSums.
sum1 = (ipHdrSums.
sum1 + (ipHdrSums.
sum1 >> 16)) & 0xFFFF;
661 ipHdrSums.
sum0 = (ipHdrSums.
sum0 + (ipHdrSums.
sum0 >> 16)) & 0xFFFF;
663 if (ipHdrSums.
sum0(15, 0) != 0x0000) {
664 printError(myName,
"Bad IP header checksum: Expected 0x0000 - Computed 0x%4.4X\n", ipHdrSums.
sum0(15, 0).to_int());
666 soIId_CsumValid.write((ipHdrSums.
sum0(15, 0) == 0x0000) && ipHdrSums.
ipMatch);
690 stream<AxisIp4> &siICl_Data,
691 stream<AxisIp4> &soICMP_Data,
692 stream<AxisIp4> &soICMP_Derr,
693 stream<AxisIp4> &soUOE_Data,
694 stream<AxisIp4> &soTOE_Data)
697 #pragma HLS INLINE off
698 #pragma HLS PIPELINE II=1 enable_flush
704 #pragma HLS RESET variable=ipr_fsmState
705 static ap_uint<2> ipr_chunkCount=0;
706 #pragma HLS RESET variable=ipr_chunkCount
707 static bool ipr_leftToWrite=
false;
708 #pragma HLS RESET variable=ipr_leftToWrite
711 static StsBit ipr_ttlExpired;
718 switch (ipr_fsmState) {
720 if (!siICl_Data.empty() &&
721 !soICMP_Derr.full() && !soICMP_Data.full() &&
722 !soUOE_Data.full() && !soTOE_Data.full()) {
723 siICl_Data.read(currChunk);
724 switch (ipr_chunkCount) {
729 if (ipr_chunkCount == 1) {
739 if (ipr_ttlExpired == 1) {
741 soICMP_Derr.write(ipr_prevChunk);
744 switch (ipr_ipProtocol) {
748 soICMP_Data.write(ipr_prevChunk);
751 soUOE_Data.write(ipr_prevChunk);
754 soTOE_Data.write(ipr_prevChunk);
760 ipr_prevChunk = currChunk;
763 ipr_leftToWrite =
true;
764 ipr_fsmState = FSM_LAST;
769 if (!soICMP_Derr.full() &&
770 !soICMP_Data.full() && !soUOE_Data.full() && !soTOE_Data.full() ) {
771 ap_uint<log2Ceil<8>::val> bitCounter = 0;
772 bitCounter = ipr_prevChunk.
getLen();
774 ipr_prevChunk.
setLE_TData(0, 63, 64-((8-bitCounter.to_int())*8));
776 if (ipr_ttlExpired == 1) {
777 soICMP_Derr.write(ipr_prevChunk);
780 switch (ipr_ipProtocol) {
782 soICMP_Data.write(ipr_prevChunk);
785 soUOE_Data.write(ipr_prevChunk);
788 soTOE_Data.write(ipr_prevChunk);
792 ipr_leftToWrite =
false;
835 stream<AxisEth> &siETH_Data,
839 stream<AxisArp> &soARP_Data,
843 stream<AxisIp4> &soICMP_Data,
844 stream<AxisIp4> &soICMP_Derr,
848 stream<AxisIp4> &soUOE_Data,
852 stream<AxisIp4> &soTOE_Data)
857 #pragma HLS INTERFACE ap_ctrl_none port=return
864 static stream<AxisEth> ssIBufToMPd_Data (
"ssIBufToMPd_Data");
865 #pragma HLS STREAM variable=ssIBufToMPd_Data depth=8192
868 static stream<AxisEth> ssMPdToILc_Data (
"ssMPdToILc_Data");
869 #pragma HLS STREAM variable=ssMPdToILc_Data depth=32
872 static stream<AxisEth> ssILcToICa_Data (
"ssILcToICa_Data");
873 #pragma HLS STREAM variable=ssILcToICa_Data depth=32
876 static stream<AxisIp4> ssICaToIId_Data (
"ssICaToIId_Data");
877 #pragma HLS STREAM variable=ssICaToIId_Data depth=1024
878 static stream<Ip4Version> ssICaToIId_IpVer (
"ssICaToIId_IpVer");
879 #pragma HLS STREAM variable=ssICaToIId_IpVer depth=32
880 static stream<CmdBit> ssICaToIId_DropFrag (
"ssICaToIId_DropFrag");
881 #pragma HLS STREAM variable=ssICaToIId_DropFrag depth=32
882 static stream<SubSums> ssICaToICc_SubSums (
"ssICaToICc_SubSums");
883 #pragma HLS DATA_PACK variable=ssICaToICc_SubSums
884 #pragma HLS STREAM variable=ssICaToICc_SubSums depth=32
887 static stream<AxisIp4> ssIIdToICl_Data (
"ssIIdToICl_Data");
888 #pragma HLS DATA_PACK variable=ssIIdToICl_Data
889 #pragma HLS STREAM variable=ssIIdToICl_Data depth=32
892 static stream<AxisIp4> ssIClToIPr_Data (
"ssIClToIPr_Data");
893 #pragma HLS DATA_PACK variable=ssIClToIPr_Data
894 #pragma HLS STREAM variable=ssIClToIPr_Data depth=32
897 static stream<ValBit> ssICcToIId_CsumVal (
"ssICcToIId_CsumVal");
898 #pragma HLS STREAM variable=ssICcToIId_CsumVal depth=32
961 #if HLS_VERSION == 2017
971 stream<AxisEth> &siETH_Data,
975 stream<AxisArp> &soARP_Data,
979 stream<AxisIp4> &soICMP_Data,
980 stream<AxisIp4> &soICMP_Derr,
984 stream<AxisIp4> &soUOE_Data,
988 stream<AxisIp4> &soTOE_Data)
991 #pragma HLS INTERFACE ap_ctrl_none port=return
997 #pragma HLS INTERFACE ap_stable register port=piMMIO_MacAddress
998 #pragma HLS INTERFACE ap_stable register port=piMMIO_Ip4Address
1000 #pragma HLS RESOURCE core=AXI4Stream variable=siETH_Data metadata="-bus_bundle siETH_Data"
1002 #pragma HLS RESOURCE core=AXI4Stream variable=soARP_Data metadata="-bus_bundle soARP_Data"
1004 #pragma HLS RESOURCE core=AXI4Stream variable=soICMP_Data metadata="-bus_bundle soICMP_Data"
1005 #pragma HLS RESOURCE core=AXI4Stream variable=soICMP_Derr metadata="-bus_bundle soICMP_Derr"
1007 #pragma HLS RESOURCE core=AXI4Stream variable=soUOE_Data metadata="-bus_bundle soUOE_Data"
1008 #pragma HLS RESOURCE core=AXI4Stream variable=soTOE_Data metadata="-bus_bundle soTOE_Data"
1011 #pragma HLS DATAFLOW
1041 stream<AxisRaw> &siETH_Data,
1045 stream<AxisRaw> &soARP_Data,
1049 stream<AxisRaw> &soICMP_Data,
1050 stream<AxisRaw> &soICMP_Derr,
1054 stream<AxisRaw> &soUOE_Data,
1058 stream<AxisRaw> &soTOE_Data)
1062 #pragma HLS INTERFACE ap_ctrl_none port=return
1064 #pragma HLS INTERFACE ap_stable port=piMMIO_MacAddress name=piMMIO_MacAddress
1065 #pragma HLS INTERFACE ap_stable port=piMMIO_Ip4Address name=piMMIO_Ip4Address
1067 #pragma HLS INTERFACE axis off port=siETH_Data name=siETH_Data
1069 #pragma HLS INTERFACE axis off port=soARP_Data name=soARP_Data
1071 #pragma HLS INTERFACE axis off port=soICMP_Data name=soICMP_Data
1072 #pragma HLS INTERFACE axis off port=soICMP_Derr name=soICMP_Derr
1074 #pragma HLS INTERFACE axis off port=soUOE_Data name=soUOE_Data
1075 #pragma HLS INTERFACE axis off port=soTOE_Data name=soTOE_Data
1078 #pragma HLS DATAFLOW disable_start_propagation
1081 static stream<AxisEth> ssiETH_Data;
1082 static stream<AxisArp> ssoARP_Data;
1083 static stream<AxisIp4> ssoICMP_Data;
1084 static stream<AxisIp4> ssoICMP_Derr;
1085 static stream<AxisIp4> ssoUOE_Data;
1086 static stream<AxisIp4> ssoTOE_Data;
Ip4DstAddrHi getIp4DstAddrHi()
Ip4Version getIp4Version()
Ip4DstAddrLo getIp4DstAddrLo()
LE_EthAddr getLE_EthDstAddr()
Ip4TotalLen getIp4TotalLen()
Ip4TotalLen getIp4TotalLen()
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 pIpCutLength(stream< AxisIp4 > &siIId_Data, stream< AxisIp4 > &soIPr_Data)
void pIpLengthChecker(stream< AxisEth > &siMPd_Data, stream< AxisEth > &soICa_Data)
const UdpLen MaxDatagramSize
void pIpInvalidDropper(stream< AxisIp4 > &siICa_Data, stream< Ip4Version > &siICa_IpVer, stream< ValBit > &siICa_DropFrag, stream< ValBit > &siICc_CsumValid, stream< AxisIp4 > &soICl_Data)
void iprx(EthAddr piMMIO_MacAddress, Ip4Addr piMMIO_Ip4Address, stream< AxisEth > &siETH_Data, stream< AxisArp > &soARP_Data, stream< AxisIp4 > &soICMP_Data, stream< AxisIp4 > &soICMP_Derr, stream< AxisIp4 > &soUOE_Data, stream< AxisIp4 > &soTOE_Data)
Main process of the IP Receive handler (IPRX).
void iprx_top(EthAddr piMMIO_MacAddress, Ip4Addr piMMIO_Ip4Address, stream< AxisRaw > &siETH_Data, stream< AxisRaw > &soARP_Data, stream< AxisRaw > &soICMP_Data, stream< AxisRaw > &soICMP_Derr, stream< AxisRaw > &soUOE_Data, stream< AxisRaw > &soTOE_Data)
Top of IP Receive handler (IPRX)
void pInputBuffer(stream< AxisEth > &siETH_Data, stream< AxisEth > &soMPd_Data)
void pMacProtocolDetector(EthAddr piMMIO_MacAddr, stream< AxisEth > &siIBuf_Data, stream< AxisArp > &soARP_Data, stream< AxisEth > &soILc_Data)
void pIpChecksumChecker(stream< SubSums > &siICa_SubSums, stream< ValBit > &soIId_CsumValid)
void pIpPacketRouter(stream< AxisIp4 > &siICl_Data, stream< AxisIp4 > &soICMP_Data, stream< AxisIp4 > &soICMP_Derr, stream< AxisIp4 > &soUOE_Data, stream< AxisIp4 > &soTOE_Data)
void pIpChecksumAccumulator(Ip4Addr piMMIO_Ip4Address, stream< AxisEth > &siILc_Data, stream< AxisIp4 > &soIId_Data, stream< Ip4Version > &soIId_IpVer, stream< CmdBit > &soIId_DropCmd, stream< SubSums > &soICc_SubSums)
#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).
void pAxisRawCast(hls::stream< TypeIn > &si, hls::stream< TypeOut > &so)
AxisRaw cast - Casts an AxisRaw stream to/from an AxisRaw derived class.
#define ETH_ETHERTYPE_ARP
#define printInfo(callerName, format,...)
A macro to print an information message.
ap_uint< 16 > Ip4TotalLen
#define printWarn(callerName, format,...)
A macro to print a warning message.
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
#define ETH_ETHERTYPE_IP4
: IP Receiver packet handler (IPRX).
ap_uint< 16 > byteSwap16(ap_uint< 16 > inputVector)