39 #define THIS_NAME "TB"
41 #define TRACE_OFF 0x0000
42 #define TRACE_CGF 1 << 1
43 #define TRACE_ALL 0xFFFF
45 #define DEBUG_LEVEL (TRACE_OFF)
71 string inpDAT_FileName,
72 string outDAT_GoldName,
80 char currPath[FILENAME_MAX];
82 int inpChunks=0, outChunks=0;
83 int inpPackets=0, outPackets=0;
84 int inpBytes=0, outBytes=0;
87 ifsDAT.open(inpDAT_FileName.c_str());
89 getcwd(currPath,
sizeof(currPath));
90 printError(myName,
"Cannot open the file: %s \n\t (FYI - The current working directory is: %s) \n",
91 inpDAT_FileName.c_str(), currPath);
95 printError(myName,
"Cannot create golden files from input file \'%s\' because file is not of type \'.dat\'.\n",
96 inpDAT_FileName.c_str());
102 remove(outDAT_GoldName.c_str());
103 if (!ofsDAT.is_open()) {
106 printFatal(myName,
"Could not open the output gold file \'%s\'. \n",
107 outDAT_GoldName.c_str());
112 while ((ifsDAT.peek() != EOF) && (
ret !=
NTS_KO)) {
118 while ((ifsDAT.peek() != EOF) && (!endOfPkt)) {
138 inpBytes += axisIp4.
getLen();
142 if (endOfPkt and
rc) {
144 printError(myName,
"IP packet #%d is dropped because it is malformed.\n", inpPackets);
153 printWarn(myName,
"IP packet #%d is dropped because it is not an ICMP packet.\n");
154 printInfo(myName,
" Received Ip4Prot = 0x%2.2X\n", ip4Prot.to_uchar());
166 printInfo(myName,
"IP4 packet #%d contains an ICMP message with an invalid checksum. It will be dropped by the ICMP core.\n", inpPackets);
167 printInfo(myName,
"\tFound checksum field=0x%4.4X, Was expecting 0x%4.4X)\n",
172 (icmpDataPacket.
getCode() == 0)) {
174 printInfo(myName,
"IP4 packet #%d contains an ICMP Echo Request message.\n", inpPackets);
175 printInfo(myName,
"\t\t(FYI: the ICMP checksum of this message = 0x%4.4X)\n", icmpDataPacket.
getIcmpChecksum().to_uint());
178 printInfo(myName,
"\tBuilding a gold ICMP Echo Reply message.\n");
190 printInfo(myName,
"\t\t(the new ICMP checksum = 0x%4.4X)\n", newCsum.to_uint());
192 if (ipGoldPacket.
addIpPayload(icmpGoldPacket) ==
false) {
193 printError(myName,
"Failed to add ICMP packet as payload to an IP4 packet.\n");
197 printError(myName,
"Failed to write IP4 packet to DAT file.\n");
202 outChunks += ipGoldPacket.
size();
203 outBytes += ipGoldPacket.
length();
207 printInfo(myName,
"IP4 packet #%d contains an unsupported ICMP message. It will be dropped by the ICMP core.\n", inpPackets);
208 printInfo(myName,
"\t(FYI: the ICMP checksum of this message is 0x%4.4X)\n", icmpDataPacket.
getIcmpChecksum().to_uint());
209 printInfo(myName,
"\t(FYI: the message-type is %d and the message-code is %d)\n",
220 printInfo(myName,
"Done with the creation of the golden file.\n");
221 printInfo(myName,
"\tProcessed %5d chunks in %4d packets, for a total of %6d bytes.\n",
222 inpChunks, inpPackets, inpBytes);
223 printInfo(myName,
"\tGenerated %5d chunks in %4d packets, for a total of %6d bytes.\n",
224 outChunks, outPackets, outBytes);
228 #if HLS_VERSION != 2017
247 stream<AxisIp4> &siIPRX_Data,
248 stream<AxisIp4> &siIPRX_Derr,
250 stream<AxisIcmp> &siUOE_Data,
252 stream<AxisIp4> &soIPTX_Data)
255 static stream<AxisRaw> ssiIPRX_Data (
"ssiIPRX_Data");
256 static stream<AxisRaw> ssiIPRX_Derr (
"ssiIPRX_Derr");
257 static stream<AxisRaw> ssiUOE_Data (
"ssiUOE_Data");
258 static stream<AxisRaw> ssoIPTX_Data (
"ssoIPTX_Data");
287 int main(
int argc,
char* argv[]) {
302 Ip4Addr myIp4Address = 0x01010101;
304 string ofsICMP_IPTX_Data_FileName =
"../../../../test/simOutFiles/soIPTX_Data.dat";
305 string ofsICMP_IPTX_Gold_FileName =
"../../../../test/simOutFiles/soIPTX_Gold.dat";
311 stream<AxisIp4> ssIPRX_ICMP_Data (
"ssIPRX_ICMP_Data");
312 int nrIPRX_ICMP_Chunks = 0;
313 int nrIPRX_ICMP_Packets= 0;
314 int nrIPRX_ICMP_Bytes = 0;
315 stream<AxisIp4> ssIPRX_ICMP_Derr (
"ssIPRX_ICMP_Derr");
317 stream<AxisIcmp> ssUDP_ICMP_Data (
"ssUDP_ICMP_Data");
319 stream<AxisIp4> ssICMP_IPTX_Data (
"ssICMP_IPTX_Data");
320 int nrICMP_IPTX_Chunks = 0;
321 int nrICMP_IPTX_Packets= 0;
322 int nrICMP_IPTX_Bytes = 0;
328 printFatal(
THIS_NAME,
"Missing testbench parameter:\n\t Expecting an input test vector file.\n");
332 myIp4Address = param;
333 printIp4Addr(
THIS_NAME,
"The input test vector is setting the IP address of the FPGA to", myIp4Address);
340 if (feedAxisFromFile<AxisIp4>(ssIPRX_ICMP_Data,
"ssIPRX_ICMP_Data",
string(argv[1]),
341 nrIPRX_ICMP_Chunks, nrIPRX_ICMP_Packets, nrIPRX_ICMP_Bytes)) {
343 printInfo(
THIS_NAME,
"\tGenerated %d chunks in %d frames, for a total of %d bytes.\n\n",
344 nrIPRX_ICMP_Chunks, nrIPRX_ICMP_Packets, nrIPRX_ICMP_Bytes);
354 ofstream ofsIPTX_Data;
355 string ofsIPTX_Data_FileName =
"../../../../test/simOutFiles/soIPTX_Data.dat";
356 string ofsIPTX_Gold_FileName =
"../../../../test/simOutFiles/soIPTX_Gold.dat";
359 remove(ofsIPTX_Data_FileName.c_str());
361 if (not
isDatFile(ofsIPTX_Data_FileName)) {
362 printError(
THIS_NAME,
"File \'%s\' is not of type \'DAT\'.\n", ofsIPTX_Data_FileName.c_str());
363 ofsIPTX_Data.close();
367 if (!ofsIPTX_Data.is_open()) {
368 ofsIPTX_Data.open(ofsIPTX_Data_FileName.c_str(),
ofstream::out);
378 if (not
createGoldenFile(
string(argv[1]), ofsIPTX_Gold_FileName, myIp4Address)) {
384 printInfo(
THIS_NAME,
"############################################################################\n");
386 printInfo(
THIS_NAME,
"############################################################################\n");
391 tbRun = (nrErr == 0) ? (nrIPRX_ICMP_Chunks +
TB_GRACE_TIME) : 0;
394 #if HLS_VERSION == 2017
416 if (not drainAxisToFile<AxisIp4>(ssICMP_IPTX_Data,
"ssICMP_IPTX_Data",
417 ofsICMP_IPTX_Data_FileName, nrICMP_IPTX_Chunks,
418 nrICMP_IPTX_Packets, nrICMP_IPTX_Bytes)) {
423 printInfo(
THIS_NAME,
"############################################################################\n");
425 printInfo(
THIS_NAME,
"############################################################################\n");
431 int res = system((
"diff --brief -w " + std::string(ofsIPTX_Data_FileName) \
432 +
" " + std::string(ofsIPTX_Gold_FileName) +
" ").c_str());
435 ofsIPTX_Data_FileName.c_str(), ofsIPTX_Gold_FileName.c_str());
448 printError(
THIS_NAME,
"#### TEST BENCH FAILED : TOTAL NUMBER OF ERROR(S) = %2d ####\n", nrErr);
451 printInfo(
THIS_NAME,
"FYI - You may want to check for \'ERROR\' and/or \'WARNING\' alarms in the LOG file...\n\n");
454 printInfo(
THIS_NAME,
"#############################################################\n");
456 printInfo(
THIS_NAME,
"#############################################################\n");
void setLE_TLast(LE_tLast last)
void setLE_TKeep(LE_tKeep keep, int leHi=64/8-1, int leLo=0)
LE_tLast getLE_TLast() const
Class ICMP Packet for simulation.
void setIcmpCode(IcmpCode code)
IcmpCsum calculateIcmpChecksum()
IcmpCsum reCalculateIcmpChecksum()
Recalculate the ICMP checksum of a packet.
void setIcmpType(IcmpType type)
IcmpCsum getIcmpChecksum()
Class IPv4 Packet for simulation.
void setIpSourceAddress(int addr)
bool isWellFormed(const char *callerName, bool checkIp4TotLen=true, bool checkIp4HdrCsum=true, bool checkUdpLen=true, bool checkLy4Csum=true)
Checks if the IP header and embedded protocol fields are properly set.
Ip4Addr getIpSourceAddress()
void pushChunk(AxisIp4 ip4Chunk)
void cloneHeader(SimIp4Packet &ipPkt)
Clone the header of an IP packet.
void setIpDestinationAddress(int addr)
Ip4Addr getIpDestinationAddress()
bool addIpPayload(SimUdpDatagram &udpDgm, int len=-1)
Append some data to this packet from a UDP datagram.
bool writeToDatFile(ofstream &outFileStream)
Dump this IP packet as AxisIp4 chunks into a file.
SimIcmpPacket getIcmpPacket()
#define TB_MAX_SIM_CYCLES
unsigned int gMaxSimCycles
int main(int argc, char *argv[])
Main function.
void icmp_top_wrap(Ip4Addr piMMIO_Ip4Address, stream< AxisIp4 > &siIPRX_Data, stream< AxisIp4 > &siIPRX_Derr, stream< AxisIcmp > &siUOE_Data, stream< AxisIp4 > &soIPTX_Data)
A wrapper for Toplevel of Internet Control Message Protocol (ICMP).
void stepSim()
Increment the simulation counter.
int createGoldenFile(string inpDAT_FileName, string outDAT_GoldName, Ip4Addr myIp4Address)
Create the golden reference file from an input test file.
void icmp_top(Ip4Addr piMMIO_Ip4Address, stream< AxisRaw > &siIPRX_Data, stream< AxisRaw > &siIPRX_Derr, stream< AxisRaw > &siUOE_Data, stream< AxisRaw > &soIPTX_Data)
Top of the Internet Control Message Protocol (ICMP) Server.
const IcmpType ICMP_ECHO_REPLY
const Ip4Prot ICMP_PROTOCOL
const IcmpType ICMP_ECHO_REQUEST
bool isDatFile(string fileName)
Checks if a file has a ".dat" extension.
bool readTbParamFromFile(const string paramName, const string datFile, unsigned int ¶mVal)
Retrieve a testbench parameter from a DAT file.
bool readAxisRawFromFile(AxisRaw &axisRaw, ifstream &inpFileStream)
Retrieve an Axis raw data chunk from a file.
#define printError(callerName, format,...)
A macro to print an error message.
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.
void printIp4Addr(const char *callerName, const char *message, Ip4Addr ip4Addr)
Print an IPv4 address prepended with a message (used for debugging).
#define printWarn(callerName, format,...)
A macro to print a warning message.
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
#define printFatal(callerName, format,...)
A macro to print a fatal error message and exit.