cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
ARP_TEST

Testbench for the Address Resolution Protocol (ARS) server of the Network Transport Stack (NTS). More...

Collaboration diagram for ARP_TEST:

Macros

#define THIS_NAME   "TB"
 
#define TRACE_OFF   0x0000
 
#define TRACE_CAM   1 << 1
 
#define TRACE_CGF   1 << 2
 
#define TRACE_EAC   1 << 3
 
#define TRACE_EIT   1 << 4
 
#define TRACE_ALL   0xFFFF
 
#define DEBUG_LEVEL   (TRACE_OFF)
 
#define TB_MAX_SIM_CYCLES   25000
 
#define TB_STARTUP_DELAY   0
 
#define TB_GRACE_TIME   500
 
#define CAM_LOOKUP_LATENCY   2
 
#define CAM_UPDATE_LATENCY   10
 

Functions

int createGoldenFile (string inpDAT_FileName, string outDAT_GoldName, EthAddr myMacAddress, Ip4Addr myIp4Address, map< Ip4Addr, EthAddr > &hostMap)
 Create the golden reference file from an input test file. More...
 
void pEmulateCam (stream< RtlMacLookupRequest > &siARS_MacLkpReq, stream< RtlMacLookupReply > &soARS_MacLkpRep, stream< RtlMacUpdateRequest > &siARS_MacUpdReq, stream< RtlMacUpdateReply > &soARS_MacUpdRep)
 Emulate the behavior of the Content Addressable Memory (CAM). More...
 
void arp_top_wrap (EthAddr piMMIO_MacAddress, Ip4Addr piMMIO_Ip4Address, stream< AxisEth > &siIPRX_Data, stream< AxisEth > &soETH_Data, stream< Ip4Addr > &siIPTX_MacLkpReq, stream< ArpLkpReply > &soIPTX_MacLkpRep, stream< RtlMacLookupRequest > &soCAM_MacLkpReq, stream< RtlMacLookupReply > &siCAM_MacLkpRep, stream< RtlMacUpdateRequest > &soCAM_MacUpdReq, stream< RtlMacUpdateReply > &siCAM_MacUpdRep)
 A wrapper for the Toplevel of the Address Resolution Protocol (ARP) Server. More...
 
int main (int argc, char *argv[])
 Main function. More...
 

Variables

const Ip4Addr RESERVED_SENDER_PROTOCOL_ADDRESS = 0xCAFEFADE
 
bool gTraceEvent
 
bool gFatalError
 
unsigned int gSimCycCnt
 
unsigned int gMaxSimCycles
 

Detailed Description

Testbench for the Address Resolution Protocol (ARS) server of the Network Transport Stack (NTS).

Macro Definition Documentation

◆ CAM_LOOKUP_LATENCY

#define CAM_LOOKUP_LATENCY   2

Definition at line 56 of file test_arp.hpp.

◆ CAM_UPDATE_LATENCY

#define CAM_UPDATE_LATENCY   10

Definition at line 57 of file test_arp.hpp.

◆ DEBUG_LEVEL

#define DEBUG_LEVEL   (TRACE_OFF)

Definition at line 49 of file test_arp.cpp.

◆ TB_GRACE_TIME

#define TB_GRACE_TIME   500

Definition at line 54 of file test_arp.hpp.

◆ TB_MAX_SIM_CYCLES

#define TB_MAX_SIM_CYCLES   25000

Definition at line 52 of file test_arp.hpp.

◆ TB_STARTUP_DELAY

#define TB_STARTUP_DELAY   0

Definition at line 53 of file test_arp.hpp.

◆ THIS_NAME

#define THIS_NAME   "TB"

Definition at line 40 of file test_arp.cpp.

◆ TRACE_ALL

#define TRACE_ALL   0xFFFF

Definition at line 47 of file test_arp.cpp.

◆ TRACE_CAM

#define TRACE_CAM   1 << 1

Definition at line 43 of file test_arp.cpp.

◆ TRACE_CGF

#define TRACE_CGF   1 << 2

Definition at line 44 of file test_arp.cpp.

◆ TRACE_EAC

#define TRACE_EAC   1 << 3

Definition at line 45 of file test_arp.cpp.

◆ TRACE_EIT

#define TRACE_EIT   1 << 4

Definition at line 46 of file test_arp.cpp.

◆ TRACE_OFF

#define TRACE_OFF   0x0000

Definition at line 42 of file test_arp.cpp.

Function Documentation

◆ arp_top_wrap()

void arp_top_wrap ( EthAddr  piMMIO_MacAddress,
Ip4Addr  piMMIO_Ip4Address,
stream< AxisEth > &  siIPRX_Data,
stream< AxisEth > &  soETH_Data,
stream< Ip4Addr > &  siIPTX_MacLkpReq,
stream< ArpLkpReply > &  soIPTX_MacLkpRep,
stream< RtlMacLookupRequest > &  soCAM_MacLkpReq,
stream< RtlMacLookupReply > &  siCAM_MacLkpRep,
stream< RtlMacUpdateRequest > &  soCAM_MacUpdReq,
stream< RtlMacUpdateReply > &  siCAM_MacUpdRep 
)

A wrapper for the Toplevel of the Address Resolution Protocol (ARP) Server.

Parameters
[in]piMMIO_MacAddressThe MAC address from MMIO (in network order).
[in]piMMIO_Ip4AddressThe IPv4 address from MMIO (in network order).
[in]siIPRX_DataData stream from the IP Rx Handler (IPRX).
[out]soETH_DataData stream to Ethernet (ETH).
[in]siIPTX_MacLkpReqMAC lookup request from [IPTX].
[out]soIPTX_MacLkpRepMAC lookup reply to [IPTX].
[out]soCAM_MacLkpReqMAC lookup request to [CAM].
[in]siCAM_MacLkpRepMAC lookup reply from [CAM].
[out]soCAM_MacUpdReqMAC update request to [CAM].
[in]siCAM_MacUpdRepMAC update reply from [CAM].

This process is a wrapper for the 'iprx_top' entity. It instantiates such an entity and further connects it with base 'AxisRaw' streams as expected by the 'iprx_top'.

Definition at line 397 of file test_arp.cpp.

