diff --git a/etc/amqp.conf b/etc/amqp.conf
new file mode 100644
index 000000000..4f80aa8d3
--- /dev/null
+++ b/etc/amqp.conf
@@ -0,0 +1,22 @@
+{
+	"nodes" : {
+		"node1" : {
+			"type" : "amqp",
+			"format" : "json",
+
+			"uri" : "amqp://broker",
+
+			"exchange" : "mytestexchange",
+			"routing_key" : "abc",
+		
+			"ssl" : {
+				"verify_hostname" : true,
+				"verify_peer" : true,
+
+				"ca_cert" : "/path/to/ca.crt",
+				"client_cert" : "/path/to/client.crt",
+				"client_key" : "/path/to/client.key"
+			}
+		}
+	}
+}
diff --git a/etc/fpga-simple.conf b/etc/fpga-simple.conf
deleted file mode 100644
index b2e22ed9f..000000000
--- a/etc/fpga-simple.conf
+++ /dev/null
@@ -1,73 +0,0 @@
-/** Example configuration file for VILLASnode.
- *
- * The syntax of this file is similar to JSON.
- * A detailed description of the format can be found here:
- *   http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
- * @license GNU General Public License (version 3)
- *
- * VILLASnode
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *********************************************************************************/
-
-# Some global settings are used by multiple configuration files
-# and therefore defined in separate files
-@include "global.conf"
-@include "plugins.conf"
-
-fpgas = {
-	vc707 = {
-		/* Card identification */
-		id = "10ee:7022";
-		slot = "01:00.0";
-
-		intc  = 0x5000;
-		reset = 0x2000;
-		do_reset = true;
-
-		ips = {
-			switch_0 = {
-				vlnv = "xilinx.com:ip:axis_interconnect:2.1"
-				baseaddr = 0x0000;
-				numports = 3;
-
-				paths = (
-					{ in = "dma_0",  out = "rtds_0" },
-					{ in = "rtds_0", out = "dma_0" }
-				)
-			},
-			rtds_0 = {
-				vlnv = "acs.eonerc.rwth-aachen.de:user:rtds_axis:1.0"
-				baseaddr = 0x3000;
-				port = 0;
-			},
-			dma_0 = {
-				vlnv = "xilinx.com:ip:axi_dma:7.1";
-				baseaddr = 0x1000;
-				port = 2;
-				irq = 0
-			}
-		}
-	}
-}
-
-nodes = {
-	rtds = {
-		datamover = "dma_0";
-		use_irqs = false;
-	}
-}
diff --git a/etc/fpga.conf b/etc/fpga.conf
deleted file mode 100644
index a0f54f06b..000000000
--- a/etc/fpga.conf
+++ /dev/null
@@ -1,168 +0,0 @@
-/** Example configuration file for VILLASfpga / VILLASnode.
- *
- * The syntax of this file is similar to JSON.
- * A detailed description of the format can be found here:
- *   http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
- * @license GNU General Public License (version 3)
- *
- * VILLASnode
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *********************************************************************************/
-
-# Some global settings are used by multiple configuration files
-# and therefore defined in separate files
-@include "global.conf"
-@include "plugins.conf"
-
-############    Dictionary of FPGAs    ############
-
-fpgas = {
-	vc707 = {
-		id = "10ee:7022";		# Card identification
-		slot = "01:00.0";		# Usually only id or slot is required
-
-		do_reset = true;		# Perform a full reset of the FPGA board
-						# Requires a IP core named 'axi_reset_0'
-
-		############   List of IP cores on FPGA   ############
-		#
-		# Every IP core can have the following settings:
-		#  baseaddr	Baseaddress as accessible from BAR0 memory region
-		#  irq		Interrupt index of MSI interrupt controller
-		#  port		Port index of AXI4-Stream interconnect
-
-		ips = {
-			### Utility IPs
-			axi_pcie_intc_0 = {
-				vlnv = "acs.eonerc.rwth-aachen.de:user:axi_pcie_intc:1.0";
-				baseaddr = 0xb000;
-			},
-			switch_0 = {
-				vlnv = "xilinx.com:ip:axis_interconnect:2.1"
-				baseaddr = 0x5000;
-				num_ports = 10;
-
-				paths = (
-			//		{ in = "fifo_mm_s_0",	out = "fifo_mm_s_0" },			# Loopback fifo_mm_s_0
-			//		{ in = "dma_0",		out = "dma_0" },			# Loopback dma_0
-			//		{ in = "dma_1",		out = "dma_1" }				# Loopback dma_1
-			//		{ in = "rtds_axis_0",	out = "fifo_mm_s_0", reverse = true }	# Linux <-> RTDS
-			//		{ in = "rtds_axis_0",	out = "dma_0", reverse = true }		# Linux (dma_0) <-> RTDS
-					{ in = "rtds_axis_0",	out = "dma_1", reverse = true }		# Linux (dma_1) <-> RTDS
-			//		{ in = "rtds_axis_0",	out = "fifo_mm_s_0", reverse = true }	# Linux (fifo_mm_s_0) <-> RTDS
-			//		{ in = "dma_0",		out = "hls_dft_0", reverse = true }	# DFT <-> Linux
-			//		{ in = "rtds_axis_0",	out = "hls_dft_0", reverse = true },	# DFT <-> RTDS
-				)
-			},
-			axi_reset_0 = {
-				vlnv = "xilinx.com:ip:axi_gpio:2.0";
-				baseaddr = 0x7000;
-			},
-			timer_0 = {
-				vlnv = "xilinx.com:ip:axi_timer:2.0";
-				baseaddr = 0x4000;
-				irq = 0;
-			},
-
-			### Data mover IPs
-			dma_0 = {
-				vlnv = "xilinx.com:ip:axi_dma:7.1";
-				baseaddr = 0x3000;
-				port = 1;
-				irq = 3; /* 3 - 4 */
-			},
-			dma_1 = {
-				vlnv = "xilinx.com:ip:axi_dma:7.1";
-				baseaddr = 0x2000;
-				port = 6;
-				irq = 3; /* 3 - 4 */
-			},
-			fifo_mm_s_0 = {
-				vlnv = "xilinx.com:ip:axi_fifo_mm_s:4.1";
-				baseaddr = 0x6000;
-				baseaddr_axi4 = 0xC000;
-				port = 2;
-				irq = 2;
-			},
-
-			### Interface IPs
-			rtds_axis_0 = {
-				vlnv = "acs.eonerc.rwth-aachen.de:user:rtds_axis:1.0";
-				baseaddr = 0x8000;
-				port = 0;
-				irq = 5; /* 5 -7 */
-			},
-
-			### Model IPs
-			hls_dft_0 = {
-				vlnv = "acs.eonerc.rwth-aachen.de:hls:hls_dft:1.0";
-				baseaddr = 0x9000;
-				port = 5;
-				irq = 1;
-
-				period = 400; /* in samples: 20ms / 50uS = 400*/
-				harmonics = [ 0, 1, 3, 5, 7 ]
-				decimation = 0; /* 0 = disabled */
-				//harmonics = [ 0, 1, 2, 5, 22 ]
-			},
-			axis_data_fifo_0 = {
-				vlnv = "xilinx.com:ip:axis_data_fifo:1.1";
-				port = 3;
-			},
-			axis_data_fifo_1 = {
-				vlnv = "xilinx.com:ip:axis_data_fifo:1.1";
-				port = 6;
-			},
-		}
-	}
-}
-
-############    Dictionary of nodes    ############
-
-nodes = {
-	dma_0 = {
-		type = "fpga";				# Datamovers to VILLASfpga
-		datamover = "dma_0";			# Name of IP core in fpga.ips
-		use_irqs = false;			# Use polling or MSI interrupts?
-	},
-	dma_1 = {
-		type = "fpga";
-		datamover = "dma_1";
-		use_irqs = false;
-	},
-	fifo_0 = {
-		type = "fpga";
-		datamover = "fifo_mm_s_0";
-		use_irqs = false;
-	},
-	simple_circuit = {
-		type = "cbuilder";
-		model = "simple_circuit",
-		timestep = 25e-6;			# in seconds
-		parameters = [
-			1.0,				# R2 = 1 Ohm
-			0.001				# C2 = 1000 uF
-		];
-	}
-}
-
-############       List of paths       ############
-
-paths = (
-	{ in = "dma_1", out = "simple_circuit", reverse = true }
-)
diff --git a/etc/influxdb.conf b/etc/influxdb.conf
new file mode 100644
index 000000000..ff1a798a5
--- /dev/null
+++ b/etc/influxdb.conf
@@ -0,0 +1,18 @@
+hugepages = 100
+
+logging = {
+	level = 10
+}
+
+nodes = {
+	influxdb_node = {
+		type = "influxdb",
+		samplelen = 3,
+
+		server = "relaxed_colden:8089",
+		key = "villas",
+		fields = [
+			"a", "b", "c"
+		]
+	}
+}
diff --git a/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_rcrd_v2.conf b/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_rcrd_v2.conf
new file mode 100644
index 000000000..e366009c8
--- /dev/null
+++ b/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_rcrd_v2.conf
@@ -0,0 +1,200 @@
+# configuration file for the setup for integration testing: inl-csu-usc-nrel
+# Test with acs-rtds (nrel), acs-opal1 (csu), acs-opal2 (usc) 
+#
+# host: inl-villas
+# inl devices: inl-rtds73, inl-rtds74, inl-rtds83
+# remote nodes: csu-villas, usc-villas, nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 5.0;
+
+nodes = {
+
+	
+# ss1-ss4 (inl-csu)
+	inl-rtds84 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12084";
+		remote = "141.221.118.84:12084";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+		#remote = "10.10.15.1:12004";  # test with acs-opal
+	}, 
+
+
+	results-ss4 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/ss1ss4_inl-csu_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	},
+
+
+
+# ss1-ss5 (inl-nrel)
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12074";
+		remote = "141.221.118.74:12074";
+	},
+	
+	#ss5 (in demo schematic)
+	nrel-rtds = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12001";  #TODO: this should be changed to 12005, ask nrel
+		remote = "192.174.56.96:12001"; 
+	},
+
+	results-ss5 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/ss1ss5_inl-nrel_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	},
+
+
+# ss1-ss7 (inl-usc)
+	inl-rtds83 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12083";
+		remote = "141.221.118.83:12083";
+	},
+	
+	#ss7 (in demo schematic) 
+	#we have to use two nodes and different ports for usc (some weird behavior of VPN/Firewall)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";  #TODO: the idea is to use ports > 13000 for inl-web, take care to avoid conflict
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	},
+
+	results-ss7 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/ss1ss7_inl-usc_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	}
+
+};
+
+
+############     paths    ############
+
+#we introduce a path for each direction as later we need it for writing to a file
+
+paths = (
+
+# ss1-ss4 (inl-csu) co-simulation interface
+	{
+		in  = "inl-rtds84",
+		out = ["csu-villas", "results-ss4"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "csu-villas",
+		out = "inl-rtds84",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss5 (inl-nrel) co-simulation interface
+	{
+		in  = "inl-rtds74",
+		out = ["nrel-rtds", "results-ss5"]
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "nrel-rtds",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss7 (inl-usc) co-simulation interface
+	{
+		in  = "inl-rtds83",
+		out = ["inl-to-usc-villas", "results-ss7"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-rtds83",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_rcrd_v3.conf b/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_rcrd_v3.conf
new file mode 100644
index 000000000..ed59479c7
--- /dev/null
+++ b/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_rcrd_v3.conf
@@ -0,0 +1,255 @@
+# configuration file for the setup for integration testing: inl-csu-usc-nrel
+# Test with acs-rtds (nrel), acs-opal1 (csu), acs-opal2 (usc) 
+#
+# host: inl-villas
+# inl devices: inl-rtds73, inl-rtds74, inl-rtds83
+# remote nodes: csu-villas, usc-villas, nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 5.0;
+
+nodes = {
+
+# ss1-ss2 (inl-rwth)
+	inl-rtds73 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12073";
+		remote = "141.221.118.73:12073";
+	},
+	
+	#ss2 (in demo schematic)
+	rwth-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12002";
+		remote = "10.10.15.1:12002";
+	}, 
+
+	results-ss2 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/IntegrationTesting_0825/ss1ss2_inl-csu_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	},
+
+	
+# ss1-ss4 (inl-csu)
+	inl-rtds84 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12084";
+		remote = "141.221.118.84:12084";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+		#remote = "10.10.15.1:12004";  # test with acs-opal
+	}, 
+
+
+	results-ss4 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/IntegrationTesting_0825/ss1ss4_inl-csu_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	},
+
+
+
+# ss1-ss5 (inl-nrel)
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12074";
+		remote = "141.221.118.74:12074";
+	},
+	
+	#ss5 (in demo schematic)
+	nrel-rtds = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12001";  #TODO: this should be changed to 12005, ask nrel
+		remote = "192.174.56.96:12001"; 
+	},
+
+	results-ss5 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/IntegrationTesting_0825/ss1ss5_inl-nrel_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	},
+
+
+# ss1-ss7 (inl-usc)
+	inl-rtds83 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12083";
+		remote = "141.221.118.83:12083";
+	},
+	
+	#ss7 (in demo schematic) 
+	#we have to use two nodes and different ports for usc (some weird behavior of VPN/Firewall)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";  #TODO: the idea is to use ports > 13000 for inl-web, take care to avoid conflict
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	},
+
+	results-ss7 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/IntegrationTesting_0825/ss1ss7_inl-usc_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	}
+
+};
+
+
+############     paths    ############
+
+#we introduce a path for each direction as later we need it for writing to a file
+
+paths = (
+
+
+# ss1-ss2 (inl-rwth) co-simulation interface
+	{
+		in  = "inl-rtds73",
+		out = ["rwth-villas", "results-ss2"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "rwth-villas",
+		out = "inl-rtds73",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss4 (inl-csu) co-simulation interface
+	{
+		in  = "inl-rtds84",
+		out = ["csu-villas", "results-ss4"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "csu-villas",
+		out = "inl-rtds84",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss5 (inl-nrel) co-simulation interface
+	{
+		in  = "inl-rtds74",
+		out = ["nrel-rtds", "results-ss5"]
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "nrel-rtds",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss7 (inl-usc) co-simulation interface
+	{
+		in  = "inl-rtds83",
+		out = ["inl-to-usc-villas", "results-ss7"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-rtds83",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_rcrd_v4.conf b/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_rcrd_v4.conf
new file mode 100644
index 000000000..b15f3293f
--- /dev/null
+++ b/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_rcrd_v4.conf
@@ -0,0 +1,255 @@
+# configuration file for the setup for integration testing: inl-csu-usc-nrel
+# Test with acs-rtds (nrel), acs-opal1 (csu), acs-opal2 (usc) 
+#
+# host: inl-villas
+# inl devices: inl-rtds73, inl-rtds74, inl-rtds83
+# remote nodes: csu-villas, usc-villas, nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 5.0;
+
+nodes = {
+
+# ss1-ss2 (inl-rwth)
+	inl-rtds73 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12073";
+		remote = "141.221.118.73:12073";
+	},
+	
+	#ss2 (in demo schematic)
+	rwth-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12002";
+		remote = "10.10.15.1:12002";
+	}, 
+	
+	results-ss2 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/IntegrationTesting_0830/ss1ss2_inl-csu_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	},
+
+	
+# ss1-ss4 (inl-csu)
+	inl-rtds84 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12084";
+		remote = "141.221.118.84:12084";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+		#remote = "10.10.15.1:12004";  # test with acs-opal
+	}, 
+	
+	
+	results-ss4 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/IntegrationTesting_0830/ss1ss4_inl-csu_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	},
+
+
+# ss1-ss5 (inl-nrel)
+	inl-rtds83 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12083";
+		remote = "141.221.118.83:12083";
+	},
+	
+	#ss5 (in demo schematic)
+	nrel-rtds = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12005";  #TODO: this should be changed to 12005, ask nrel
+		remote = "192.174.56.96:12005"; 
+	},
+	
+	
+	
+	results-ss5 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/IntegrationTesting_0830/ss1ss5_inl-nrel_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	},
+
+
+# ss1-ss7 (inl-usc)
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12074";
+		remote = "141.221.118.74:12074";
+	},
+	
+	#ss7 (in demo schematic) 
+	#we have to use two nodes and different ports for usc (some weird behavior of VPN/Firewall)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";  #TODO: the idea is to use ports > 13000 for inl-web, take care to avoid conflict
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	},
+	
+		results-ss7 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/IntegrationTesting_0830/ss1ss7_inl-usc_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	}
+
+
+};
+
+
+############     paths    ############
+
+#we introduce a path for each direction as later we need it for writing to a file
+
+paths = (
+
+# ss1-ss2 (inl-rwth) co-simulation interface
+	{
+		in  = "inl-rtds73",
+		out = ["rwth-villas", "results-ss2"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "rwth-villas",
+		out = "inl-rtds73",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+# ss1-ss4 (inl-csu) co-simulation interface
+	{
+		in  = "inl-rtds84",
+		out = ["csu-villas", "results-ss4"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "csu-villas",
+		out = "inl-rtds84",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss5 (inl-nrel) co-simulation interface
+	{
+		in  = "inl-rtds83",
+		out = ["nrel-rtds", "results-ss5"]
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "nrel-rtds",
+		out = "inl-rtds83",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss7 (inl-usc) co-simulation interface
+	{
+		in  = "inl-rtds74",
+		out = ["inl-to-usc-villas", "results-ss7"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_v2.conf b/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_v2.conf
new file mode 100644
index 000000000..6d75fbf91
--- /dev/null
+++ b/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_v2.conf
@@ -0,0 +1,171 @@
+# configuration file for the setup for integration testing: inl-csu-usc-nrel
+# Test with acs-rtds (nrel), acs-opal1 (csu), acs-opal2 (usc) 
+#
+# host: inl-villas
+# inl devices: inl-rtds73, inl-rtds74, inl-rtds83
+# remote nodes: csu-villas, usc-villas, nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 5.0;
+
+nodes = {
+
+	
+# ss1-ss4 (inl-csu)
+	inl-rtds84 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12084";
+		remote = "141.221.118.84:12084";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+		#remote = "10.10.15.1:12004";  # test with acs-opal
+	}, 
+
+
+# ss1-ss5 (inl-nrel)
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12074";
+		remote = "141.221.118.74:12074";
+	},
+	
+	#ss5 (in demo schematic)
+	nrel-rtds = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12001";  #TODO: this should be changed to 12005, ask nrel
+		remote = "192.174.56.96:12001"; 
+	},
+
+
+# ss1-ss7 (inl-usc)
+	inl-rtds83 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12083";
+		remote = "141.221.118.83:12083";
+	},
+	
+	#ss7 (in demo schematic) 
+	#we have to use two nodes and different ports for usc (some weird behavior of VPN/Firewall)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";  #TODO: the idea is to use ports > 13000 for inl-web, take care to avoid conflict
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	}
+
+};
+
+
+############     paths    ############
+
+#we introduce a path for each direction as later we need it for writing to a file
+
+paths = (
+
+# ss1-ss4 (inl-csu) co-simulation interface
+	{
+		in  = "inl-rtds84",
+		out = "csu-villas", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "csu-villas",
+		out = "inl-rtds84",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss5 (inl-nrel) co-simulation interface
+	{
+		in  = "inl-rtds74",
+		out = "nrel-rtds", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "nrel-rtds",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss7 (inl-usc) co-simulation interface
+	{
+		in  = "inl-rtds83",
+		out = "inl-to-usc-villas", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-rtds83",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_v3.conf b/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_v3.conf
new file mode 100644
index 000000000..40683bd67
--- /dev/null
+++ b/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_v3.conf
@@ -0,0 +1,215 @@
+# configuration file for the setup for integration testing: inl-csu-usc-nrel
+# Test with acs-rtds (nrel), acs-opal1 (csu), acs-opal2 (usc) 
+#
+# host: inl-villas
+# inl devices: inl-rtds73, inl-rtds74, inl-rtds83
+# remote nodes: csu-villas, usc-villas, nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 5.0;
+
+nodes = {
+
+# ss1-ss2 (inl-rwth)
+	inl-rtds73 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12073";
+		remote = "141.221.118.73:12073";
+	},
+	
+	#ss2 (in demo schematic)
+	rwth-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12002";
+		remote = "10.10.15.1:12002";
+	}, 
+
+	
+# ss1-ss4 (inl-csu)
+	inl-rtds84 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12084";
+		remote = "141.221.118.84:12084";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+		#remote = "10.10.15.1:12004";  # test with acs-opal
+	}, 
+
+
+# ss1-ss5 (inl-nrel)
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12074";
+		remote = "141.221.118.74:12074";
+	},
+	
+	#ss5 (in demo schematic)
+	nrel-rtds = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12001";  #TODO: this should be changed to 12005, ask nrel
+		remote = "192.174.56.96:12001"; 
+	},
+
+
+# ss1-ss7 (inl-usc)
+	inl-rtds83 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12083";
+		remote = "141.221.118.83:12083";
+	},
+	
+	#ss7 (in demo schematic) 
+	#we have to use two nodes and different ports for usc (some weird behavior of VPN/Firewall)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";  #TODO: the idea is to use ports > 13000 for inl-web, take care to avoid conflict
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	}
+
+};
+
+
+############     paths    ############
+
+#we introduce a path for each direction as later we need it for writing to a file
+
+paths = (
+
+# ss1-ss2 (inl-rwth) co-simulation interface
+	{
+		in  = "inl-rtds73",
+		out = "rwth-villas", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "rwth-villas",
+		out = "inl-rtds73",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+# ss1-ss4 (inl-csu) co-simulation interface
+	{
+		in  = "inl-rtds84",
+		out = "csu-villas", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "csu-villas",
+		out = "inl-rtds84",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss5 (inl-nrel) co-simulation interface
+	{
+		in  = "inl-rtds74",
+		out = "nrel-rtds", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "nrel-rtds",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss7 (inl-usc) co-simulation interface
+	{
+		in  = "inl-rtds83",
+		out = "inl-to-usc-villas", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-rtds83",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_v4.conf b/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_v4.conf
new file mode 100644
index 000000000..b4457a20c
--- /dev/null
+++ b/etc/inl/IntegrationTesting/inl-integration-csu-nrel-usc_v4.conf
@@ -0,0 +1,215 @@
+# configuration file for the setup for integration testing: inl-csu-usc-nrel
+# Test with acs-rtds (nrel), acs-opal1 (csu), acs-opal2 (usc) 
+#
+# host: inl-villas
+# inl devices: inl-rtds73, inl-rtds74, inl-rtds83
+# remote nodes: csu-villas, usc-villas, nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 5.0;
+
+nodes = {
+
+# ss1-ss2 (inl-rwth)
+	inl-rtds73 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12073";
+		remote = "141.221.118.73:12073";
+	},
+	
+	#ss2 (in demo schematic)
+	rwth-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12002";
+		remote = "10.10.15.1:12002";
+	}, 
+
+	
+# ss1-ss4 (inl-csu)
+	inl-rtds84 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12084";
+		remote = "141.221.118.84:12084";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+		#remote = "10.10.15.1:12004";  # test with acs-opal
+	}, 
+
+
+# ss1-ss5 (inl-nrel)
+	inl-rtds83 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12083";
+		remote = "141.221.118.83:12083";
+	},
+	
+	#ss5 (in demo schematic)
+	nrel-rtds = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12005";  #TODO: this should be changed to 12005, ask nrel
+		remote = "192.174.56.96:12005"; 
+	},
+
+
+# ss1-ss7 (inl-usc)
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12074";
+		remote = "141.221.118.74:12074";
+	},
+	
+	#ss7 (in demo schematic) 
+	#we have to use two nodes and different ports for usc (some weird behavior of VPN/Firewall)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";  #TODO: the idea is to use ports > 13000 for inl-web, take care to avoid conflict
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	}
+
+};
+
+
+############     paths    ############
+
+#we introduce a path for each direction as later we need it for writing to a file
+
+paths = (
+
+# ss1-ss2 (inl-rwth) co-simulation interface
+	{
+		in  = "inl-rtds73",
+		out = "rwth-villas", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "rwth-villas",
+		out = "inl-rtds73",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+# ss1-ss4 (inl-csu) co-simulation interface
+	{
+		in  = "inl-rtds84",
+		out = "csu-villas", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "csu-villas",
+		out = "inl-rtds84",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss5 (inl-nrel) co-simulation interface
+	{
+		in  = "inl-rtds83",
+		out = "nrel-rtds", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "nrel-rtds",
+		out = "inl-rtds83",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss7 (inl-usc) co-simulation interface
+	{
+		in  = "inl-rtds74",
+		out = "inl-to-usc-villas", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/IntegrationTesting/old/inl-integration-acs-prelim-csu.conf b/etc/inl/IntegrationTesting/old/inl-integration-acs-prelim-csu.conf
new file mode 100644
index 000000000..05ff56fe6
--- /dev/null
+++ b/etc/inl/IntegrationTesting/old/inl-integration-acs-prelim-csu.conf
@@ -0,0 +1,171 @@
+# configuration file for the setup for integration testing: inl-csu-usc-nrel
+# Test with acs-rtds (nrel), acs-opal1 (csu), acs-opal2 (usc) 
+#
+# host: inl-villas
+# inl devices: inl-rtds73, inl-rtds74, inl-rtds83
+# remote nodes: csu-villas, usc-villas, nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 5.0;
+
+nodes = {
+
+	
+# ss1-ss4 (inl-csu)
+	inl-rtds73 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12073";
+		remote = "141.221.118.73:12073";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+		#remote = "10.10.15.1:12004";  # test with acs-opal
+	}, 
+
+
+# ss1-ss5 (inl-nrel)
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12074";
+		remote = "141.221.118.74:12074";
+	},
+	
+	#ss5 (in demo schematic)
+	nrel-rtds = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12001";  #TODO: this should be changed to 12005, ask nrel
+		remote = "192.174.56.96:12001"; 
+	},
+
+
+# ss1-ss7 (inl-usc)
+	inl-rtds83 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12083";
+		remote = "141.221.118.83:12083";
+	},
+	
+	#ss7 (in demo schematic) 
+	#we have to use two nodes and different ports for usc (some weird behavior of VPN/Firewall)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";  #TODO: the idea is to use ports > 13000 for inl-web, take care to avoid conflict
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	}
+
+};
+
+
+############     paths    ############
+
+#we introduce a path for each direction as later we need it for writing to a file
+
+paths = (
+
+# ss1-ss4 (inl-csu) co-simulation interface
+	{
+		in  = "inl-rtds73",
+		out = "csu-villas", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "csu-villas",
+		out = "inl-rtds73",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss5 (inl-nrel) co-simulation interface
+	{
+		in  = "inl-rtds74",
+		out = "nrel-rtds", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "nrel-rtds",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss7 (inl-usc) co-simulation interface
+	{
+		in  = "inl-rtds83",
+		out = "inl-to-usc-villas", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-rtds83",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/IntegrationTesting/old/inl-integration-csu-nrel-usc.conf b/etc/inl/IntegrationTesting/old/inl-integration-csu-nrel-usc.conf
new file mode 100644
index 000000000..05ff56fe6
--- /dev/null
+++ b/etc/inl/IntegrationTesting/old/inl-integration-csu-nrel-usc.conf
@@ -0,0 +1,171 @@
+# configuration file for the setup for integration testing: inl-csu-usc-nrel
+# Test with acs-rtds (nrel), acs-opal1 (csu), acs-opal2 (usc) 
+#
+# host: inl-villas
+# inl devices: inl-rtds73, inl-rtds74, inl-rtds83
+# remote nodes: csu-villas, usc-villas, nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 5.0;
+
+nodes = {
+
+	
+# ss1-ss4 (inl-csu)
+	inl-rtds73 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12073";
+		remote = "141.221.118.73:12073";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+		#remote = "10.10.15.1:12004";  # test with acs-opal
+	}, 
+
+
+# ss1-ss5 (inl-nrel)
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12074";
+		remote = "141.221.118.74:12074";
+	},
+	
+	#ss5 (in demo schematic)
+	nrel-rtds = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12001";  #TODO: this should be changed to 12005, ask nrel
+		remote = "192.174.56.96:12001"; 
+	},
+
+
+# ss1-ss7 (inl-usc)
+	inl-rtds83 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12083";
+		remote = "141.221.118.83:12083";
+	},
+	
+	#ss7 (in demo schematic) 
+	#we have to use two nodes and different ports for usc (some weird behavior of VPN/Firewall)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";  #TODO: the idea is to use ports > 13000 for inl-web, take care to avoid conflict
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	}
+
+};
+
+
+############     paths    ############
+
+#we introduce a path for each direction as later we need it for writing to a file
+
+paths = (
+
+# ss1-ss4 (inl-csu) co-simulation interface
+	{
+		in  = "inl-rtds73",
+		out = "csu-villas", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "csu-villas",
+		out = "inl-rtds73",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss5 (inl-nrel) co-simulation interface
+	{
+		in  = "inl-rtds74",
+		out = "nrel-rtds", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "nrel-rtds",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss7 (inl-usc) co-simulation interface
+	{
+		in  = "inl-rtds83",
+		out = "inl-to-usc-villas", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-rtds83",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/IntegrationTesting/old/inl-integration-csu-nrel-usc_rcrd.conf b/etc/inl/IntegrationTesting/old/inl-integration-csu-nrel-usc_rcrd.conf
new file mode 100644
index 000000000..6ffaf311d
--- /dev/null
+++ b/etc/inl/IntegrationTesting/old/inl-integration-csu-nrel-usc_rcrd.conf
@@ -0,0 +1,200 @@
+# configuration file for the setup for integration testing: inl-csu-usc-nrel
+# Test with acs-rtds (nrel), acs-opal1 (csu), acs-opal2 (usc) 
+#
+# host: inl-villas
+# inl devices: inl-rtds73, inl-rtds74, inl-rtds83
+# remote nodes: csu-villas, usc-villas, nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 5.0;
+
+nodes = {
+
+	
+# ss1-ss4 (inl-csu)
+	inl-rtds73 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12073";
+		remote = "141.221.118.73:12073";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+		#remote = "10.10.15.1:12004";  # test with acs-opal
+	}, 
+
+
+	results-ss4 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/ss1ss4_inl-csu_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	},
+
+
+
+# ss1-ss5 (inl-nrel)
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12074";
+		remote = "141.221.118.74:12074";
+	},
+	
+	#ss5 (in demo schematic)
+	nrel-rtds = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12001";  #TODO: this should be changed to 12005, ask nrel
+		remote = "192.174.56.96:12001"; 
+	},
+
+	results-ss5 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/ss1ss5_inl-nrel_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	},
+
+
+# ss1-ss7 (inl-usc)
+	inl-rtds83 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12083";
+		remote = "141.221.118.83:12083";
+	},
+	
+	#ss7 (in demo schematic) 
+	#we have to use two nodes and different ports for usc (some weird behavior of VPN/Firewall)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";  #TODO: the idea is to use ports > 13000 for inl-web, take care to avoid conflict
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	},
+
+	results-ss7 = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/IntegrationTesting/ss1ss7_inl-usc_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	}
+
+};
+
+
+############     paths    ############
+
+#we introduce a path for each direction as later we need it for writing to a file
+
+paths = (
+
+# ss1-ss4 (inl-csu) co-simulation interface
+	{
+		in  = "inl-rtds73",
+		out = ["csu-villas", "results-ss4"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "csu-villas",
+		out = "inl-rtds73",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss5 (inl-nrel) co-simulation interface
+	{
+		in  = "inl-rtds74",
+		out = ["nrel-rtds", "results-ss5"]
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "nrel-rtds",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+
+# ss1-ss7 (inl-usc) co-simulation interface
+	{
+		in  = "inl-rtds83",
+		out = ["inl-to-usc-villas", "results-ss7"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-rtds83",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/NREL/inl-nrel-cosim.conf b/etc/inl/NREL/inl-nrel-cosim.conf
new file mode 100644
index 000000000..f12c9e862
--- /dev/null
+++ b/etc/inl/NREL/inl-nrel-cosim.conf
@@ -0,0 +1,70 @@
+# configuration file for the setup for integration testing: inl-csu-usc-nrel
+# Test with acs-rtds (nrel), acs-opal1 (csu), acs-opal2 (usc) 
+#
+# host: inl-villas
+# inl devices: inl-rtds73, inl-rtds74, inl-rtds83
+# remote nodes: csu-villas, usc-villas, nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 5.0;
+
+nodes = {
+
+
+# ss1-ss5 (inl-nrel)
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12074";
+		remote = "141.221.118.74:12074";
+	},
+	
+	#ss5 (in demo schematic)
+	nrel-rtds = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12001";  #TODO: this should be changed to 12005, ask nrel
+		remote = "192.174.56.96:12001"; 
+	}
+
+};
+
+
+############     paths    ############
+
+#we introduce a path for each direction as later we need it for writing to a file
+
+paths = (
+
+# ss1-ss5 (inl-nrel) co-simulation interface
+	{
+		in  = "inl-rtds74",
+		out = "nrel-rtds", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "nrel-rtds",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/NREL/inl-nrel-cosim_v5.conf b/etc/inl/NREL/inl-nrel-cosim_v5.conf
new file mode 100644
index 000000000..3fd65e8a7
--- /dev/null
+++ b/etc/inl/NREL/inl-nrel-cosim_v5.conf
@@ -0,0 +1,70 @@
+# configuration file for the setup for integration testing: inl-csu-usc-nrel
+# Test with acs-rtds (nrel), acs-opal1 (csu), acs-opal2 (usc) 
+#
+# host: inl-villas
+# inl devices: inl-rtds73, inl-rtds74, inl-rtds83
+# remote nodes: csu-villas, usc-villas, nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 5.0;
+
+nodes = {
+
+
+# ss1-ss5 (inl-nrel)
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12074";
+		remote = "141.221.118.74:12074";
+	},
+	
+	#ss5 (in demo schematic)
+	nrel-rtds = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12005";  #TODO: this should be changed to 12005, ask nrel
+		remote = "192.174.56.96:12005"; 
+	}
+
+};
+
+
+############     paths    ############
+
+#we introduce a path for each direction as later we need it for writing to a file
+
+paths = (
+
+# ss1-ss5 (inl-nrel) co-simulation interface
+	{
+		in  = "inl-rtds74",
+		out = "nrel-rtds", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "nrel-rtds",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/cosim/inl-cosim-acs.conf b/etc/inl/cosim/inl-cosim-acs.conf
new file mode 100644
index 000000000..65b8adbe0
--- /dev/null
+++ b/etc/inl/cosim/inl-cosim-acs.conf
@@ -0,0 +1,63 @@
+# configuration file for co-simulation setup acs-inl: inl-rtds - inl-villas -- acs-villas - acs-rtds
+# 
+# host: inl-villas
+# inl devices: inl-rtds11
+# remote nodes: acs-villas
+#
+
+
+############     nodes    ############
+
+stats = 1.0;
+
+nodes = {
+
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12074";
+		remote = "141.221.118.74:12074";
+	}
+
+	
+	#ss2(in demo schematic)
+	acs-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12002";
+		remote = "10.10.15.1:12002";
+	}
+
+};
+
+
+############     paths    ############
+
+paths = (
+	{
+		in  = "inl-rtds74",
+		out = "acs-villas",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "acs-villas",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/cosim/inl-cosim-acs_rcrd.conf b/etc/inl/cosim/inl-cosim-acs_rcrd.conf
new file mode 100644
index 000000000..9085f433a
--- /dev/null
+++ b/etc/inl/cosim/inl-cosim-acs_rcrd.conf
@@ -0,0 +1,73 @@
+# configuration file for co-simulation setup acs-inl: inl-rtds - inl-villas -- acs-villas - acs-rtds
+# 
+# host: inl-villas
+# inl devices: inl-rtds11
+# remote nodes: acs-villas
+#
+
+
+############     nodes    ############
+
+stats = 0.1;
+
+nodes = {
+
+	inl-rtds11 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.74:12011";
+	}
+
+	
+	#ss2(in demo schematic)
+	acs-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12002";
+		remote = "10.10.15.1:12002";
+	},
+
+
+	results = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/cosim_generic/acs-inl/test_rcrd/ssA_cosim_inl-acs_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				#flush = false,
+				mode = "w+"
+			}
+	}
+
+};
+
+
+############     paths    ############
+
+paths = (
+	{
+		in  = "inl-rtds11",
+		out = ["acs-villas", "results"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "acs-villas",
+		out = "inl-rtds11",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/cosim/inl-cosim-acs_rcrd_tmp.conf b/etc/inl/cosim/inl-cosim-acs_rcrd_tmp.conf
new file mode 100644
index 000000000..a6f98ca24
--- /dev/null
+++ b/etc/inl/cosim/inl-cosim-acs_rcrd_tmp.conf
@@ -0,0 +1,73 @@
+# configuration file for co-simulation setup acs-inl: inl-rtds - inl-villas -- acs-villas - acs-rtds
+# 
+# host: inl-villas
+# inl devices: inl-rtds11
+# remote nodes: acs-villas
+#
+
+
+############     nodes    ############
+
+stats = 0.1;
+
+nodes = {
+
+	inl-rtds11 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.74:12011";
+	}
+
+	
+	#ss2(in demo schematic)
+	acs-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12002";
+		remote = "10.10.15.1:12002";
+	},
+
+
+	results = {
+		type = "file",
+			out = {
+				uri = "tmp/rtsuperlab/acs-inl/test_rcrd/ssA_cosim_inl-acs_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				#flush = false,
+				mode = "w+"
+			}
+	}
+
+};
+
+
+############     paths    ############
+
+paths = (
+	{
+		in  = "inl-rtds11",
+		out = ["acs-villas", "results"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "acs-villas",
+		out = "inl-rtds11",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/cosim/inl-cosim-csu.conf b/etc/inl/cosim/inl-cosim-csu.conf
new file mode 100644
index 000000000..d79f31aac
--- /dev/null
+++ b/etc/inl/cosim/inl-cosim-csu.conf
@@ -0,0 +1,56 @@
+# configuration file
+# host: inl-villas
+# inl devices: inl-rtds83
+# remote nodes: csu-villas
+# Test: rtds - VILLASnode - VILLASnode - opal
+#
+#
+############     nodes    ############
+
+stats = 1.0;
+http = {enabled = false}
+
+nodes = {
+
+	inl-rtds83 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12083";
+		remote = "141.221.118.83:12083";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+	}
+};
+
+paths = (
+	{
+		in  = "inl-rtds83",
+		out = "csu-villas"
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000
+			#format = "json"
+			}
+		)
+       },
+
+	{
+		in  = "csu-villas",
+		out = "inl-rtds83",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000
+			#format = "json"
+			}
+		)
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/cosim/inl-cosim-csu_rcrd.conf b/etc/inl/cosim/inl-cosim-csu_rcrd.conf
new file mode 100644
index 000000000..2c5f87f04
--- /dev/null
+++ b/etc/inl/cosim/inl-cosim-csu_rcrd.conf
@@ -0,0 +1,68 @@
+# configuration file
+# host: inl-villas
+# inl devices: inl-rtds11
+# remote nodes: csu-villas
+# Test: rtds - VILLASnode - VILLASnode - opal
+#
+#
+############     nodes    ############
+
+stats = 1.0;
+http = {enabled = false}
+
+
+nodes = {
+
+	inl-rtds83 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12083";
+		remote = "141.221.118.83:12083";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+	},
+
+	results = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/cosim_wscc_ssX/csu-inl/test1/ss1_cosim_inl-csu_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	}
+
+
+};
+
+paths = (
+	{
+		in  = "inl-rtds83", 
+		out = ["csu-villas", "results"]
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000
+			#format = "json"
+			}
+		)
+       },
+
+	{
+		in  = "csu-villas",
+		out = "inl-rtds83",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000
+			#format = "json"
+			}
+		)
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/cosim/inl-cosim-fsu.conf b/etc/inl/cosim/inl-cosim-fsu.conf
new file mode 100644
index 000000000..692ff779f
--- /dev/null
+++ b/etc/inl/cosim/inl-cosim-fsu.conf
@@ -0,0 +1,59 @@
+# configuration file for co-simulation setup fsu-inl: inl-rtds - inl-villas -- fsu-villas - fsu-rtds
+# 
+# host: fsu-villas
+# inl devices: fsu-rtds11
+# remote nodes: fsu-villas
+
+
+############     nodes    ############
+
+stats = 0.1;
+
+nodes = {
+
+	inl-rtds11 = {
+		#Card 3, Port 1
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.74:12011";
+	}
+	
+	#ss8 (in demo schematic)
+	fsu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12008";
+		remote = "10.146.64.3:12008";
+	}
+
+};
+
+paths = (
+	{
+		in  = "inl-rtds11",
+		out = "fsu-villas",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "fsu-villas",
+		out = "inl-rtds11",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/cosim/inl-cosim-fsu_rcrd.conf b/etc/inl/cosim/inl-cosim-fsu_rcrd.conf
new file mode 100644
index 000000000..69d3c861c
--- /dev/null
+++ b/etc/inl/cosim/inl-cosim-fsu_rcrd.conf
@@ -0,0 +1,68 @@
+# configuration file for co-simulation setup fsu-inl: inl-rtds - inl-villas -- fsu-villas - fsu-rtds
+# 
+# host: fsu-villas
+# inl devices: fsu-rtds11
+# remote nodes: fsu-villas
+
+
+############     nodes    ############
+
+stats = 0.1;
+
+nodes = {
+
+	inl-rtds11 = {
+		#Card 3, Port 1
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.74:12011";
+	}
+	
+	#ss8 (in demo schematic)
+	fsu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12008";
+		remote = "10.146.64.3:12008";
+	},
+
+	results = {
+		type = "file",
+			out = {
+				uri = "rtsuperlab/cosim_generic/fsu-inl/test2/ssA_cosim_inl-fsu_%Y%m%d_%H-%M-%S.csv", # start the file name with ssN (id of subsystem that DRTS in your labsimulates)
+				flush = false,
+				mode = "w+"
+			}
+	}
+
+};
+
+paths = (
+	{
+		in  = "inl-rtds11",
+		out = ["fsu-villas", "results"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "fsu-villas",
+		out = "inl-rtds11",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/cosim/inl-cosim-nrel.conf b/etc/inl/cosim/inl-cosim-nrel.conf
new file mode 100644
index 000000000..d0c341b65
--- /dev/null
+++ b/etc/inl/cosim/inl-cosim-nrel.conf
@@ -0,0 +1,64 @@
+# configuration file for co-simulation setup acs-inl: inl-rtds - inl-villas -- acs-villas - acs-rtds
+# 
+# host: inl-villas
+# inl devices: inl-rtds11
+# remote nodes: nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 1.0;
+
+nodes = {
+
+	inl-rtds74 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.74:12011";
+	},
+
+	
+	#ss?(in demo schematic)
+	nrel-rtds = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12001";
+		remote = "192.174.56.96:12001";
+	}
+
+};
+
+
+############     paths    ############
+
+paths = (
+	{
+		in  = "inl-rtds74",
+		out = "nrel-rtds",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "nrel-rtds",
+		out = "inl-rtds74",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/cosim/inl-cosim-usc-opal_2.conf b/etc/inl/cosim/inl-cosim-usc-opal_2.conf
new file mode 100644
index 000000000..8fa85c8a1
--- /dev/null
+++ b/etc/inl/cosim/inl-cosim-usc-opal_2.conf
@@ -0,0 +1,68 @@
+# configuration file
+# host: inl-villas
+# remote nodes:usc-villas
+#
+#
+############     nodes    ############
+
+http = {enabled = false};
+
+stats = 1.0;
+
+nodes = {
+	
+	
+	inl-rtds83 = {
+		#Card 3, Port 1
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12083";
+		remote = "141.221.118.83:12083";
+	},
+
+	#ss7 (in demo schematic)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	}
+	
+};
+
+paths = (
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-rtds83",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+       },
+
+	{
+		in  = "inl-rtds83",
+		out = "inl-to-usc-villas",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+       }
+);
+
+
+
diff --git a/etc/inl/cosim/inl-rtds-opal.conf b/etc/inl/cosim/inl-rtds-opal.conf
new file mode 100644
index 000000000..dba7108b1
--- /dev/null
+++ b/etc/inl/cosim/inl-rtds-opal.conf
@@ -0,0 +1,65 @@
+# configuration file for the setup for integration testing: inl-csu-usc-nrel
+# Test with acs-rtds (nrel), acs-opal1 (csu), acs-opal2 (usc) 
+#
+# host: inl-villas
+# inl devices: inl-rtds73, inl-rtds74, inl-rtds83
+# remote nodes: csu-villas, usc-villas, nrel-rtds
+#
+
+
+############     nodes    ############
+
+stats = 1.0;
+
+nodes = {
+
+	inl-rtds73 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12073";
+		remote = "141.221.118.74:12073";
+	},
+
+	
+	inl-opal = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12099";
+		remote = "141.221.118.109:12099"	
+	} 
+
+};
+
+
+############     paths    ############
+
+paths = (
+
+	#inl-csu co-simulation interface
+	{
+		in  = "inl-rtds73",
+		out = "inl-opal", 
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "inl-opal",
+		out = "inl-rtds73",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/fsu-issue/inl-rtds-polito_fsuIssueSKT17.conf b/etc/inl/fsu-issue/inl-rtds-polito_fsuIssueSKT17.conf
new file mode 100644
index 000000000..b4c0b0315
--- /dev/null
+++ b/etc/inl/fsu-issue/inl-rtds-polito_fsuIssueSKT17.conf
@@ -0,0 +1,61 @@
+# configuration file
+# host: inl-villas
+# inl devices: inl-rtds11, inl-rtds21
+# remote nodes: acs-villas, polito_villas, csu-villas
+#
+#
+############     nodes    ############
+
+stats = 0.1;
+
+nodes = {
+
+	
+	inl-rtds12 = {
+		#SKT 1.17
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.73:12011";
+	},
+	
+	
+	#ss3 (in demo schematic)
+	polito-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12003";
+		remote = "130.192.95.241:12003";
+	}
+};
+
+paths = (
+	{
+		in  = "inl-rtds12",
+		out = "polito-villas",
+        	#reverse = true,
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			verbose = true, 
+			format = "json"
+			}
+		)
+       },
+
+	{
+		in  = "polito-villas",
+		out = "inl-rtds12",
+        	#reverse = true,
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			verbose = true, 
+			format = "json"
+			}
+		)
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/fsu-issue/inl-rtds-polito_fsuIssueSKT18.conf b/etc/inl/fsu-issue/inl-rtds-polito_fsuIssueSKT18.conf
new file mode 100644
index 000000000..8e6471fdd
--- /dev/null
+++ b/etc/inl/fsu-issue/inl-rtds-polito_fsuIssueSKT18.conf
@@ -0,0 +1,60 @@
+# configuration file
+# host: inl-villas
+# inl devices: inl-rtds11, inl-rtds21
+# remote nodes: acs-villas, polito_villas, csu-villas
+#
+#
+############     nodes    ############
+
+stats = 0.1;
+
+nodes = {
+
+	inl-rtds11 = {
+		#SKT 1.18
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.74:12011";
+	},
+	
+	
+	#ss3 (in demo schematic)
+	polito-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12003";
+		remote = "130.192.95.241:12003";
+	}
+};
+
+paths = (
+	{
+		in  = "inl-rtds11",
+		out = "polito-villas",
+        	#reverse = true,
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			verbose = true, 
+			format = "json"
+			}
+		)
+       },
+
+	{
+		in  = "polito-villas",
+		out = "inl-rtds11",
+        	#reverse = true,
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			verbose = true, 
+			format = "json"
+			}
+		)
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/fsu-issue/inl-rtds_fsuIssueSKT17.conf b/etc/inl/fsu-issue/inl-rtds_fsuIssueSKT17.conf
new file mode 100644
index 000000000..d5ec57e42
--- /dev/null
+++ b/etc/inl/fsu-issue/inl-rtds_fsuIssueSKT17.conf
@@ -0,0 +1,38 @@
+# configuration file
+# host: inl-villas
+# inl devices: inl-rtds11, inl-rtds21
+# remote nodes: acs-villas, polito_villas, csu-villas
+#
+#
+############     nodes    ############
+
+stats = 0.1;
+
+nodes = {
+
+	
+	inl-rtds12 = {
+		#SKT 1.17
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.73:12011";
+	}
+};
+
+paths = (
+	{
+		in  = "inl-rtds12",
+		out = "inl-rtds12",
+        	#reverse = true,
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			verbose = true, 
+			format = "json"
+			}
+		)
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/fsu-issue/inl-rtds_fsuIssueSKT18.conf b/etc/inl/fsu-issue/inl-rtds_fsuIssueSKT18.conf
new file mode 100644
index 000000000..1c297dcdd
--- /dev/null
+++ b/etc/inl/fsu-issue/inl-rtds_fsuIssueSKT18.conf
@@ -0,0 +1,36 @@
+# configuration file
+# host: inl-villas
+# inl devices: inl-rtds11, inl-rtds21
+# remote nodes: acs-villas, polito_villas, csu-villas
+#
+#
+############     nodes    ############
+
+stats = 0.1;
+
+nodes = {
+
+	inl-rtds11 = {
+		#SKT 1.18
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.74:12011";
+	}
+};
+
+paths = (
+	{
+		in  = "inl-rtds11",
+		out = "inl-rtds11",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			verbose = true, 
+			format = "json"
+			}
+		)
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/inl-TestCommSS1-villasweb.conf b/etc/inl/inl-TestCommSS1-villasweb.conf
new file mode 100644
index 000000000..ad02790be
--- /dev/null
+++ b/etc/inl/inl-TestCommSS1-villasweb.conf
@@ -0,0 +1,48 @@
+# configuration file 
+# 
+# host: inl-villas
+
+#
+
+
+############     nodes    ############
+
+stats = 1.0;
+
+nodes = {
+
+	inl-rtds73 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12073";
+		remote = "141.221.118.73:12073";
+	},
+
+
+	inl-web = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12022";
+		remote = "141.221.118.94:12022";
+	}
+
+};
+
+
+############     paths    ############
+
+paths = (
+	{
+		in  = "inl-rtds73",
+		out =  "inl-web",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/inl-cosim-acs-villasweb.conf b/etc/inl/inl-cosim-acs-villasweb.conf
new file mode 100644
index 000000000..b04dc120b
--- /dev/null
+++ b/etc/inl/inl-cosim-acs-villasweb.conf
@@ -0,0 +1,70 @@
+# configuration file for co-simulation setup acs-inl: inl-rtds - inl-villas -- acs-villas - acs-rtds
+# 
+# host: inl-villas
+# inl devices: inl-rtds11
+# remote nodes: acs-villas
+#
+
+
+############     nodes    ############
+
+stats = 1.0;
+
+nodes = {
+
+	inl-rtds11 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.74:12011";
+	},
+
+
+	inl-web = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12022";
+		remote = "141.221.118.94:12022";
+	},	
+
+	#ss2(in demo schematic)
+	acs-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12002";
+		remote = "10.10.15.1:12002";
+	}
+
+};
+
+
+############     paths    ############
+
+paths = (
+	{
+		in  = "inl-rtds11",
+		out = ["acs-villas","inl-web"],
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       },
+
+	{
+		in  = "acs-villas",
+		out = "inl-rtds11",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/inl/inl-opal-villas-picard.conf b/etc/inl/inl/inl-opal-villas-picard.conf
new file mode 100644
index 000000000..23a25f0ae
--- /dev/null
+++ b/etc/inl/inl/inl-opal-villas-picard.conf
@@ -0,0 +1,61 @@
+# configuration file
+# host: inl-villas
+# remote nodes:inl-opal
+#
+#
+############     nodes    ############
+
+http = {enabled = false}
+
+stats = 1.0;
+
+nodes = {
+	
+	inl-opal = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12109";
+		remote = "141.221.118.109:12109";
+	},
+
+	inl-picard160 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12160";
+		remote = "141.221.118.160:5000";
+	}
+	
+};
+
+paths = (
+	{
+		in  = "inl-opal",
+		out = "inl-picard160",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+		
+       },
+
+
+	{
+		in  = "inl-picard160",
+		out = "inl-opal",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+		
+       }
+);
+
+
+
diff --git a/etc/inl/inl/inl-opal-villas.conf b/etc/inl/inl/inl-opal-villas.conf
new file mode 100644
index 000000000..5d56b09d7
--- /dev/null
+++ b/etc/inl/inl/inl-opal-villas.conf
@@ -0,0 +1,40 @@
+# configuration file
+# host: inl-villas
+# remote nodes:inl-opal
+#
+#
+############     nodes    ############
+
+http = {enabled = false}
+
+stats = 1.0;
+
+nodes = {
+	
+	
+	inl-opal = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12109";
+		remote = "141.221.118.109:12109";
+	}
+	
+};
+
+paths = (
+	{
+		in  = "inl-opal",
+		out = "inl-opal",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			#format = "json"
+			}
+		)
+		
+       }
+);
+
+
+
diff --git a/etc/inl/inl/inl-rtds-picard.conf b/etc/inl/inl/inl-rtds-picard.conf
new file mode 100644
index 000000000..e78c516ec
--- /dev/null
+++ b/etc/inl/inl/inl-rtds-picard.conf
@@ -0,0 +1,52 @@
+# configuration file
+# host: inl-villas
+# remote nodes:usc-villas
+#
+#
+############     nodes    ############
+
+http = {enabled = false}
+
+nodes = {
+	
+	
+	inl-rtds11 = {
+		#Card 3, Port 1
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:11000";
+		remote = "141.221.118.160:5000";
+	},
+
+	#ss7 (in demo schematic)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	}
+	
+};
+
+paths = (
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-rtds11"
+       },
+
+	{
+		in  = "inl-rtds11",
+		out = "inl-to-usc-villas"
+       }
+);
+
+
+
diff --git a/etc/inl/loopback/inl-lpbck-csu.conf b/etc/inl/loopback/inl-lpbck-csu.conf
new file mode 100644
index 000000000..ad5627357
--- /dev/null
+++ b/etc/inl/loopback/inl-lpbck-csu.conf
@@ -0,0 +1,33 @@
+# configuration file
+# host: inl-villas
+# remote nodes:csu-villas
+#
+#
+############     nodes    ############
+
+nodes = {
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+	}
+	
+};
+
+paths = (
+	{
+		in  = "csu-villas",
+		out = "csu-villas" 
+		#hooks = (
+		#	{
+		#		type = "print";
+		#	}
+		#)
+       }
+);
+
+
+
diff --git a/etc/inl/loopback/inl-lpbck-fsu.conf b/etc/inl/loopback/inl-lpbck-fsu.conf
new file mode 100644
index 000000000..3d1c8c50a
--- /dev/null
+++ b/etc/inl/loopback/inl-lpbck-fsu.conf
@@ -0,0 +1,34 @@
+# configuration file
+# host: inl-villas
+# remote nodes:fsu-villas
+#
+#
+############     nodes    ############
+
+nodes = {
+	
+	#ss8 (in demo schematic)
+	fsu-villas = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12008";
+		remote = "10.146.64.3:12008";
+	}
+	
+};
+
+paths = (
+	{
+		in  = "fsu-villas",
+		out = "fsu-villas" 
+		#hooks = (
+		#	{
+		#		type = "print";
+		#	}
+		#)
+       }
+);
+
+
+
diff --git a/etc/inl/loopback/inl-lpbck-polito.conf b/etc/inl/loopback/inl-lpbck-polito.conf
new file mode 100644
index 000000000..016ceacad
--- /dev/null
+++ b/etc/inl/loopback/inl-lpbck-polito.conf
@@ -0,0 +1,40 @@
+# configuration file
+# host: inl-villas
+# remote nodes: acs-villas, polito_villas, csu-villas
+#
+#
+############     nodes    ############
+
+nodes = {
+	#ss2(in demo schematic)
+	acs-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12002";
+		remote = "10.10.15.1:12002";
+	},
+	
+	#ss3 (in demo schematic)
+	polito-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12003";
+		remote = "130.192.95.241:12003";
+	}
+	
+};
+
+paths = (
+	{
+		in  = "polito-villas",
+		out = "polito-villas",
+		hooks = (
+			{
+				type = "print";
+			}
+		)
+       }
+);
+
+
+
diff --git a/etc/inl/loopback/inl-lpbck-rtds.conf b/etc/inl/loopback/inl-lpbck-rtds.conf
new file mode 100644
index 000000000..d2d76d835
--- /dev/null
+++ b/etc/inl/loopback/inl-lpbck-rtds.conf
@@ -0,0 +1,23 @@
+# configuration file
+# host: inl-villas
+# loopback to GTNET-SKT
+#
+############     nodes    ############
+
+nodes = {
+
+	inl-rtds11 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12001";
+		remote = "141.221.118.73:12001";
+	}
+};
+
+paths = (
+	{
+		in  = "inl-rtds11",
+		out = "inl-rtds11"
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/loopback/inl-lpbck-usc.conf b/etc/inl/loopback/inl-lpbck-usc.conf
new file mode 100644
index 000000000..3c202a004
--- /dev/null
+++ b/etc/inl/loopback/inl-lpbck-usc.conf
@@ -0,0 +1,40 @@
+# configuration file
+# host: inl-villas
+# remote nodes:usc-villas
+#
+#
+############     nodes    ############
+
+nodes = {
+	#ss2(in demo schematic)
+	acs-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12002";
+		remote = "10.10.15.1:12002";
+	},
+	
+	#ss7 (in demo schematic)
+	usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";
+	}
+	
+};
+
+paths = (
+	{
+		in  = "usc-villas",
+		out = "usc-villas", 
+		hooks = (
+			{
+				type = "print";
+			}
+		)
+       }
+);
+
+
+
diff --git a/etc/inl/loopback/inl-lpbck-usc1.conf b/etc/inl/loopback/inl-lpbck-usc1.conf
new file mode 100644
index 000000000..24c1c6314
--- /dev/null
+++ b/etc/inl/loopback/inl-lpbck-usc1.conf
@@ -0,0 +1,37 @@
+# configuration file
+# host: inl-villas
+# remote nodes:usc-villas
+#
+#
+############     nodes    ############
+
+http = {enabled = false}
+
+nodes = {
+	
+	#ss7 (in demo schematic)
+	usc-villas1 = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";
+	},
+
+	usc-villas2 = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	}
+	
+};
+
+paths = (
+	{
+		in  = "usc-villas2",
+		out = "usc-villas1"
+       }
+);
+
+
+
diff --git a/etc/inl/loopback/inl-lpbck.conf b/etc/inl/loopback/inl-lpbck.conf
new file mode 100644
index 000000000..391f6a1ca
--- /dev/null
+++ b/etc/inl/loopback/inl-lpbck.conf
@@ -0,0 +1,42 @@
+# configuration file
+# host: inl-villas
+# remote nodes: acs-villas, polito_villas, usc-villas, fsu-villas
+#
+#
+############     nodes    ############
+
+nodes = {
+	#ss2(in demo schematic)
+	acs-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12002";
+		remote = "10.10.15.1:12002";
+	},
+	
+	#ss3 (in demo schematic)
+	polito-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12003";
+		remote = "130.192.95.241:12003";
+	},
+
+	#ss7 (in demo schematic)
+	usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:12007";
+	}
+	
+	#ss8 (in demo schematic)
+	fsu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12008";
+		remote = "10.146.64.3:12008";
+	}
+	
+}
+
diff --git a/etc/inl/loopback_drts/inl-lpbck-usc-opal_2.conf b/etc/inl/loopback_drts/inl-lpbck-usc-opal_2.conf
new file mode 100644
index 000000000..bed692e2f
--- /dev/null
+++ b/etc/inl/loopback_drts/inl-lpbck-usc-opal_2.conf
@@ -0,0 +1,37 @@
+# configuration file
+# host: inl-villas
+# remote nodes:usc-villas
+#
+#
+############     nodes    ############
+
+http = {enabled = false}
+
+nodes = {
+	
+	#ss7 (in demo schematic)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	}
+	
+};
+
+paths = (
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-to-usc-villas"
+       }
+);
+
+
+
diff --git a/etc/inl/loopback_drts/inl-rtds-acs.conf b/etc/inl/loopback_drts/inl-rtds-acs.conf
new file mode 100644
index 000000000..bcc8b33af
--- /dev/null
+++ b/etc/inl/loopback_drts/inl-rtds-acs.conf
@@ -0,0 +1,67 @@
+# configuration file
+# host: inl-villas
+# inl devices: inl-rtds11, inl-rtds21
+# remote nodes: acs-villas, polito_villas, csu-villas
+#
+#
+############     nodes    ############
+
+stats = 0.1;
+
+nodes = {
+
+	inl-rtds11 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12008";
+		remote = "141.221.118.73:12008";
+	},
+	
+	inl-rtds21 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12009";
+		remote = "141.221.118.83:12009";
+	},
+	
+	#ss2(in demo schematic)
+	acs-villas = {
+		type = "socket";
+		layer = "udp";
+		#header = "gtnet-skt";
+		local  = "141.221.118.93:12002";
+		remote = "10.10.15.1:12002";
+	}
+};
+
+paths = (
+	{
+		in  = "inl-rtds21",
+		out = "acs-villas",
+        	#reverse = true,
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			verbose = true, 
+			format = "json"
+			}
+		)
+       },
+
+	{
+		in  = "acs-villas",
+		out = "inl-rtds21",
+        	#reverse = true,
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			verbose = true, 
+			format = "json"
+			}
+		)
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/loopback_drts/inl-rtds-csu.conf b/etc/inl/loopback_drts/inl-rtds-csu.conf
new file mode 100644
index 000000000..09519f797
--- /dev/null
+++ b/etc/inl/loopback_drts/inl-rtds-csu.conf
@@ -0,0 +1,56 @@
+# configuration file
+# host: inl-villas
+# inl devices: inl-rtds11
+# remote nodes: csu-villas
+# Test: rtds - VILLASnode - VILLASnode - opal
+#
+#
+############     nodes    ############
+
+stats = 1.0;
+
+nodes = {
+
+	inl-rtds11 = {
+		#Card 3, Port 1
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.74:12011";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+	}
+};
+
+paths = (
+	{
+		in  = "inl-rtds11",
+		out = "csu-villas"
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000
+			#format = "json"
+			}
+		)
+       },
+
+	{
+		in  = "csu-villas",
+		out = "inl-rtds11",
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000
+			#format = "json"
+			}
+		)
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/loopback_drts/inl-rtds-fsu.conf b/etc/inl/loopback_drts/inl-rtds-fsu.conf
new file mode 100644
index 000000000..219bf14a1
--- /dev/null
+++ b/etc/inl/loopback_drts/inl-rtds-fsu.conf
@@ -0,0 +1,58 @@
+# configuration file
+# host: inl-villas
+# inl devices: inl-rtds11, inl-rtds21
+# remote nodes: fsu-villas
+# Test: rtds - VILLASnode - VILLASnode - rtds
+#
+#
+############     nodes    ############
+
+stats = 0.1;
+
+nodes = {
+
+	inl-rtds11 = {
+		#Card 3, Port 1
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12001";
+		remote = "141.221.118.74:12001";
+	},
+	
+	inl-rtds21 = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12002";
+		remote = "141.221.118.83:12002";
+	},
+	
+	#ss8 (in demo schematic)
+	fsu-villas = {
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12008";
+		remote = "10.146.64.3:12008";
+	}
+};
+
+paths = (
+	{
+		in  = "inl-rtds11",
+		out = "fsu-villas",
+        	reverse = true,
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			format = "json"
+			}
+
+		#	{
+		#	type="print";
+		#	}
+		)
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/loopback_drts/inl-rtds-usc-opal_2.conf b/etc/inl/loopback_drts/inl-rtds-usc-opal_2.conf
new file mode 100644
index 000000000..f816db165
--- /dev/null
+++ b/etc/inl/loopback_drts/inl-rtds-usc-opal_2.conf
@@ -0,0 +1,52 @@
+# configuration file
+# host: inl-villas
+# remote nodes:usc-villas
+#
+#
+############     nodes    ############
+
+http = {enabled = false}
+
+nodes = {
+	
+	
+	inl-rtds11 = {
+		#Card 3, Port 1
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.74:12011";
+	},
+
+	#ss7 (in demo schematic)
+	inl-to-usc-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12007";
+		remote = "129.252.22.104:13007";
+	},
+
+	usc-to-inl-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12077";
+		remote = "129.252.22.104:13077";
+	}
+	
+};
+
+paths = (
+	{
+		in  = "usc-to-inl-villas",
+		out = "inl-rtds11"
+       },
+
+	{
+		in  = "inl-rtds11",
+		out = "inl-to-usc-villas"
+       }
+);
+
+
+
diff --git a/etc/inl/loopback_drts/inl-rtds-usc.conf b/etc/inl/loopback_drts/inl-rtds-usc.conf
new file mode 100644
index 000000000..9cedeb9d5
--- /dev/null
+++ b/etc/inl/loopback_drts/inl-rtds-usc.conf
@@ -0,0 +1,45 @@
+# configuration file
+# host: inl-villas
+# inl devices: inl-rtds11
+# remote nodes: csu-villas
+# Test: rtds - VILLASnode - VILLASnode - opal
+#
+#
+############     nodes    ############
+
+stats = 0.1;
+
+nodes = {
+
+	inl-rtds11 = {
+		#Card 3, Port 1
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12001";
+		remote = "141.221.118.74:12001";
+	},
+	
+	#ss4 (in demo schematic)
+	csu-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12004";
+		remote = "129.82.106.227:12004";
+	}
+};
+
+paths = (
+	{
+		in  = "inl-rtds11",
+		out = "csu-villas",
+        	reverse = true,
+		hooks = (
+			{ 
+			type = "stats",
+			warmup = 3000,
+			format = "json"
+			}
+		)
+       }
+);
\ No newline at end of file
diff --git a/etc/inl/monitor_testForVILLASweb/inl-monitor-polito.conf b/etc/inl/monitor_testForVILLASweb/inl-monitor-polito.conf
new file mode 100644
index 000000000..b8e0a62e2
--- /dev/null
+++ b/etc/inl/monitor_testForVILLASweb/inl-monitor-polito.conf
@@ -0,0 +1,37 @@
+# configuration file
+# host: inl-villas
+# remote nodes: acs-villas, polito_villas, csu-villas
+#
+#
+############     nodes    ############
+
+nodes = {
+	
+	#ss3 (in demo schematic)
+	polito-villas = {
+		type = "socket";
+		layer = "udp";
+		local  = "141.221.118.93:12003";
+		remote = "130.192.95.241:12003";
+	},
+
+	inl-rtds11 = {
+		#Card 3, Port 1
+		type = "socket";
+		layer = "udp";
+		header = "gtnet-skt";
+		local  = "141.221.118.93:12011";
+		remote = "141.221.118.74:12011";
+	}
+	
+};
+
+paths = (
+	{
+		in  = "polito-villas",
+		out = "inl-rtds11"
+       }
+);
+
+
+
diff --git a/etc/loopback2.conf b/etc/loopback2.conf
new file mode 100644
index 000000000..f4f2436a4
--- /dev/null
+++ b/etc/loopback2.conf
@@ -0,0 +1,37 @@
+stats = 1
+
+nodes = {
+	socket_node1 = {
+		type = "socket",
+
+		local = "*:12000",
+		remote = "127.0.0.1:12000"
+	},
+	socket_node2 = {
+		type = "socket",
+
+		local = "*:12001",
+		remote = "127.0.0.1:12001"
+	}
+	
+	socket_node2a = {
+		type = "socket",
+
+		local = "*:12003",
+		remote = "127.0.0.1:12001"
+	}
+}
+
+paths = (
+	{
+		in = [
+			"socket_node1.data[0-3]",
+			"socket_node2.data[0-3]"
+		]
+		hooks = (
+			{
+				type = "print"
+			}
+		)
+	}
+)
diff --git a/etc/multiple_dest.conf b/etc/multiple_dest.conf
new file mode 100644
index 000000000..9da738117
--- /dev/null
+++ b/etc/multiple_dest.conf
@@ -0,0 +1,20 @@
+nodes = {
+  node_a = {
+    type = "signal"
+    signal = "sine"
+  }
+  
+  results-ss2 = {
+                  type = "file",
+                  uri = "asdasrtsuperlab/ss1ss2_inl-csu_%Y%m%d_%H-%M-%S.csv",
+                  flush = false,
+                  mode = "w+"
+          }
+}
+
+paths = (
+  {
+    in = "node_a"
+    out = [ "results-ss2" ]
+    }
+)
diff --git a/etc/pipe-loopback-nanomsg.conf b/etc/pipe-loopback-nanomsg.conf
new file mode 100644
index 000000000..11a91cc71
--- /dev/null
+++ b/etc/pipe-loopback-nanomsg.conf
@@ -0,0 +1,13 @@
+log = {
+  level = 15
+}
+
+http = {
+  port = 8081
+}
+
+nodes = {
+	node1 = {
+		type = "loopback";
+	}
+}
diff --git a/etc/pipe-loopback-websocket.json b/etc/pipe-loopback-websocket.json
new file mode 100644
index 000000000..9ed9e4b92
--- /dev/null
+++ b/etc/pipe-loopback-websocket.json
@@ -0,0 +1,11 @@
+{
+	"nodes" : {
+		"node1" : {
+			"type" : "websocket",
+
+			"destinations" : [
+				"ws://localhost/node1"
+			]
+		}
+	}
+}
\ No newline at end of file
diff --git a/etc/sampled_values.conf b/etc/sampled_values.conf
new file mode 100644
index 000000000..7137b9fd8
--- /dev/null
+++ b/etc/sampled_values.conf
@@ -0,0 +1,52 @@
+{
+	"logging" : {
+		"level" : 1
+	},
+	"nodes" : {
+		"node1" : {
+			"type" : "iec61850-9-2",
+			
+			"interface" : "lo",
+			"dst_address" : "01:0c:cd:01:00:01",
+		
+			"publish" : {
+				"fields" : [
+					"float32",
+					"float64",
+					"int8",
+					"int32"
+				],
+				
+				"svid" : "test1234",
+				"datset" : "test",
+				"smpmod" : "samples_per_second",
+				"confrev" : 55
+			},
+			"subscribe" : {
+				"fields" : [
+					"float32",
+					"float64",
+					"int8",
+					"int32"
+				]
+			}
+		},
+		
+
+		"node2" : {
+			"type" : "iec61850-9-2",
+		
+			"interface" : "lo",
+		
+			"publish" : {
+				"svid" : "testSV",
+				"datset" : "abc",
+				"fields" : [ "float32", "float64", "int8", "int32" ]
+			},
+			"subscribe" : {
+				"fields" : [ "float32", "float64", "int8", "int32" ]
+			}
+		}
+
+	}
+}
diff --git a/etc/unix_domain.conf b/etc/unix_domain.conf
new file mode 100644
index 000000000..d3bea0b39
--- /dev/null
+++ b/etc/unix_domain.conf
@@ -0,0 +1,14 @@
+nodes = {
+	unix_domain_node = {
+		type	= "socket",
+		layer	= "udp",
+#		layer	= "unix",
+		format	= "protobuf",
+		
+		local	= "*:12000";
+		remote	= "127.0.0.1:12001"
+		
+#		local	= "/var/run/villas-node.server.sock",
+#		remote	= "/var/run/villas-node.client.sock",
+	}
+}
diff --git a/etc/websocket-demo2.conf b/etc/websocket-demo2.conf
new file mode 100644
index 000000000..19972cf88
--- /dev/null
+++ b/etc/websocket-demo2.conf
@@ -0,0 +1,108 @@
+/** Example configuration file for VILLASnode.
+ *
+ * The syntax of this file is similar to JSON.
+ * A detailed description of the format can be found here:
+ *   http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files
+ *
+ * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
+ * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
+ * @license GNU General Public License (version 3)
+ *
+ * VILLASnode
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *********************************************************************************/
+
+stats = 1;
+
+logging = {
+	level = 1
+}
+
+nodes = {
+	sig = {
+		type = "signal",
+		vectorize = 1,
+		
+		signal = "mixed",
+		values = 5,
+		rate = 40,
+		amplitude = 2000000,
+		hooks = (
+			{ type = "stats" }
+		)
+	},
+	sig2 = {
+		type = "signal",
+		vectorize = 1,
+
+		signal = "mixed",
+		values = 5,
+		rate = 40,
+		hooks = (
+			{ type = "stats" }
+		)
+	},
+	stats = {
+		type = "stats",
+
+		node = "sig",
+		rate = 40
+	},
+	ws_stats = {
+		type = "websocket"
+		vectorize = 40,
+		
+	},
+	ws_sig = {
+		type = "websocket",
+		vectorize = 40,
+		
+		description = "Demo Channel",
+		series = (
+			{ label = "Random walk", unit = "V", yaxis = 2 },
+			{ label = "Sine",        unit = "A" },
+			{ label = "Square",      unit = "Var"},
+			{ label = "Triangle",    unit = "°C" },
+			{ label = "Ramp",        unit = "°C" }
+		),
+		hooks = (
+			{ type = "stats" }
+		)
+	},
+	ws_sig2 = {
+		type = "websocket",
+		vectorize = 40,
+		
+		description = "Demo Channel",
+		series = (
+			{ label = "Random walk", unit = "V", yaxis = 2 },
+			{ label = "Sine",        unit = "A" },
+			{ label = "Square",      unit = "Var"},
+			{ label = "Triangle",    unit = "°C" },
+			{ label = "Ramp",        unit = "°C" }
+		),
+		hooks = (
+			{ type = "stats" }
+		)
+	},
+};
+
+############       List of paths       ############
+
+paths = (
+	{ in = "sig", out = "ws_sig" },
+	{ in = "sig2", out = "ws_sig2" },
+	{ in = "stats", out = "ws_stats" }
+);
diff --git a/include/villas/fpga/card.h b/include/villas/fpga/card.h
deleted file mode 100644
index 90fc48142..000000000
--- a/include/villas/fpga/card.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/** FPGA card
- *
- * This class represents a FPGA device.
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
- * @license GNU General Public License (version 3)
- *
- * VILLASnode
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *********************************************************************************/
-
-/** @addtogroup fpga VILLASfpga
- * @{
- */
-
-#pragma once
-
-#include <jansson.h>
-
-#include "common.h"
-#include "kernel/pci.h"
-#include "kernel/vfio.h"
-
-/* Forward declarations */
-struct fpga_ip;
-struct vfio_container;
-
-struct fpga_card {
-	char *name;			/**< The name of the FPGA card */
-
-	enum state state;		/**< The state of this FPGA card. */
-
-	struct pci *pci;
-	struct pci_device filter;		/**< Filter for PCI device. */
-
-	struct vfio_container *vfio_container;
-	struct vfio_device vfio_device;	/**< VFIO device handle. */
-
-	int do_reset;			/**< Reset VILLASfpga during startup? */
-	int affinity;			/**< Affinity for MSI interrupts */
-
-	struct list ips;		/**< List of IP components on FPGA. */
-
-	char *map;			/**< PCI BAR0 mapping for register access */
-
-	size_t maplen;
-	size_t dmalen;
-
-	/* Some IP cores are special and referenced here */
-	struct fpga_ip *intc;
-	struct fpga_ip *reset;
-	struct fpga_ip *sw;
-};
-
-/** Initialize FPGA card and its IP components. */
-int fpga_card_init(struct fpga_card *c, struct pci *pci, struct vfio_container *vc);
-
-/** Parse configuration of FPGA card including IP cores from config. */
-int fpga_card_parse(struct fpga_card *c, json_t *cfg, const char *name);
-
-int fpga_card_parse_list(struct list *l, json_t *cfg);
-
-/** Check if the FPGA card configuration is plausible. */
-int fpga_card_check(struct fpga_card *c);
-
-/** Start FPGA card. */
-int fpga_card_start(struct fpga_card *c);
-
-/** Stop FPGA card. */
-int fpga_card_stop(struct fpga_card *c);
-
-/** Destroy FPGA card. */
-int fpga_card_destroy(struct fpga_card *c);
-
-/** Dump details of FPGA card to stdout. */
-void fpga_card_dump(struct fpga_card *c);
-
-/** Reset the FPGA to a known state */
-int fpga_card_reset(struct fpga_card *c);
-
-/** @} */
diff --git a/include/villas/fpga/ip.h b/include/villas/fpga/ip.h
deleted file mode 100644
index 918173114..000000000
--- a/include/villas/fpga/ip.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/** Interlectual Property component.
- *
- * This class represents a module within the FPGA.
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
- * @license GNU General Public License (version 3)
- *
- * VILLASnode
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *********************************************************************************/
-
-/** @addtogroup fpga VILLASfpga
- * @{
- */
-
-#pragma once
-
-#include <stdint.h>
-
-#include "common.h"
-
-#include "fpga/vlnv.h"
-
-#include "fpga/ips/dma.h"
-#include "fpga/ips/switch.h"
-#include "fpga/ips/fifo.h"
-#include "fpga/ips/rtds_axis.h"
-#include "fpga/ips/timer.h"
-#include "fpga/ips/model.h"
-#include "fpga/ips/dft.h"
-#include "fpga/ips/intc.h"
-
-enum fpga_ip_types {
-	FPGA_IP_TYPE_DM_DMA,	/**< A datamover IP exchanges streaming data between the FPGA and the CPU. */
-	FPGA_IP_TYPE_DM_FIFO,	/**< A datamover IP exchanges streaming data between the FPGA and the CPU. */
-	FPGA_IP_TYPE_MODEL,	/**< A model IP simulates a system on the FPGA. */
-	FPGA_IP_TYPE_MATH,	/**< A math IP performs some kind of mathematical operation on the streaming data */
-	FPGA_IP_TYPE_MISC,	/**< Other IP components like timer, counters, interrupt conctrollers or routing. */
-	FPGA_IP_TYPE_INTERFACE	/**< A interface IP connects the FPGA to another system or controller. */
-} type;
-
-struct fpga_ip_type {
-	struct fpga_vlnv vlnv;
-
-	enum fpga_ip_types type;
-
-	int (*init)(struct fpga_ip *c);
-	int (*parse)(struct fpga_ip *c, json_t *cfg);
-	int (*check)(struct fpga_ip *c);
-	int (*start)(struct fpga_ip *c);
-	int (*stop)(struct fpga_ip *c);
-	int (*destroy)(struct fpga_ip *c);
-	int (*reset)(struct fpga_ip *c);
-	void (*dump)(struct fpga_ip *c);
-
-	size_t size;			/**< Amount of memory which should be reserved for struct fpga_ip::_vd */
-};
-
-struct fpga_ip {
-	char *name;			/**< Name of the FPGA IP component. */
-	struct fpga_vlnv vlnv;		/**< The Vendor, Library, Name, Version tag of the FPGA IP component. */
-
-	enum state state;		/**< The current state of the FPGA IP component. */
-
-	struct fpga_ip_type *_vt;	/**< Vtable containing FPGA IP type function pointers. */
-	void *_vd;			/**< Virtual data (used by struct fpga_ip::_vt functions) */
-
-	uintptr_t baseaddr;		/**< The baseadress of this FPGA IP component */
-	uintptr_t baseaddr_axi4;	/**< Used by AXI4 FIFO DM */
-
-	int port;			/**< The port of the AXI4-Stream switch to which this FPGA IP component is connected. */
-	int irq;			/**< The interrupt number of the FPGA IP component. */
-
-	struct fpga_card *card;		/**< The FPGA to which this IP instance belongs to. */
-};
-
-/** Initialize IP core. */
-int fpga_ip_init(struct fpga_ip *c, struct fpga_ip_type *vt);
-
-/** Parse IP core configuration from configuration file */
-int fpga_ip_parse(struct fpga_ip *c, json_t *cfg, const char *name);
-
-/** Check configuration of IP core. */
-int fpga_ip_check(struct fpga_ip *c);
-
-/** Start IP core. */
-int fpga_ip_start(struct fpga_ip *c);
-
-/** Stop IP core. */
-int fpga_ip_stop(struct fpga_ip *c);
-
-/** Release dynamic memory allocated by this IP core. */
-int fpga_ip_destroy(struct fpga_ip *c);
-
-/** Dump details about this IP core to stdout. */
-void fpga_ip_dump(struct fpga_ip *c);
-
-/** Reset IP component to its initial state. */
-int fpga_ip_reset(struct fpga_ip *c);
-
-/** Find a registered FPGA IP core type with the given VLNV identifier. */
-struct fpga_ip_type * fpga_ip_type_lookup(const char *vstr);
-
-
-/** @} */
diff --git a/include/villas/fpga/ips/dft.h b/include/villas/fpga/ips/dft.h
deleted file mode 100644
index 03c08dbdf..000000000
--- a/include/villas/fpga/ips/dft.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/** Moving window / Recursive DFT implementation based on HLS
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
-**********************************************************************************/
-
-/** @addtogroup fpga VILLASfpga
- * @{
- */
-
-#pragma once
-
-#include <xilinx/xhls_dft.h>
-
-/* Forward declaration */
-struct ip;
-
-struct dft {
-	XHls_dft inst;
-
-	int period; /* in samples */
-	int num_harmonics;
-	float *fharmonics;
-	int decimation;
-};
-
-int dft_parse(struct fpga_ip *c, json_t *cfg);
-
-int dft_start(struct fpga_ip *c);
-
-int dft_stop(struct fpga_ip *c);
-
-int dft_destroy(struct fpga_ip *c);
-
-/** @} */
diff --git a/include/villas/fpga/ips/dma.h b/include/villas/fpga/ips/dma.h
deleted file mode 100644
index 7aa126d75..000000000
--- a/include/villas/fpga/ips/dma.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/** DMA related helper functions.
- *
- * These functions present a simpler interface to Xilinx' DMA driver (XAxiDma_*).
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-/** @addtogroup fpga VILLASfpga
- * @{
- */
-
-#pragma once
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <xilinx/xaxidma.h>
-
-/* Forward declarations */
-struct fpga_ip;
-
-#define FPGA_DMA_BASEADDR	0x00000000
-#define FPGA_DMA_BOUNDARY	0x1000
-#define FPGA_DMA_BD_OFFSET	0xC0000000
-#define FPGA_DMA_BD_SIZE	(32 << 20) // 32 MB
-
-#define XAXIDMA_SR_SGINCL_MASK	0x00000008
-
-struct dma_mem {
-	char *base_virt;
-	char *base_phys;
-	size_t len;
-};
-
-struct dma {
-	XAxiDma inst;
-
-	struct dma_mem bd;
-};
-
-struct ip;
-
-int dma_mem_split(struct dma_mem *o, struct dma_mem *a, struct dma_mem *b);
-
-int dma_alloc(struct fpga_ip *c, struct dma_mem *mem, size_t len, int flags);
-int dma_free(struct fpga_ip *c, struct dma_mem *mem);
-
-int dma_write(struct fpga_ip *c, char *buf, size_t len);
-int dma_read(struct fpga_ip *c, char *buf, size_t len);
-int dma_read_complete(struct fpga_ip *c, char **buf, size_t *len);
-int dma_write_complete(struct fpga_ip *c, char **buf, size_t *len);
-
-int dma_sg_write(struct fpga_ip *c, char *buf, size_t len);
-int dma_sg_read(struct fpga_ip *c, char *buf, size_t len);
-
-int dma_sg_write_complete(struct fpga_ip *c, char **buf, size_t *len);
-int dma_sg_read_complete(struct fpga_ip *c, char **buf, size_t *len);
-
-int dma_simple_read(struct fpga_ip *c, char *buf, size_t len);
-int dma_simple_write(struct fpga_ip *c, char *buf, size_t len);
-
-int dma_simple_read_complete(struct fpga_ip *c, char **buf, size_t *len);
-int dma_simple_write_complete(struct fpga_ip *c, char **buf, size_t *len);
-
-int dma_ping_pong(struct fpga_ip *c, char *src, char *dst, size_t len);
-
-int dma_start(struct fpga_ip *c);
-
-/** @} */
diff --git a/include/villas/fpga/ips/fifo.h b/include/villas/fpga/ips/fifo.h
deleted file mode 100644
index e9520350c..000000000
--- a/include/villas/fpga/ips/fifo.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/** FIFO related helper functions
- *
- * These functions present a simpler interface to Xilinx' FIFO driver (XLlFifo_*)
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-/** @addtogroup fpga VILLASfpga
- * @{
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#include <xilinx/xstatus.h>
-#include <xilinx/xllfifo.h>
-
-struct fifo {
-	XLlFifo inst;
-
-	uint32_t baseaddr_axi4;
-};
-
-/* Forward declarations */
-struct ip;
-
-int fifo_start(struct fpga_ip *c);
-
-ssize_t fifo_write(struct fpga_ip *c, char *buf, size_t len);
-
-ssize_t fifo_read(struct fpga_ip *c, char *buf, size_t len);
-
-/** @} */
diff --git a/include/villas/fpga/ips/intc.h b/include/villas/fpga/ips/intc.h
deleted file mode 100644
index 6b66b5a61..000000000
--- a/include/villas/fpga/ips/intc.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/** AXI-PCIe Interrupt controller
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-/** @addtogroup fpga VILLASfpga
- * @{
- */
-
-#pragma once
-
-#include <xilinx/xintc.h>
-
-enum intc_flags {
-	INTC_ENABLED = (1 << 0),
-	INTC_POLLING = (1 << 1)
-};
-
-struct intc {
-	int num_irqs;		/**< Number of available MSI vectors */
-
-	int efds[32];		/**< Event FDs */
-	int nos[32];		/**< Interrupt numbers from /proc/interrupts */
-
-	int flags[32];		/**< Mask of intc_flags */
-};
-
-int intc_init(struct fpga_ip *c);
-
-int intc_destroy(struct fpga_ip *c);
-
-int intc_enable(struct fpga_ip *c, uint32_t mask, int poll);
-
-int intc_disable(struct fpga_ip *c, uint32_t mask);
-
-uint64_t intc_wait(struct fpga_ip *c, int irq);
-
-/** @} */
diff --git a/include/villas/fpga/ips/model.h b/include/villas/fpga/ips/model.h
deleted file mode 100644
index 441ae2cf1..000000000
--- a/include/villas/fpga/ips/model.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/** Interface to Xilinx System Generator Models via PCIe
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- *********************************************************************************/
-
-/** @addtogroup fpga VILLASfpga
- * @{
- */
-
-#pragma once
-
-#include <stdlib.h>
-#include <stdint.h>
-
-#include "list.h"
-
-#define XSG_MAPLEN		0x1000
-#define XSG_MAGIC		0xDEADBABE
-
-/* Forward declaration */
-struct ip;
-
-enum model_type {
-	MODEL_TYPE_HLS,
-	MODEL_TYPE_XSG
-};
-
-enum model_xsg_block_type {
-	XSG_BLOCK_GATEWAY_IN	= 0x1000,
-	XSG_BLOCK_GATEWAY_OUT	= 0x1001,
-	XSG_BLOCK_INFO		= 0x2000
-};
-
-enum model_parameter_type {
-	MODEL_PARAMETER_TYPE_UFIX,
-	MODEL_PARAMETER_TYPE_FIX,
-	MODEL_PARAMETER_TYPE_FLOAT,
-	MODEL_PARAMETER_TYPE_BOOLEAN
-};
-
-enum model_parameter_direction {
-	MODEL_PARAMETER_IN,
-	MODEL_PARAMETER_OUT,
-	MODEL_PARAMETER_INOUT
-};
-
-union model_parameter_value {
-	uint32_t ufix;
-	int32_t  fix;
-	float    flt;
-	bool     bol;
-};
-
-struct xsg_model {
-	uint32_t *map;
-	ssize_t maplen;
-};
-
-struct hls_model {
-
-};
-
-struct model {
-	enum model_type type;		/**< Either HLS or XSG model */
-
-	struct list parameters;		/**< List of model parameters. */
-	struct list infos;		/**< A list of key / value pairs with model details */
-
-	union {
-		struct xsg_model xsg;	/**< XSG specific model data */
-		struct hls_model hls;	/**< HLS specific model data */
-	};
-};
-
-struct model_info {
-	char *field;
-	char *value;
-};
-
-struct model_parameter {
-	char *name;				/**< Name of the parameter */
-
-	enum model_parameter_direction direction;	/**< Read / Write / Read-write? */
-	enum model_parameter_type type;		/**< Data type. Integers are represented by MODEL_GW_TYPE_(U)FIX with model_gw::binpt == 0 */
-
-	int binpt;				/**< Binary point for type == MODEL_GW_TYPE_(U)FIX */
-	uintptr_t offset;			/**< Register offset to model::baseaddress */
-
-	union model_parameter_value default_value;
-
-	struct fpga_ip *ip;				/**< A pointer to the model structure to which this parameters belongs to. */
-};
-
-/** Initialize a model */
-int model_init(struct fpga_ip *c);
-
-/** Parse model */
-int model_parse(struct fpga_ip *c, json_t *cfg);
-
-/** Destroy a model */
-int model_destroy(struct fpga_ip *c);
-
-/** Print detailed information about the model to the screen. */
-void model_dump(struct fpga_ip *c);
-
-/** Add a new parameter to the model */
-void model_parameter_add(struct fpga_ip *c, const char *name, enum model_parameter_direction dir, enum model_parameter_type type);
-
-/** Remove an existing parameter by its name */
-int model_parameter_remove(struct fpga_ip *c, const char *name);
-
-/** Read a model parameter.
- *
- * Note: the data type of the register is taken into account.
- * All datatypes are converted to double.
- */
-int model_parameter_read(struct model_parameter *p, double *v);
-
-/** Update a model parameter.
- *
- * Note: the data type of the register is taken into account.
- * The double argument will be converted to the respective data type of the
- * GatewayIn/Out block.
- */
-int model_parameter_write(struct model_parameter *p, double v);
-
-int model_parameter_update(struct model_parameter *p, struct model_parameter *u);
-
-/** @} */
diff --git a/include/villas/fpga/ips/rtds_axis.h b/include/villas/fpga/ips/rtds_axis.h
deleted file mode 100644
index 5c699d135..000000000
--- a/include/villas/fpga/ips/rtds_axis.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/** Driver for AXI Stream wrapper around RTDS_InterfaceModule (rtds_axis )
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-/** @addtogroup fpga VILLASfpga
- * @{
- */
-
-#pragma once
-
-/* Forward declarations */
-struct ip;
-
-#define RTDS_HZ				100000000 // 100 MHz
-
-#define RTDS_AXIS_MAX_TX		64	/**< The amount of values which is supported by the vfpga card */
-#define RTDS_AXIS_MAX_RX		64	/**< The amount of values which is supported by the vfpga card */
-
-/* Register offsets */
-#define RTDS_AXIS_SR_OFFSET		0x00	/**< Status Register (read-only). See RTDS_AXIS_SR_* constant. */
-#define RTDS_AXIS_CR_OFFSET		0x04	/**< Control Register (read/write) */
-#define RTDS_AXIS_TSCNT_LOW_OFFSET	0x08	/**< Lower 32 bits of timestep counter (read-only). */
-#define RTDS_AXIS_TSCNT_HIGH_OFFSET	0x0C	/**< Higher 32 bits of timestep counter (read-only). */
-#define RTDS_AXIS_TS_PERIOD_OFFSET	0x10	/**< Period in clock cycles of previous timestep (read-only). */
-#define RTDS_AXIS_COALESC_OFFSET	0x14	/**< IRQ Coalescing register (read/write). */
-#define RTDS_AXIS_VERSION_OFFSET	0x18	/**< 16 bit version field passed back to the rack for version reporting (visible from “status” command, read/write). */
-#define RTDS_AXIS_MRATE			0x1C	/**< Multi-rate register */
-
-/* Status register bits */
-#define RTDS_AXIS_SR_CARDDETECTED	(1 << 0)/**< ‘1’ when RTDS software has detected and configured card. */
-#define RTDS_AXIS_SR_LINKUP		(1 << 1)/**< ‘1’ when RTDS communication link has been negotiated. */
-#define RTDS_AXIS_SR_TX_FULL		(1 << 2)/**< Tx buffer is full, writes that happen when UserTxFull=’1’ will be dropped (Throttling / buffering is performed by hardware). */
-#define RTDS_AXIS_SR_TX_INPROGRESS	(1 << 3)/**< Indicates when data is being put on link. */
-#define RTDS_AXIS_SR_CASE_RUNNING	(1 << 4)/**< There is currently a simulation running. */
-
-/* Control register bits */
-#define RTDS_AXIS_CR_DISABLE_LINK	0	/**< Disable SFP TX when set */
-
-void rtds_axis_dump(struct fpga_ip *c);
-
-double rtds_axis_dt(struct fpga_ip *c);
-
-/** @} */
diff --git a/include/villas/fpga/ips/switch.h b/include/villas/fpga/ips/switch.h
deleted file mode 100644
index 19b8b5417..000000000
--- a/include/villas/fpga/ips/switch.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/** AXI Stream interconnect related helper functions
- *
- * These functions present a simpler interface to Xilinx' AXI Stream switch driver (XAxis_Switch_*)
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-/** @addtogroup fpga VILLASfpga
- * @{
- */
-
-#pragma once
-
-#include <jansson.h>
-#include <xilinx/xaxis_switch.h>
-
-#include "list.h"
-
-/* Forward declarations */
-struct ip;
-
-struct sw_path {
-	const char *in;
-	const char *out;
-};
-
-struct sw {
-	XAxis_Switch inst;
-
-	int num_ports;
-	struct list paths;
-};
-
-struct ip;
-
-int switch_start(struct fpga_ip *c);
-
-/** Initialize paths which have been parsed by switch_parse() */
-int switch_init_paths(struct fpga_ip *c);
-
-int switch_destroy(struct fpga_ip *c);
-
-int switch_parse(struct fpga_ip *c, json_t *cfg);
-
-int switch_connect(struct fpga_ip *c, struct fpga_ip *mi, struct fpga_ip *si);
-
-int switch_disconnect(struct fpga_ip *c, struct fpga_ip *mi, struct fpga_ip *si);
-
-/** @} */
diff --git a/include/villas/fpga/ips/timer.h b/include/villas/fpga/ips/timer.h
deleted file mode 100644
index 4bdc23296..000000000
--- a/include/villas/fpga/ips/timer.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/** Timer related helper functions
- *
- * These functions present a simpler interface to Xilinx' Timer Counter driver (XTmrCtr_*)
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-/** @addtogroup fpga VILLASfpga
- * @{
- */
-
-#pragma once
-
-#include <xilinx/xtmrctr.h>
-
-/* Forward declarations */
-struct fpga_ip;
-
-struct timer {
-	XTmrCtr inst;
-};
-
-int timer_start(struct fpga_ip *c);
-
-/** @} */
diff --git a/include/villas/fpga/vlnv.h b/include/villas/fpga/vlnv.h
deleted file mode 100644
index 01d9f5d43..000000000
--- a/include/villas/fpga/vlnv.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/** Vendor, Library, Name, Version (VLNV) tag.
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
- * @license GNU General Public License (version 3)
- *
- * VILLASnode
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *********************************************************************************/
-
-/** @addtogroup fpga VILLASfpga
- * @{
- */
-
-#ifndef _FPGA_VLNV_H_
-#define _FPGA_VLNV_H_
-
-/* Forward declarations */
-struct list;
-
-struct fpga_vlnv {
-	char *vendor;
-	char *library;
-	char *name;
-	char *version;
-};
-
-/** Return the first IP block in list \p l which matches the VLNV */
-struct fpga_ip * fpga_vlnv_lookup(struct list *l, struct fpga_vlnv *v);
-
-/** Check if IP block \p c matched VLNV. */
-int fpga_vlnv_cmp(struct fpga_vlnv *a, struct fpga_vlnv *b);
-
-/** Tokenizes VLNV \p vlnv and stores it into \p c */
-int fpga_vlnv_parse(struct fpga_vlnv *c, const char *vlnv);
-
-/** Release memory allocated by fpga_vlnv_parse(). */
-int fpga_vlnv_destroy(struct fpga_vlnv *v);
-
-#endif /** _FPGA_VLNV_H_ @} */
diff --git a/include/villas/kernel/if.h b/include/villas/kernel/if.h
index 417931020..258c7ff6e 100644
--- a/include/villas/kernel/if.h
+++ b/include/villas/kernel/if.h
@@ -24,7 +24,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *********************************************************************************/
 
