diff --git a/hls/axi_utils.hpp b/hls/axi_utils.hpp index ec71b2df64ce19b71f01a5282b61e2a5f38d44fd..a8122f38f5e898df4a5a2b57a1a84b965e30bc7f 100644 --- a/hls/axi_utils.hpp +++ b/hls/axi_utils.hpp @@ -109,7 +109,7 @@ bool scan(std::istream& inputFile, ap_uint<D>& data) return false; } } - return inputFile.good(); + return (bool) inputFile; } template<int D> @@ -136,7 +136,7 @@ bool scan(std::istream& inputFile, net_axis<D>& word) word.last = lastTemp; //if (!inputFile) // std::cerr << "[ERROR]: could not scan input" << std::endl; - return inputFile.good(); + return (bool) inputFile; } template<int D> @@ -155,7 +155,7 @@ bool scanLE(std::istream& inputFile, ap_uint<D>& data) return false; } } - return inputFile.good(); + return (bool) inputFile; } template<int D> @@ -180,7 +180,7 @@ bool scanLE(std::istream& inputFile, net_axis<D>& word) inputFile >> lastTemp; word.keep = keepTemp; word.last = lastTemp; - return inputFile.good(); + return (bool) inputFile; } template<int D> diff --git a/hls/ip_handler/ip_handler.cpp b/hls/ip_handler/ip_handler.cpp index ed8883e5f04d326ce9cd4f960d8c77c0d921baba..abddda834c498e7961ea5e99122dcb898bbf6c15 100755 --- a/hls/ip_handler/ip_handler.cpp +++ b/hls/ip_handler/ip_handler.cpp @@ -291,6 +291,52 @@ void cut_length(hls::stream<net_axis<WIDTH> > &dataIn, hls::stream<net_axis<WIDT } //switch } +void cut_length(hls::stream<net_axis<512> > &dataIn, hls::stream<net_axis<512> > &dataOut) +{ + #pragma HLS PIPELINE II=1 + #pragma HLS INLINE off + + enum cl_stateType {FIRST, REST}; + static cl_stateType cl_state = FIRST; + + switch (cl_state) + { + case FIRST: + if (!dataIn.empty()) + { + net_axis<512> currWord = dataIn.read(); + + + ap_uint<16> totalLength; + totalLength(7, 0) = currWord.data(31, 24); + totalLength(15, 8) = currWord.data(23, 16); + + if (currWord.last) + { + currWord.keep = lenToKeep(totalLength); + } + else + { + cl_state = REST; + } + dataOut.write(currWord); + } //emtpy + break; + case REST: + if (!dataIn.empty()) + { + net_axis<512> currWord = dataIn.read(); + dataOut.write(currWord); + if (currWord.last) + { + cl_state = FIRST; + } + } + break; + } //switch +} + + /* * Detects IP protocol in the packet. ICMP, UDP and TCP packets are forwarded, packets of other IP protocols are discarded. */ diff --git a/hls/ip_handler/ip_handler_config.hpp.in b/hls/ip_handler/ip_handler_config.hpp.in index e6c018a8fee808b93de26a69b51e840de50e4648..b685f8d1ad5d2a75ef0f74594475ba89ec40edcb 100644 --- a/hls/ip_handler/ip_handler_config.hpp.in +++ b/hls/ip_handler/ip_handler_config.hpp.in @@ -1,3 +1,6 @@ #pragma once +#include <string> const unsigned DATA_WIDTH = ${DATA_WIDTH} * 8; + +const std::string currentDirectory = "${CMAKE_CURRENT_SOURCE_DIR}"; diff --git a/hls/ip_handler/make.tcl.in b/hls/ip_handler/make.tcl.in index 223b5c2a80578de9003c3d37cc9d89be2650c735..114b54928ca80fe82f7b076587a6de5d574930a4 100644 --- a/hls/ip_handler/make.tcl.in +++ b/hls/ip_handler/make.tcl.in @@ -23,7 +23,7 @@ set command [lindex $argv 2] if {$command == "synthesis"} { csynth_design } elseif {$command == "csim"} { - csim_design -clean -argv {${CMAKE_CURRENT_SOURCE_DIR}/newtcp.in ${CMAKE_CURRENT_SOURCE_DIR}/tcp.out} + csim_design -clean } elseif {$command == "ip"} { export_design -format ip_catalog -ipname "ip_handler" -display_name "IP Handler" -vendor "ethz.systems.fpga" -version "2.0" } elseif {$command == "installip"} { diff --git a/hls/ip_handler/tcp.gold b/hls/ip_handler/tcp.gold index bd5c22c07cbc13f2806eee7edf913d89dca41652..bc592a1bd20796cff38d7c63eebfa59646bbb930 100644 --- a/hls/ip_handler/tcp.gold +++ b/hls/ip_handler/tcp.gold @@ -1,8 +1,3 @@ -ICMPv6 -IPv6 UDP -ARP -ICMP -UDP TCP 45 00 00 37 00 00 00 00 ff 0 40 06 76 b5 01 01 01 01 ff 0 diff --git a/hls/ip_handler/tcp.in b/hls/ip_handler/tcp.in index c784c93ba7d29286f8fb75d184d78e69ced90efb..b54cb4e186eacb1b46d0e454db3f845d6b7da137 100644 --- a/hls/ip_handler/tcp.in +++ b/hls/ip_handler/tcp.in @@ -48,4 +48,4 @@ b4 63 b7 c0 00 00 01 01 ff 0 10 50 a9 d8 87 4b b1 01 ff 0 48 0e 00 00 5c f9 ff ff ff 0 6c 65 4d 20 6f 6c 6c 65 ff 0 -00 00 00 2e 72 65 78 65 1f 1 +00 00 00 2e 72 65 78 65 1f 1 \ No newline at end of file diff --git a/hls/ip_handler/test_ip_handler.cpp b/hls/ip_handler/test_ip_handler.cpp index 6b485142824417e663460d82eb6d768b23d70618..33a49fbb411cf78a12c2fe9bc8b6dc4cb603eba0 100755 --- a/hls/ip_handler/test_ip_handler.cpp +++ b/hls/ip_handler/test_ip_handler.cpp @@ -27,6 +27,42 @@ */ #include "ip_handler_config.hpp" #include "ip_handler.hpp" +#include <algorithm> + + +void writeToOutputFile(std::ofstream& outputFile, std::string name, hls::stream<net_axis<64> >& outFifo) +{ + net_axis<64> outWord; + if (!outFifo.empty()) + { + outputFile << name << std::endl; + } + while (!outFifo.empty()) + { + outFifo.read(outWord); + print(outputFile, outWord); + outputFile << std::endl; + } +} + +bool compareFiles(const std::string& filename1, const std::string& filename2) +{ + std::ifstream file1(filename1, std::ifstream::ate | std::ifstream::binary); //open file at the end + std::ifstream file2(filename2, std::ifstream::ate | std::ifstream::binary); //open file at the end + const std::ifstream::pos_type fileSize = file1.tellg(); + + if (fileSize != file2.tellg()) { + return false; //different file size + } + + file1.seekg(0); //rewind + file2.seekg(0); //rewind + + std::istreambuf_iterator<char> begin1(file1); + std::istreambuf_iterator<char> begin2(file2); + + return std::equal(begin1,std::istreambuf_iterator<char>(),begin2); //Second argument is end-of-range iterator +} int main(int argc, char* argv[]) { hls::stream<net_axis<64> > inFifo64("inFIFO"); @@ -54,122 +90,80 @@ int main(int argc, char* argv[]) { hls::stream<net_axis<64> > outFifoIPv6UDP64("outFifoIPv6UDP64"); hls::stream<net_axis<DATA_WIDTH> > outFifoIPv6UDP("outFifoIPv6UDP"); - std::ifstream inputFile; - std::ifstream goldenFile; - std::ofstream outputFile; ap_uint<32> ipAddress = 0x0a010101; - int errCount = 0; - - /*inputFile.open("../../../../in.dat"); - if (!inputFile) { - cout << "Error: could not open test input file." << endl; - return -1; - } - outputFile.open("../../../../out.dat"); - if (!outputFile) { - cout << "Error: could not open test output file." << endl; - return -1; - } - goldenFile.open("../../../../out.gold"); - if (!goldenFile) { - cerr << " Error opening golden output file!" << endl; - return -1; - }*/ - if (argc < 3) - { - std::cout << "[ERROR] missing arguments." << std::endl; - return -1; - } - - inputFile.open(argv[1]); - if (!inputFile) - { - std::cout << "[ERROR] could not open test rx input file." << std::endl; - return -1; - } - - outputFile.open(argv[2]); - if (!outputFile) - { - std::cout << "[ERROR] could not open test rx output file." << std::endl; - return -1; - } net_axis<64> inWord; int count = 0; - while (scanLE(inputFile, inWord)) { - inFifo64.write(inWord); - ip_handler_top(inFifo, outFifoARP, outFifoICMPv6, outFifoIPv6UDP, outFifoICMP, outFifoUDP, outFifoTCP, outFifoROCE, ipAddress); - - convertStreamWidth<64, 14>(inFifo64, inFifo); - - convertStreamWidth<DATA_WIDTH, 15>(outFifoARP,outFifoARP64); - convertStreamWidth<DATA_WIDTH, 16>(outFifoICMPv6,outFifoICMPv6_64); - convertStreamWidth<DATA_WIDTH, 17>(outFifoIPv6UDP,outFifoIPv6UDP64); - convertStreamWidth<DATA_WIDTH, 18>(outFifoICMP,outFifoICMP64); - convertStreamWidth<DATA_WIDTH, 19>(outFifoUDP,outFifoUDP64); - convertStreamWidth<DATA_WIDTH, 20>(outFifoTCP,outFifoTCP64); - convertStreamWidth<DATA_WIDTH, 21>(outFifoROCE, outFifoROCE64); - - } - while (count < 30000) { - ip_handler_top(inFifo, outFifoARP, outFifoICMPv6, outFifoIPv6UDP, outFifoICMP, outFifoUDP, outFifoTCP, outFifoROCE, ipAddress); - - convertStreamWidth<64, 22>(inFifo64, inFifo); - - convertStreamWidth<DATA_WIDTH, 23>(outFifoARP,outFifoARP64); - convertStreamWidth<DATA_WIDTH, 24>(outFifoICMPv6,outFifoICMPv6_64); - convertStreamWidth<DATA_WIDTH, 25>(outFifoIPv6UDP,outFifoIPv6UDP64); - convertStreamWidth<DATA_WIDTH, 26>(outFifoICMP,outFifoICMP64); - convertStreamWidth<DATA_WIDTH, 27>(outFifoUDP,outFifoUDP64); - convertStreamWidth<DATA_WIDTH, 28>(outFifoTCP,outFifoTCP64); - convertStreamWidth<DATA_WIDTH, 29>(outFifoROCE, outFifoROCE64); - - - count++; - } - - net_axis<64> outWord; - outputFile << "ICMPv6" << std::endl; - while (!outFifoICMPv6_64.empty()) + size_t numFiles = 2; + std::string inputFiles[numFiles] = {"tcp", "udp"}; + for (int i = 0; i < numFiles; i++) { - outFifoICMPv6_64.read(outWord); - print(outputFile, outWord); - outputFile << std::endl; - } - - outputFile << "IPv6 UDP" << std::endl; - while (!outFifoIPv6UDP64.empty()) - { - outFifoIPv6UDP64.read(outWord); - print(outputFile, outWord); - outputFile << std::endl; - } - - outputFile << "ARP" << std::endl; - while (!(outFifoARP64.empty())) { - outFifoARP64.read(outWord); - print(outputFile, outWord); - outputFile << std::endl; - } - outputFile << "ICMP" << std::endl; - while (!(outFifoICMP64.empty())) { - outFifoICMP64.read(outWord); - print(outputFile, outWord); - outputFile << std::endl; - } - outputFile << "UDP" << std::endl; - while (!(outFifoUDP64.empty())) { - outFifoUDP64.read(outWord); - print(outputFile, outWord); - outputFile << std::endl; - } - outputFile << "TCP" << std::endl; - while (!(outFifoTCP64.empty())) { - outFifoTCP64.read(outWord); - print(outputFile, outWord); - outputFile << std::endl; + std::ifstream inputFile; + std::ofstream outputFile; + + inputFile.open(currentDirectory+"/"+inputFiles[i]+".in"); + if (!inputFile) + { + std::cout << "[ERROR] could not open test input file: " << inputFiles[i] << std::endl; + return -1; + } + outputFile.open(currentDirectory+"/"+inputFiles[i]+".out"); + if (!outputFile) + { + std::cout << "[ERROR] could not open test rx output file." << std::endl; + return -1; + } + + std::cout << "Using input file: " << inputFiles[i] << ".in" << std::endl; + + while (scanLE(inputFile, inWord)) + { + inFifo64.write(inWord); + std::cout << "INWORD: "; + printLE(std::cout, inWord); + std::cout << std::endl; + ip_handler<DATA_WIDTH>(inFifo, outFifoARP, outFifoICMPv6, outFifoIPv6UDP, outFifoICMP, outFifoUDP, outFifoTCP, outFifoROCE, ipAddress); + + convertStreamWidth<64, 14>(inFifo64, inFifo); + + convertStreamWidth<DATA_WIDTH, 15>(outFifoARP,outFifoARP64); + convertStreamWidth<DATA_WIDTH, 16>(outFifoICMPv6,outFifoICMPv6_64); + convertStreamWidth<DATA_WIDTH, 17>(outFifoIPv6UDP,outFifoIPv6UDP64); + convertStreamWidth<DATA_WIDTH, 18>(outFifoICMP,outFifoICMP64); + convertStreamWidth<DATA_WIDTH, 19>(outFifoUDP,outFifoUDP64); + convertStreamWidth<DATA_WIDTH, 20>(outFifoTCP,outFifoTCP64); + convertStreamWidth<DATA_WIDTH, 21>(outFifoROCE, outFifoROCE64); + + } + count = 0; + while (count < 30000) { + ip_handler<DATA_WIDTH>(inFifo, outFifoARP, outFifoICMPv6, outFifoIPv6UDP, outFifoICMP, outFifoUDP, outFifoTCP, outFifoROCE, ipAddress); + + convertStreamWidth<64, 22>(inFifo64, inFifo); + + convertStreamWidth<DATA_WIDTH, 23>(outFifoARP,outFifoARP64); + convertStreamWidth<DATA_WIDTH, 24>(outFifoICMPv6,outFifoICMPv6_64); + convertStreamWidth<DATA_WIDTH, 25>(outFifoIPv6UDP,outFifoIPv6UDP64); + convertStreamWidth<DATA_WIDTH, 26>(outFifoICMP,outFifoICMP64); + convertStreamWidth<DATA_WIDTH, 27>(outFifoUDP,outFifoUDP64); + convertStreamWidth<DATA_WIDTH, 28>(outFifoTCP,outFifoTCP64); + convertStreamWidth<DATA_WIDTH, 29>(outFifoROCE, outFifoROCE64); + + + count++; + } + + writeToOutputFile(outputFile, "ICMPv6", outFifoICMPv6_64); + writeToOutputFile(outputFile, "IPv6 UDP", outFifoIPv6UDP64); + writeToOutputFile(outputFile, "ARP", outFifoARP64); + writeToOutputFile(outputFile, "ICMP", outFifoICMP64); + writeToOutputFile(outputFile, "UDP", outFifoUDP64); + writeToOutputFile(outputFile, "TCP", outFifoTCP64); + writeToOutputFile(outputFile, "ICMPv6", outFifoICMPv6_64); + + inputFile.close(); + outputFile.close(); } /*cerr << " done." << endl << endl; if (errCount == 0) { @@ -180,10 +174,42 @@ int main(int argc, char* argv[]) { cerr << endl << endl; return -1; } - inputFile.close(); outputFile.close(); goldenFile.close();*/ - return 0; + //Compare output files with golden files + int errorCount = 0; + for (int i = 0; i < numFiles; i++) + { + /*std::ifstream outputFile; + std::ifstream goldenFile; + outputFile.open(currentDirectory+"/"+inputFiles[i]+".out");*/ + std::string outputFileName = currentDirectory+"/"+inputFiles[i]+".out"; + std::string goldenFileName = currentDirectory+"/"+inputFiles[i]+".gold"; + + /*if (!outputFile) + { + std::cout << "[ERROR] could not open test input file: " << inputFiles[i] << std::endl; + return -1; + } + goldenFile.open(currentDirectory+"/"+inputFiles[i]+".gold"); + if (!outputFile) + { + std::cout << "[ERROR] could not open test rx output file." << std::endl; + return -1; + }*/ + + bool equal = compareFiles(outputFileName, goldenFileName); + if (!equal) + { + std::cout << "[ERROR] files do not match: " << inputFiles[i] << std::endl; + errorCount++; + } + + //outputFile.close(); + //goldenFile.close(); + } + + return errorCount; } diff --git a/hls/ip_handler/udp.gold b/hls/ip_handler/udp.gold new file mode 100644 index 0000000000000000000000000000000000000000..769ba768f78aab7eae4dd809fa8fd61b9de28045 --- /dev/null +++ b/hls/ip_handler/udp.gold @@ -0,0 +1,7 @@ +UDP +45 00 00 30 00 00 00 00 ff 0 +40 11 98 e0 0b 01 d4 d1 ff 0 +01 01 01 0a 48 53 12 b7 ff 0 +00 1c 00 00 11 00 ff ff ff 0 +ff ff aa aa aa aa aa aa ff 0 +aa aa bb bb bb bb bb bb ff 1 diff --git a/hls/ip_handler/udp.in b/hls/ip_handler/udp.in new file mode 100644 index 0000000000000000000000000000000000000000..66843a163948ff90961ae7c8e526d36f1335c4f8 --- /dev/null +++ b/hls/ip_handler/udp.in @@ -0,0 +1,8 @@ +0a 00 ab 89 67 45 23 01 ff 0 +00 45 00 08 e5 9d 02 35 ff 0 +11 40 00 00 00 00 30 00 ff 0 +01 01 d1 d4 01 0b e0 98 ff 0 +1c 00 b7 12 53 48 0a 01 ff 0 +ff ff ff ff 00 11 00 00 ff 0 +aa aa aa aa aa aa aa aa ff 0 +bb bb bb bb bb bb bb bb ff 1 \ No newline at end of file