413 {
414  //-- LOCAL INPUT and OUTPUT STREAMS -------------------
415  static stream<AxisRaw> ssiIPRX_Data ("ssiIPRX_Data");
416  static stream<AxisRaw> ssoETH_Data ("ssoETH_Data");
417 
418  //-- INPUT STREAM CASTING -----------------------------
419  pAxisRawCast(siIPRX_Data, ssiIPRX_Data);
420 
421  //-- MAIN IPRX_TOP PROCESS ----------------------------
422  arp_top(
423  piMMIO_MacAddress,
424  piMMIO_Ip4Address,
425  ssiIPRX_Data,
426  ssoETH_Data,
427  siIPTX_MacLkpReq,
428  soIPTX_MacLkpRep,
429  soCAM_MacLkpReq,
430  siCAM_MacLkpRep,
431  soCAM_MacUpdReq,
432  siCAM_MacUpdRep);
433 
434  //-- OUTPUT STREAM CASTING ----------------------------
435  pAxisRawCast(ssoETH_Data, soETH_Data);
436 }
void arp_top(EthAddr piMMIO_MacAddress, Ip4Addr piMMIO_Ip4Address, stream< AxisRaw > &siIPRX_Data, stream< AxisRaw > &soETH_Data, stream< Ip4Addr > &siIPTX_MacLkpReq, stream< ArpLkpReply > &soIPTX_MacLkpRep, stream< RtlMacLookupRequest > &soCAM_MacLkpReq, stream< RtlMacLookupReply > &siCAM_MacLkpRep, stream< RtlMacUpdateRequest > &soCAM_MacUpdReq, stream< RtlMacUpdateReply > &siCAM_MacUpdRep)
Top of Address Resolution Protocol (ARP) Server.
Definition: arp.cpp:664
void pAxisRawCast(hls::stream< TypeIn > &si, hls::stream< TypeOut > &so)
AxisRaw cast - Casts an AxisRaw stream to/from an AxisRaw derived class.
Definition: AxisRaw.hpp:148
Here is the call graph for this function:
Here is the caller graph for this function:

◆ createGoldenFile()

int createGoldenFile ( string  inpDAT_FileName,
string  outDAT_GoldName,
EthAddr  myMacAddress,
Ip4Addr  myIp4Address,
map< Ip4Addr, EthAddr > &  hostMap 
)

Create the golden reference file from an input test file.

Parameters
[in]inpDAT_FileNamethe input DAT file to generate from.
[in]outDAT_GoldNamethe output DAT gold file to create.
[in]myMacAddressthe MAC address of the FPGA.
[in]myIp4Addressthe IPv4 address of the FPGA.
[in]hostMapa ref to an associative container which holds the ARP binding addresses of the hosts involved in the current testbench run.
Returns
NTS_ OK if successful, otherwise NTS_KO.

Definition at line 78 of file test_arp.cpp.