-/** @addtogroup fpga Kernel @{ */
+/** @addtogroup kernel Kernel @{ */
 
 #pragma once
 
diff --git a/include/villas/kernel/kernel.h b/include/villas/kernel/kernel.h
index 05a8ab913..6b39dc40c 100644
--- a/include/villas/kernel/kernel.h
+++ b/include/villas/kernel/kernel.h
@@ -21,7 +21,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *********************************************************************************/
 
-/** @addtogroup fpga Kernel @{ */
+/** @addtogroup kernel Kernel @{ */
 
 #pragma once
 
diff --git a/include/villas/kernel/nl.h b/include/villas/kernel/nl.h
index 56edf9347..879312cd9 100644
--- a/include/villas/kernel/nl.h
+++ b/include/villas/kernel/nl.h
@@ -21,7 +21,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *********************************************************************************/
 
-/** @addtogroup fpga Kernel @{ */
+/** @addtogroup kernel Kernel @{ */
 
 #pragma once
 
diff --git a/include/villas/kernel/pci.h b/include/villas/kernel/pci.h
deleted file mode 100644
index 821d0d6df..000000000
--- a/include/villas/kernel/pci.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/** Linux PCI helpers
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-/** @addtogroup fpga Kernel @{ */
-
-#pragma once
-
-#include "list.h"
-
-#define PCI_SLOT(devfn)		(((devfn) >> 3) & 0x1f)
-#define PCI_FUNC(devfn)		((devfn) & 0x07)
-
-struct pci_device {
-	struct {
-		int vendor;
-		int device;
-		int class;
-	} id;
-
-	struct {
-		int domain;
-		int bus;
-		int device;
-		int function;
-	} slot;			/**< Bus, Device, Function (BDF) */
-};
-
-struct pci {
-	struct list devices; /**< List of available PCI devices in the system (struct pci_device) */
-};
-
-/** Initialize Linux PCI handle.
- *
- * This search for all available PCI devices under /sys/bus/pci
- *
- * @retval 0 Success. Everything went well.
- * @retval <0 Error. Something went wrong.
- */
-int pci_init(struct pci *p);
-
-/** Destroy handle. */
-int pci_destroy(struct pci *p);
-
-int pci_device_parse_slot(struct pci_device *f, const char *str, const char **error);
-
-int pci_device_parse_id(struct pci_device *f, const char *str, const char **error);
-
-int pci_device_compare(const struct pci_device *d, const struct pci_device *f);
-
-struct pci_device * pci_lookup_device(struct pci *p, struct pci_device *filter);
-
-/** Bind a new LKM to the PCI device */
-int pci_attach_driver(struct pci_device *d, const char *driver);
-
-/** Return the IOMMU group of this PCI device or -1 if the device is not in a group. */
-int pci_get_iommu_group(struct pci_device *d);
-
-/** @} */
diff --git a/include/villas/kernel/rt.h b/include/villas/kernel/rt.h
index 44c22a0b5..f1c8b5bc6 100644
--- a/include/villas/kernel/rt.h
+++ b/include/villas/kernel/rt.h
@@ -22,7 +22,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *********************************************************************************/
 
