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