84 {
85  const char *myName = concat3(THIS_NAME, "/", "CGF");
86 
87  ifstream ifsDAT;
88  ofstream ofsDAT;
89 
90  char currPath[FILENAME_MAX];
91  int ret=NTS_OK;
92  int inpChunks=0, outChunks=0;
93  int inpFrames=0, outFrames=0;
94  int inpBytes=0, outBytes=0;
95 
96  //-- STEP-1 : OPEN INPUT FILE AND ASSESS ITS EXTENSION
97  ifsDAT.open(inpDAT_FileName.c_str());
98  if (!ifsDAT) {
99  getcwd(currPath, sizeof(currPath));
100  printError(myName, "Cannot open the file: %s \n\t (FYI - The current working directory is: %s) \n",
101  inpDAT_FileName.c_str(), currPath);
102  return(NTS_KO);
103  }
104  if (not isDatFile(inpDAT_FileName)) {
105  printError(myName, "Cannot create golden files from input file \'%s\' because file is not of type \'.dat\'.\n",
106  inpDAT_FileName.c_str());
107  ifsDAT.close();
108  return(NTS_KO);
109  }
110 
111  //-- STEP-2 : OPEN THE OUTPUT GOLD FILE
112  remove(outDAT_GoldName.c_str());
113  if (!ofsDAT.is_open()) {
114  ofsDAT.open (outDAT_GoldName.c_str(), ofstream::out);
115  if (!ofsDAT) {
116  printFatal(THIS_NAME, "Could not open the output gold file \'%s\'. \n",
117  outDAT_GoldName.c_str());
118  }
119  }
120 
121  //-- STEP-3 : READ AND PARSE THE INPUT ARP FILE
122  while ((ifsDAT.peek() != EOF) && (ret != NTS_KO)) {
123  SimEthFrame ethFrame(0);
124  AxisEth axisEth;
125  bool endOfFrame=false;
126  bool rc;
127  // Read one frame at a time from input file
128  while ((ifsDAT.peek() != EOF) && (!endOfFrame)) {
129  rc = readAxisRawFromFile(axisEth, ifsDAT);
130  if (rc) {
131  if (axisEth.isValid()) {
132  ethFrame.pushChunk(axisEth);
133  if (axisEth.getTLast()) {
134  inpFrames++;
135  endOfFrame = true;
136  }
137  }
138  else {
139  // We always abort the stream as this point by asserting
140  // 'tlast' and de-asserting 'tkeep'.
141  axisEth.setTKeep(0x00);
142  axisEth.setTLast(TLAST);
143  ethFrame.pushChunk(axisEth);
144  inpFrames++;
145  endOfFrame = true;
146  }
147  inpChunks++;
148  inpBytes += axisEth.getLen();
149  }
150  }
151  // Build an ARP reply frame based on the ARP frame read from file
152  if (endOfFrame) {
153  // Assess MAC_DA = FF:FF:FF:FF:FF:FF
154  EthAddr macDA = ethFrame.getMacDestinAddress();
155  if(macDA != ETH_BROADCAST_ADDR) {
156  printWarn(myName, "Frame #%d is dropped because it is not a broadcast frame.\n");
157  printEthAddr(myName, " Received", macDA);
158  printEthAddr(myName, " Expected", ETH_BROADCAST_ADDR);
159  continue;
160  }
161  // Assess EtherType is ARP
162  EtherType etherType = ethFrame.getTypeLength();
163  if (etherType != ETH_ETHERTYPE_ARP) {
164  printWarn(myName, "Frame #%d is dropped because it is not an ARP frame.\n");
165  printInfo(myName, " Received EtherType = 0x%4.4X\n", etherType.to_ushort());
166  printInfo(myName, " Expected EtherType = 0x%4.4X\n", ETH_ETHERTYPE_ARP);
167  continue;
168  }
169  // Retrieve the ARP packet from the frame
170  SimArpPacket arpDataPacket;
171  arpDataPacket = ethFrame.getArpPacket();
172  // Always collect the ARP-SHA and ARP-SPA for further testing
173  ArpSendProtAddr spa = arpDataPacket.getSenderProtAddr();
174  ArpSendHwAddr sha = arpDataPacket.getSenderHwAddr();
176  printFatal(myName, "A DAT file cannot use the Sender Protocol Address (0x%8.8X) because it is reserved for specific testing.\n", RESERVED_SENDER_PROTOCOL_ADDRESS.to_uint());
177  }
178  hostMap[spa] = sha;
179  // Assess the Target Protocol Address
180  if (arpDataPacket.getTargetProtAddr() != myIp4Address) {
181  printWarn(myName, "Frame #%d is skipped because the Target Protocol Address (TPA) of the ARP-REQUEST does not match the IP address of this core.\n");
182  printIp4Addr(myName, " Received TPA", arpDataPacket.getTargetProtAddr());
183  printIp4Addr(myName, " Expected TPA", myIp4Address.to_uint());
184  continue;
185  }
186  // Build ARP Gold packet
187  SimArpPacket arpGoldPacket(28);
188  arpGoldPacket.setHardwareType(ARP_HTYPE_ETHERNET);
189  arpGoldPacket.setProtocolType(ARP_PTYPE_IPV4);
190  arpGoldPacket.setHardwareLength(ARP_HLEN_ETHERNET);
191  arpGoldPacket.setProtocolLength(ARP_PLEN_IPV4);
192  arpGoldPacket.setOperation(ARP_OPER_REPLY);
193  arpGoldPacket.setSenderHwAddr(myMacAddress);
194  arpGoldPacket.setSenderProtAddr(myIp4Address);
195  arpGoldPacket.setTargetHwAddr(arpDataPacket.getSenderHwAddr());
196  arpGoldPacket.setTargetProtAddr(arpDataPacket.getSenderProtAddr());
197 
198  // Build ETHERNET Gold Frame
199  SimEthFrame ethGoldFrame(14);
200  ethGoldFrame.setMacDestinAddress(ethFrame.getMacSourceAddress());
201  ethGoldFrame.setMacSourceAddress(myMacAddress);
202  ethGoldFrame.setTypeLength(ETH_ETHERTYPE_ARP);
203  // Write the ARP packet as data payload of the ETHERNET frame.
204  if (ethGoldFrame.addPayload(arpGoldPacket) == false) {
205  printError(myName, "Failed to add ARP packet as payload of an ETH frame.\n");
206  ret = NTS_KO;
207  }
208  else if (ethGoldFrame.writeToDatFile(ofsDAT) == false) {
209  printError(myName, "Failed to write ETH frame to DAT file.\n");
210  ret = NTS_KO;
211  }
212  else {
213  outFrames += 1;
214  outChunks += ethGoldFrame.size();
215  outBytes += ethGoldFrame.length();
216  }
217  } // End-of if (endOfFrame)
218 
219  } // End-of While ()
220 
221  //-- STEP-3: GENERATE THE ARP-REQUEST PACKET (this is always the last one)
222  // Build ARP Gold packet
223  SimArpPacket arpGoldPacket(28);
224  arpGoldPacket.setHardwareType(ARP_HTYPE_ETHERNET);
225  arpGoldPacket.setProtocolType(ARP_PTYPE_IPV4);
226  arpGoldPacket.setHardwareLength(ARP_HLEN_ETHERNET);
227  arpGoldPacket.setProtocolLength(ARP_PLEN_IPV4);
228  arpGoldPacket.setOperation(ARP_OPER_REQUEST);
229  arpGoldPacket.setSenderHwAddr(myMacAddress);
230  arpGoldPacket.setSenderProtAddr(myIp4Address);
231  arpGoldPacket.setTargetHwAddr(0x00000000);
232  arpGoldPacket.setTargetProtAddr(RESERVED_SENDER_PROTOCOL_ADDRESS);
233 
234  // Build ETHERNET Gold Frame
235  SimEthFrame ethGoldFrame(14);
236  ethGoldFrame.setMacDestinAddress(ETH_BROADCAST_ADDR);
237  ethGoldFrame.setMacSourceAddress(myMacAddress);
238  ethGoldFrame.setTypeLength(ETH_ETHERTYPE_ARP);
239  // Write the ARP packet as data payload of the ETHERNET frame.
240  if (ethGoldFrame.addPayload(arpGoldPacket) == false) {
241  printError(myName, "Failed to add ARP packet as payload of an ETH frame.\n");
242  ret = NTS_KO;
243  }
244  else if (ethGoldFrame.writeToDatFile(ofsDAT) == false) {
245  printError(myName, "Failed to write ETH frame to DAT file.\n");
246  ret = NTS_KO;
247  }
248  else {
249  outFrames += 1;
250  outChunks += ethGoldFrame.size();
251  outBytes += ethGoldFrame.length();
252  }
253 
254  //-- STEP-4: CLOSE FILES
255  ifsDAT.close();
256  ofsDAT.close();
257 
258  //-- STEP-5: PRINT RESULTS
259  printInfo(myName, "Done with the creation of the golden file.\n");
260  printInfo(myName, "\tProcessed %5d chunks in %4d frames, for a total of %6d bytes.\n",
261  inpChunks, inpFrames, inpBytes);
262  printInfo(myName, "\tGenerated %5d chunks in %4d frames, for a total of %6d bytes.\n",
263  outChunks, outFrames, outBytes);
264  printInfo(myName, "\tDetected a total of %4d sender host(s).\n\n",
265  hostMap.size());
266  return(ret);
267 }
void setTLast(tLast last)
Definition: AxisRaw.hpp:246
tLast getTLast() const
Definition: AxisRaw.hpp:219
void setTKeep(tKeep keep)
Definition: AxisRaw.hpp:239
int getLen() const
Definition: AxisRaw.hpp:411
bool isValid() const
Definition: AxisRaw.hpp:434
Class ARP Packet for simulation.
ArpTargProtAddr getTargetProtAddr()
ArpSendProtAddr getSenderProtAddr()
ArpSendHwAddr getSenderHwAddr()
Class ETHERNET Frame.
Definition: SimEthFrame.hpp:55
const Ip4Addr RESERVED_SENDER_PROTOCOL_ADDRESS
Definition: test_arp.hpp:59
#define THIS_NAME
Definition: test_arp.cpp:40
bool isDatFile(string fileName)
Checks if a file has a ".dat" extension.
Definition: SimNtsUtils.cpp:52
bool readAxisRawFromFile(AxisRaw &axisRaw, ifstream &inpFileStream)
Retrieve an Axis raw data chunk from a file.
#define NTS_KO
Definition: nts_types.hpp:56
#define ARP_PTYPE_IPV4
Definition: nts_types.hpp:162
ap_uint< 48 > EthAddr
Definition: AxisEth.hpp:120
#define ARP_HTYPE_ETHERNET
Definition: nts_types.hpp:161
#define printError(callerName, format,...)
A macro to print an error message.
Definition: nts_utils.hpp:195
ap_uint< 48 > ArpSendHwAddr
Definition: AxisArp.hpp:100
#define ARP_OPER_REQUEST
Definition: nts_types.hpp:165
ap_uint< 32 > ArpSendProtAddr
Definition: AxisArp.hpp:101
#define ARP_PLEN_IPV4
Definition: nts_types.hpp:164
#define NTS_OK
Definition: nts_types.hpp:55
#define ETH_ETHERTYPE_ARP
Definition: nts_types.hpp:156
#define ARP_HLEN_ETHERNET
Definition: nts_types.hpp:163
#define printInfo(callerName, format,...)
A macro to print an information message.
Definition: nts_utils.hpp:169
#define ETH_BROADCAST_ADDR
Definition: nts_types.hpp:152
void printIp4Addr(const char *callerName, const char *message, Ip4Addr ip4Addr)
Print an IPv4 address prepended with a message (used for debugging).
Definition: nts_utils.cpp:205
#define printWarn(callerName, format,...)
A macro to print a warning message.
Definition: nts_utils.hpp:182
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
Definition: nts_utils.hpp:161
#define ARP_OPER_REPLY
Definition: nts_types.hpp:166
void printEthAddr(const char *callerName, const char *message, EthAddr ethAddr)
Print an ETHERNET MAC address prepended with a message (for debug).
Definition: nts_utils.cpp:237
#define printFatal(callerName, format,...)
A macro to print a fatal error message and exit.
Definition: nts_utils.hpp:208
#define TLAST
Definition: AxisRaw.hpp:116
ap_uint< 16 > EtherType
Definition: AxisEth.hpp:122
out
Definition: test.py:12
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *  argv[] 
)