-/** @addtogroup fpga Kernel @{ */
+/** @addtogroup kernel Kernel @{ */
 
 #pragma once
 
diff --git a/include/villas/kernel/tc.h b/include/villas/kernel/tc.h
index da3cd712c..c6c69f2db 100644
--- a/include/villas/kernel/tc.h
+++ b/include/villas/kernel/tc.h
@@ -26,7 +26,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *********************************************************************************/
 
-/** @addtogroup fpga Kernel @{ */
+/** @addtogroup kernel Kernel @{ */
 
 #pragma once
 
diff --git a/include/villas/kernel/vfio.h b/include/villas/kernel/vfio.h
deleted file mode 100644
index bb6f12329..000000000
--- a/include/villas/kernel/vfio.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/** Virtual Function IO wrapper around kernel API
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- *********************************************************************************/
-
-/** @addtogroup fpga Kernel @{ */
-
-#pragma once
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/mman.h>
-
-#include <linux/vfio.h>
-#include <linux/pci_regs.h>
-
-#include "list.h"
-
-#define VFIO_DEV(x)	"/dev/vfio/" x
-
-/* Forward declarations */
-struct pci_device;
-
-struct vfio_group {
-	int fd;					/**< VFIO group file descriptor */
-	int index;				/**< Index of the IOMMU group as listed under /sys/kernel/iommu_groups/ */
-
-	struct vfio_group_status status;	/**< Status of group */
-
-	struct list devices;
-
-	struct vfio_container *container;	/**< The VFIO container to which this group is belonging */
-};
-
-struct vfio_device {
-	char *name;				/**< Name of the device as listed under /sys/kernel/iommu_groups/[vfio_group::index]/devices/ */
-	int fd;					/**< VFIO device file descriptor */
-
-	struct vfio_device_info info;
-	struct vfio_irq_info *irqs;
-	struct vfio_region_info *regions;
-
-	void **mappings;
-
-	struct pci_device *pci_device;		/**< libpci handle of the device */
-	struct vfio_group *group;		/**< The VFIO group this device belongs to */
-};
-
-struct vfio_container {
-	int fd;
-	int version;
-	int extensions;
-
-	uint64_t iova_next;			/**< Next free IOVA address */
-
-	struct list groups;
-};
-
-/** Initialize a new VFIO container. */
-int vfio_init(struct vfio_container *c);
-
-/** Initialize a VFIO group and attach it to an existing VFIO container. */
-int vfio_group_attach(struct vfio_group *g, struct vfio_container *c, int index);
-
-/** Initialize a VFIO device, lookup the VFIO group it belongs to, create the group if not already existing. */
-int vfio_device_attach(struct vfio_device *d, struct vfio_container *c, const char *name, int index);
-
-/** Initialie a VFIO-PCI device (uses vfio_device_attach() internally) */
-int vfio_pci_attach(struct vfio_device *d, struct vfio_container *c, struct pci_device *pdev);
-
-/** Hot resets a VFIO-PCI device */
-int vfio_pci_reset(struct vfio_device *d);
-
-int vfio_pci_msi_init(struct vfio_device *d, int efds[32]);
-
-int vfio_pci_msi_deinit(struct vfio_device *d, int efds[32]);
-
-int vfio_pci_msi_find(struct vfio_device *d, int nos[32]);
-
-/** Enable memory accesses and bus mastering for PCI device */
-int vfio_pci_enable(struct vfio_device *d);
-
-/** Reset a VFIO device */
-int vfio_device_reset(struct vfio_device *d);
-
-/** Release memory and close container */
-int vfio_destroy(struct vfio_container *c);
-
-/** Release memory of group */
-int vfio_group_destroy(struct vfio_group *g);
-
-/** Release memory of device */
-int vfio_device_destroy(struct vfio_device *g);
-
-/** Print a dump of all attached groups and their devices including regions and IRQs */
-void vfio_dump(struct vfio_container *c);
-
-/** Map a device memory region to the application address space (e.g. PCI BARs) */
-void * vfio_map_region(struct vfio_device *d, int idx);
-
-/** Map VM to an IOVA, which is accessible by devices in the container */
-int vfio_map_dma(struct vfio_container *c, uint64_t virt, uint64_t phys, size_t len);
-
-/** Unmap DMA memory */
-int vfio_unmap_dma(struct vfio_container *c, uint64_t virt, uint64_t phys, size_t len);
-
-/** munmap() a region which has been mapped by vfio_map_region() */
-int vfio_unmap_region(struct vfio_device *d, int idx);
-
-/** @} */
diff --git a/lib/fpga/Makefile.inc b/lib/fpga/Makefile.inc
deleted file mode 100644
index c87dd59f9..000000000
--- a/lib/fpga/Makefile.inc
+++ /dev/null
@@ -1,24 +0,0 @@
-# Makefile.
-#
-# @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
-# @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
-# @license GNU General Public License (version 3)
-#
-# VILLASnode
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-###################################################################################
-
-LIB_SRCS += $(wildcard lib/fpga/*.c)
-LIB_SRCS += $(wildcard lib/fpga/ips/*.c)
diff --git a/lib/fpga/card.c b/lib/fpga/card.c
deleted file mode 100644
index d994e92ef..000000000
--- a/lib/fpga/card.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/** FPGA card.
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
- * @license GNU General Public License (version 3)
- *
- * VILLASnode
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *********************************************************************************/
-
-#include <unistd.h>
-
-#include "config.h"
-#include "log.h"
-#include "log_config.h"
-#include "list.h"
-#include "utils.h"
-
-#include "kernel/pci.h"
-#include "kernel/vfio.h"
-
-#include "fpga/ip.h"
-#include "fpga/card.h"
-
-int fpga_card_init(struct fpga_card *c, struct pci *pci, struct vfio_container *vc)
-{
-	assert(c->state = STATE_DESTROYED);
-
-	c->vfio_container = vc;
-	c->pci = pci;
-
-	list_init(&c->ips);
-
-	/* Default values */
-	c->filter.id.vendor = FPGA_PCI_VID_XILINX;
-	c->filter.id.device = FPGA_PCI_PID_VFPGA;
-
-	c->affinity = 0;
-	c->do_reset = 0;
-
-	c->state = STATE_INITIALIZED;
-
-	return 0;
-}
-
-int fpga_card_parse(struct fpga_card *c, json_t *cfg, const char *name)
-{
-	int ret;
-
-	json_t *json_ips;
-	json_t *json_slot = NULL;
-	json_t *json_id = NULL;
-	json_error_t err;
-
-	c->name = strdup(name);
-
-	ret = json_unpack_ex(cfg, &err, 0, "{ s?: i, s?: b, s?: o, s?: o, s: o }",
-		"affinity", &c->affinity,
-		"do_reset", &c->do_reset,
-		"slot", &json_slot,
-		"id", &json_id,
-		"ips", &json_ips
-	);
-	if (ret)
-		jerror(&err, "Failed to parse FPGA vard configuration");
-
-	if (json_slot) {
-		const char *err, *slot;
-
-		slot = json_string_value(json_slot);
-		if (slot) {
-			ret = pci_device_parse_slot(&c->filter, slot, &err);
-			if (ret)
-				error("Failed to parse PCI slot: %s", err);
-		}
-		else
-			error("PCI slot must be a string");
-	}
-
-	if (json_id) {
-		const char *err, *id;
-
-		id = json_string_value(json_id);
-		if (id) {
-			ret = pci_device_parse_id(&c->filter, (char*) id, &err);
-			if (ret)
-				error("Failed to parse PCI id: %s", err);
-		}
-		else
-			error("PCI ID must be a string");
-	}
-
-	if (!json_is_object(json_ips))
-		error("FPGA card IPs section must be an object");
-
-	const char *name_ip;
-	json_t *json_ip;
-	json_object_foreach(json_ips, name_ip, json_ip) {
-		const char *vlnv;
-
-		struct fpga_ip_type *vt;
-		struct fpga_ip *ip = (struct fpga_ip *) alloc(sizeof(struct fpga_ip));
-
-		ip->card = c;
-
-		ret = json_unpack_ex(json_ip, &err, 0, "{ s: s }", "vlnv", &vlnv);
-		if (ret)
-			error("Failed to parse FPGA IP '%s' of card '%s'", name_ip, name);
-
-		vt = fpga_ip_type_lookup(vlnv);
-		if (!vt)
-			error("FPGA IP core VLNV identifier '%s' is invalid", vlnv);
-
-		ret = fpga_ip_init(ip, vt);
-		if (ret)
-			error("Failed to initalize FPGA IP core");
-
-		ret = fpga_ip_parse(ip, json_ip, name_ip);
-		if (ret)
-			error("Failed to parse FPGA IP core");
-
-		list_push(&c->ips, ip);
-	}
-
-	c->state = STATE_PARSED;
-
-	return 0;
-}
-
-int fpga_card_parse_list(struct list *cards, json_t *cfg)
-{
-	int ret;
-
-	if (!json_is_object(cfg))
-		error("FPGA card configuration section must be a JSON object");
-
-	const char *name;
-	json_t *json_fpga;
-	json_object_foreach(cfg, name, json_fpga) {
-		struct fpga_card *c = (struct fpga_card *) alloc(sizeof(struct fpga_card));
-
-		ret = fpga_card_parse(c, json_fpga, name);
-		if (ret)
-			error("Failed to parse FPGA card configuration");
-
-		list_push(cards, c);
-	}
-
-	return 0;
-}
-
-int fpga_card_start(struct fpga_card *c)
-{
-	int ret;
-
-	struct pci_device *pdev;
-
-	assert(c->state == STATE_CHECKED);
-
-	/* Search for FPGA card */
-	pdev = pci_lookup_device(c->pci, &c->filter);
-	if (!pdev)
-		error("Failed to find PCI device");
-
-	/* Attach PCIe card to VFIO container */
-	ret = vfio_pci_attach(&c->vfio_device, c->vfio_container, pdev);
-	if (ret)
-		error("Failed to attach VFIO device");
-
-	/* Map PCIe BAR */
-	c->map = vfio_map_region(&c->vfio_device, VFIO_PCI_BAR0_REGION_INDEX);
-	if (c->map == MAP_FAILED)
-		serror("Failed to mmap() BAR0");
-
-	/* Enable memory access and PCI bus mastering for DMA */
-	ret = vfio_pci_enable(&c->vfio_device);
-	if (ret)
-		serror("Failed to enable PCI device");
-
-	/* Reset system? */
-	if (c->do_reset) {
-		/* Reset / detect PCI device */
-		ret = vfio_pci_reset(&c->vfio_device);
-		if (ret)
-			serror("Failed to reset PCI device");
-
-		ret = fpga_card_reset(c);
-		if (ret)
-			error("Failed to reset FGPA card");
-	}
-
-	/* Initialize IP cores */
-	for (size_t j = 0; j < list_length(&c->ips); j++) {
-		struct fpga_ip *i = (struct fpga_ip *) list_at(&c->ips, j);
-
-		ret = fpga_ip_start(i);
-		if (ret)
-			error("Failed to initalize FPGA IP core: %s (%u)", i->name, ret);
-	}
-
-	c->state = STATE_STARTED;
-
-	return 0;
-}
-
-int fpga_card_stop(struct fpga_card *c)
-{
-	int ret;
-
-	assert(c->state == STATE_STOPPED);
-
-	for (size_t j = 0; j < list_length(&c->ips); j++) {
-		struct fpga_ip *i = (struct fpga_ip *) list_at(&c->ips, j);
-
-		ret = fpga_ip_stop(i);
-		if (ret)
-			error("Failed to stop FPGA IP core: %s (%u)", i->name, ret);
-	}
-
-	c->state = STATE_STOPPED;
-
-	return 0;
-}
-
-void fpga_card_dump(struct fpga_card *c)
-{
-	info("VILLASfpga card:");
-	{ INDENT
-		info("Slot: %04x:%02x:%02x.%d", c->vfio_device.pci_device->slot.domain, c->vfio_device.pci_device->slot.bus, c->vfio_device.pci_device->slot.device, c->vfio_device.pci_device->slot.function);
-		info("Vendor ID: %04x", c->vfio_device.pci_device->id.vendor);
-		info("Device ID: %04x", c->vfio_device.pci_device->id.device);
-		info("Class  ID: %04x", c->vfio_device.pci_device->id.class);
-
-		info("BAR0 mapped at %p", c->map);
-
-		info("IP blocks:");
-		for (size_t j = 0; j < list_length(&c->ips); j++) { INDENT
-			struct fpga_ip *i = (struct fpga_ip *) list_at(&c->ips, j);
-
-			fpga_ip_dump(i);
-		}
-	}
-
-	vfio_dump(c->vfio_device.group->container);
-}
-
-int fpga_card_check(struct fpga_card *c)
-{
-	/* Check FPGA configuration */
-	c->reset = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_gpio", NULL });
-	if (!c->reset)
-		error("FPGA is missing a reset controller");
-
-	c->intc = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { "acs.eonerc.rwth-aachen.de", "user", "axi_pcie_intc", NULL });
-	if (!c->intc)
-		error("FPGA is missing a interrupt controller");
-
-	c->sw = fpga_vlnv_lookup(&c->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axis_interconnect", NULL });
-	if (!c->sw)
-		warn("FPGA is missing an AXI4-Stream switch");
-
-	return 0;
-}
-
-int fpga_card_destroy(struct fpga_card *c)
-{
-	list_destroy(&c->ips, (dtor_cb_t) fpga_ip_destroy, true);
-
-	return 0;
-}
-
-int fpga_card_reset(struct fpga_card *c)
-{
-	int ret;
-	char state[4096];
-
-	/* Save current state of PCI configuration space */
-	ret = pread(c->vfio_device.fd, state, sizeof(state), (off_t) VFIO_PCI_CONFIG_REGION_INDEX << 40);
-	if (ret != sizeof(state))
-		return -1;
-
-	uint32_t *rst_reg = (uint32_t *) (c->map + c->reset->baseaddr);
-
-	debug(3, "FPGA: reset");
-	rst_reg[0] = 1;
-
-	usleep(100000);
-
-	/* Restore previous state of PCI configuration space */
-	ret = pwrite(c->vfio_device.fd, state, sizeof(state), (off_t) VFIO_PCI_CONFIG_REGION_INDEX << 40);
-	if (ret != sizeof(state))
-		return -1;
-
-	/* After reset the value should be zero again */
-	if (rst_reg[0])
-		return -2;
-
-	c->state = STATE_INITIALIZED;
-
-	return 0;
-}
diff --git a/lib/fpga/ip.c b/lib/fpga/ip.c
deleted file mode 100644
index 86841db12..000000000
--- a/lib/fpga/ip.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/** FPGA IP component.
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
- * @license GNU General Public License (version 3)
- *
- * VILLASnode
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *********************************************************************************/
-
-#include "log_config.h"
-#include "log.h"
-#include "plugin.h"
-
-int fpga_ip_init(struct fpga_ip *c, struct fpga_ip_type *vt)
-{
-	int ret;
-
-	assert(c->state == STATE_DESTROYED);
-
-	c->_vt = vt;
-	c->_vd = alloc(vt->size);
-
-	ret = c->_vt->init ? c->_vt->init(c) : 0;
-	if (ret)
-		return ret;
-
-	c->state = STATE_INITIALIZED;
-
-	debug(8, "IP Core %s initalized (%u)", c->name, ret);
-
-	return ret;
-}
-
-int fpga_ip_parse(struct fpga_ip *c, json_t *cfg, const char *name)
-{
-	int ret, baseaddr = -1;
-
-	assert(c->state != STATE_STARTED && c->state != STATE_DESTROYED);
-
-	c->name = strdup(name);
-	c->baseaddr = -1;
-	c->irq = -1;
-	c->port = -1;
-
-	json_error_t err;
-
-	ret = json_unpack_ex(cfg, &err, 0, "{ s?: i, s?: i, s?: i }",
-		"baseaddr", &baseaddr,
-		"irq", &c->irq,
-		"port", &c->port
-	);
-	if (ret)
-		jerror(&err, "Failed to parse configuration for FPGA IP '%s'", name);
-
-	c->baseaddr = baseaddr;
-
-	/* Type sepecific settings */
-	ret = c->_vt && c->_vt->parse ? c->_vt->parse(c, cfg) : 0;
-	if (ret)
-		error("Failed to parse settings for IP core '%s'", name);
-
-	c->state = STATE_PARSED;
-
-	return 0;
-}
-
-int fpga_ip_start(struct fpga_ip *c)
-{
-	int ret;
-
-	assert(c->state == STATE_CHECKED);
-
-	ret = c->_vt->start ? c->_vt->start(c) : 0;
-	if (ret)
-		return ret;
-
-	c->state = STATE_STARTED;
-
-	return 0;
-}
-
-int fpga_ip_stop(struct fpga_ip *c)
-{
-	int ret;
-
-	assert(c->state == STATE_STARTED);
-
-	ret = c->_vt->stop ? c->_vt->stop(c) : 0;
-	if (ret)
-		return ret;
-
-	c->state = STATE_STOPPED;
-
-	return 0;
-}
-
-int fpga_ip_destroy(struct fpga_ip *c)
-{
-	int ret;
-
-	assert(c->state != STATE_DESTROYED);
-
-	fpga_vlnv_destroy(&c->vlnv);
-
-	ret = c->_vt->destroy ? c->_vt->destroy(c) : 0;
-	if (ret)
-		return ret;
-
-	c->state = STATE_DESTROYED;
-
-	free(c->_vd);
-
-	return 0;
-}
-
-int fpga_ip_reset(struct fpga_ip *c)
-{
-	debug(3, "Reset IP core: %s", c->name);
-
-	return c->_vt->reset ? c->_vt->reset(c) : 0;
-}
-
-void fpga_ip_dump(struct fpga_ip *c)
-{
-	assert(c->state != STATE_DESTROYED);
-
-	info("IP %s: vlnv=%s:%s:%s:%s baseaddr=%#jx, irq=%d, port=%d",
-		c->name, c->vlnv.vendor, c->vlnv.library, c->vlnv.name, c->vlnv.version,
-		c->baseaddr, c->irq, c->port);
-
-	if (c->_vt->dump)
-		c->_vt->dump(c);
-}
-
-struct fpga_ip_type * fpga_ip_type_lookup(const char *vstr)
-{
-	int ret;
-
-	struct fpga_vlnv vlnv;
-
-	ret = fpga_vlnv_parse(&vlnv, vstr);
-	if (ret)
-		return NULL;
-
-	/* Try to find matching IP type */
-	for (size_t i = 0; i < list_length(&plugins); i++) {
-		struct plugin *p = (struct plugin *) list_at(&plugins, i);
-
-		if (p->type == PLUGIN_TYPE_FPGA_IP && !fpga_vlnv_cmp(&vlnv, &p->ip.vlnv))
-			return &p->ip;
-	}
-
-	return NULL;
-}
diff --git a/lib/fpga/ips/Makefile.inc b/lib/fpga/ips/Makefile.inc
deleted file mode 100644
index ca6f74d36..000000000
--- a/lib/fpga/ips/Makefile.inc
+++ /dev/null
@@ -1,25 +0,0 @@
-# Makefile.
-#
-# @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
-# @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
-# @license GNU General Public License (version 3)
-#
-# VILLASnode
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-###################################################################################
-
-LIB_SRCS += $(wildcard lib/fpga/*.c)
-
-include lib/fpga/ips/Makefile.inc
diff --git a/lib/fpga/ips/dft.c b/lib/fpga/ips/dft.c
deleted file mode 100644
index b64d346af..000000000
--- a/lib/fpga/ips/dft.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/** Moving window / Recursive DFT implementation based on HLS
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-#include "log.h"
-#include "log_config.h"
-#include "plugin.h"
-
-#include "fpga/ip.h"
-#include "fpga/card.h"
-#include "fpga/ips/dft.h"
-
-int dft_parse(struct fpga_ip *c, json_t *cfg)
-{
-	struct dft *dft = (struct dft *) c->_vd;
-
-	int ret;
-
-	json_t *json_harms;
-	json_error_t err;
-
-	ret = json_unpack_ex(cfg, &err, 0, "{ s: i, s: i, s: o }",
-		"period", &dft->period,
-		"decimation", &dft->decimation,
-		"harmonics", &json_harms
-	);
-	if (ret)
-		jerror(&err, "Failed to parse configuration of FPGA IP '%s'", c->name);
-
-	if (!json_is_array(json_harms))
-		error("DFT IP core requires 'harmonics' to be an array of integers!");
-
-	dft->num_harmonics = json_array_size(json_harms);
-	if (dft->num_harmonics <= 0)
-		error("DFT IP core requires 'harmonics' to contain at least 1 value!");
-
-	dft->fharmonics = alloc(sizeof(float) * dft->num_harmonics);
-
-	size_t index;
-	json_t *json_harm;
-	json_array_foreach(json_harms, index, json_harm) {
-		if (!json_is_real(json_harm))
-			error("DFT IP core requires all 'harmonics' values to be of floating point type");
-
-		dft->fharmonics[index] = (float) json_number_value(json_harm) / dft->period;
-	}
-
-	return 0;
-}
-
-int dft_start(struct fpga_ip *c)
-{
-	int ret;
-
-	struct fpga_card *f = c->card;
-	struct dft *dft = (struct dft *) c->_vd;
-
-	XHls_dft *xdft = &dft->inst;
-	XHls_dft_Config xdft_cfg = {
-		.Ctrl_BaseAddress = (uintptr_t) f->map + c->baseaddr
-	};
-
-	ret = XHls_dft_CfgInitialize(xdft, &xdft_cfg);
-	if (ret != XST_SUCCESS)
-		return ret;
-
-	int max_harmonics = XHls_dft_Get_fharmonics_TotalBytes(xdft) / sizeof(dft->fharmonics[0]);
-
-	if (dft->num_harmonics > max_harmonics)
-		error("DFT IP core supports a maximum of %u harmonics", max_harmonics);
-
-	XHls_dft_Set_num_harmonics_V(xdft, dft->num_harmonics);
-
-	XHls_dft_Set_decimation_V(xdft, dft->decimation);
-
-	memcpy((void *) (uintptr_t) XHls_dft_Get_fharmonics_BaseAddress(xdft), dft->fharmonics, dft->num_harmonics * sizeof(dft->fharmonics[0]));
-
-	XHls_dft_EnableAutoRestart(xdft);
-	XHls_dft_Start(xdft);
-
-	return 0;
-}
-
-int dft_stop(struct fpga_ip *c)
-{
-	struct dft *dft = (struct dft *) c->_vd;
-
-	XHls_dft *xdft = &dft->inst;
-
-	XHls_dft_DisableAutoRestart(xdft);
-
-	return 0;
-}
-
-int dft_destroy(struct fpga_ip *c)
-{
-	struct dft *dft = (struct dft *) c->_vd;
-
-	if (dft->fharmonics) {
-		free(dft->fharmonics);
-		dft->fharmonics = NULL;
-	}
-
-	return 0;
-}
-
-static struct plugin p = {
-	.name		= "Discrete Fourier Transform",
-	.description	= "Perfom Discrete Fourier Transforms with variable number of harmonics on the FPGA",
-	.type		= PLUGIN_TYPE_FPGA_IP,
-	.ip		= {
-		.vlnv	= { "acs.eonerc.rwth-aachen.de", "hls", "hls_dft", NULL },
-		.type	= FPGA_IP_TYPE_MATH,
-		.start	= dft_start,
-		.stop	= dft_stop,
-		.destroy = dft_destroy,
-		.parse	= dft_parse,
-		.size	= sizeof(struct dft)
-	}
-};
-
-REGISTER_PLUGIN(&p)
diff --git a/lib/fpga/ips/dma.c b/lib/fpga/ips/dma.c
deleted file mode 100644
index 5384f98fa..000000000
--- a/lib/fpga/ips/dma.c
+++ /dev/null
@@ -1,641 +0,0 @@
-/** DMA related helper functions
- *
- * These functions present a simpler interface to Xilinx' DMA driver (XAxiDma_*)
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <sys/mman.h>
-
-#include "log.h"
-#include "plugin.h"
-#include "utils.h"
-
-#include "fpga/ip.h"
-#include "fpga/card.h"
-#include "fpga/ips/dma.h"
-
-int dma_mem_split(struct dma_mem *o, struct dma_mem *a, struct dma_mem *b)
-{
-	int split = o->len / 2;
-
-	a->base_virt = o->base_virt;
-	a->base_phys = o->base_phys;
-
-	b->base_virt = a->base_virt + split;
-	b->base_phys = a->base_phys + split;
-
-	a->len = split;
-	b->len = o->len - split;
-
-	return 0;
-}
-
-int dma_alloc(struct fpga_ip *c, struct dma_mem *mem, size_t len, int flags)
-{
-	int ret;
-
-	struct fpga_card *f = c->card;
-
-	/* Align to next bigger page size chunk */
-	if (len & 0xFFF) {
-		len += 0x1000;
-		len &= ~0xFFF;
-	}
-
-	mem->len = len;
-	mem->base_phys = (void *) -1; /* find free */
-	mem->base_virt = mmap(0, mem->len, PROT_READ | PROT_WRITE, flags | MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, 0, 0);
-	if (mem->base_virt == MAP_FAILED)
-		return -1;
-
-	ret = vfio_map_dma(f->vfio_device.group->container, (uint64_t) mem->base_virt, (uint64_t) mem->base_phys, mem->len);
-	if (ret)
-		return -2;
-
-	return 0;
-}
-
-int dma_free(struct fpga_ip *c, struct dma_mem *mem)
-{
-	int ret;
-
-	ret = vfio_unmap_dma(c->card->vfio_device.group->container, (uint64_t) mem->base_virt, (uint64_t) mem->base_phys, mem->len);
-	if (ret)
-		return ret;
-
-	ret = munmap(mem->base_virt, mem->len);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
-int dma_ping_pong(struct fpga_ip *c, char *src, char *dst, size_t len)
-{
-	int ret;
-
-	ret = dma_read(c, dst, len);
-	if (ret)
-		return ret;
-
-	ret = dma_write(c, src, len);
-	if (ret)
-		return ret;
-
-	ret = dma_write_complete(c, NULL, NULL);
-	if (ret)
-		return ret;
-
-	ret = dma_read_complete(c, NULL, NULL);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
-int dma_write(struct fpga_ip *c, char *buf, size_t len)
-{
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-
-	debug(25, "DMA write: dmac=%s buf=%p len=%#zx", c->name, buf, len);
-
-	return xdma->HasSg
-		? dma_sg_write(c, buf, len)
-		: dma_simple_write(c, buf, len);
-}
-
-int dma_read(struct fpga_ip *c, char *buf, size_t len)
-{
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-
-	debug(25, "DMA read: dmac=%s buf=%p len=%#zx", c->name, buf, len);
-
-	return xdma->HasSg
-		? dma_sg_read(c, buf, len)
-		: dma_simple_read(c, buf, len);
-}
-
-int dma_read_complete(struct fpga_ip *c, char **buf, size_t *len)
-{
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-
-	debug(25, "DMA read complete: dmac=%s", c->name);
-
-	return xdma->HasSg
-		? dma_sg_read_complete(c, buf, len)
-		: dma_simple_read_complete(c, buf, len);
-}
-
-int dma_write_complete(struct fpga_ip *c, char **buf, size_t *len)
-{
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-
-	debug(25, "DMA write complete: dmac=%s", c->name);
-
-	return xdma->HasSg
-		? dma_sg_write_complete(c, buf, len)
-		: dma_simple_write_complete(c, buf, len);
-}
-
-int dma_sg_write(struct fpga_ip *c, char *buf, size_t len)
-{
-	int ret, bdcnt;
-
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-	XAxiDma_BdRing *ring = XAxiDma_GetTxRing(xdma);
-	XAxiDma_Bd *bds, *bd;
-
-	uint32_t remaining, bdlen, bdbuf, cr;
-
-	/* Checks */
-	if (!xdma->HasSg)
-		return -1;
-
-	if (len < 1)
-		return -2;
-
-	if (!xdma->HasMm2S)
-		return -3;
-
-	if (!ring->HasDRE) {
-		uint32_t mask = xdma->MicroDmaMode ? XAXIDMA_MICROMODE_MIN_BUF_ALIGN : ring->DataWidth - 1;
-		if ((uintptr_t) buf & mask)
-			return -4;
-	}
-
-	bdcnt = CEIL(len, FPGA_DMA_BOUNDARY);
-	ret = XAxiDma_BdRingAlloc(ring, bdcnt, &bds);
-	if (ret != XST_SUCCESS)
-		return -5;
-
-	remaining = len;
-	bdbuf = (uintptr_t) buf;
-	bd = bds;
-	for (int i = 0; i < bdcnt; i++) {
-		bdlen = MIN(remaining, FPGA_DMA_BOUNDARY);
-
-		ret = XAxiDma_BdSetBufAddr(bd, bdbuf);
-		if (ret != XST_SUCCESS)
-			goto out;
-
-		ret = XAxiDma_BdSetLength(bd, bdlen, ring->MaxTransferLen);
-		if (ret != XST_SUCCESS)
-			goto out;
-
-		/* Set SOF / EOF / ID */
-		cr = 0;
-		if (i == 0)
-			cr |= XAXIDMA_BD_CTRL_TXSOF_MASK;
-		if (i == bdcnt - 1)
-			cr |= XAXIDMA_BD_CTRL_TXEOF_MASK;
-
-		XAxiDma_BdSetCtrl(bd, cr);
-		XAxiDma_BdSetId(bd, (uintptr_t) buf);
-
-		remaining -= bdlen;
-		bdbuf += bdlen;
-		bd = (XAxiDma_Bd *) XAxiDma_BdRingNext(ring, bd);
-	}
-
-	/* Give the BD to DMA to kick off the transmission. */
-	ret = XAxiDma_BdRingToHw(ring, bdcnt, bds);
-	if (ret != XST_SUCCESS)
-		return -8;
-
-	return 0;
-
-out:
-	ret = XAxiDma_BdRingUnAlloc(ring, bdcnt, bds);
-	if (ret != XST_SUCCESS)
-		return -6;
-
-	return -5;
-}
-
-int dma_sg_read(struct fpga_ip *c, char *buf, size_t len)
-{
-	int ret, bdcnt;
-
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-	XAxiDma_BdRing *ring = XAxiDma_GetRxRing(xdma);
-	XAxiDma_Bd *bds, *bd;
-
-	uint32_t remaining, bdlen, bdbuf;
-
-	/* Checks */
-	if (!xdma->HasSg)
-		return -1;
-
-	if (len < 1)
-		return -2;
-
-	if (!xdma->HasS2Mm)
-		return -3;
-
-	if (!ring->HasDRE) {
-		uint32_t mask = xdma->MicroDmaMode ? XAXIDMA_MICROMODE_MIN_BUF_ALIGN : ring->DataWidth - 1;
-		if ((uintptr_t) buf & mask)
-			return -4;
-	}
-
-	bdcnt = CEIL(len, FPGA_DMA_BOUNDARY);
-	ret = XAxiDma_BdRingAlloc(ring, bdcnt, &bds);
-	if (ret != XST_SUCCESS)
-		return -5;
-
-	bdbuf = (uintptr_t) buf;
-	remaining = len;
-	bd = bds;
-	for (int i = 0; i < bdcnt; i++) {
-		bdlen = MIN(remaining, FPGA_DMA_BOUNDARY);
-		ret = XAxiDma_BdSetLength(bd, bdlen, ring->MaxTransferLen);
-		if (ret != XST_SUCCESS)
-			goto out;
-
-		ret = XAxiDma_BdSetBufAddr(bd, bdbuf);
-		if (ret != XST_SUCCESS)
-			goto out;
-
-		/* Receive BDs do not need to set anything for the control
-		* The hardware will set the SOF/EOF bits per stream ret */
-		XAxiDma_BdSetCtrl(bd, 0);
-		XAxiDma_BdSetId(bd, (uintptr_t) buf);
-
-		remaining -= bdlen;
-		bdbuf += bdlen;
-		bd = (XAxiDma_Bd *) XAxiDma_BdRingNext(ring, bd);
-	}
-
-	ret = XAxiDma_BdRingToHw(ring, bdcnt, bds);
-	if (ret != XST_SUCCESS)
-		return -8;
-
-	return 0;
-
-out:
-	ret = XAxiDma_BdRingUnAlloc(ring, bdcnt, bds);
-	if (ret != XST_SUCCESS)
-		return -6;
-
-	return -5;
-}
-
-int dma_sg_write_complete(struct fpga_ip *c, char **buf, size_t *len)
-{
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-	XAxiDma_BdRing *ring = XAxiDma_GetTxRing(xdma);
-	XAxiDma_Bd *bds;
-
-	int processed, ret;
-
-	/* Wait until the one BD TX transaction is done */
-	while (!(XAxiDma_IntrGetIrq(xdma, XAXIDMA_DMA_TO_DEVICE) & XAXIDMA_IRQ_IOC_MASK))
-		intc_wait(c->card->intc, c->irq);
-	XAxiDma_IntrAckIrq(xdma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DMA_TO_DEVICE);
-
-	processed = XAxiDma_BdRingFromHw(ring, XAXIDMA_ALL_BDS, &bds);
-
-	if (len != NULL)
-		*len = XAxiDma_BdGetActualLength(bds, XAXIDMA_MAX_TRANSFER_LEN);
-
-	if (buf != NULL)
-		*buf = (char *) (uintptr_t) XAxiDma_BdGetId(bds);
-
-	/* Free all processed TX BDs for future transmission */
-	ret = XAxiDma_BdRingFree(ring, processed, bds);
-	if (ret != XST_SUCCESS)
-		return -1;
-
-	return 0;
-}
-
-int dma_sg_read_complete(struct fpga_ip *c, char **buf, size_t *len)
-{
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-	XAxiDma_BdRing *ring = XAxiDma_GetRxRing(xdma);
-	XAxiDma_Bd *bds, *bd;
-
-	int ret, bdcnt;
-	uint32_t recvlen, sr;
-	uintptr_t recvbuf = 0;
-
-	if (!xdma->HasSg)
-		return -1;
-
-	while (!(XAxiDma_IntrGetIrq(xdma, XAXIDMA_DEVICE_TO_DMA) & XAXIDMA_IRQ_IOC_MASK))
-		intc_wait(c->card->intc, c->irq + 1);
-	XAxiDma_IntrAckIrq(xdma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DEVICE_TO_DMA);
-
-	bdcnt = XAxiDma_BdRingFromHw(ring, XAXIDMA_ALL_BDS, &bds);
-
-	recvlen = 0;
-
-	bd = bds;
-	for (int i = 0; i < bdcnt; i++) {
-		recvlen += XAxiDma_BdGetActualLength(bd, ring->MaxTransferLen);
-
-		sr = XAxiDma_BdGetSts(bd);
-		if (sr & XAXIDMA_BD_STS_RXSOF_MASK)
-			if (i != 0)
-				warn("sof not first");
-
-		if (sr & XAXIDMA_BD_STS_RXEOF_MASK)
-			if (i != bdcnt - 1)
-				warn("eof not last");
-
-		recvbuf = XAxiDma_BdGetId(bd);
-
- 		bd = (XAxiDma_Bd *) XAxiDma_BdRingNext(ring, bd);
-	}
-
-	if (len != NULL)
-		*len = recvlen;
-	if (buf != NULL)
-		*buf = (char *) recvbuf;
-
-	/* Free all processed RX BDs for future transmission */
-	ret = XAxiDma_BdRingFree(ring, bdcnt, bds);
-	if (ret != XST_SUCCESS)
-		return -3;
-
-	return 0;
-}
-
-int dma_simple_read(struct fpga_ip *c, char *buf, size_t len)
-{
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-	XAxiDma_BdRing *ring = XAxiDma_GetRxRing(xdma);
-
-	/* Checks */
-	if (xdma->HasSg)
-		return -1;
-
-	if ((len < 1) || (len > FPGA_DMA_BOUNDARY))
-		return -2;
-
-	if (!xdma->HasS2Mm)
-		return -3;
-
-	if (!ring->HasDRE) {
-		uint32_t mask = xdma->MicroDmaMode ? XAXIDMA_MICROMODE_MIN_BUF_ALIGN : ring->DataWidth - 1;
-		if ((uintptr_t) buf & mask)
-			return -4;
-	}
-
-	if(!(XAxiDma_ReadReg(ring->ChanBase, XAXIDMA_SR_OFFSET) & XAXIDMA_HALTED_MASK)) {
-		if (XAxiDma_Busy(xdma, XAXIDMA_DEVICE_TO_DMA))
-			return -5;
-	}
-
-	XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_DESTADDR_OFFSET, LOWER_32_BITS((uintptr_t) buf));
-	if (xdma->AddrWidth > 32)
-		XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_DESTADDR_MSB_OFFSET,  UPPER_32_BITS((uintptr_t) buf));
-
-	XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_CR_OFFSET, XAxiDma_ReadReg(ring->ChanBase, XAXIDMA_CR_OFFSET) | XAXIDMA_CR_RUNSTOP_MASK);
-	XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_BUFFLEN_OFFSET, len);
-
-	return XST_SUCCESS;
-}
-
-int dma_simple_write(struct fpga_ip *c, char *buf, size_t len)
-{
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-	XAxiDma_BdRing *ring = XAxiDma_GetTxRing(xdma);
-
-	/* Checks */
-	if (xdma->HasSg)
-		return -1;
-
-	if ((len < 1) || (len > FPGA_DMA_BOUNDARY))
-		return -2;
-
-	if (!xdma->HasMm2S)
-		return -3;
-
-	if (!ring->HasDRE) {
-		uint32_t mask = xdma->MicroDmaMode ? XAXIDMA_MICROMODE_MIN_BUF_ALIGN : ring->DataWidth - 1;
-		if ((uintptr_t) buf & mask)
-			return -4;
-	}
-
-	/* If the engine is doing transfer, cannot submit  */
-	if(!(XAxiDma_ReadReg(ring->ChanBase, XAXIDMA_SR_OFFSET) & XAXIDMA_HALTED_MASK)) {
-		if (XAxiDma_Busy(xdma, XAXIDMA_DMA_TO_DEVICE))
-			return -5;
-	}
-
-	XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_SRCADDR_OFFSET, LOWER_32_BITS((uintptr_t) buf));
-	if (xdma->AddrWidth > 32)
-		XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_SRCADDR_MSB_OFFSET, UPPER_32_BITS((uintptr_t) buf));
-
-	XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_CR_OFFSET, XAxiDma_ReadReg(ring->ChanBase, XAXIDMA_CR_OFFSET) | XAXIDMA_CR_RUNSTOP_MASK);
-	XAxiDma_WriteReg(ring->ChanBase, XAXIDMA_BUFFLEN_OFFSET, len);
-
-	return XST_SUCCESS;
-}
-
-int dma_simple_read_complete(struct fpga_ip *c, char **buf, size_t *len)
-{
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-	XAxiDma_BdRing *ring = XAxiDma_GetRxRing(xdma);
-
-	while (!(XAxiDma_IntrGetIrq(xdma, XAXIDMA_DEVICE_TO_DMA) & XAXIDMA_IRQ_IOC_MASK))
-		intc_wait(c->card->intc, c->irq + 1);
-	XAxiDma_IntrAckIrq(xdma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DEVICE_TO_DMA);
-
-	if (len)
-		*len = XAxiDma_ReadReg(ring->ChanBase, XAXIDMA_BUFFLEN_OFFSET);
-
-	if (buf) {
-		*buf = (char *) (uintptr_t) XAxiDma_ReadReg(ring->ChanBase, XAXIDMA_DESTADDR_OFFSET);
-		if (xdma->AddrWidth > 32)
-			*buf += XAxiDma_ReadReg(ring->ChanBase, XAXIDMA_DESTADDR_MSB_OFFSET);
-	}
-
-	return 0;
-}
-
-int dma_simple_write_complete(struct fpga_ip *c, char **buf, size_t *len)
-{
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-	XAxiDma_BdRing *ring = XAxiDma_GetTxRing(xdma);
-
-	while (!(XAxiDma_IntrGetIrq(xdma, XAXIDMA_DMA_TO_DEVICE) & XAXIDMA_IRQ_IOC_MASK))
-		intc_wait(c->card->intc, c->irq);
-	XAxiDma_IntrAckIrq(xdma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DMA_TO_DEVICE);
-
-	if (len)
-		*len = XAxiDma_ReadReg(ring->ChanBase, XAXIDMA_BUFFLEN_OFFSET);
-
-	if (buf) {
-		*buf = (char *) (uintptr_t) XAxiDma_ReadReg(ring->ChanBase, XAXIDMA_SRCADDR_OFFSET);
-		if (xdma->AddrWidth > 32)
-			*buf += XAxiDma_ReadReg(ring->ChanBase, XAXIDMA_SRCADDR_MSB_OFFSET);
-	}
-
-	return 0;
-}
-
-static int dma_setup_ring(XAxiDma_BdRing *ring, struct dma_mem *bdbuf)
-{
-	int delay = 0;
-	int coalesce = 1;
-	int ret, cnt;
-
-	XAxiDma_Bd clearbd;
-
-	/* Disable all RX interrupts before RxBD space setup */
-	XAxiDma_BdRingIntDisable(ring, XAXIDMA_IRQ_ALL_MASK);
-
-	/* Set delay and coalescing */
-	XAxiDma_BdRingSetCoalesce(ring, coalesce, delay);
-
-	/* Setup Rx BD space */
-	cnt = XAxiDma_BdRingCntCalc(XAXIDMA_BD_MINIMUM_ALIGNMENT, bdbuf->len);
-
-	ret = XAxiDma_BdRingCreate(ring, (uintptr_t) bdbuf->base_phys, (uintptr_t) bdbuf->base_virt, XAXIDMA_BD_MINIMUM_ALIGNMENT, cnt);
-	if (ret != XST_SUCCESS)
-		return -1;
-
-	XAxiDma_BdClear(&clearbd);
-	ret = XAxiDma_BdRingClone(ring, &clearbd);
-	if (ret != XST_SUCCESS)
-		return -2;
-
-	/* Start the channel */
-	ret = XAxiDma_BdRingStart(ring);
-	if (ret != XST_SUCCESS)
-		return -3;
-
-	return XST_SUCCESS;
-}
-
-static int dma_init_rings(XAxiDma *xdma, struct dma_mem *bd)
-{
-	int ret;
-
-	struct dma_mem bd_rx, bd_tx;
-
-	ret = dma_mem_split(bd, &bd_rx, &bd_tx);
-	if (ret)
-		return -1;
-
-	ret = dma_setup_ring(XAxiDma_GetRxRing(xdma), &bd_rx);
-	if (ret != XST_SUCCESS)
-		return -2;
-
-	ret = dma_setup_ring(XAxiDma_GetTxRing(xdma), &bd_tx);
-	if (ret != XST_SUCCESS)
-		return -3;
-
-	return 0;
-}
-
-int dma_start(struct fpga_ip *c)
-{
-	int ret, sg;
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma *xdma = &dma->inst;
-
-	/* Guess DMA type */
-	sg = (XAxiDma_In32((uintptr_t) c->card->map + c->baseaddr + XAXIDMA_TX_OFFSET+ XAXIDMA_SR_OFFSET) &
-	      XAxiDma_In32((uintptr_t) c->card->map + c->baseaddr + XAXIDMA_RX_OFFSET+ XAXIDMA_SR_OFFSET) & XAXIDMA_SR_SGINCL_MASK) ? 1 : 0;
-
-	XAxiDma_Config xdma_cfg = {
-		.BaseAddr = (uintptr_t) c->card->map + c->baseaddr,
-		.HasStsCntrlStrm = 0,
-		.HasMm2S = 1,
-		.HasMm2SDRE = 1,
-		.Mm2SDataWidth = 128,
-		.HasS2Mm = 1,
-		.HasS2MmDRE = 1, /* Data Realignment Engine */
-		.HasSg = sg,
-		.S2MmDataWidth = 128,
-		.Mm2sNumChannels = 1,
-		.S2MmNumChannels = 1,
-		.Mm2SBurstSize = 64,
-		.S2MmBurstSize = 64,
-		.MicroDmaMode = 0,
-		.AddrWidth = 32
-	};
-
-	ret = XAxiDma_CfgInitialize(xdma, &xdma_cfg);
-	if (ret != XST_SUCCESS)
-		return -1;
-
-	/* Perform selftest */
-	ret = XAxiDma_Selftest(xdma);
-	if (ret != XST_SUCCESS)
-		return -2;
-
-	/* Map buffer descriptors */
-	if (xdma->HasSg) {
-		ret = dma_alloc(c, &dma->bd, FPGA_DMA_BD_SIZE, 0);
-		if (ret)
-			return -3;
-
-		ret = dma_init_rings(xdma, &dma->bd);
-		if (ret)
-			return -4;
-	}
-
-	/* Enable completion interrupts for both channels */
-	XAxiDma_IntrEnable(xdma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DMA_TO_DEVICE);
-	XAxiDma_IntrEnable(xdma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DEVICE_TO_DMA);
-
-	return 0;
-}
-
-int dma_reset(struct fpga_ip *c)
-{
-	struct dma *dma = (struct dma *) c->_vd;
-
-	XAxiDma_Reset(&dma->inst);
-
-	return 0;
-}
-
-static struct plugin p = {
-	.name		= "Xilinx's AXI4 Direct Memory Access Controller",
-	.description	= "Transfer data streams between VILLASnode and VILLASfpga",
-	.type		= PLUGIN_TYPE_FPGA_IP,
-	.ip		= {
-		.vlnv	= { "xilinx.com", "ip", "axi_dma", NULL },
-		.type	= FPGA_IP_TYPE_DM_DMA,
-		.init	= dma_start,
-		.reset	= dma_reset,
-		.size	= sizeof(struct dma)
-	}
-};
-
-REGISTER_PLUGIN(&p)
diff --git a/lib/fpga/ips/fifo.c b/lib/fpga/ips/fifo.c
deleted file mode 100644
index b57a3ecc9..000000000
--- a/lib/fpga/ips/fifo.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/** FIFO related helper functions
- *
- * These functions present a simpler interface to Xilinx' FIFO driver (XLlFifo_*)
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-#include <unistd.h>
-
-#include "utils.h"
-#include "plugin.h"
-
-#include "fpga/ip.h"
-#include "fpga/card.h"
-#include "fpga/ips/fifo.h"
-#include "fpga/ips/intc.h"
-
-int fifo_start(struct fpga_ip *c)
-{
-	int ret;
-
-	struct fpga_card *f = c->card;
-	struct fifo *fifo = (struct fifo *) c->_vd;
-
-	XLlFifo *xfifo = &fifo->inst;
-	XLlFifo_Config fifo_cfg = {
-		.BaseAddress = (uintptr_t) f->map + c->baseaddr,
-		.Axi4BaseAddress = (uintptr_t) c->card->map + fifo->baseaddr_axi4,
-		.Datainterface = (fifo->baseaddr_axi4 != -1) ? 1 : 0 /* use AXI4 for Data, AXI4-Lite for control */
-	};
-
-	ret = XLlFifo_CfgInitialize(xfifo, &fifo_cfg, (uintptr_t) c->card->map + c->baseaddr);
-	if (ret != XST_SUCCESS)
-		return -1;
-
-	XLlFifo_IntEnable(xfifo, XLLF_INT_RC_MASK); /* Receive complete IRQ */
-
-	return 0;
-}
-
-int fifo_stop(struct fpga_ip *c)
-{
-	struct fifo *fifo = (struct fifo *) c->_vd;
-
-	XLlFifo *xfifo = &fifo->inst;
-
-	XLlFifo_IntDisable(xfifo, XLLF_INT_RC_MASK); /* Receive complete IRQ */
-
-	return 0;
-}
-
-ssize_t fifo_write(struct fpga_ip *c, char *buf, size_t len)
-{
-	struct fifo *fifo = (struct fifo *) c->_vd;
-
-	XLlFifo *xllfifo = &fifo->inst;
-
-	uint32_t tdfv;
-
-	tdfv = XLlFifo_TxVacancy(xllfifo);
-	if (tdfv < len)
-		return -1;
-
-	XLlFifo_Write(xllfifo, buf, len);
-	XLlFifo_TxSetLen(xllfifo, len);
-
-	return len;
-}
-
-ssize_t fifo_read(struct fpga_ip *c, char *buf, size_t len)
-{
-	struct fifo *fifo = (struct fifo *) c->_vd;
-
-	XLlFifo *xllfifo = &fifo->inst;
-
-	size_t nextlen = 0;
-	uint32_t rxlen;
-
-	while (!XLlFifo_IsRxDone(xllfifo))
-		intc_wait(c->card->intc, c->irq);
-	XLlFifo_IntClear(xllfifo, XLLF_INT_RC_MASK);
-
-	/* Get length of next frame */
-	rxlen = XLlFifo_RxGetLen(xllfifo);
-	nextlen = MIN(rxlen, len);
-
-	/* Read from FIFO */
-	XLlFifo_Read(xllfifo, buf, nextlen);
-
-	return nextlen;
-}
-
-int fifo_parse(struct fpga_ip *c, json_t *cfg)
-{
-	struct fifo *fifo = (struct fifo *) c->_vd;
-
-	int baseaddr_axi4 = -1, ret;
-
-	json_error_t err;
-
-	fifo->baseaddr_axi4 = -1;
-
-	ret = json_unpack_ex(cfg, &err, 0, "{ s?: i }", "baseaddr_axi4", &baseaddr_axi4);
-	if (ret)
-		jerror(&err, "Failed to parse configuration of FPGA IP '%s'", c->name);
-
-	fifo->baseaddr_axi4 = baseaddr_axi4;
-
-	return 0;
-}
-
-int fifo_reset(struct fpga_ip *c)
-{
-	struct fifo *fifo = (struct fifo *) c->_vd;
-
-	XLlFifo_Reset(&fifo->inst);
-
-	return 0;
-}
-
-static struct plugin p = {
-	.name		= "Xilinx's AXI4 FIFO data mover",
-	.description	= "",
-	.type		= PLUGIN_TYPE_FPGA_IP,
-	.ip		= {
-		.vlnv	= { "xilinx.com", "ip", "axi_fifo_mm_s", NULL },
-		.type	= FPGA_IP_TYPE_DM_FIFO,
-		.start	= fifo_start,
-		.stop	= fifo_stop,
-		.parse	= fifo_parse,
-		.reset	= fifo_reset,
-		.size	= sizeof(struct fifo)
-	}
-};
-
-REGISTER_PLUGIN(&p)
diff --git a/lib/fpga/ips/intc.c b/lib/fpga/ips/intc.c
deleted file mode 100644
index 1a6d1356a..000000000
--- a/lib/fpga/ips/intc.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/** AXI-PCIe Interrupt controller
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-#include <unistd.h>
-
-#include "config.h"
-#include "log.h"
-#include "plugin.h"
-
-#include "nodes/fpga.h"
-
-#include "kernel/vfio.h"
-#include "kernel/kernel.h"
-
-#include "fpga/ip.h"
-#include "fpga/card.h"
-#include "fpga/ips/intc.h"
-
-int intc_start(struct fpga_ip *c)
-{
-	int ret;
-
-	struct fpga_card *f = c->card;
-	struct intc *intc = (struct intc *) c->_vd;
-
-	uintptr_t base = (uintptr_t) f->map + c->baseaddr;
-
-	if (c != f->intc)
-		error("There can be only one interrupt controller per FPGA");
-
-	intc->num_irqs = vfio_pci_msi_init(&f->vfio_device, intc->efds);
-	if (intc->num_irqs < 0)
-		return -1;
-
-	ret = vfio_pci_msi_find(&f->vfio_device, intc->nos);
-	if (ret)
-		return -2;
-
-	/* For each IRQ */
-	for (int i = 0; i < intc->num_irqs; i++) {
-		/* Pin to core */
-		ret = kernel_irq_setaffinity(intc->nos[i], f->affinity, NULL);
-		if (ret)
-			serror("Failed to change affinity of VFIO-MSI interrupt");
-
-		/* Setup vector */
-		XIntc_Out32(base + XIN_IVAR_OFFSET + i * 4, i);
-	}
-
-	XIntc_Out32(base + XIN_IMR_OFFSET, 0);		/* Use manual acknowlegement for all IRQs */
-	XIntc_Out32(base + XIN_IAR_OFFSET, 0xFFFFFFFF); /* Acknowlege all pending IRQs manually */
-	XIntc_Out32(base + XIN_IMR_OFFSET, 0xFFFFFFFF); /* Use fast acknowlegement for all IRQs */
-	XIntc_Out32(base + XIN_IER_OFFSET, 0x00000000); /* Disable all IRQs by default */
-	XIntc_Out32(base + XIN_MER_OFFSET, XIN_INT_HARDWARE_ENABLE_MASK | XIN_INT_MASTER_ENABLE_MASK);
-
-	debug(4, "FPGA: enabled interrupts");
-
-	return 0;
-}
-
-int intc_destroy(struct fpga_ip *c)
-{
-	struct fpga_card *f = c->card;
-	struct intc *intc = (struct intc *) c->_vd;
-
-	vfio_pci_msi_deinit(&f->vfio_device, intc->efds);
-
-	return 0;
-}
-
-int intc_enable(struct fpga_ip *c, uint32_t mask, int flags)
-{
-	struct fpga_card *f = c->card;
-	struct intc *intc = (struct intc *) c->_vd;
-
-	uint32_t ier, imr;
-	uintptr_t base = (uintptr_t) f->map + c->baseaddr;
-
-	/* Current state of INTC */
-	ier = XIntc_In32(base + XIN_IER_OFFSET);
-	imr = XIntc_In32(base + XIN_IMR_OFFSET);
-
-	/* Clear pending IRQs */
-	XIntc_Out32(base + XIN_IAR_OFFSET, mask);
-
-	for (int i = 0; i < intc->num_irqs; i++) {
-		if (mask & (1 << i))
-			intc->flags[i] = flags;
-	}
-
-	if (flags & INTC_POLLING) {
-		XIntc_Out32(base + XIN_IMR_OFFSET, imr & ~mask);
-		XIntc_Out32(base + XIN_IER_OFFSET, ier & ~mask);
-	}
-	else {
-		XIntc_Out32(base + XIN_IER_OFFSET, ier | mask);
-		XIntc_Out32(base + XIN_IMR_OFFSET, imr | mask);
-	}
-
-	debug(3, "New ier = %#x", XIntc_In32(base + XIN_IER_OFFSET));
-	debug(3, "New imr = %#x", XIntc_In32(base + XIN_IMR_OFFSET));
-	debug(3, "New isr = %#x", XIntc_In32(base + XIN_ISR_OFFSET));
-
-	debug(8, "FPGA: Interupt enabled: mask=%#x flags=%#x", mask, flags);
-
-	return 0;
-}
-
-int intc_disable(struct fpga_ip *c, uint32_t mask)
-{
-	struct fpga_card *f = c->card;
-
-	uintptr_t base = (uintptr_t) f->map + c->baseaddr;
-	uint32_t ier = XIntc_In32(base + XIN_IER_OFFSET);
-
-	XIntc_Out32(base + XIN_IER_OFFSET, ier & ~mask);
-
-	return 0;
-}
-
-uint64_t intc_wait(struct fpga_ip *c, int irq)
-{
-	struct fpga_card *f = c->card;
-	struct intc *intc = (struct intc *) c->_vd;
-
-	uintptr_t base = (uintptr_t) f->map + c->baseaddr;
-
-	if (intc->flags[irq] & INTC_POLLING) {
-		uint32_t isr, mask = 1 << irq;
-
-		do {
-			isr = XIntc_In32(base + XIN_ISR_OFFSET);
-			pthread_testcancel();
-		} while ((isr & mask) != mask);
-
-		XIntc_Out32(base + XIN_IAR_OFFSET, mask);
-
-		return 1;
-	}
-	else {
-		uint64_t cnt;
-		ssize_t ret = read(intc->efds[irq], &cnt, sizeof(cnt));
-		if (ret != sizeof(cnt))
-			return 0;
-
-		return cnt;
-	}
-}
-
-static struct plugin p = {
-	.name		= "Xilinx's programmable interrupt controller",
-	.description	= "",
-	.type		= PLUGIN_TYPE_FPGA_IP,
-	.ip		= {
-		.vlnv	= { "acs.eonerc.rwth-aachen.de", "user", "axi_pcie_intc", NULL },
-		.type	= FPGA_IP_TYPE_MISC,
-		.start	= intc_start,
-		.destroy = intc_destroy,
-		.size	= sizeof(struct intc)
-	}
-};
-
-REGISTER_PLUGIN(&p)
diff --git a/lib/fpga/ips/model.c b/lib/fpga/ips/model.c
deleted file mode 100644
index d795e050f..000000000
--- a/lib/fpga/ips/model.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/** Interface to Xilinx System Generator Models via PCIe
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- *********************************************************************************/
-
-#include <stdint.h>
-#include <time.h>
-#include <string.h>
-#include <math.h>
-
-#include "utils.h"
-#include "log.h"
-#include "log_config.h"
-#include "plugin.h"
-
-#include "fpga/ip.h"
-#include "fpga/card.h"
-#include "fpga/ips/model.h"
-
-static int model_parameter_destroy(struct model_parameter *p)
-{
-	free(p->name);
-
-	return 0;
-}
-
-static int model_info_destroy(struct model_info *i)
-{
-	free(i->field);
-	free(i->value);
-
-	return 0;
-}
-
-static uint32_t model_xsg_map_checksum(uint32_t *map, size_t len)
-{
-	uint32_t chks = 0;
-
-	for (int i = 2; i < len-1; i++)
-		chks += map[i];
-
-	return chks; /* moduluo 2^32 because of overflow */
-}
-
-static int model_xsg_map_parse(uint32_t *map, size_t len, struct list *parameters, struct list *infos)
-{
-#define copy_string(off) strndup((char *) (data + (off)), (length - (off)) * 4);
-	int j;
-	struct model_info *i;
-
-	/* Check magic */
-	if (map[0] != XSG_MAGIC)
-		error("Invalid magic: %#x", map[0]);
-
-	for (j = 2; j < len-1;) {
-		uint16_t type   = map[j] & 0xFFFF;
-		uint16_t length = map[j] >> 16;
-		uint32_t *data  = &map[j+1];
-
-		switch (type) {
-			case XSG_BLOCK_GATEWAY_IN:
-			case XSG_BLOCK_GATEWAY_OUT:
-				if (length < 4)
-					break; /* block is to small to describe a gateway */
-
-				struct model_parameter *e, *p = (struct model_parameter *) alloc(sizeof(struct model_parameter));
-
-				p->name          =  copy_string(3);
-				p->default_value.flt =  *((float *) &data[1]);
-				p->offset        = data[2];
-				p->direction     = type & 0x1;
-				p->type          = (data[0] >> 0) & 0xFF;
-				p->binpt         = (data[0] >> 8) & 0xFF;
-
-				e = list_lookup(parameters, p->name);
-				if (e)
-					model_parameter_update(e, p);
-				else
-					list_push(parameters, p);
-				break;
-
-			case XSG_BLOCK_INFO:
-				i = alloc(sizeof(struct model_info));
-
-				i->field = copy_string(0);
-				i->value = copy_string((int) ceil((double) (strlen(i->field) + 1) / 4))
-
-				list_push(infos, i);
-				break;
-
-			default:
-				warn("Unknown block type: %#06x", type);
-		}
-
-		j += length + 1;
-	}
-
-	return 0;
-
-#undef copy_string
-}
-
-static uint32_t model_xsg_map_read_word(uint32_t offset, void *baseaddr)
-{
-	volatile uint32_t *addr = baseaddr + 0x00;
-	volatile uint32_t *data = baseaddr + 0x04;
-
-	*addr = offset; /* Update addr reg */
-
-	return *data; /* Read data reg */
-}
-
-static int model_xsg_map_read(uint32_t *map, size_t len, void *baseaddr)
-{
-	size_t maplen;
-	uint32_t magic;
-
-	/* Check magic */
-	magic = model_xsg_map_read_word(0, baseaddr);
-	if (magic != XSG_MAGIC)
-		return -1;
-
-	maplen = model_xsg_map_read_word(1, baseaddr);
-	if (maplen < 3)
-		return -2;
-
-	/* Read Data */
-	int i;
-	for (i = 0; i < MIN(maplen, len); i++)
-		map[i] = model_xsg_map_read_word(i, baseaddr);
-
-	return i;
-}
-
-int model_parse(struct fpga_ip *c, json_t *cfg)
-{
-	struct model *m = (struct model *) c->_vd;
-
-	int ret;
-
-	json_t *json_params;
-	json_error_t err;
-
-	if      (strcmp(c->vlnv.library, "hls") == 0)
-		m->type = MODEL_TYPE_HLS;
-	else if (strcmp(c->vlnv.library, "sysgen") == 0)
-		m->type = MODEL_TYPE_XSG;
-	else
-		error("Unsupported model type: %s", c->vlnv.library);
-
-	ret = json_unpack_ex(cfg, &err, 0, "{ s?: o }", "parameters", &json_params);
-	if (ret)
-		jerror(&err, "Failed to parse configuration of FPGA IP '%s'", c->name);
-
-	if (json_params) {
-		if (!json_is_object(json_params))
-			error("Setting 'parameters' must be a JSON object");
-
-		const char *name;
-		json_t *value;
-		json_object_foreach(json_params, name, value) {
-			if (!json_is_real(value))
-				error("Parameters of FPGA IP '%s' must be of type floating point", c->name);
-
-			struct model_parameter *p = (struct model_parameter *) alloc(sizeof(struct model_parameter));
-
-			p->name = strdup(name);
-			p->default_value.flt = json_real_value(value);
-
-			list_push(&m->parameters, p);
-		}
-	}
-
-	return 0;
-}
-
-static int model_init_from_xsg_map(struct model *m, void *baseaddr)
-{
-	int ret, chks;
-
-	if (baseaddr == (void *) -1)
-		return -1;
-
-	m->xsg.map = alloc(XSG_MAPLEN);
-	m->xsg.maplen = model_xsg_map_read(m->xsg.map, XSG_MAPLEN, baseaddr);
-	if (m->xsg.maplen < 0)
-		return -1;
-
-	debug(5, "XSG: memory map length = %#zx", m->xsg.maplen);
-
-	chks = m->xsg.map[m->xsg.maplen - 1];
-	if (chks != model_xsg_map_checksum(m->xsg.map, m->xsg.maplen))
-		return -2;
-
-	ret = model_xsg_map_parse(m->xsg.map, m->xsg.maplen, &m->parameters, &m->infos);
-	if (ret)
-		return -3;
-
-	debug(5, "XSG: Parsed %zu parameters and %zu model infos", list_length(&m->parameters), list_length(&m->infos));
-
-	return 0;
-}
-
-int model_init(struct fpga_ip *c)
-{
-	int ret;
-
-	struct model *m = (struct model *) c->_vd;
-
-	list_init(&m->parameters);
-	list_init(&m->infos);
-
-	if (!fpga_vlnv_cmp(&c->vlnv, &(struct fpga_vlnv) { NULL, "sysgen", NULL, NULL }))
-		ret = model_init_from_xsg_map(m, c->card->map + c->baseaddr);
-	else
-		ret = 0;
-
-	/* Set default values for parameters */
-	for (size_t i = 0; i < list_length(&m->parameters); i++) {
-		struct model_parameter *p = (struct model_parameter *) list_at(&m->parameters, i);
-
-		p->ip = c;
-
-		if (p->direction == MODEL_PARAMETER_IN) {
-			model_parameter_write(p, p->default_value.flt);
-			info("Set parameter '%s' updated to default value: %f", p->name, p->default_value.flt);
-		}
-	}
-
-	if (ret)
-		error("Failed to init XSG model: %d", ret);
-
-	return 0;
-}
-
-int model_destroy(struct fpga_ip *c)
-{
-	struct model *m = (struct model *) c->_vd;
-
-	list_destroy(&m->parameters, (dtor_cb_t) model_parameter_destroy, true);
-	list_destroy(&m->infos, (dtor_cb_t) model_info_destroy, true);
-
-	if (m->xsg.map != NULL)
-		free(m->xsg.map);
-
-	return 0;
-}
-
-void model_dump(struct fpga_ip *c)
-{
-	struct model *m = (struct model *) c->_vd;
-
-	const char *param_type[] = { "UFix", "Fix", "Float", "Boolean" };
-	const char *parameter_dirs[] = { "In", "Out", "In/Out" };
-
-	{ INDENT
-		info("Parameters:");
-		for (size_t i = 0; i < list_length(&m->parameters); i++) { INDENT
-			struct model_parameter *p = (struct model_parameter *) list_at(&m->parameters, i);
-
-			if (p->direction == MODEL_PARAMETER_IN)
-				info("%#jx: %s (%s) = %.3f %s %u",
-					p->offset,
-					p->name,
-					parameter_dirs[p->direction],
-					p->default_value.flt,
-					param_type[p->type],
-					p->binpt
-				);
-			else if (p->direction == MODEL_PARAMETER_OUT)
-				info("%#jx: %s (%s)",
-					p->offset,
-					p->name,
-					parameter_dirs[p->direction]
-				);
-		}
-
-		info("Infos:");
-		for (size_t j = 0; j < list_length(&m->infos); j++) { INDENT
-			struct model_info *i = (struct model_info *) list_at(&m->infos, j);
-
-			info("%s: %s", i->field, i->value);
-		}
-	}
-}
-
-int model_parameter_read(struct model_parameter *p, double *v)
-{
-	struct fpga_ip *c = p->ip;
-
-	union model_parameter_value *ptr = (union model_parameter_value *) (c->card->map + c->baseaddr + p->offset);
-
-	switch (p->type) {
-		case MODEL_PARAMETER_TYPE_UFIX:
-			*v = (double) ptr->ufix / (1 << p->binpt);
-			break;
-
-		case MODEL_PARAMETER_TYPE_FIX:
-			*v = (double) ptr->fix / (1 << p->binpt);
-			break;
-
-		case MODEL_PARAMETER_TYPE_FLOAT:
-			*v = (double) ptr->flt;
-			break;
-
-		case MODEL_PARAMETER_TYPE_BOOLEAN:
-			*v = (double) ptr->ufix ? 1 : 0;
-	}
-
-	return 0;
-}
-
-int model_parameter_write(struct model_parameter *p, double v)
-{
-	struct fpga_ip *c = p->ip;
-
-	union model_parameter_value *ptr = (union model_parameter_value *) (c->card->map + c->baseaddr + p->offset);
-
-	switch (p->type) {
-		case MODEL_PARAMETER_TYPE_UFIX:
-			ptr->ufix = (uint32_t) (v * (1 << p->binpt));
-			break;
-
-		case MODEL_PARAMETER_TYPE_FIX:
-			ptr->fix = (int32_t) (v * (1 << p->binpt));
-			break;
-
-		case MODEL_PARAMETER_TYPE_FLOAT:
-			ptr->flt = (float) v;
-			break;
-
-		case MODEL_PARAMETER_TYPE_BOOLEAN:
-			ptr->bol = (bool) v;
-			break;
-	}
-
-	return 0;
-}
-
-void model_parameter_add(struct fpga_ip *c, const char *name, enum model_parameter_direction dir, enum model_parameter_type type)
-{
-	struct model *m = (struct model *) c->_vd;
-	struct model_parameter *p = (struct model_parameter *) alloc(sizeof(struct model_parameter));
-
-	p->name = strdup(name);
-	p->type = type;
-	p->direction = dir;
-
-	list_push(&m->parameters, p);
-}
-
-int model_parameter_remove(struct fpga_ip *c, const char *name)
-{
-	struct model *m = (struct model *) c->_vd;
-	struct model_parameter *p;
-
-	p = list_lookup(&m->parameters, name);
-	if (!p)
-		return -1;
-
-	list_remove(&m->parameters, p);
-
-	return 0;
-}
-
-int model_parameter_update(struct model_parameter *p, struct model_parameter *u)
-{
-	if (strcmp(p->name, u->name) != 0)
-		return -1;
-
-	p->direction = u->direction;
-	p->type = u->type;
-	p->binpt = u->binpt;
-	p->offset = u->offset;
-
-	return 0;
-}
-
-static struct plugin p_hls = {
-	.name		= "Xilinx High Level Synthesis (HLS) model",
-	.description	= "",
-	.type		= PLUGIN_TYPE_FPGA_IP,
-	.ip		= {
-		.vlnv	= { NULL, "hls", NULL, NULL },
-		.type	= FPGA_IP_TYPE_MODEL,
-		.init	= model_init,
-		.destroy = model_destroy,
-		.dump	= model_dump,
-		.parse	= model_parse
-	}
-};
-
-REGISTER_PLUGIN(&p_hls)
-
-static struct plugin p_sysgen = {
-	.name		= "Xilinx System Generator for DSP (XSG) model",
-	.description	= "",
-	.type		= PLUGIN_TYPE_FPGA_IP,
-	.ip		= {
-		.vlnv	= { NULL, "sysgen", NULL, NULL },
-		.type	= FPGA_IP_TYPE_MODEL,
-		.init	= model_init,
-		.destroy = model_destroy,
-		.dump	= model_dump,
-		.parse	= model_parse,
-		.size	= sizeof(struct model)
-	}
-};
-
-REGISTER_PLUGIN(&p_sysgen)
diff --git a/lib/fpga/ips/rtds_axis.c b/lib/fpga/ips/rtds_axis.c
deleted file mode 100644
index 5468bcfc7..000000000
--- a/lib/fpga/ips/rtds_axis.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/** Driver for AXI Stream wrapper around RTDS_InterfaceModule (rtds_axis )
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-#include <stdint.h>
-
-#include "log.h"
-#include "utils.h"
-#include "plugin.h"
-
-#include "fpga/ip.h"
-#include "fpga/card.h"
-#include "fpga/ips/rtds_axis.h"
-
-void rtds_axis_dump(struct fpga_ip *c)
-{
-	/* Check RTDS_Axis registers */
-	uint32_t *regs = (uint32_t *) (c->card->map + c->baseaddr);
-
-	uint32_t sr = regs[RTDS_AXIS_SR_OFFSET/4];
-	info("RTDS AXI Stream interface details");
-	{ INDENT
-		info("RTDS status:  %#08x", sr);
-		{ INDENT
-			info("Card detected:  %s", sr & RTDS_AXIS_SR_CARDDETECTED ?  CLR_GRN("yes") : CLR_RED("no"));
-			info("Link up:        %s", sr & RTDS_AXIS_SR_LINKUP ?        CLR_GRN("yes") : CLR_RED("no"));
-			info("TX queue full:  %s", sr & RTDS_AXIS_SR_TX_FULL ?       CLR_RED("yes") : CLR_GRN("no"));
-			info("TX in progress: %s", sr & RTDS_AXIS_SR_TX_INPROGRESS ? CLR_YEL("yes") :         "no");
-			info("Case running:   %s", sr & RTDS_AXIS_SR_CASE_RUNNING ?  CLR_GRN("yes") : CLR_RED("no"));
-		}
-
-		info("RTDS control: %#08x", regs[RTDS_AXIS_CR_OFFSET/4]);
-		info("RTDS IRQ coalesc: %u", regs[RTDS_AXIS_COALESC_OFFSET/4]);
-		info("RTDS IRQ version: %#06x", regs[RTDS_AXIS_VERSION_OFFSET/4]);
-		info("RTDS IRQ multi-rate: %u", regs[RTDS_AXIS_MRATE/4]);
-
-		info("RTDS timestep counter: %lu", (uint64_t) regs[RTDS_AXIS_TSCNT_LOW_OFFSET/4] | (uint64_t) regs[RTDS_AXIS_TSCNT_HIGH_OFFSET/4] << 32);
-		info("RTDS timestep period:  %.3f uS", rtds_axis_dt(c) * 1e6);
-	}
-}
-
-double rtds_axis_dt(struct fpga_ip *c)
-{
-	uint32_t *regs = (uint32_t *) (c->card->map + c->baseaddr);
-	uint16_t dt = regs[RTDS_AXIS_TS_PERIOD_OFFSET/4];
-
-	return (dt == 0xFFFF) ? -1.0 : (double) dt / RTDS_HZ;
-}
-
-static struct plugin p = {
-	.name		= "RTDS's AXI4-Stream - GTFPGA interface",
-	.description	= "",
-	.type		= PLUGIN_TYPE_FPGA_IP,
-	.ip		= {
-		.vlnv	= { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL },
-		.type	= FPGA_IP_TYPE_INTERFACE,
-		.dump	= rtds_axis_dump,
-		.size	= 0
-	}
-};
-
-REGISTER_PLUGIN(&p)
diff --git a/lib/fpga/ips/switch.c b/lib/fpga/ips/switch.c
deleted file mode 100644
index 261832062..000000000
--- a/lib/fpga/ips/switch.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/** AXI Stream interconnect related helper functions
- *
- * These functions present a simpler interface to Xilinx' AXI Stream switch driver (XAxis_Switch_*)
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-#include "list.h"
-#include "log.h"
-#include "log_config.h"
-#include "plugin.h"
-
-#include "fpga/ip.h"
-#include "fpga/card.h"
-#include "fpga/ips/switch.h"
-
-int switch_start(struct fpga_ip *c)
-{
-	int ret;
-
-	struct fpga_card *f = c->card;
-	struct sw *sw = (struct sw *) c->_vd;
-
-	XAxis_Switch *xsw = &sw->inst;
-
-	if (c != f->sw)
-		error("There can be only one AXI4-Stream interconnect per FPGA");
-
-
-	/* Setup AXI-stream switch */
-	XAxis_Switch_Config sw_cfg = {
-		.BaseAddress = (uintptr_t) f->map + c->baseaddr,
-		.MaxNumMI = sw->num_ports,
-		.MaxNumSI = sw->num_ports
-	};
-
-	ret = XAxisScr_CfgInitialize(xsw, &sw_cfg, (uintptr_t) c->card->map + c->baseaddr);
-	if (ret != XST_SUCCESS)
-		return -1;
-
-	/* Disable all masters */
-	XAxisScr_RegUpdateDisable(xsw);
-	XAxisScr_MiPortDisableAll(xsw);
-	XAxisScr_RegUpdateEnable(xsw);
-
-	switch_init_paths(c);
-
-	return 0;
-}
-
-int switch_init_paths(struct fpga_ip *c)
-{
-	int ret;
-	struct sw *sw = (struct sw *) c->_vd;
-
-	XAxis_Switch *xsw = &sw->inst;
-
-	XAxisScr_RegUpdateDisable(xsw);
-	XAxisScr_MiPortDisableAll(xsw);
-
-	for (size_t i = 0; i < list_length(&sw->paths); i++) {
-		struct sw_path *p = (struct sw_path *) list_at(&sw->paths, i);
-		struct fpga_ip *mi, *si;
-
-		mi = list_lookup(&c->card->ips, p->out);
-		si = list_lookup(&c->card->ips, p->in);
-
-		if (!mi || !si || mi->port == -1 || si->port == -1)
-			error("Invalid path configuration for FPGA");
-
-		ret = switch_connect(c, mi, si);
-		if (ret)
-			error("Failed to configure switch");
-	}
-
-	XAxisScr_RegUpdateEnable(xsw);
-
-	return 0;
-}
-
-int switch_destroy(struct fpga_ip *c)
-{
-	struct sw *sw = (struct sw *) c->_vd;
-
-	list_destroy(&sw->paths, NULL, true);
-
-	return 0;
-}
-
-int switch_parse(struct fpga_ip *c, json_t *cfg)
-{
-	struct sw *sw = (struct sw *) c->_vd;
-
-	int ret;
-	size_t index;
-	json_error_t err;
-	json_t *json_path, *json_paths = NULL;
-
-	list_init(&sw->paths);
-
-	ret = json_unpack_ex(cfg, &err, 0, "{ s: i, s?: o }",
-		"num_ports", &sw->num_ports,
-		"paths", &json_paths
-	);
-	if (ret)
-		jerror(&err, "Failed to parse configuration of FPGA IP '%s'", c->name);
-
-	if (!json_paths)
-		return 0; /* no switch config available */
-
-	if (!json_is_array(json_paths))
-		error("Setting 'paths' of FPGA IP '%s' should be an array of JSON objects", c->name);
-
-	json_array_foreach(json_paths, index, json_path) {
-		struct sw_path *p = (struct sw_path *) alloc(sizeof(struct sw_path));
-		int reverse = 0;
-
-		ret = json_unpack_ex(json_path, &err, 0, "{ s?: b, s: s, s: s }",
-			"reverse", &reverse,
-			"in", &p->in,
-			"out", &p->out
-		);
-		if (ret)
-			jerror(&err, "Failed to parse path %zu of FPGA IP '%s'", index, c->name);
-
-		list_push(&sw->paths, p);
-
-		if (reverse) {
-			struct sw_path *r = memdup(p, sizeof(struct sw_path));
-
-			r->in = p->out;
-			r->out = p->in;
-
-			list_push(&sw->paths, r);
-		}
-	}
-
-	return 0;
-}
-
-int switch_connect(struct fpga_ip *c, struct fpga_ip *mi, struct fpga_ip *si)
-{
-	struct sw *sw = (struct sw *) c->_vd;
-	XAxis_Switch *xsw = &sw->inst;
-
-	uint32_t mux, port;
-
-	/* Check if theres already something connected */
-	for (int i = 0; i < sw->num_ports; i++) {
-		mux = XAxisScr_ReadReg(xsw->Config.BaseAddress, XAXIS_SCR_MI_MUX_START_OFFSET + i * 4);
-		if (!(mux & XAXIS_SCR_MI_X_DISABLE_MASK)) {
-			port = mux & ~XAXIS_SCR_MI_X_DISABLE_MASK;
-
-			if (port == si->port) {
-				warn("Switch: Slave port %s (%u) has been connected already to port %u. Disconnecting...", si->name, si->port, i);
-				XAxisScr_RegUpdateDisable(xsw);
-				XAxisScr_MiPortDisable(xsw, i);
-				XAxisScr_RegUpdateEnable(xsw);
-			}
-		}
-	}
-
-	/* Reconfigure switch */
-	XAxisScr_RegUpdateDisable(xsw);
-	XAxisScr_MiPortEnable(xsw, mi->port, si->port);
-	XAxisScr_RegUpdateEnable(xsw);
-
-	/* Reset IPs */
-	/*ip_reset(mi);
-	ip_reset(si);*/
-
-	debug(8, "FPGA: Switch connected %s (%u) to %s (%u)", mi->name, mi->port, si->name, si->port);
-
-	return 0;
-}
-
-int switch_disconnect(struct fpga_ip *c, struct fpga_ip *mi, struct fpga_ip *si)
-{
-	struct sw *sw = (struct sw *) c->_vd;
-	XAxis_Switch *xsw = &sw->inst;
-
-	if (!XAxisScr_IsMiPortEnabled(xsw, mi->port, si->port))
-		return -1;
-
-	XAxisScr_MiPortDisable(xsw, mi->port);
-
-	return 0;
-}
-
-static struct plugin p = {
-	.name		= "Xilinx's AXI4-Stream switch",
-	.description	= "",
-	.type		= PLUGIN_TYPE_FPGA_IP,
-	.ip		= {
-		.vlnv	= { "xilinx.com", "ip", "axis_interconnect", NULL },
-		.type	= FPGA_IP_TYPE_MISC,
-		.start	= switch_start,
-		.destroy = switch_destroy,
-		.parse	= switch_parse,
-		.size	= sizeof(struct sw)
-	}
-};
-
-REGISTER_PLUGIN(&p)
diff --git a/lib/fpga/ips/timer.c b/lib/fpga/ips/timer.c
deleted file mode 100644
index b45e89c78..000000000
--- a/lib/fpga/ips/timer.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/** Timer related helper functions
- *
- * These functions present a simpler interface to Xilinx' Timer Counter driver (XTmrCtr_*)
- *
- * @file
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-#include "config.h"
-#include "plugin.h"
-
-#include "fpga/ip.h"
-#include "fpga/card.h"
-#include "fpga/ips/timer.h"
-
-int timer_start(struct fpga_ip *c)
-{
-	struct fpga_card *f = c->card;
-	struct timer *tmr = (struct timer *) c->_vd;
-
-	XTmrCtr *xtmr = &tmr->inst;
-	XTmrCtr_Config xtmr_cfg = {
-		.BaseAddress = (uintptr_t) f->map + c->baseaddr,
-		.SysClockFreqHz = FPGA_AXI_HZ
-	};
-
-	XTmrCtr_CfgInitialize(xtmr, &xtmr_cfg, (uintptr_t) f->map + c->baseaddr);
-	XTmrCtr_InitHw(xtmr);
-
-	return 0;
-}
-
-static struct plugin p = {
-	.name		= "Xilinx's programmable timer / counter",
-	.description	= "",
-	.type		= PLUGIN_TYPE_FPGA_IP,
-	.ip		= {
-		.vlnv	= { "xilinx.com", "ip", "axi_timer", NULL },
-		.type	= FPGA_IP_TYPE_MISC,
-		.start	= timer_start,
-		.size	= sizeof(struct timer)
-	}
-};
-
-REGISTER_PLUGIN(&p)
diff --git a/lib/fpga/vlnv.c b/lib/fpga/vlnv.c
deleted file mode 100644
index 582e42d8f..000000000
--- a/lib/fpga/vlnv.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/** Vendor, Library, Name, Version (VLNV) tag
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
- * @license GNU General Public License (version 3)
- *
- * VILLASnode
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *********************************************************************************/
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "fpga/vlnv.h"
-#include "fpga/ip.h"
-
-struct fpga_ip * fpga_vlnv_lookup(struct list *l, struct fpga_vlnv *v)
-{
-	return (struct fpga_ip *) list_search(l, (cmp_cb_t) fpga_vlnv_cmp, v);
-}
-
-int fpga_vlnv_cmp(struct fpga_vlnv *a, struct fpga_vlnv *b)
-{
-	return ((!a->vendor  || !b->vendor  || !strcmp(a->vendor,  b->vendor ))	&&
-		(!a->library || !b->library || !strcmp(a->library, b->library))	&&
-		(!a->name    || !b->name    || !strcmp(a->name,    b->name   ))	&&
-		(!a->version || !b->version || !strcmp(a->version, b->version))) ? 0 : 1;
-}
-
-int fpga_vlnv_parse(struct fpga_vlnv *c, const char *vlnv)
-{
-	char *tmp = strdup(vlnv);
-
-	c->vendor  = strdup(strtok(tmp, ":"));
-	c->library = strdup(strtok(NULL, ":"));
-	c->name    = strdup(strtok(NULL, ":"));
-	c->version = strdup(strtok(NULL, ":"));
-
-	free(tmp);
-
-	return 0;
-}
-
-int fpga_vlnv_destroy(struct fpga_vlnv *v)
-{
-	free(v->vendor);
-	free(v->library);
-	free(v->name);
-	free(v->version);
-
-	return 0;
-}
diff --git a/lib/nodes/Makefile.inc b/lib/nodes/Makefile.inc
index c3ed7bb50..46cff0df2 100644
--- a/lib/nodes/Makefile.inc
+++ b/lib/nodes/Makefile.inc
@@ -38,7 +38,7 @@ WITH_SHMEM     ?= 1
 WITH_STATS     ?= 1
 WITH_INFLUXDB  ?= 1
 WITH_AMQP      ?= 1