Main function.

Main function for the test of the TOP of UDP Shell Interface (USIF).

Main function for the test of the UDP Application Flash (UAF) TOP.

Main function for the test of the TCP Shell Interface (TSIF) TOP.

Main function for the test of the TCP Application Flash (TAF) TOP.

Parameters
[in]inpFile,Thepathame of an input test vector. (e.g., ../../../../test/testVectors/siIPRX_Data_ArpFrame.dat)
[in]modeThe test mode (0=RX_MODE, 1=TX_MODE, 2=BIDIR_MODE, 3=ECHO_MODE).
[in]inpFile1The pathname of the input file containing the test vectors to be fed to the TOE: If (mode==0 || mode=2) inpFile1 = siIPRX_<TestName> Else inpFile1 = siTAIF_<TestName>.
[in]inpFile2The pathname of the second input file containing the test vectors to be fed to the TOE: inpFile2 == siTAIF_<TestName>.
Remarks
: The number of input parameters is variable and depends on the testing mode. Example (see also file '../run_hls.tcl'): csim_design -argv "0 ../../../../test/testVectors/ipRx_OneSynPkt.dat"

Main testbench for the user-application for MCEuropeanEngine on host. Server

Returns
O on success, 1 on fail

This test take 0,1,2,3 or 4 parameters in the following order:

Parameters
[in]Thenumber of bytes to generate in 'Echo' or "Dump' mode [1:65535].
[in]TheIPv4 address to open (must be in the range [0x00000000:0xFFFFFFFF].
[in]TheTCP port number to open (must be in the range [0:65535].
[in]Thenumber of bytes to generate in 'Tx' test mode [1:65535] or '0' to simply open a port w/o triggering the Tx test mode.
[in]Thenumber of bytes to generate in 'Echo' mode [1:65535].
[in]TheIP4 destination address of the remote host.
[in]TheUDP destination port of the remote host.
[in]Thenumber of bytes to generate in or "Test' mode [1:65535].

@info Usage example --> "512 10.11.12.13 2718 1024"

Definition at line 445 of file test_arp.cpp.

445  {
446 
447  //------------------------------------------------------
448  //-- TESTBENCH GLOBAL VARIABLES
449  //------------------------------------------------------
450  gTraceEvent = false;
451  gFatalError = false;
452  gSimCycCnt = 0;
454 
455  //------------------------------------------------------
456  //-- TESTBENCH LOCAL VARIABLES
457  //------------------------------------------------------
458  int nrErr = 0; // Total number of testbench errors
459  int tbRun = 0; // Total duration of the test (in clock cycles)
460  EthAddr myMacAddress = 0x010203040506;
461  Ip4Addr myIp4Address = 0x0A0CC807; // Might be overwritten by the content of the DAT file.
462 
463  string ofsARS_ETH_Data_FileName = "../../../../test/soETH_Data.dat";
464  string ofsARS_ETH_Gold_FileName = "../../../../test/soETH_Gold.dat";
465 
466  map<Ip4Addr,EthAddr> hostMap; // A map to collect the ARP {SHA,SPA} bindings
467  map<Ip4Addr,EthAddr>::iterator hostMapIter;
468 
469  //------------------------------------------------------
470  //-- DUT STREAM INTERFACES and RELATED VARIABLEs
471  //------------------------------------------------------
472  //-- From IPRX
473  stream<AxisEth> ssIPRX_ARS_Data ("ssIPRX_ARS_Data");
474  int nrIPRX_ARS_Chunks = 0;
475  int nrIPRX_ARS_Frames = 0;
476  int nrIPRX_ARS_Bytes = 0;
477 
478  //-- To ETH (via L2MUX)
479  stream<AxisEth> ssARS_ETH_Data ("ssARS_ETH_Data");
480  int nrARS_ETH_Chunks = 0;
481  int nrARS_ETH_Frames = 0;
482  int nrARS_ETH_Bytes = 0;
483 
484  //-- To/From IPTX
485  stream<Ip4Addr> ssIPTX_ARS_MacLkpReq ("ssIPTX_ARS_MacLkpReq");
486  stream<ArpLkpReply> ssARS_IPTX_MacLkpRep ("ssARS_IPTX_MacLkpRep");
487 
488  //-- To/From CAM
489  stream<RtlMacLookupRequest> ssARS_CAM_MacLkpReq("ssARS_CAM_MacLkpReq");
490  stream<RtlMacLookupReply> ssCAM_ARS_MacLkpRep("ssCAM_ARS_MacLkpRep");
491  stream<RtlMacUpdateRequest> ssARS_CAM_MacUpdReq("ssARS_CAM_MacUpdReq");
492  stream<RtlMacUpdateReply> ssCAM_ARS_MacUpdRep("ssCAM_ARS_MacUpdRep");
493 
494  //------------------------------------------------------
495  //-- READ GLOBAL PARAMETERS FROM INPUT TEST VECTOR FILE
496  //------------------------------------------------------
497  if (argc != 2) {
498  printFatal(THIS_NAME, "Missing testbench parameter:\n\t Expecting an input test vector file.\n");
499  }
500  unsigned int param;
501  if (readTbParamFromFile("FpgaIp4Addr", string(argv[1]), param)) {
502  myIp4Address = param;
503  printIp4Addr(THIS_NAME, "The input test vector is setting the IP address of the FPGA to", myIp4Address);
504  }
505 
506  //------------------------------------------------------
507  //-- CREATE DUT INPUT TRAFFIC AS STREAMS
508  //------------------------------------------------------
509  if (feedAxisFromFile<AxisEth>(ssIPRX_ARS_Data, "sIPRX_ARS_Data", string(argv[1]),
510  nrIPRX_ARS_Chunks, nrIPRX_ARS_Frames, nrIPRX_ARS_Bytes)) {
511  printInfo(THIS_NAME, "Done with the creation of the input traffic as streams:\n");
512  printInfo(THIS_NAME, "\tGenerated %d chunks in %d frames, for a total of %d bytes.\n\n",
513  nrIPRX_ARS_Chunks, nrIPRX_ARS_Frames, nrIPRX_ARS_Bytes);
514  }
515  else {
516  printError(THIS_NAME, "Failed to create traffic as input stream. \n");
517  nrErr++;
518  }
519 
520  //------------------------------------------------------
521  //-- CREATE DUT OUTPUT TRAFFIC AS STREAMS
522  //------------------------------------------------------
523  ofstream ofsETH_Data;
524  string ofsETH_Data_FileName = "../../../../test/soETH_Data.dat";
525  string ofsETH_Gold_FileName = "../../../../test/soETH_Gold.dat";
526 
527  //-- Assess that file has ".dat" extension
528  if (not isDatFile(ofsETH_Data_FileName)) {
529  printFatal(THIS_NAME, "File \'%s\' is not of type \'DAT\'.\n", ofsETH_Data_FileName.c_str());
530  }
531  else {
532  //-- Remove previous file
533  remove(ofsETH_Data_FileName.c_str());
534  //-- Open file
535  if (!ofsETH_Data.is_open()) {
536  ofsETH_Data.open(ofsETH_Data_FileName.c_str(), ofstream::out);
537  if (!ofsETH_Data) {
538  printError(THIS_NAME, "Cannot open the file: \'%s\'.\n", ofsETH_Data_FileName.c_str());
539  nrErr++;
540  }
541  }
542  }
543 
544  //------------------------------------------------------
545  //-- CREATE OUTPUT GOLD TRAFFIC
546  //------------------------------------------------------
547  if (not createGoldenFile(string(argv[1]), ofsETH_Gold_FileName,
548  myMacAddress, myIp4Address, hostMap)) {
549  printError(THIS_NAME, "Failed to create golden file. \n");
550  nrErr++;
551  }
552 
553  printf("\n\n");
554  printInfo(THIS_NAME, "############################################################################\n");
555  printInfo(THIS_NAME, "## TESTBENCH 'test_arp' PART-1 STARTS HERE ##\n");
556  printInfo(THIS_NAME, "############################################################################\n");
557 
558  //-----------------------------------------------------
559  //-- MAIN LOOP-1 : Handle incoming ARP packets generated
560  //-- from the input test vectors.
561  //-----------------------------------------------------
562  tbRun = (nrErr == 0) ? (nrIPRX_ARS_Chunks + TB_GRACE_TIME) : 0;
563  while (tbRun) {
564  //-- RUN DUT --------------------------------------
565  #if HLS_VERSION == 2017
566  arp_top(
567  myMacAddress,
568  myIp4Address,
569  ssIPRX_ARS_Data,
570  ssARS_ETH_Data,
571  ssIPTX_ARS_MacLkpReq,
572  ssARS_IPTX_MacLkpRep,
573  ssARS_CAM_MacLkpReq,
574  ssCAM_ARS_MacLkpRep,
575  ssARS_CAM_MacUpdReq,
576  ssCAM_ARS_MacUpdRep);
577  #else
578  arp_top_wrap(
579  myMacAddress,
580  myIp4Address,
581  ssIPRX_ARS_Data,
582  ssARS_ETH_Data,
583  ssIPTX_ARS_MacLkpReq,
584  ssARS_IPTX_MacLkpRep,
585  ssARS_CAM_MacLkpReq,
586  ssCAM_ARS_MacLkpRep,
587  ssARS_CAM_MacUpdReq,
588  ssCAM_ARS_MacUpdRep);
589  #endif
590 
591  //-- EMULATE ARP CAM ------------------------------
592  pEmulateCam(
593  ssARS_CAM_MacLkpReq,
594  ssCAM_ARS_MacLkpRep,
595  ssARS_CAM_MacUpdReq,
596  ssCAM_ARS_MacUpdRep
597  );
598 
599  tbRun--;
600  stepSim();
601  } // End of: while()
602 
603  printf("\n\n");
604  printInfo(THIS_NAME, "############################################################################\n");
605  printInfo(THIS_NAME, "## TESTBENCH 'test_arp' PART-2 STARTS HERE ##\n");
606  printInfo(THIS_NAME, "############################################################################\n");
607 
608  //-----------------------------------------------------
609  //-- MAIN LOOP-2 : Generate a single MAC lookup request
610  //-- that will not be found in the CAM. This will
611  //-- trigger the generation of an ARP-REQUEST packet.
612  //-----------------------------------------------------
613  tbRun = (nrErr == 0) ? (TB_GRACE_TIME) : 0;
614  ssIPTX_ARS_MacLkpReq.write(RESERVED_SENDER_PROTOCOL_ADDRESS);
615  while (tbRun) {
616  //-- RUN DUT --------------------------------------
617  #if HLS_VERSION == 2017
618  arp_top(
619  myMacAddress,
620  myIp4Address,
621  ssIPRX_ARS_Data,
622  ssARS_ETH_Data,
623  ssIPTX_ARS_MacLkpReq,
624  ssARS_IPTX_MacLkpRep,
625  ssARS_CAM_MacLkpReq,
626  ssCAM_ARS_MacLkpRep,
627  ssARS_CAM_MacUpdReq,
628  ssCAM_ARS_MacUpdRep);
629  #else
630  arp_top_wrap(
631  myMacAddress,
632  myIp4Address,
633  ssIPRX_ARS_Data,
634  ssARS_ETH_Data,
635  ssIPTX_ARS_MacLkpReq,
636  ssARS_IPTX_MacLkpRep,
637  ssARS_CAM_MacLkpReq,
638  ssCAM_ARS_MacLkpRep,
639  ssARS_CAM_MacUpdReq,
640  ssCAM_ARS_MacUpdRep);
641  #endif
642 
643  //-- EMULATE ARP CAM ------------------------------
644  pEmulateCam(
645  ssARS_CAM_MacLkpReq,
646  ssCAM_ARS_MacLkpRep,
647  ssARS_CAM_MacUpdReq,
648  ssCAM_ARS_MacUpdRep
649  );
650 
651  tbRun--;
652  stepSim();
653  } // End of: while()
654 
655  printf("\n\n");
656  printInfo(THIS_NAME, "############################################################################\n");
657  printInfo(THIS_NAME, "## TESTBENCH 'test_arp' PART-3 STARTS HERE ##\n");
658  printInfo(THIS_NAME, "############################################################################\n");
659 
660  //-----------------------------------------------------
661  //-- MAIN LOOP-3 : Handle MAC lookup requests from IPRX
662  //-----------------------------------------------------
663  tbRun = (nrErr == 0) ? (hostMap.size() * (CAM_LOOKUP_LATENCY + 10)) : 0;
664  //-- Feed the MAC lookup requests issued by [IPTX]
665  hostMapIter = hostMap.begin();
666  while (hostMapIter != hostMap.end()) {
667  ssIPTX_ARS_MacLkpReq.write(hostMapIter->first);
668  hostMapIter++;
669  }
670  while (tbRun) {
671  //-- RUN DUT --------------------------------------
672  #if HLS_VERSION == 2017
673  arp_top(
674  myMacAddress,
675  myIp4Address,
676  ssIPRX_ARS_Data,
677  ssARS_ETH_Data,
678  ssIPTX_ARS_MacLkpReq,
679  ssARS_IPTX_MacLkpRep,
680  ssARS_CAM_MacLkpReq,
681  ssCAM_ARS_MacLkpRep,
682  ssARS_CAM_MacUpdReq,
683  ssCAM_ARS_MacUpdRep);
684  #else
685  arp_top_wrap(
686  myMacAddress,
687  myIp4Address,
688  ssIPRX_ARS_Data,
689  ssARS_ETH_Data,
690  ssIPTX_ARS_MacLkpReq,
691  ssARS_IPTX_MacLkpRep,
692  ssARS_CAM_MacLkpReq,
693  ssCAM_ARS_MacLkpRep,
694  ssARS_CAM_MacUpdReq,
695  ssCAM_ARS_MacUpdRep);
696  #endif
697 
698  //-- EMULATE ARP CAM ------------------------------
699  pEmulateCam(
700  ssARS_CAM_MacLkpReq,
701  ssCAM_ARS_MacLkpRep,
702  ssARS_CAM_MacUpdReq,
703  ssCAM_ARS_MacUpdRep
704  );
705 
706  tbRun--;
707  stepSim();
708  } // End of: while()
709 
710  //---------------------------------------------------------------
711  //-- DRAIN ARS-->ETH OUTPUT STREAM
712  //---------------------------------------------------------------
713  if (not drainAxisToFile<AxisEth>(ssARS_ETH_Data, "ssARS_ETH_Data",
714  ofsARS_ETH_Data_FileName, nrARS_ETH_Chunks,
715  nrARS_ETH_Frames, nrARS_ETH_Bytes)) {
716  printError(THIS_NAME, "Failed to drain ARS-to-ETH traffic from DUT. \n");
717  nrErr++;
718  }
719 
720  //---------------------------------------------------------------
721  //-- DRAIN ARS-->IPTX OUTPUT STREAM
722  //-- With respect to MAIN-LOOP-2, expect the first MAC lookup
723  //-- to be a 'NOT-HIT'.
724  //---------------------------------------------------------------
725  ArpLkpReply macLkpRep = ssARS_IPTX_MacLkpRep.read();
726  if (macLkpRep.hit != false) {
727  // RESERVED_SENDER_PROTOCOL_ADDRESS;
728  printError(THIS_NAME, "Expecting the first MAC lookup of this testbench to be a \'NO_HIT\' flag.\n");
729  nrErr++;
730  }
731  hostMapIter = hostMap.begin();
732  while (hostMapIter != hostMap.end()) {
733  ArpLkpReply macLkpRep = ssARS_IPTX_MacLkpRep.read();
734  if (macLkpRep.hit == false) {
735  // RESERVED_SENDER_PROTOCOL_ADDRESS;
736  printError(THIS_NAME, "Receive a MAC lookup reply with a \'NO_HIT\' flag.\n");
737  nrErr++;
738  }
739  else if (macLkpRep.macAddress != (hostMapIter->second)) {
740  printError(THIS_NAME, "Received a wrong MAC lookup reply.\n");
741  printEthAddr(THIS_NAME, " Expected : ", (hostMapIter->second));
742  printEthAddr(THIS_NAME, " Received : ", macLkpRep.macAddress);
743  nrErr++;
744  }
745  hostMapIter++;
746  }
747 
748  printInfo(THIS_NAME, "############################################################################\n");
749  printInfo(THIS_NAME, "## TESTBENCH 'test_arp' ENDS HERE ##\n");
750  printInfo(THIS_NAME, "############################################################################\n");
751  stepSim();
752 
753  //---------------------------------------------------------------
754  //-- COMPARE OUTPUT DAT and GOLD STREAMS
755  //---------------------------------------------------------------
756  int res = system(("diff --brief -w " + std::string(ofsETH_Data_FileName) \
757  + " " + std::string(ofsETH_Gold_FileName) + " ").c_str());
758  if (res) {
759  printError(THIS_NAME, "File \'%s\' does not match \'%s\'.\n", \
760  ofsETH_Data_FileName.c_str(), ofsETH_Gold_FileName.c_str());
761  nrErr += 1;
762  }
763 
764  //---------------------------------------------------------------
765  //-- PRINT TESTBENCH STATUS
766  //---------------------------------------------------------------
767  printf("\n\n");
768  printInfo(THIS_NAME, "This testbench was executed with the following test-file: \n");
769  printInfo(THIS_NAME, "\t==> %s\n\n", argv[1]);
770 
771  if (nrErr) {
772  printError(THIS_NAME, "###########################################################\n");
773  printError(THIS_NAME, "#### TEST BENCH FAILED : TOTAL NUMBER OF ERROR(S) = %2d ####\n", nrErr);
774  printError(THIS_NAME, "###########################################################\n\n");
775 
776  printInfo(THIS_NAME, "FYI - You may want to check for \'ERROR\' and/or \'WARNING\' alarms in the LOG file...\n\n");
777  }
778  else {
779  printInfo(THIS_NAME, "#############################################################\n");
780  printInfo(THIS_NAME, "#### SUCCESSFUL END OF TEST ####\n");
781  printInfo(THIS_NAME, "#############################################################\n");
782  }
783 
784  return nrErr;
785 
786 }
EthAddr macAddress
Definition: nts_types.hpp:351
HitBool hit
Definition: nts_types.hpp:352
unsigned int gSimCycCnt
Definition: tb_nal.cpp:150
bool gTraceEvent
Definition: tb_nal.cpp:151
bool gFatalError
Definition: tb_nal.cpp:152
#define TB_STARTUP_DELAY
Definition: test_arp.hpp:53
#define TB_GRACE_TIME
Definition: test_arp.hpp:54
void stepSim()
Increment the simulation counter.
Definition: test_arp.cpp:54
#define TB_MAX_SIM_CYCLES
Definition: test_arp.hpp:52
int createGoldenFile(string inpDAT_FileName, string outDAT_GoldName, EthAddr myMacAddress, Ip4Addr myIp4Address, map< Ip4Addr, EthAddr > &hostMap)
Create the golden reference file from an input test file.
Definition: test_arp.cpp:78
#define CAM_LOOKUP_LATENCY
Definition: test_arp.hpp:56
unsigned int gMaxSimCycles
Definition: test_arp.hpp:69
void arp_top_wrap(EthAddr piMMIO_MacAddress, Ip4Addr piMMIO_Ip4Address, stream< AxisEth > &siIPRX_Data, stream< AxisEth > &soETH_Data, stream< Ip4Addr > &siIPTX_MacLkpReq, stream< ArpLkpReply > &soIPTX_MacLkpRep, stream< RtlMacLookupRequest > &soCAM_MacLkpReq, stream< RtlMacLookupReply > &siCAM_MacLkpRep, stream< RtlMacUpdateRequest > &soCAM_MacUpdReq, stream< RtlMacUpdateReply > &siCAM_MacUpdRep)
A wrapper for the Toplevel of the Address Resolution Protocol (ARP) Server.
Definition: test_arp.cpp:397
void pEmulateCam(stream< RtlMacLookupRequest > &siARS_MacLkpReq, stream< RtlMacLookupReply > &soARS_MacLkpRep, stream< RtlMacUpdateRequest > &siARS_MacUpdReq, stream< RtlMacUpdateReply > &soARS_MacUpdRep)
Emulate the behavior of the Content Addressable Memory (CAM).
Definition: test_arp.cpp:278
bool readTbParamFromFile(const string paramName, const string datFile, unsigned int &paramVal)
Retrieve a testbench parameter from a DAT file.
ap_uint< 32 > Ip4Addr
Definition: AxisIp4.hpp:169
Here is the call graph for this function:

◆ pEmulateCam()

void pEmulateCam ( stream< RtlMacLookupRequest > &  siARS_MacLkpReq,
stream< RtlMacLookupReply > &  soARS_MacLkpRep,
stream< RtlMacUpdateRequest > &  siARS_MacUpdReq,
stream< RtlMacUpdateReply > &  soARS_MacUpdRep 
)

Emulate the behavior of the Content Addressable Memory (CAM).

Parameters
[in]siARS_MacLkpReqMAC lookup request from AddressResolutionServer (ARS).
[out]soARS_MacLkpRepMAC lookup reply to [ARS].
[in]siARS_MacUpdReqMAC update request from [ARS].
[out]soARS_MacUpdRepMAC update reply to [ARS].

Definition at line 278 of file test_arp.cpp.

283 {
284  const char *myName = concat3(THIS_NAME, "/", "CAM");
285 
286  static map<Ip4Addr,EthAddr> LOOKUP_TABLE; // <key,value>
287 
288  static enum CamFsmStates { CAM_WAIT_4_REQ=0,
289  CAM_LOOKUP_REP,
290  CAM_UPDATE_REP } camFsmState;
291 
292  static RtlMacLookupRequest macLkpReq;
293  static RtlMacUpdateRequest macUpdReq;
294  static int camUpdateIdleCnt = 0;
295  volatile static int camLookupIdleCnt = 0;
296  map<Ip4Addr,EthAddr>::const_iterator findPos;
297 
298  //-----------------------------------------------------
299  //-- CONTENT ADDRESSABLE MEMORY PROCESS
300  //-----------------------------------------------------
301  switch (camFsmState) {
302 
303  case CAM_WAIT_4_REQ:
304  if (!siARS_MacLkpReq.empty()) {
305  siARS_MacLkpReq.read(macLkpReq);
306  camLookupIdleCnt = CAM_LOOKUP_LATENCY;
307  camFsmState = CAM_LOOKUP_REP;
308  if (DEBUG_LEVEL & TRACE_CAM) {
309  printInfo(myName, "Received a MAC lookup request from ARS for key: \n");
310  printIp4Addr(myName, macLkpReq.key);
311  }
312  }
313  else if (!siARS_MacUpdReq.empty()) {
314  siARS_MacUpdReq.read(macUpdReq);
315  camUpdateIdleCnt = CAM_UPDATE_LATENCY;
316  camFsmState = CAM_UPDATE_REP;
317  if (DEBUG_LEVEL & TRACE_CAM) {
318  printInfo(myName, "Received a MAC update request from ARS for ARP binding:\n");
319  printArpBindPair(myName, ArpBindPair(macUpdReq.value, macUpdReq.key));
320  }
321  }
322  break;
323  case CAM_LOOKUP_REP:
324  //-- Wait some cycles to match the RTL implementation
325  if (camLookupIdleCnt > 0) {
326  camLookupIdleCnt--;
327  }
328  else {
329  findPos = LOOKUP_TABLE.find(macLkpReq.key);
330  if (findPos != LOOKUP_TABLE.end()) { // hit
331  soARS_MacLkpRep.write(RtlMacLookupReply(LKP_HIT, findPos->second));
332  if (DEBUG_LEVEL & TRACE_CAM) {
333  printInfo(myName, "Result of MAC lookup = HIT \n");
334  }
335  }
336  else {
337  soARS_MacLkpRep.write(RtlMacLookupReply(LKP_NO_HIT, 0xDEADBEEFDEAD));
338  if (DEBUG_LEVEL & TRACE_CAM) {
339  printInfo(myName, "Result of session lookup = NO-HIT\n");
340  }
341  }
342  camFsmState = CAM_WAIT_4_REQ;
343  }
344  break;
345  case CAM_UPDATE_REP:
346  //-- Wait some cycles to match the RTL implementation
347  if (camUpdateIdleCnt > 0) {
348  camUpdateIdleCnt--;
349  }
350  else {
351  if (macUpdReq.opcode == ARP_INSERT) {
352  // Overwrite value if 'key' already exists
353  LOOKUP_TABLE[macUpdReq.key] = macUpdReq.value;
354  soARS_MacUpdRep.write(RtlMacUpdateReply(ARP_INSERT));
355  if (DEBUG_LEVEL & TRACE_CAM) {
356  printInfo(myName, "Successful insertion of ARP binding pair:\n");
357  printArpBindPair(myName, ArpBindPair(macUpdReq.value, macUpdReq.key));
358  }
359  }
360  else { // DELETE
361  LOOKUP_TABLE.erase(macUpdReq.key);
362  soARS_MacUpdRep.write(RtlMacUpdateReply(ARP_DELETE));
363  if (DEBUG_LEVEL & TRACE_CAM) {
364  printInfo(myName, "Successful deletion of ARP binding pair:\n");
365  printArpBindPair(myName, ArpBindPair(macUpdReq.value, macUpdReq.key));
366  }
367  }
368  camFsmState = CAM_WAIT_4_REQ;
369  }
370  break;
371 
372  } // End-of: switch()
373 
374 } // End-of: pEmulateCam()
ArpLkpOp opcode
Definition: arp.hpp:96
EthAddr value
Definition: arp.hpp:94
Ip4Addr key
Definition: arp.hpp:95
#define TRACE_CAM
Definition: test_arp.cpp:43
#define DEBUG_LEVEL
Definition: test_arp.cpp:49
#define CAM_UPDATE_LATENCY
Definition: test_arp.hpp:57
@ ARP_INSERT
Definition: arp.hpp:87
@ ARP_DELETE
Definition: arp.hpp:87
void printArpBindPair(const char *callerName, ArpBindPair arpBind)
Print an ARP binding pair association.
Definition: nts_utils.cpp:80
#define LKP_NO_HIT
Definition: nts_types.hpp:77
#define LKP_HIT
Definition: nts_types.hpp:76
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ gFatalError

bool gFatalError

Definition at line 67 of file test_arp.hpp.

◆ gMaxSimCycles

unsigned int gMaxSimCycles

Definition at line 69 of file test_arp.hpp.

◆ gSimCycCnt

unsigned int gSimCycCnt

GLOBAL VARIABLES USED BY THE SIMULATION ENVIRONMENT

Definition at line 68 of file test_arp.hpp.

◆ gTraceEvent

bool gTraceEvent

HELPERS FOR THE DEBUGGING TRACES .e.g: DEBUG_LEVEL = (MDL_TRACE | IPS_TRACE)

Definition at line 66 of file test_arp.hpp.

◆ RESERVED_SENDER_PROTOCOL_ADDRESS

const Ip4Addr RESERVED_SENDER_PROTOCOL_ADDRESS = 0xCAFEFADE

Definition at line 59 of file test_arp.hpp.