-WITH_IEC61850  ?= 1
+WITH_IEC61850  ?= 0
 
 # Enabled loopback node-type
 ifeq ($(WITH_LOOPBACK),1)
@@ -97,15 +97,12 @@ ifneq ($(or $(wildcard /usr/include/libiec61850/*), $(wildcard /usr/local/includ
 endif
 endif
 
-# Enable VILLASfpga support when libxil is available
+# Enable VILLASfpga support when libvillas-fpga is available
 ifeq ($(WITH_FPGA),1)
-ifeq ($(shell $(PKGCONFIG) libxil; echo $$?),0)
-	LIB_SRCS += $(addprefix lib/nodes/, fpga.c) \
-	            $(addprefix lib/kernel/, pci.c vfio.c) \
+ifeq ($(shell $(PKGCONFIG) libvillas-fpga; echo $$?),0)
+	LIB_SRCS += lib/nodes/fpga.c
 
-	include lib/fpga/Makefile.inc
-
-	LIB_PKGS    += libxil
+	LIB_PKGS    += libvillas-fpga
 	LIB_CFLAGS += -DWITH_FPGA
 endif
 endif
diff --git a/packaging/docker/Dockerfile.dev b/packaging/docker/Dockerfile.dev
index 1dd29df21..a31e984d8 100644
--- a/packaging/docker/Dockerfile.dev
+++ b/packaging/docker/Dockerfile.dev
@@ -81,7 +81,6 @@ RUN dnf -y install \
 	libwebsockets-devel \
 	zeromq-devel \
 	nanomsg-devel \
-	libxil-devel \
 	protobuf-c-devel \
 	libiec61850-devel
 
diff --git a/packaging/docker/Dockerfile.dev-centos b/packaging/docker/Dockerfile.dev-centos
index 207cd5d2b..1817b5bb0 100644
--- a/packaging/docker/Dockerfile.dev-centos
+++ b/packaging/docker/Dockerfile.dev-centos
@@ -81,7 +81,6 @@ RUN yum -y install \
 	libnl3-devel \
 	zeromq-devel \
 	nanomsg-devel \
-	libxil-devel \
 	protobuf-c-devel \
 	libiec61850-devel
 
diff --git a/packaging/docker/Dockerfile.dev-ubuntu b/packaging/docker/Dockerfile.dev-ubuntu
index d28c57071..e1fda2518 100644
--- a/packaging/docker/Dockerfile.dev-ubuntu
+++ b/packaging/docker/Dockerfile.dev-ubuntu
@@ -86,10 +86,6 @@ RUN apt-get update && apt-get install -y \
 COPY thirdparty/criterion /tmp/criterion
 RUN mkdir -p /tmp/criterion/build && cd /tmp/criterion/build && cmake .. && make install && rm -rf /tmp/*
 
-# Build & Install libxil
-COPY thirdparty/libxil /tmp/libxil
-RUN mkdir -p /tmp/libxil/build && cd /tmp/libxil/build && cmake .. && make install && rm -rf /tmp/*
-
 # Build & Install libwebsockets
 COPY thirdparty/libwebsockets /tmp/libwebsockets
 RUN mkdir -p /tmp/libwebsockets/build && cd /tmp/libwebsockets/build && cmake -DLWS_IPV6=1 -DLWS_WITH_STATIC=0 -DLWS_WITHOUT_TESTAPPS=1 -DLWS_WITH_HTTP2=1 .. && make install && rm -rf /tmp/*
diff --git a/src/Makefile.inc b/src/Makefile.inc
index fb9c06680..19d3e081e 100644
--- a/src/Makefile.inc
+++ b/src/Makefile.inc
@@ -39,28 +39,10 @@ ifeq ($(WITH_WEBSOCKET),1)
 endif
 endif
 
-# Enable VILLASfpga support when libxil is available
-ifeq ($(shell $(PKGCONFIG) libxil; echo $$?),0)
-	LIB_SRCS    += $(addprefix lib/nodes/, fpga.c)
-	LIB_SRCS    += $(addprefix lib/kernel/, pci.c vfio.c)
-	LIB_SRCS    += $(wildcard  lib/fpga/*.c)
-	TARGETS     += $(BUILDDIR)/villas-fpga
-	PKGS        += libxil
-
-	# Add support for LAPACK / BLAS benchmarks / solvers
-	ifeq ($(shell $(PKGCONFIG) blas lapack; echo $$?),0)
-		PKGS        += blas lapack
-		BENCH_OBJS  += fpga-bench-overruns.o
-	endif
-endif
-
 src: $(TARGETS)
 
 $(TARGETS): $(BUILDDIR)/villas-%: $(BUILDDIR)/src/%.o
 
-# Some additional prereqs for individual binaries
-$(BUILDDIR)/villas-fpga: $(addprefix $(BUILDDIR)/src/,fpga-bench.o $(BENCH_OBJS))
-
 # Compile executable objects
 $(BUILDDIR)/src/%.o: src/%.c | $$(dir $$@)
 	$(CC) $(SRC_CFLAGS) -c $< -o $@
diff --git a/src/fpga-bench-overruns.c b/src/fpga-bench-overruns.c
deleted file mode 100644
index 4e82a2dd5..000000000
--- a/src/fpga-bench-overruns.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/** Benchmarks for VILLASfpga: LAPACK & BLAS
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-#include <stdio.h>
-#include <sys/utsname.h>
-
-#include <fpga/card.h>
-#include <fpga/ip.h>
-#include <fpga/ips/switch.h>
-#include <fpga/ips/intc.h>
-#include <utils.h>
-#include <villas/log.h>
-
-/* Some hard-coded configuration for the FPGA benchmarks */
-#define BENCH_WARMUP		100
-
-/* Declared in fpga-bench.c */
-extern int intc_flags;
-extern struct utsname uts;
-
-/* LAPACK & BLAS Fortran prototypes */
-extern int dgemm_(char *transa, char *transb, int *m, int *n, int *k, double *alpha, double *a, int *lda, double *b, int *ldb, double *beta, double *c, int *ldc);
-extern int dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info);
-extern int dgetri_(int *n, double *a, int *lda, int *ipiv, double *work, int *lwork, int *info);
-
-static int lapack_generate_workload(int N, double *C)
-{
-	double *A = alloc(N * N * sizeof(double));
-
-	srand(time(NULL));
-
-	for (int i = 0; i < N * N; i++)
-		A[i] = 100 * (double) rand() / RAND_MAX + 1;
-
-	char transA = 'T';
-	char transB = 'N';
-	double alpha = 1;
-	double beta = 1;
-
-	/* C = A' * A, to get an invertible matrix */
-	dgemm_(&transA, &transB, &N, &N, &N, &alpha, A, &N, A, &N, &beta, C, &N);
-
-	free(A);
-
-	return 0;
-}
-
-static int lapack_workload(int N, double *A)
-{
-	int info = 0;
-	int lworkspace = N;
-	int ipiv[N];
-	double workspace[N];
-
-	dgetrf_(&N, &N, A, &N, ipiv, &info);
-	if (info > 0)
-		error("Failed to pivot matrix");
-
-	dgetri_(&N, A, &N, ipiv, workspace, &lworkspace, &info);
-	if (info > 0)
-		error("Failed to LU factorized matrix");
-
-	return 0;
-}
-
-int fpga_benchmark_overruns(struct fpga_card *c)
-{
-	struct fpga_ip *rtds, *dm;
-
-	dm = list_lookup(&c->ips, "dma_1");
-	rtds = list_lookup(&c->ips, "rtds_axis_0");
-	if (!rtds || !c->intc)
-		return -1;
-
-	int ret;
-	float period = 50e-6;
-	int runs = 1.0 / period;
-	int overruns;
-
-	info("runs = %u", runs);
-
-	switch_connect(c->sw, dm, rtds);
-	switch_connect(c->sw, rtds, dm);
-
-	intc_enable(c->intc, (1 << (dm->irq + 1  )), intc_flags);
-
-	/* Dump results */
-	char fn[256];
-	snprintf(fn, sizeof(fn), "results/overruns_lu_rtds_axis_%s_%s.dat", intc_flags & INTC_POLLING ? "polling" : "irq", uts.release);
-	FILE *g = fopen(fn, "w");
-	fprintf(g, "# period = %f\n", period);
-	fprintf(g, "# runs = %u\n", runs);
-
-	struct dma_mem mem;
-	ret = dma_alloc(dm, &mem, 0x1000, 0);
-	if (ret)
-		error("Failed to allocate DMA memory");
-
-	uint32_t *data_rx = (uint32_t *) mem.base_virt;
-	uint32_t *data_tx = (uint32_t *) mem.base_virt + 0x200;
-	uint64_t total, start, stop;
-	for (int p = 3; p < 45; p++) {
-		double *A = alloc(p*p*sizeof(double));
-
-		lapack_generate_workload(p, A);
-
-		overruns = 0;
-		total = 0;
-
-		for (int i = 0; i < 2000; i++) {
-			dma_read(dm, mem.base_phys, 0x200);
-			dma_read_complete(dm, NULL, NULL);
-		}
-
-		for (int i = 0; i < runs + BENCH_WARMUP; i++) {
-			dma_read(dm, mem.base_phys, 0x200);
-
-			start = rdtsc();
-			lapack_workload(p, A);
-			stop = rdtsc();
-
-			dma_read_complete(dm, NULL, NULL);
-
-			/* Send data to rtds */
-			data_tx[0] = i;
-			dma_write(dm, mem.base_phys + 0x200, 64 * sizeof(data_tx[0]));
-
-			if (i < BENCH_WARMUP)
-				continue;
-
-			if (i - data_rx[0] > 2)
-				overruns++;
-			total += stop - start;
-		}
-
-		free(A);
-
-		info("iter = %u clks = %ju overruns = %u", p, total / runs, overruns);
-		fprintf(g, "%u %ju %u\n", p, total / runs, overruns);
-
-		if (overruns >= runs)
-			break;
-	}
-
-	fclose(g);
-	return 0;
-}
diff --git a/src/fpga-bench.c b/src/fpga-bench.c
deleted file mode 100644
index a4c821ee0..000000000
--- a/src/fpga-bench.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/** Benchmarks for VILLASfpga
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/utsname.h>
-
-#include <villas/utils.h>
-#include <villas/log.h>
-#include <villas/timing.h>
-
-#include <villas/fpga/ip.h>
-#include <villas/fpga/card.h>
-#include <villas/fpga/ips/intc.h>
-#include <villas/fpga/ips/timer.h>
-
-#include "config.h"
-
-/* Some hard-coded configuration for the FPGA benchmarks */
-#define BENCH_DM		3
-// 1 FIFO
-// 2 DMA SG
-// 3 DMA Simple
-
-#define BENCH_RUNS		3000000
-#define BENCH_WARMUP		100
-#define BENCH_DM_EXP_MIN	0
-#define BENCH_DM_EXP_MAX	20
-
-int fpga_benchmark_datamover(struct fpga_card *c);
-int fpga_benchmark_jitter(struct fpga_card *c);
-int fpga_benchmark_memcpy(struct fpga_card *c);
-int fpga_benchmark_latency(struct fpga_card *c);
-
-#if defined(WITH_BLAS) && defined(WITH_LAPACK)
-int fpga_benchmark_overruns(struct fpga_card *c);
-#endif
-
-int intc_flags = 0;
-struct utsname uts;
-
-int fpga_benchmarks(int argc, char *argv[], struct fpga_card *c)
-{
-	int ret;
-	struct bench {
-		const char *name;
-		int (*func)(struct fpga_card *c);
-	} benchmarks[] = {
-		{ "datamover",	fpga_benchmark_datamover },
-		{ "jitter",	fpga_benchmark_jitter },
-		{ "memcpy",	fpga_benchmark_memcpy },
-#if defined(WITH_BLAS) && defined(WITH_LAPACK)
-		{ "overruns",	fpga_benchmark_overruns },
-#endif
-		{ "latency",	fpga_benchmark_latency }
-	};
-
-	if (argc < 2)
-		error("Usage: fpga benchmark (bench)");
-
-	struct bench *bench = NULL;
-	for (int i = 0; i < ARRAY_LEN(benchmarks); i++) {
-		if (strcmp(benchmarks[i].name, argv[1]) == 0) {
-			bench = &benchmarks[i];
-			break;
-		}
-	}
-
-	if (bench == NULL)
-		error("There is no benchmark named: %s", argv[1]);
-
-	ret = uname(&uts);
-	if (ret)
-		return -1;
-
-again:	ret = bench->func(c);
-	if (ret)
-		error("Benchmark %s failed", bench->name);
-
-	/* Rerun test with polling */
-	if (intc_flags == 0) {
-		intc_flags |= INTC_POLLING;
-		getchar();
-		goto again;
-	}
-
-	return -1;
-}
-
-int fpga_benchmark_jitter(struct fpga_card *c)
-{
-	int ret;
-
-	struct fpga_ip *ip = list_lookup(&c->ips, "timer_0");
-	if (!ip || !c->intc)
-		return -1;
-
-	struct timer *tmr = (struct timer *) ip->_vd;
-
-	XTmrCtr *xtmr = &tmr->inst;
-
-	ret = intc_enable(c->intc, (1 << ip->irq), intc_flags);
-	if (ret)
-		error("Failed to enable interrupt");
-
-	float period = 50e-6;
-	int runs = 300.0 / period;
-
-	int *hist = alloc(8 << 20);
-
-	XTmrCtr_SetOptions(xtmr, 0, XTC_INT_MODE_OPTION | XTC_EXT_COMPARE_OPTION | XTC_DOWN_COUNT_OPTION | XTC_AUTO_RELOAD_OPTION);
-	XTmrCtr_SetResetValue(xtmr, 0, period * FPGA_AXI_HZ);
-	XTmrCtr_Start(xtmr, 0);
-
-	uint64_t end, start = rdtsc();
-	for (int i = 0; i < runs; i++) {
-		uint64_t cnt = intc_wait(c->intc, ip->irq);
-		if (cnt != 1)
-			warn("fail");
-
-		/* Ackowledge IRQ */
-		XTmrCtr_WriteReg((uintptr_t) c->map + ip->baseaddr, 0, XTC_TCSR_OFFSET, XTmrCtr_ReadReg((uintptr_t) c->map + ip->baseaddr, 0, XTC_TCSR_OFFSET));
-
-		end = rdtsc();
-		hist[i] = end - start;
-		start = end;
-	}
-
-	XTmrCtr_Stop(xtmr, 0);
-
-	char fn[256];
-	snprintf(fn, sizeof(fn), "results/jitter_%s_%s.dat", intc_flags & INTC_POLLING ? "polling" : "irq", uts.release);
-	FILE *g = fopen(fn, "w");
-	for (int i = 0; i < runs; i++)
-		fprintf(g, "%u\n", hist[i]);
-	fclose(g);
-
-	free(hist);
-
-	ret = intc_disable(c->intc, (1 << ip->irq));
-	if (ret)
-		error("Failed to disable interrupt");
-
-	return 0;
-}
-
-int fpga_benchmark_latency(struct fpga_card *c)
-{
-	int ret;
-
-	uint64_t start, end;
-
-	if (!c->intc)
-		return -1;
-
-	int runs = 1000000;
-	int hist[runs];
-
-	ret = intc_enable(c->intc, 0x100, intc_flags);
-	if (ret)
-		error("Failed to enable interrupts");
-
-	for (int i = 0; i < runs; i++) {
-		start = rdtsc();
-		XIntc_Out32((uintptr_t) c->map + c->intc->baseaddr + XIN_ISR_OFFSET, 0x100);
-
-		intc_wait(c->intc, 8);
-		end = rdtsc();
-
-		hist[i] = end - start;
-	}
-
-	char fn[256];
-	snprintf(fn, sizeof(fn), "results/latency_%s_%s.dat", intc_flags & INTC_POLLING ? "polling" : "irq", uts.release);
-	FILE *g = fopen(fn, "w");
-	for (int i = 0; i < runs; i++)
-		fprintf(g, "%u\n", hist[i]);
-	fclose(g);
-
-	ret = intc_disable(c->intc, 0x100);
-	if (ret)
-		error("Failed to disable interrupt");
-
-	return 0;
-}
-
-int fpga_benchmark_datamover(struct fpga_card *c)
-{
-	int ret;
-
-	struct fpga_ip *dm;
-	struct dma_mem mem, src, dst;
-
-#if BENCH_DM == 1
-	char *dm_name = "fifo_mm_s_0";
-#elif BENCH_DM == 2
-	char *dm_name = "dma_0";
-#elif BENCH_DM == 3
-	char *dm_name = "dma_1";
-#endif
-
-	dm = list_lookup(&c->ips, dm_name);
-	if (!dm)
-		error("Unknown datamover");
-
-	ret = switch_connect(c->sw, dm, dm);
-	if (ret)
-		error("Failed to configure switch");
-
-	ret = intc_enable(c->intc, (1 << dm->irq) | (1 << (dm->irq + 1)), intc_flags);
-	if (ret)
-		error("Failed to enable interrupt");
-
-	/* Allocate DMA memory */
-	ret = dma_alloc(dm, &mem, 2 * (1 << BENCH_DM_EXP_MAX), 0);
-	if (ret)
-		error("Failed to allocate DMA memory");
-
-	ret = dma_mem_split(&mem, &src, &dst);
-	if (ret)
-		return -1;
-
-	/* Open file for results */
-	char fn[256];
-	snprintf(fn, sizeof(fn), "results/datamover_%s_%s_%s.dat", dm_name, intc_flags & INTC_POLLING ? "polling" : "irq", uts.release);
-	FILE *g = fopen(fn, "w");
-
-	for (int exp = BENCH_DM_EXP_MIN; exp <= BENCH_DM_EXP_MAX; exp++) {
-		uint64_t start, stop, total = 0, len = 1 << exp;
-
-#if BENCH_DM == 1
-		if (exp > 11)
-			break; /* FIFO and Simple DMA are limited to 4kb */
-#elif BENCH_DM == 3
-		if (exp >= 12)
-			break; /* FIFO and Simple DMA are limited to 4kb */
-#endif
-
-		read_random(src.base_virt, len);
-		memset(dst.base_virt, 0, len);
-
-		info("Start DM bench: len=%#jx", len);
-
-		uint64_t runs = BENCH_RUNS >> exp;
-		for (int i = 0; i < runs + BENCH_WARMUP; i++) {
-			start = rdtsc();
-#if BENCH_DM == 1
-			ssize_t ret;
-
-			ret = fifo_write(dm, src.base_virt, len);
-			if (ret < 0)
-				error("Failed write to FIFO with len = %zu", len);
-
-			ret = fifo_read(dm, dst.base_virt, dst.len);
-			if (ret < 0)
-				error("Failed read from FIFO with len = %zu", len);
-#else
-			ret = dma_ping_pong(dm, src.base_phys, dst.base_phys, len);
-			if (ret)
-				error("DMA ping pong failed");
-#endif
-			stop = rdtsc();
-
-			if (memcmp(src.base_virt, dst.base_virt, len))
-				warn("Compare failed");
-
-			if (i > BENCH_WARMUP)
-				total += stop - start;
-		}
-
-		info("exp %u avg %lu", exp, total / runs);
-		fprintf(g, "%lu %lu\n", len, total / runs);
-	}
-
-	fclose(g);
-
-	ret = switch_disconnect(c->sw, dm, dm);
-	if (ret)
-		error("Failed to configure switch");
-
-	ret = dma_free(dm, &mem);
-	if (ret)
-		error("Failed to release DMA memory");
-
-	ret = intc_disable(c->intc, (1 << dm->irq) | (1 << (dm->irq + 1)));
-	if (ret)
-		error("Failed to enable interrupt");
-
-
-	return 0;
-}
-
-int fpga_benchmark_memcpy(struct fpga_card *c)
-{
-	char *map = c->map + 0x200000;
-	uint32_t *mapi = (uint32_t *) map;
-
-	char fn[256];
-	snprintf(fn, sizeof(fn), "results/bar0_%s_%s.dat", intc_flags & INTC_POLLING ? "polling" : "irq", uts.release);
-	FILE *g = fopen(fn, "w");
-	fprintf(g, "# bytes cycles\n");
-
-	uint32_t dummy = 0;
-
-	for (int exp = BENCH_DM_EXP_MIN; exp <= BENCH_DM_EXP_MAX; exp++) {
-		uint64_t len = 1 << exp;
-		uint64_t start, end, total = 0;
-		uint64_t runs = (BENCH_RUNS << 2) >> exp;
-
-		for (int i = 0; i < runs + BENCH_WARMUP; i++) {
-			start = rdtsc();
-
-			for (int j = 0; j < len / 4; j++)
-//				mapi[j] = j;		// write
-				dummy += mapi[j];	// read
-
-			end = rdtsc();
-
-			if (i > BENCH_WARMUP)
-				total += end - start;
-		}
-
-		info("exp = %u\truns = %ju\ttotal = %ju\tavg = %ju\tavgw = %ju", exp, runs, total, total / runs, total / (runs * len));
-		fprintf(g, "%zu %lu %ju\n", len, total / runs, runs);
-	}
-
-	fclose(g);
-
-	return 0;
-}
diff --git a/src/fpga.c b/src/fpga.c
deleted file mode 100644
index 2f7d4f853..000000000
--- a/src/fpga.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/** VILLASfpga utility for tests and benchmarks
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- **********************************************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <getopt.h>
-
-#include <villas/log.h>
-#include <villas/super_node.h>
-#include <villas/timing.h>
-#include <villas/utils.h>
-#include <villas/memory.h>
-#include <villas/nodes/fpga.h>
-#include <villas/kernel/rt.h>
-#include <villas/kernel/pci.h>
-#include <villas/kernel/kernel.h>
-
-#include <villas/fpga/card.h>
-
-/* Declarations */
-int fpga_benchmarks(int argc, char *argv[], struct fpga_card *c);
-
-void usage()
-{
-	printf("Usage: villas-fpga [OPTIONS] CONFIG CARD\n\n");
-	printf("  CONFIG  path to a configuration file\n");
-	printf("  CARD    name of the FPGA card\n");
-	printf("  OPTIONS is one or more of the following options:\n");
-	printf("    -d      set log level\n");
-	printf("    -h      show this help\n");
-	printf("    -V      show the version of the tool\n");
-	printf("\n");
-	print_copyright();
-}
-
-int main(int argc, char *argv[])
-{
-	int ret;
-
-	struct super_node sn;
-	struct fpga_card *card;
-
-	/* Parse arguments */
-	char c, *endptr;
-	while ((c = getopt(argc, argv, "Vd:h")) != -1) {
-		switch (c) {
-			case 'V':
-				print_version();
-				exit(EXIT_SUCCESS);
-			case 'd':
-				sn.log.level = strtoul(optarg, &endptr, 10);
-				goto check;
-
-			case 'h':
-			case '?':
-			default:
-				usage();
-				exit(EXIT_SUCCESS);
-		}
-
-check:		if (optarg == endptr)
-			error("Failed to parse parse option argument '-%c %s'", c, optarg);
-	}
-
-	if (argc != optind + 2) {
-		usage();
-		exit(EXIT_FAILURE);
-	}
-
-	char *configfile = argv[optind];
-
-	super_node_init(&sn);
-	super_node_parse_uri(&sn, configfile);
-
-	log_init(&sn.log, sn.log.level, sn.log.facilities);
-	rt_init(sn.priority, sn.affinity);
-	memory_init(sn.hugepages);
-
-	/* Initialize VILLASfpga card */
-	ret = fpga_init(&sn);
-	if (ret)
-		error("Failed to initialize FPGA card");
-
-	card = fpga_lookup_card(argv[2]);
-	if (!card)
-		error("FPGA card '%s' does not exist", argv[2]);
-
-	fpga_card_dump(card);
-
-	/* Run benchmarks */
-	fpga_benchmarks(argc-optind-1, argv+optind+1, card);
-
-	/* Shutdown */
-	ret = fpga_deinit();
-	if (ret)
-		error("Failed to de-initialize FPGA card");
-
-	super_node_destroy(&sn);
-
-	return 0;
-}
diff --git a/tests/unit/fpga.c b/tests/unit/fpga.c
deleted file mode 100644
index 5b9647f00..000000000
--- a/tests/unit/fpga.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/** Test procedures for VILLASfpga
- *
- * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
- * @copyright 2017, Steffen Vogel
- *********************************************************************************/
-
-#ifdef WITH_FPGA
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <math.h>
-
-#include <criterion/criterion.h>
-#include <criterion/options.h>
-
-#include <xilinx/xtmrctr.h>
-
-#include <villas/super_node.h>
-#include <villas/utils.h>
-#include <villas/nodes/fpga.h>
-
-#include <villas/fpga/ip.h>
-#include <villas/fpga/card.h>
-#include <villas/fpga/vlnv.h>
-
-#include <villas/fpga/ips/intc.h>
-#include <villas/fpga/ips/timer.h>
-
-#define TEST_CONFIG	"/villas/etc/fpga.conf"
-#define TEST_LEN	0x1000
-
-#define CPU_HZ		3392389000
-#define FPGA_AXI_HZ	125000000
-
-static struct list cards;
-static struct fpga_card *card;
-static struct super_node sn = { .state = STATE_DESTROYED };
-static struct pci pci;
-static struct vfio_container vc;
-
-static void init()
-{
-	int ret;
-
-	ret = super_node_init(&sn);
-	cr_assert_eq(ret, 0, "Failed to initialize Supernode");
-
-	ret = super_node_parse_uri(&sn, TEST_CONFIG);
-	cr_assert_eq(ret, 0, "Failed to parse configuration");
-
-	ret = super_node_check(&sn);
-	cr_assert_eq(ret, 0, "Failed to check configuration");
-
-	ret = pci_init(&pci);
-	cr_assert_eq(ret, 0, "Failed to initialize PCI sub-system");
-
-	ret = vfio_init(&vc);
-	cr_assert_eq(ret, 0, "Failed to initiliaze VFIO sub-system");
-
-	/* Parse FPGA configuration */
-	list_init(&cards);
-	ret = fpga_card_parse_list(&cards, sn.cfg);
-	cr_assert_eq(ret, 0, "Failed to parse FPGA config");
-
-	card = list_lookup(&cards, "vc707");
-	cr_assert(card, "FPGA card not found");
-
-	if (criterion_options.logging_threshold < CRITERION_IMPORTANT)
-		fpga_card_dump(card);
-}
-
-static void fini()
-{
-	int ret;
-
-	ret = fpga_card_destroy(card);
-	cr_assert_eq(ret, 0, "Failed to de-initilize FPGA");
-
-	super_node_destroy(&sn);
-}
-
-TestSuite(fpga,
-	.init = init,
-	.fini = fini,
-	.description = "VILLASfpga",
-	.disabled = true);
-
-Test(fpga, intc, .description = "Interrupt Controller")
-{
-	int ret;
-	uint32_t isr;
-
-	cr_assert(card->intc);
-
-	ret = intc_enable(card->intc, 0xFF00, 0);
-	cr_assert_eq(ret, 0, "Failed to enable interrupt");
-
-	/* Fake IRQs in software by writing to ISR */
-	XIntc_Out32((uintptr_t) card->map + card->intc->baseaddr + XIN_ISR_OFFSET, 0xFF00);
-
-	/* Wait for 8 SW triggered IRQs */
-	for (int i = 0; i < 8; i++)
-		intc_wait(card->intc, i+8);
-
-	/* Check ISR if all SW IRQs have been deliverd */
-	isr = XIntc_In32((uintptr_t) card->map + card->intc->baseaddr + XIN_ISR_OFFSET);
-
-	ret = intc_disable(card->intc, 0xFF00);
-	cr_assert_eq(ret, 0, "Failed to disable interrupt");
-
-	cr_assert_eq(isr & 0xFF00, 0); /* ISR should get cleared by MSI_Grant_signal */
-}
-
-Test(fpga, xsg, .description = "XSG: multiply_add")
-{
-	int ret;
-	double factor, err = 0;
-
-	struct fpga_ip *ip, *dma;
-	struct model_parameter *p;
-	struct dma_mem mem;
-
-	ip = fpga_vlnv_lookup(&card->ips, &(struct fpga_vlnv) { NULL, "sysgen", "xsg_multiply", NULL });
-	cr_assert(ip);
-
-	dma = fpga_vlnv_lookup(&card->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_dma", NULL });
-	cr_assert(dma);
-
-	struct model *model = (struct model *) ip->_vd;
-
-	p = list_lookup(&model->parameters, "factor");
-	if (!p)
-		error("Missing parameter 'factor' for model '%s'", ip->name);
-
-	ret = model_parameter_read(p, &factor);
-	cr_assert_eq(ret, 0, "Failed to read parameter 'factor' from model '%s'", ip->name);
-
-	info("Model param: factor = %f", factor);
-
-	ret = switch_connect(card->sw, dma, ip);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	ret = switch_connect(card->sw, ip, dma);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	ret = dma_alloc(dma, &mem, 0x1000, 0);
-	cr_assert_eq(ret, 0, "Failed to allocate DMA memory");
-
-	float *src = (float *) mem.base_virt;
-	float *dst = (float *) mem.base_virt + 0x800;
-
-	for (int i = 0; i < 6; i++)
-		src[i] = 1.1 * (i+1);
-
-	ret = dma_ping_pong(dma, (char *) src, (char *) dst, 6 * sizeof(float));
-	cr_assert_eq(ret, 0, "Failed to to ping pong DMA transfer: %d", ret);
-
-	for (int i = 0; i < 6; i++)
-		err += fabs(factor * src[i] - dst[i]);
-
-	info("Error after FPGA operation: err = %f", err);
-
-	ret = switch_disconnect(card->sw, dma, ip);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	ret = switch_disconnect(card->sw, ip, dma);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	ret = dma_free(dma, &mem);
-	cr_assert_eq(ret, 0, "Failed to release DMA memory");
-
-	cr_assert(err < 1e-3);
-}
-
-Test(fpga, hls_dft, .description = "HLS: hls_dft")
-{
-	int ret;
-	struct fpga_ip *hls, *rtds;
-
-	rtds = fpga_vlnv_lookup(&card->ips, &(struct fpga_vlnv) { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL });
-	hls = fpga_vlnv_lookup(&card->ips, &(struct fpga_vlnv) { NULL, "hls", "hls_dft", NULL });
-
-	/* Check if required IP is available on FPGA */
-	cr_assert(hls && rtds);
-
-	ret = intc_enable(card->intc, (1 << rtds->irq), 0);
-	cr_assert_eq(ret, 0, "Failed to enable interrupt");
-
-	ret = switch_connect(card->sw, rtds, hls);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	ret = switch_connect(card->sw, hls, rtds);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	while(1) {
-		/* Dump RTDS AXI Stream state */
-		rtds_axis_dump(rtds);
-		sleep(1);
-	}
-#if 0
-	int len = 2000;
-	int NSAMPLES = 400;
-	float src[len], dst[len];
-
-	for (int i = 0; i < len; i++) {
-		src[i] = 4 + 5.0 * sin(2.0 * M_PI * 1 * i / NSAMPLES) +
-		             2.0 * sin(2.0 * M_PI * 2 * i / NSAMPLES) +
-			     1.0 * sin(2.0 * M_PI * 5 * i / NSAMPLES) +
-			     0.5 * sin(2.0 * M_PI * 9 * i / NSAMPLES) +
-			     0.2 * sin(2.0 * M_PI * 15 * i / NSAMPLES);
-
-		fifo_write()
-	}
-#endif
-
-	ret = switch_disconnect(card->sw, rtds, hls);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	ret = switch_disconnect(card->sw, hls, rtds);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-}
-
-Test(fpga, fifo, .description = "FIFO")
-{
-	int ret;
-	ssize_t len;
-	char src[255], dst[255];
-	struct fpga_ip *fifo;
-
-	fifo = fpga_vlnv_lookup(&card->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_fifo_mm_s", NULL });
-	cr_assert(fifo);
-
-	ret = intc_enable(card->intc, (1 << fifo->irq), 0);
-	cr_assert_eq(ret, 0, "Failed to enable interrupt");
-
-	ret = switch_connect(card->sw, fifo, fifo);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	/* Get some random data to compare */
-	memset(dst, 0, sizeof(dst));
-	len = read_random((char *) src, sizeof(src));
-	if (len != sizeof(src))
-		error("Failed to get random data");
-
-	len = fifo_write(fifo, (char *) src, sizeof(src));
-	if (len != sizeof(src))
-		error("Failed to send to FIFO");
-
-	len = fifo_read(fifo, (char *) dst, sizeof(dst));
-	if (len != sizeof(dst))
-		error("Failed to read from FIFO");
-
-	ret = intc_disable(card->intc, (1 << fifo->irq));
-	cr_assert_eq(ret, 0, "Failed to disable interrupt");
-
-	ret = switch_disconnect(card->sw, fifo, fifo);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	/* Compare data */
-	cr_assert_eq(memcmp(src, dst, sizeof(src)), 0);
-}
-
-Test(fpga, dma, .description = "DMA")
-{
-	int ret = -1;
-	struct dma_mem mem, src, dst;
-
-	for (size_t i = 0; i < list_length(&card->ips); i++) { INDENT
-		struct fpga_ip *dm = (struct fpga_ip *) list_at(&card->ips, i);
-
-		if (fpga_vlnv_cmp(&dm->vlnv, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_dma", NULL }))
-			continue; /* skip non DMA IP cores */
-
-		struct dma *dma = (struct dma *) dm->_vd;
-
-		/* Simple DMA can only transfer up to 4 kb due to
-		 * PCIe page size burst limitation */
-		ssize_t len2, len = dma->inst.HasSg ? 64 << 20 : 1 << 2;
-
-		ret = dma_alloc(dm, &mem, 2 * len, 0);
-		cr_assert_eq(ret, 0);
-
-		ret = dma_mem_split(&mem, &src, &dst);
-		cr_assert_eq(ret, 0);
-
-		/* Get new random data */
-		len2 = read_random(src.base_virt, len);
-		if (len2 != len)
-			serror("Failed to get random data");
-
-		int irq_mm2s = dm->irq;
-		int irq_s2mm = dm->irq + 1;
-
-		ret = intc_enable(card->intc, (1 << irq_mm2s) | (1 << irq_s2mm), 0);
-		cr_assert_eq(ret, 0, "Failed to enable interrupt");
-
-		ret = switch_connect(card->sw, dm, dm);
-		cr_assert_eq(ret, 0, "Failed to configure switch");
-
-		/* Start transfer */
-		ret = dma_ping_pong(dm, src.base_phys, dst.base_phys, dst.len);
-		cr_assert_eq(ret, 0, "DMA ping pong failed");
-
-		ret = memcmp(src.base_virt, dst.base_virt, src.len);
-
-		info("DMA %s (%s): %s", dm->name, dma->inst.HasSg ? "scatter-gather" : "simple", ret ? CLR_RED("failed") : CLR_GRN("passed"));
-
-		ret = switch_disconnect(card->sw, dm, dm);
-		cr_assert_eq(ret, 0, "Failed to configure switch");
-
-		ret = intc_disable(card->intc, (1 << irq_mm2s) | (1 << irq_s2mm));
-		cr_assert_eq(ret, 0, "Failed to disable interrupt");
-
-		ret = dma_free(dm, &mem);
-		cr_assert_eq(ret, 0, "Failed to release DMA memory");
-	}
-
-	cr_assert_eq(ret, 0);
-}
-
-Test(fpga, timer, .description = "Timer Counter")
-{
-	int ret;
-	struct fpga_ip *ip;
-	struct timer *tmr;
-
-	ip = fpga_vlnv_lookup(&card->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_timer", NULL });
-	cr_assert(ip);
-
-	tmr = (struct timer *) ip->_vd;
-
-	XTmrCtr *xtmr = &tmr->inst;
-
-	ret = intc_enable(card->intc, (1 << ip->irq), 0);
-	cr_assert_eq(ret, 0, "Failed to enable interrupt");
-
-	XTmrCtr_SetOptions(xtmr, 0, XTC_EXT_COMPARE_OPTION | XTC_DOWN_COUNT_OPTION);
-	XTmrCtr_SetResetValue(xtmr, 0, FPGA_AXI_HZ / 125);
-	XTmrCtr_Start(xtmr, 0);
-
-	uint64_t counter = intc_wait(card->intc, ip->irq);
-	info("Got IRQ: counter = %ju", counter);
-
-	if (counter == 1)
-		return;
-	else
-		warn("Counter was not 1");
-
-	intc_disable(card->intc, (1 << ip->irq));
-	cr_assert_eq(ret, 0, "Failed to disable interrupt");
-
-	return;
-}
-
-Test(fpga, rtds_rtt, .description = "RTDS: tight rtt")
-{
-	int ret;
-	struct fpga_ip *ip, *rtds;
-	struct dma_mem buf;
-	size_t recvlen;
-
-	/* Get IP cores */
-	rtds = fpga_vlnv_lookup(&card->ips, &(struct fpga_vlnv) { "acs.eonerc.rwth-aachen.de", "user", "rtds_axis", NULL });
-	cr_assert(rtds);
-
-	ip   = fpga_vlnv_lookup(&card->ips, &(struct fpga_vlnv) { "xilinx.com", "ip", "axi_dma", NULL });
-	cr_assert(ip);
-
-	ret = switch_connect(card->sw, rtds, ip);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	ret = switch_connect(card->sw, ip, rtds);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	ret = dma_alloc(ip, &buf, 0x100, 0);
-	cr_assert_eq(ret, 0, "Failed to allocate DMA memory");
-
-	while (1) {
-
-		ret = dma_read(ip, buf.base_phys, buf.len);
-		cr_assert_eq(ret, 0, "Failed to start DMA read: %d", ret);
-
-		ret = dma_read_complete(ip, NULL, &recvlen);
-		cr_assert_eq(ret, 0, "Failed to complete DMA read: %d", ret);
-
-		ret = dma_write(ip, buf.base_phys, recvlen);
-		cr_assert_eq(ret, 0, "Failed to start DMA write: %d", ret);
-
-		ret = dma_write_complete(ip, NULL, NULL);
-		cr_assert_eq(ret, 0, "Failed to complete DMA write: %d", ret);
-	}
-
-	ret = switch_disconnect(card->sw, rtds, ip);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	ret = switch_disconnect(card->sw, ip, rtds);
-	cr_assert_eq(ret, 0, "Failed to configure switch");
-
-	ret = dma_free(ip, &buf);
-	cr_assert_eq(ret, 0, "Failed to release DMA memory");
-}
-
-#endif /* WITH_FPGA */
diff --git a/tools/integration-tests.sh b/tools/integration-tests.sh
index 00686f26f..dcfa2cf6b 100755
--- a/tools/integration-tests.sh
+++ b/tools/integration-tests.sh
@@ -84,7 +84,7 @@ SKIPPED=0
 TIMEDOUT=0
 
 # Preamble
-echo -e "Starting integration tests for VILLASnode/fpga:\n"
+echo -e "Starting integration tests for VILLASnode:\n"
 
 for TEST in ${TESTS}; do
 	TESTNAME=$(basename -s .sh ${TEST})
diff --git a/tools/rebind_device.sh b/tools/rebind_device.sh
deleted file mode 100755
index 67fb75bbe..000000000
--- a/tools/rebind_device.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash
-#
-# Detach and rebind a PCI device to a PCI kernel driver
-#
-# @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
-# @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
-# @license GNU General Public License (version 3)
-#
-# VILLASnode
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-##################################################################################
-
-if [ "$#" -ne 2 ]; then
-	echo "usage: $0 BUS:DEV:FNC DRIVER"
-	exit 1
-fi
-
-BDF=$1
-DRIVER=$2
-
-VENDOR=$(cut -b3- /sys/bus/pci/devices/${BDF}/vendor)
-DEVICE=$(cut -b3- /sys/bus/pci/devices/${BDF}/device)
-
-SYSFS_DEVICE=/sys/bus/pci/devices/${BDF}
-SYSFS_DRIVER=/sys/bus/pci/drivers/${DRIVER}
-
-echo "Device: $VENDOR $DEVICE $BDF"
-
-if [ -L "${SYSFS_DEVICE}/driver" ] && [ -d "${SYSFS_DEVICE}/driver" ]; then
-	echo ${BDF}              > ${SYSFS_DEVICE}/driver/unbind
-fi
-
-echo "${VENDOR} ${DEVICE}" > ${SYSFS_DRIVER}/new_id
-echo "${BDF}"              > ${SYSFS_DRIVER}/bind
-echo "${VENDOR} ${DEVICE}" > ${SYSFS_DRIVER}/remove_id
diff --git a/tools/reset_pci_device.sh b/tools/reset_pci_device.sh
deleted file mode 100755
index ae3b14486..000000000
--- a/tools/reset_pci_device.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-#
-# Reset PCI devices like FPGAs after a reflash
-#
-# @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
-# @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
-# @license GNU General Public License (version 3)
-#
-# VILLASnode
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-##################################################################################
-
-if [ "$#" -ne 1 ]; then
-        echo "usage: $0 BUS:DEV:FNC"
-        exit 1
-fi
-
-BDF=$1
-
-echo "1" > /sys/bus/pci/devices/$BDF/remove
-echo "1" > /sys/bus/pci/rescan
-echo "1" > /sys/bus/pci/devices/$BDF/enable
-