diff --git a/examples/stdp.cpp b/examples/stdp.cpp
index 8c1afdc284d71e52b01e98c9e4f0b81c5e22dd53..38056eef0f5c78f843a6dff6e12cef4838c1417f 100644
--- a/examples/stdp.cpp
+++ b/examples/stdp.cpp
@@ -1,8 +1,10 @@
 #include <s2pp.h>
 #include <stdint.h>
-#include "libnux/correlation.h"
-#include "libnux/dls.h"
-#include "libnux/mailbox.h"
+#include "libnux/vx/correlation.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/mailbox.h"
+
+using namespace libnux::vx;
 
 // Mailbox index at which the program "listens" for the commands, which are
 // "wait", "update" and "stop"
@@ -37,7 +39,7 @@ void measure_offsets(__vector uint8_t ca_offsets[], __vector uint8_t ac_offsets[
 		// clang-format on
 	}
 	asm volatile("sync");
-	libnux_mailbox_write_string("Offsets measured\n");
+	mailbox_write_string("Offsets measured\n");
 }
 
 // Update the weights:
@@ -98,12 +100,12 @@ void update_weights(
 		// clang-format on
 	}
 	asm volatile("sync");
-	libnux_mailbox_write_string("Update done\n");
+	mailbox_write_string("Update done\n");
 }
 
 void print_weights(void)
 {
-	libnux_mailbox_write_string("Weights are\n");
+	mailbox_write_string("Weights are\n");
 	for (uint32_t index = 0; index < dls_num_synapse_vectors; index++) {
 		uint8_t __vector weights;
 		// clang-format off
@@ -118,11 +120,11 @@ void print_weights(void)
 			: "kv1");
 		// clang-format on
 		for (uint32_t j = 0; j < 16; j++) {
-			libnux_mailbox_write_int(weights[j]);
-			libnux_mailbox_write_string(" ");
+			mailbox_write_int(weights[j]);
+			mailbox_write_string(" ");
 		}
 		if ((index % 2) == 1) {
-			libnux_mailbox_write_string("\n");
+			mailbox_write_string("\n");
 		}
 	}
 }
@@ -131,7 +133,7 @@ int start(void)
 {
 	// Initialize
 	reset_all_correlations();
-	libnux_mailbox_write_string("Synapses reset done\n");
+	mailbox_write_string("Synapses reset done\n");
 
 	// Measure offsets
 	__vector uint8_t ca_offsets[dls_num_synapse_vectors];
@@ -141,16 +143,16 @@ int start(void)
 	// Execute
 	uint8_t signal = signal_wait;
 	do {
-		signal = libnux_mailbox_read_u8(signal_addr_offset);
+		signal = mailbox_read_u8(signal_addr_offset);
 		if (signal == signal_update) {
-			libnux_mailbox_write_u8(signal_addr_offset, signal_wait);
-			uint8_t const factor = libnux_mailbox_read_u8(factor_addr_offset);
+			mailbox_write_u8(signal_addr_offset, signal_wait);
+			uint8_t const factor = mailbox_read_u8(factor_addr_offset);
 			update_weights(factor, ca_offsets, ac_offsets);
 		}
 	} while (signal != signal_stop);
 
 	// Print the whole weight matrix at the end of the emulation
 	print_weights();
-	libnux_mailbox_write_string("Program exited gracefully\n");
+	mailbox_write_string("Program exited gracefully\n");
 	return 0;
 }
diff --git a/libnux/mailbox.h b/libnux/mailbox.h
deleted file mode 100644
index c7182e24d2e8646cd954091d4a01652d8bad74ca..0000000000000000000000000000000000000000
--- a/libnux/mailbox.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-
-#include <s2pp.h>
-#include <stdint.h>
-
-extern uint8_t mailbox_base;
-extern uint8_t mailbox_end;
-
-uint32_t mailbox_write(uint32_t const offset, uint8_t const * src, uint32_t const size);
-uint32_t mailbox_read(uint8_t * dest, uint32_t const offset, uint32_t const size);
-
-uint8_t libnux_mailbox_read_u8(uint32_t const offset);
-void libnux_mailbox_write_u8(uint32_t const offset, uint8_t byte);
-
-/**
- * Null-terminate any string in the mailbox.
- */
-void libnux_mailbox_string_terminate();
-
-uint32_t libnux_mailbox_write_string(char const * str);
-uint32_t libnux_mailbox_write_int(uint32_t const n);
-uint32_t libnux_mailbox_write_signed_int(int32_t const n);
-
-uint32_t libnux_mailbox_write_vector(__vector uint8_t const& vec);
-uint32_t libnux_mailbox_write_vector(__vector uint16_t const& vec);
-uint32_t libnux_mailbox_write_signed_vector(__vector int8_t const& vec);
-uint32_t libnux_mailbox_write_signed_vector(__vector int16_t const& vec);
diff --git a/libnux/sync.h b/libnux/sync.h
deleted file mode 100644
index 1dc661785d8876822fb24a5babddacf4d9deeb45..0000000000000000000000000000000000000000
--- a/libnux/sync.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-#include "libnux/attrib.h"
-
-ATTRIB_UNUSED static void sync()
-{
-	asm volatile("sync");
-}
diff --git a/libnux/attrib.h b/libnux/vx/attrib.h
similarity index 100%
rename from libnux/attrib.h
rename to libnux/vx/attrib.h
diff --git a/libnux/bitformatting.h b/libnux/vx/bitformatting.h
similarity index 82%
rename from libnux/bitformatting.h
rename to libnux/vx/bitformatting.h
index 5e8c59d2a9b98a596d2661ff265ba202176defa2..d1c73ac5c572537f85f3d0c01940812c268eac4c 100644
--- a/libnux/bitformatting.h
+++ b/libnux/vx/bitformatting.h
@@ -3,8 +3,12 @@
 #include <s2pp.h>
 #include <stdint.h>
 
+namespace libnux::vx {
+
 // Reverse all bits in the given byte
 uint8_t reverse_byte(uint8_t b);
 
 // Reverse all bits for all contained bytes in the vector
 void vector_reverse_bytes(__vector uint8_t* data);
+
+} // namespace libnux::vx
diff --git a/libnux/correlation.h b/libnux/vx/correlation.h
similarity index 95%
rename from libnux/correlation.h
rename to libnux/vx/correlation.h
index 7e6a263a9094702c4dca98bd4b1c11dc51014739..222dffc860451824a2bf641a56b7ffe5725a443e 100644
--- a/libnux/correlation.h
+++ b/libnux/vx/correlation.h
@@ -2,10 +2,13 @@
 
 #include <s2pp.h>
 #include <stdint.h>
-#include "dls.h"
+#include "libnux/vx/dls.h"
 
-// FIXME: write test 
+namespace libnux::vx {
+
+// FIXME: write test
 void reset_all_correlations();
+
 //   Saves causal & acausal correlation of both halves of a synapse row
 //   in arrays at `first_half`, `second half`, respectively.
 static inline void get_correlation(
@@ -72,3 +75,5 @@ static inline void reset_correlation(uint8_t row)
 		// clang-format on
 	);
 }
+
+} // namespace libnux::vx
diff --git a/libnux/vx/dls.h b/libnux/vx/dls.h
new file mode 100644
index 0000000000000000000000000000000000000000..e3ab8912e064c7ca2f9d63a6b5f2b6cae7783a39
--- /dev/null
+++ b/libnux/vx/dls.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <stdint.h>
+#include "libnux/vx/omnibus.h"
+
+namespace libnux::vx {
+
+#include "libnux/vx/dls.tcc"
+
+} // namespace libnux::vx
diff --git a/libnux/dls.h b/libnux/vx/dls.tcc
similarity index 96%
rename from libnux/dls.h
rename to libnux/vx/dls.tcc
index 2748f4d684d614aff00218ffc7ff001c6c121cb3..c2c473a3f79ba2cd3060c624b0d59ef267f00116 100644
--- a/libnux/dls.h
+++ b/libnux/vx/dls.tcc
@@ -1,20 +1,9 @@
-#pragma once
-
-#include <stdint.h>
-#include "omnibus.h"
-
-using namespace libnux;
-
-namespace libnux {
-
 enum class PPUOnDLS : uint32_t
 {
 	top,
 	bottom
 };
 
-} // namespace libnux
-
 /* Size of synram */
 constexpr static uint32_t dls_num_rows = 256;
 constexpr static uint32_t dls_num_columns = 256;
diff --git a/libnux/exp.h b/libnux/vx/exp.h
similarity index 75%
rename from libnux/exp.h
rename to libnux/vx/exp.h
index 19c79998c6cc9db448d618b27bc65f27907e7fee..4038047ea4aa4efaf0d748b2cf9fa03d3e8b052f 100644
--- a/libnux/exp.h
+++ b/libnux/vx/exp.h
@@ -2,6 +2,10 @@
 
 #include <stdint.h>
 
+namespace libnux::vx {
+
 extern int32_t exp_6(int32_t x);
 extern int32_t exp_6b(int32_t x);
 extern int32_t exp_n(int32_t x, const uint32_t n);
+
+} // namespace libnux::vx
diff --git a/libnux/fxdpt.h b/libnux/vx/fxdpt.h
similarity index 92%
rename from libnux/fxdpt.h
rename to libnux/vx/fxdpt.h
index c1be1dbc1bb1eb395ad2fbf4a00217f1c6a7afda..32f9cde0060c6ec861ff898332b5b25151a2fa36 100644
--- a/libnux/fxdpt.h
+++ b/libnux/vx/fxdpt.h
@@ -1,7 +1,7 @@
 #pragma once
 
 #include <stdint.h>
-#include "libnux/attrib.h"
+#include "libnux/vx/attrib.h"
 
 /** INV_SCALE 0x10000 is the 16.16 fixedpoint representation
  * MAX:       65536
@@ -19,6 +19,8 @@
 #define INV_FP(x) ((double)x*SCALE)
 #define FP_MUL(x,y) (x*y / INV_SCALE)
 
+namespace libnux::vx {
+
 ATTRIB_UNUSED static int16_t fxdpt_32_to_16_bits(const int32_t x)
 {
 	if( INV_SCALE_16 < INV_SCALE )
@@ -27,6 +29,7 @@ ATTRIB_UNUSED static int16_t fxdpt_32_to_16_bits(const int32_t x)
 		return (int16_t)( x * (INV_SCALE_16 / INV_SCALE) );
 }
 
+} // namespace libnux::vx
 
 #define F16_MAX (0x7fff)
 #define F16_MIN (0x8000)
diff --git a/libnux/fxv.h b/libnux/vx/fxv.h
similarity index 90%
rename from libnux/fxv.h
rename to libnux/vx/fxv.h
index b9eb74fee60f68fea471cbc8a911f79bf4d25c90..8ad2a49bca1352f45bd04d4cbb09633a3498dd17 100644
--- a/libnux/fxv.h
+++ b/libnux/vx/fxv.h
@@ -1,8 +1,9 @@
 #pragma once
 
-#include "libnux/dls.h"
+#include "libnux/vx/dls.h"
 #include <stdint.h>
 
+namespace libnux::vx {
 
 //--------------------------------------------------------------------------------
 // Types
@@ -32,3 +33,5 @@ typedef enum {
 //--------------------------------------------------------------------------------
 
 extern void fxv_zero_vrf();
+
+} // namespace libnux::vx
diff --git a/libnux/helper.h b/libnux/vx/helper.h
similarity index 95%
rename from libnux/helper.h
rename to libnux/vx/helper.h
index 6f06b2ce1f6b3de4cb4e369b81993cd7dda5bbfd..4746cc0462f48d2904249477df75484d656dd8df 100644
--- a/libnux/helper.h
+++ b/libnux/vx/helper.h
@@ -3,6 +3,8 @@
 #include <array>
 #include <stdint.h>
 
+namespace libnux::vx {
+
 // Returns the absolute difference of the two values
 template <typename T>
 T abs_diff(T input_1, T input_2)
@@ -47,3 +49,5 @@ __attribute__((always_inline)) inline void do_not_optimize_away(T const& value)
 {
 	asm volatile("" : "+m"(const_cast<T&>(value)));
 }
+
+} // namespace libnux::vx
diff --git a/libnux/location.h b/libnux/vx/location.h
similarity index 92%
rename from libnux/location.h
rename to libnux/vx/location.h
index df7ea00f8102ab173893686e9e68e3591d28ed3d..a93b9dacc68520d171d22e7ba82a74cf2d9b643e 100644
--- a/libnux/location.h
+++ b/libnux/vx/location.h
@@ -1,9 +1,9 @@
 #pragma once
 
-#include "libnux/dls.h"
-#include "libnux/vector.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/vector.h"
 
-namespace libnux {
+namespace libnux::vx {
 
 /**
  * Get location of execution by local write, global read operations.
@@ -42,4 +42,4 @@ inline bool get_location(PPUOnDLS& ppu)
 	return valid;
 }
 
-} // namespace libnux
+} // namespace libnux::vx
diff --git a/libnux/vx/mailbox.h b/libnux/vx/mailbox.h
new file mode 100644
index 0000000000000000000000000000000000000000..008709de2817c9d7fb66841293557afae4aa8bf3
--- /dev/null
+++ b/libnux/vx/mailbox.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <s2pp.h>
+#include <stdint.h>
+
+extern uint8_t mailbox_base;
+extern uint8_t mailbox_end;
+
+namespace libnux::vx {
+
+uint32_t mailbox_write(uint32_t const offset, uint8_t const * src, uint32_t const size);
+uint32_t mailbox_read(uint8_t * dest, uint32_t const offset, uint32_t const size);
+
+uint8_t mailbox_read_u8(uint32_t const offset);
+void mailbox_write_u8(uint32_t const offset, uint8_t byte);
+
+/**
+ * Null-terminate any string in the mailbox.
+ */
+void mailbox_string_terminate();
+
+uint32_t mailbox_write_string(char const * str);
+uint32_t mailbox_write_int(uint32_t const n);
+uint32_t mailbox_write_signed_int(int32_t const n);
+
+uint32_t mailbox_write_vector(__vector uint8_t const& vec);
+uint32_t mailbox_write_vector(__vector uint16_t const& vec);
+uint32_t mailbox_write_signed_vector(__vector int8_t const& vec);
+uint32_t mailbox_write_signed_vector(__vector int16_t const& vec);
+
+} // namespace libnux::vx
diff --git a/libnux/malloc.h b/libnux/vx/malloc.h
similarity index 100%
rename from libnux/malloc.h
rename to libnux/vx/malloc.h
diff --git a/libnux/new.h b/libnux/vx/new.h
similarity index 95%
rename from libnux/new.h
rename to libnux/vx/new.h
index 4d9b9f753b4769d228c6ba3b60b31d44c8dfc40e..2156f0a9a9f31135f8cba176aff19114d98acb3c 100644
--- a/libnux/new.h
+++ b/libnux/vx/new.h
@@ -1,5 +1,6 @@
 #pragma once
-#include "libnux/malloc.h"
+
+#include "libnux/vx/malloc.h"
 
 namespace std {
 typedef size_t size_t;
diff --git a/libnux/omnibus.h b/libnux/vx/omnibus.h
similarity index 95%
rename from libnux/omnibus.h
rename to libnux/vx/omnibus.h
index 11f5388f1863db4162b0fa07f1bf4bdbfb81278e..06e15ac61aa13960b52a522f3dea37624125617a 100644
--- a/libnux/omnibus.h
+++ b/libnux/vx/omnibus.h
@@ -2,7 +2,7 @@
 
 #include <stdint.h>
 
-namespace libnux {
+namespace libnux::vx {
 
 typedef uint32_t omnibus_address_t;
 typedef uint32_t omnibus_word_t;
@@ -39,4 +39,4 @@ inline void omnibus_write(omnibus_address_t const address, omnibus_word_t const
 	*get_omnibus_pointer(address) = value;
 }
 
-} // namespace libnux
+} // namespace libnux::vx
diff --git a/libnux/random.h b/libnux/vx/random.h
similarity index 80%
rename from libnux/random.h
rename to libnux/vx/random.h
index 92b05fdb5e60cfaae74f6418343e017371a9b301..730b70d4c903837ec6cc667ff39cfacd5be9f748 100644
--- a/libnux/random.h
+++ b/libnux/vx/random.h
@@ -4,6 +4,10 @@
 #include <s2pp.h>
 #include <stdint.h>
 
+namespace libnux::vx {
+
 uint32_t xorshift32(uint32_t* seed);
 uint32_t draw_poisson(uint32_t* seed, uint32_t cutoff, uint32_t dt);
 uint32_t random_lcg(uint32_t *seed);
+
+} // namespace libnux::vx
diff --git a/libnux/reset_neurons.h b/libnux/vx/reset_neurons.h
similarity index 93%
rename from libnux/reset_neurons.h
rename to libnux/vx/reset_neurons.h
index 862e15b9b740ec6ebdd6393cae148aa3f592e698..68ac7de8fed77863d0c345ee69b7ce9ec3bcd7ad 100644
--- a/libnux/reset_neurons.h
+++ b/libnux/vx/reset_neurons.h
@@ -1,9 +1,9 @@
 #pragma once
 
 #include <s2pp.h>
-#include "libnux/dls.h"
+#include "libnux/vx/dls.h"
 
-namespace libnux {
+namespace libnux::vx {
 
 /**
  * Reset neurons (of hemisphere) where given mask is larger than zero.
@@ -51,4 +51,4 @@ inline void reset_neurons()
 	// clang-format on
 }
 
-} // namespace libnux
+} // namespace libnux::vx
diff --git a/libnux/spikes.h b/libnux/vx/spikes.h
similarity index 68%
rename from libnux/spikes.h
rename to libnux/vx/spikes.h
index 066f6c0612d286838f7738217384c7fdfb9a9a6f..c84c2a941f35defe4585c9d2bd443f38590c1969 100644
--- a/libnux/spikes.h
+++ b/libnux/vx/spikes.h
@@ -1,11 +1,11 @@
 #pragma once
 
 #include <stdint.h>
-#include "dls.h"
-#include "omnibus.h"
-#include "time.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/omnibus.h"
+#include "libnux/vx/time.h"
 
-using namespace libnux;
+namespace libnux::vx {
 
 typedef struct
 {
@@ -19,3 +19,5 @@ static inline void send_spike(spike_t* sp)
 }
 
 void send_uniform_spiketrain(spike_t* single_spike, uint32_t number, uint32_t isi_usec);
+
+} // namespace libnux::vx
diff --git a/libnux/spr.h b/libnux/vx/spr.h
similarity index 97%
rename from libnux/spr.h
rename to libnux/vx/spr.h
index dfc37fb3cf6cc239c3aec849940d5d2a19e3b62e..60e6279039a556e191a8b15803c18af44f209c51 100644
--- a/libnux/spr.h
+++ b/libnux/vx/spr.h
@@ -1,7 +1,7 @@
 #pragma once
 
 #include <stdint.h>
-#include "libnux/attrib.h"
+#include "libnux/vx/attrib.h"
 
 #define SPR_SETTER(name, code) \
 ATTRIB_UNUSED static void name (const uint32_t v) \
@@ -29,6 +29,7 @@ ATTRIB_UNUSED static uint32_t name () \
 	return rv;                          \
 }
 
+namespace libnux::vx {
 
 SPR_GETTER(get_tbu, "mfspr %0, 285")
 SPR_GETTER(get_tbl, "mfspr %0, 284")
@@ -119,6 +120,8 @@ ATTRIB_UNUSED static uint8_t get_fit_period()
 	return (get_tcr() >> TCR_FP_OFF) & TCR_FP_MASK;
 }
 
+} // namespace libnux::vx
+
 //---------------------------------------------------------------------------
 
 /* not needed outside */
diff --git a/libnux/syn.h b/libnux/vx/syn.h
similarity index 93%
rename from libnux/syn.h
rename to libnux/vx/syn.h
index 4916bab6a9e62fa07cd60b9bffd5e958b7fb9ed1..2c9d3255f9302343ac22ca67f9b0c4ab5e57fa48 100644
--- a/libnux/syn.h
+++ b/libnux/vx/syn.h
@@ -2,7 +2,9 @@
 
 #include <s2pp.h>
 #include <stdint.h>
-#include "dls.h"
+#include "libnux/vx/dls.h"
+
+namespace libnux::vx {
 
 // Get weights of synapse row `row` and save in vectors `first_half`, `second_half`.
 inline void get_weights(__vector uint8_t* first_half, __vector uint8_t* second_half, uint8_t row)
@@ -37,3 +39,5 @@ inline void set_weights(__vector uint8_t* first_half, __vector uint8_t* second_h
 		// clang-format on
 	);
 }
+
+} // namespace libnux::vx
diff --git a/libnux/vx/sync.h b/libnux/vx/sync.h
new file mode 100644
index 0000000000000000000000000000000000000000..35168492725a4bcc91085809aa38866444b40a8f
--- /dev/null
+++ b/libnux/vx/sync.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "libnux/vx/attrib.h"
+
+namespace libnux::vx {
+
+ATTRIB_UNUSED static void sync()
+{
+	asm volatile("sync");
+}
+
+} // namespace libnux::vx
diff --git a/libnux/time.h b/libnux/vx/time.h
similarity index 86%
rename from libnux/time.h
rename to libnux/vx/time.h
index 592efba704ea44f103c73123025f960b48023481..3cdb6257a89a6551f210e83f75e041feacdd1a90 100644
--- a/libnux/time.h
+++ b/libnux/vx/time.h
@@ -3,10 +3,12 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "libnux/attrib.h"
-#include "libnux/mailbox.h"
-#include "libnux/spr.h"
-#include "libnux/time.h"
+#include "libnux/vx/attrib.h"
+#include "libnux/vx/mailbox.h"
+#include "libnux/vx/spr.h"
+#include "libnux/vx/time.h"
+
+namespace libnux::vx {
 
 constexpr static uint32_t default_ppu_cycles_per_us = 250;
 
@@ -118,18 +120,18 @@ time_base_t min(times<N> const& t)
 template <size_t N>
 void print_measurement(char const* msg, times<N> const& t)
 {
-	libnux_mailbox_write_string(msg);
-	libnux_mailbox_write_string(": ");
+	mailbox_write_string(msg);
+	mailbox_write_string(": ");
 
 	time_base_t t_avg = average(t);
 	time_base_t t_max = max(t);
 	time_base_t t_min = min(t);
-	libnux_mailbox_write_int(t_avg);
-	libnux_mailbox_write_string(" (max: ");
-	libnux_mailbox_write_int(t_max);
-	libnux_mailbox_write_string(", min: ");
-	libnux_mailbox_write_int(t_min);
-	libnux_mailbox_write_string(")\n");
+	mailbox_write_int(t_avg);
+	mailbox_write_string(" (max: ");
+	mailbox_write_int(t_max);
+	mailbox_write_string(", min: ");
+	mailbox_write_int(t_min);
+	mailbox_write_string(")\n");
 }
 
 /*
@@ -164,3 +166,5 @@ void measure_empty(times<N>& t)
 	}
 	print_measurement("empty", t);
 }
+
+} // namespace libnux::vx
diff --git a/libnux/unittest.h b/libnux/vx/unittest.h
similarity index 63%
rename from libnux/unittest.h
rename to libnux/vx/unittest.h
index 3f426a33b76308df3495d064b067ae1b1dc6391c..04a07e3318b11d594f32b3ed2c54bdf1b9ac27a3 100644
--- a/libnux/unittest.h
+++ b/libnux/vx/unittest.h
@@ -2,32 +2,34 @@
 
 #include <stdint.h>
 
-uint32_t libnux_test_write_string(char const * str);
-uint32_t libnux_test_write_int(uint32_t const n);
+namespace libnux::vx {
+
+uint32_t test_write_string(char const * str);
+uint32_t test_write_int(uint32_t const n);
 
 /**
  * Null-terminate the test result.
  */
-void libnux_test_write_termination();
+void test_write_termination();
 
-void libnux_test_init(void);
-void libnux_test_shutdown(void);
+void test_init(void);
+void test_shutdown(void);
 
 typedef enum {
-	libnux_test_action_warning,
-	libnux_test_action_shutdown
-} libnux_test_action_type;
+	test_action_warning,
+	test_action_shutdown
+} test_action_type;
 
-uint32_t libnux_test_get_passed();
-uint32_t libnux_test_get_failed();
-uint32_t libnux_testcase_get_passed();
-uint32_t libnux_testcase_get_failed();
+uint32_t test_get_passed();
+uint32_t test_get_failed();
+uint32_t testcase_get_passed();
+uint32_t testcase_get_failed();
 
-void libnux_test_set_action(libnux_test_action_type const);
-libnux_test_action_type libnux_test_get_action();
+void test_set_action(test_action_type const);
+test_action_type test_get_action();
 
-void libnux_test_inc_passed(void);
-void libnux_test_inc_failed(void);
+void test_inc_passed(void);
+void test_inc_failed(void);
 
 /* Print macros */
 
@@ -37,14 +39,14 @@ void libnux_test_inc_failed(void);
 #ifdef LIBNUX_TEST_MODE_VERBOSE
 #define LIBNUX_TEST_WRITE_PASSED(msg, args)                                                        \
 	do {                                                                                           \
-		libnux_test_write_string(__FILE__);                                                        \
-		libnux_test_write_string(":");                                                             \
-		libnux_test_write_string(LIBNUX_TEST_TO_STRING(__LINE__));                                 \
-		libnux_test_write_string(": passed: ");                                                    \
-		libnux_test_write_string(msg);                                                             \
-		libnux_test_write_string("(");                                                             \
-		libnux_test_write_string(args);                                                            \
-		libnux_test_write_string(")\n");                                                           \
+		test_write_string(__FILE__);                                                               \
+		test_write_string(":");                                                                    \
+		test_write_string(LIBNUX_TEST_TO_STRING(__LINE__));                                        \
+		test_write_string(": passed: ");                                                           \
+		test_write_string(msg);                                                                    \
+		test_write_string("(");                                                                    \
+		test_write_string(args);                                                                   \
+		test_write_string(")\n");                                                                  \
 	} while (0)
 #else
 #define LIBNUX_TEST_WRITE_PASSED(msg, args)
@@ -52,29 +54,29 @@ void libnux_test_inc_failed(void);
 
 #define LIBNUX_TEST_WRITE_FAILED(msg, args)                                                        \
 	do {                                                                                           \
-		libnux_test_write_string(__FILE__);                                                        \
-		libnux_test_write_string(":");                                                             \
-		libnux_test_write_string(LIBNUX_TEST_TO_STRING(__LINE__));                                 \
-		libnux_test_write_string(": failed: ");                                                    \
-		libnux_test_write_string(msg);                                                             \
-		libnux_test_write_string("(");                                                             \
-		libnux_test_write_string(args);                                                            \
-		libnux_test_write_string(")\n");                                                           \
+		test_write_string(__FILE__);                                                               \
+		test_write_string(":");                                                                    \
+		test_write_string(LIBNUX_TEST_TO_STRING(__LINE__));                                        \
+		test_write_string(": failed: ");                                                           \
+		test_write_string(msg);                                                                    \
+		test_write_string("(");                                                                    \
+		test_write_string(args);                                                                   \
+		test_write_string(")\n");                                                                  \
 	} while (0)
 
 #define LIBNUX_TEST_FAILED(msg, args)                                                              \
 	do {                                                                                           \
 		LIBNUX_TEST_WRITE_FAILED(msg, args);                                                       \
-		libnux_test_inc_failed();                                                                  \
-		if (libnux_test_get_action() == libnux_test_action_shutdown) {                             \
-			libnux_test_shutdown();                                                                \
+		test_inc_failed();                                                                         \
+		if (test_get_action() == test_action_shutdown) {                                           \
+			test_shutdown();                                                                       \
 		}                                                                                          \
 	} while (0)
 
 #define LIBNUX_TEST_PASSED(msg, args)                                                              \
 	do {                                                                                           \
 		LIBNUX_TEST_WRITE_PASSED(msg, args);                                                       \
-		libnux_test_inc_passed();                                                                  \
+		test_inc_passed();                                                                         \
 	} while (0)
 
 /* Check macros */
@@ -99,37 +101,37 @@ void libnux_test_inc_failed(void);
 /* Check functions */
 
 template <typename T, typename U>
-void libnux_test_equal(const T& fst, const U& snd)
+void test_equal(const T& fst, const U& snd)
 {
 	LIBNUX_TEST_EQUAL(fst, snd);
 }
 
 template <typename T>
-void libnux_test_true(const T& cond)
+void test_true(const T& cond)
 {
 	LIBNUX_TEST_TRUE(cond);
 }
 
 template <typename T>
-void libnux_test_null(const T& ptr)
+void test_null(const T& ptr)
 {
 	LIBNUX_TEST_NULL(ptr);
 }
 
 template <typename T>
-void libnux_test_not_null(const T& ptr)
+void test_not_null(const T& ptr)
 {
 	LIBNUX_TEST_NOT_NULL(ptr);
 }
 
 /* Testcases */
 
-void libnux_testcase_begin(char const * name);
-void libnux_testcase_end(void);
+void testcase_begin(char const * name);
+void testcase_end(void);
 
 /* Test summary */
 
-void libnux_test_summary(void);
+void test_summary(void);
 
 /* not needed outside */
 
@@ -144,3 +146,5 @@ void libnux_test_summary(void);
 #undef LIBNUX_TEST_TRUE
 #undef LIBNUX_TEST_NULL
 #undef LIBNUX_TEST_NOT_NULL
+
+} // namespace libnux::vx
diff --git a/libnux/vx/v1/bitformatting.h b/libnux/vx/v1/bitformatting.h
new file mode 100644
index 0000000000000000000000000000000000000000..de5c2bc7babf172e077816e58925e7928d5d5325
--- /dev/null
+++ b/libnux/vx/v1/bitformatting.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "libnux/vx/bitformatting.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::reverse_byte;
+using libnux::vx::vector_reverse_bytes;
+
+} // namespace libnux::vx:v1
diff --git a/libnux/vx/v1/correlation.h b/libnux/vx/v1/correlation.h
new file mode 100644
index 0000000000000000000000000000000000000000..c40a12f9ad19a79e10776fede7f50abbb156997e
--- /dev/null
+++ b/libnux/vx/v1/correlation.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "libnux/vx/correlation.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::reset_all_correlations;
+using libnux::vx::get_correlation;
+using libnux::vx::get_causal_correlation;
+using libnux::vx::reset_correlation;
+
+} // namespace libnux::vx:v1
diff --git a/libnux/vx/v1/dls.h b/libnux/vx/v1/dls.h
new file mode 100644
index 0000000000000000000000000000000000000000..5cd673a6ee3ca56bb3dc7b34a6ad88f8751d5b33
--- /dev/null
+++ b/libnux/vx/v1/dls.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <stdint.h>
+#include "libnux/vx/v1/omnibus.h"
+
+namespace libnux::vx::v1 {
+
+#include "libnux/vx/dls.tcc"
+
+} // namespace libnux::vx::v1
diff --git a/libnux/vx/v1/exp.h b/libnux/vx/v1/exp.h
new file mode 100644
index 0000000000000000000000000000000000000000..4d93bad01c57fb44dea4a18d7b12a8035a6d223d
--- /dev/null
+++ b/libnux/vx/v1/exp.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "libnux/vx/exp.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::exp_6;
+using libnux::vx::exp_6b;
+using libnux::vx::exp_n;
+
+} // namespace libnux::vx:v1
diff --git a/libnux/vx/v1/fxv.h b/libnux/vx/v1/fxv.h
new file mode 100644
index 0000000000000000000000000000000000000000..66cbe1d49011e857ac4ccc7d85282a16f78bffa0
--- /dev/null
+++ b/libnux/vx/v1/fxv.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "libnux/vx/fxv.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::fxv_array_t;
+using libnux::vx::fxv_cond_t;
+using libnux::vx::fxv_reorder_t;
+
+using libnux::vx::fxv_zero_vrf;
+
+} // namespace libnux::vx:v1
diff --git a/libnux/vx/v1/helper.h b/libnux/vx/v1/helper.h
new file mode 100644
index 0000000000000000000000000000000000000000..9b131232014d7f8f855a3396c8c495ed4fcd0683
--- /dev/null
+++ b/libnux/vx/v1/helper.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "libnux/vx/helper.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::abs_diff;
+using libnux::vx::find_max_amount;
+using libnux::vx::do_not_optimize_away;
+
+} // namespace libnux::vx:v1
diff --git a/libnux/vx/v1/location.h b/libnux/vx/v1/location.h
new file mode 100644
index 0000000000000000000000000000000000000000..bfd80cbed3b11974a324a505122e0c3f5f8621ad
--- /dev/null
+++ b/libnux/vx/v1/location.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "libnux/vx/location.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::get_location;
+
+} // namespace libnux::vx:v1
diff --git a/libnux/vx/v1/mailbox.h b/libnux/vx/v1/mailbox.h
new file mode 100644
index 0000000000000000000000000000000000000000..3506a3dcdba6d88471dc8919216749382ef50cbc
--- /dev/null
+++ b/libnux/vx/v1/mailbox.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "libnux/vx/mailbox.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::mailbox_write;
+using libnux::vx::mailbox_read;
+
+using libnux::vx::mailbox_read_u8;
+using libnux::vx::mailbox_write_u8;
+
+using libnux::vx::mailbox_string_terminate;
+
+using libnux::vx::mailbox_write_string;
+using libnux::vx::mailbox_write_int;
+
+using libnux::vx::mailbox_write_vector;
+using libnux::vx::mailbox_write_signed_vector;
+
+} // namespace libnux::vx::v1
diff --git a/libnux/vx/v1/omnibus.h b/libnux/vx/v1/omnibus.h
new file mode 100644
index 0000000000000000000000000000000000000000..f5b5af1b84490d0fcea1789d0c2b425cee99b080
--- /dev/null
+++ b/libnux/vx/v1/omnibus.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "libnux/vx/omnibus.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::omnibus_address_t;
+using libnux::vx::omnibus_word_t;
+
+using libnux::vx::get_omnibus_pointer;
+
+using libnux::vx::omnibus_read;
+using libnux::vx::omnibus_write;
+
+} // namespace libnux::vx::v1
diff --git a/libnux/vx/v1/random.h b/libnux/vx/v1/random.h
new file mode 100644
index 0000000000000000000000000000000000000000..962da99d8b304981819834c2992fe24718bb1223
--- /dev/null
+++ b/libnux/vx/v1/random.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "libnux/vx/random.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::xorshift32;
+using libnux::vx::draw_poisson;
+using libnux::vx::random_lcg;
+
+} // namespace libnux::vx:v1
diff --git a/libnux/vx/v1/reset_neurons.h b/libnux/vx/v1/reset_neurons.h
new file mode 100644
index 0000000000000000000000000000000000000000..1cbfc81cc9702bcdadf6ada1818c10441133dff5
--- /dev/null
+++ b/libnux/vx/v1/reset_neurons.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "libnux/vx/reset_neurons.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::reset_neurons;
+
+} // namespace libnux::vx:v1
diff --git a/libnux/vx/v1/spikes.h b/libnux/vx/v1/spikes.h
new file mode 100644
index 0000000000000000000000000000000000000000..bef3db832e09b03855ec48471f78bc1a2a8de80c
--- /dev/null
+++ b/libnux/vx/v1/spikes.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "libnux/vx/spikes.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::spike_t;
+
+using libnux::vx::send_spike;
+using libnux::vx::send_uniform_spiketrain;
+
+} // namespace libnux::vx:v1
diff --git a/libnux/vx/v1/spr.h b/libnux/vx/v1/spr.h
new file mode 100644
index 0000000000000000000000000000000000000000..7bb37d4460d4a611efeec2b623be8509555dc110
--- /dev/null
+++ b/libnux/vx/v1/spr.h
@@ -0,0 +1,47 @@
+#pragma once
+
+#include "libnux/vx/spr.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::time_base_t;
+
+using libnux::vx::get_tbu;
+using libnux::vx::get_tbl;
+
+using libnux::vx::get_time_base;
+
+using libnux::vx::set_dec;
+using libnux::vx::get_dec;
+
+using libnux::vx::set_decar;
+using libnux::vx::get_decar;
+
+using libnux::vx::set_tcr;
+using libnux::vx::get_tcr;
+
+using libnux::vx::clear_tsr;
+using libnux::vx::get_tsr;
+
+using libnux::vx::set_msr;
+using libnux::vx::get_msr;
+
+using libnux::vx::get_esr;
+
+using libnux::vx::set_iccr;
+using libnux::vx::get_iccr;
+
+using libnux::vx::set_srr0;
+using libnux::vx::get_srr0;
+using libnux::vx::set_srr1;
+using libnux::vx::get_srr1;
+
+using libnux::vx::set_goe;
+using libnux::vx::get_goe;
+using libnux::vx::set_gout;
+using libnux::vx::get_gin;
+
+using libnux::vx::set_fit_period;
+using libnux::vx::get_fit_period;
+
+} // namespace libnux::vx:v1
diff --git a/libnux/vx/v1/syn.h b/libnux/vx/v1/syn.h
new file mode 100644
index 0000000000000000000000000000000000000000..a396e019f7214f4d71c22818f4881795bd3d4e8e
--- /dev/null
+++ b/libnux/vx/v1/syn.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "libnux/vx/syn.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::get_weights;
+using libnux::vx::set_weights;
+
+} // namespace libnux::vx:v1
diff --git a/libnux/vx/v1/time.h b/libnux/vx/v1/time.h
new file mode 100644
index 0000000000000000000000000000000000000000..ccdcf6e6cae5f618f96922e82c3bd3069e20ecfd
--- /dev/null
+++ b/libnux/vx/v1/time.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "libnux/vx/time.h"
+
+namespace libnux::vx::v1 {
+
+constexpr static uint32_t default_ppu_cycles_per_us =
+   libnux::vx::default_ppu_cycles_per_us;
+
+using libnux::vx::sleep_cycles;
+
+using libnux::vx::now;
+
+using time_pair = libnux::vx::time_pair;
+
+template <size_t N>
+using times = libnux::vx::times<N>;
+
+using libnux::vx::average;
+using libnux::vx::max;
+using libnux::vx::min;
+
+using libnux::vx::print_measurement;
+using libnux::vx::print_measurements_header;
+using libnux::vx::print_measurements_footer;
+using libnux::vx::measure_empty;
+
+} // namespace libnux::vx::v1
diff --git a/libnux/vx/v1/unittest.h b/libnux/vx/v1/unittest.h
new file mode 100644
index 0000000000000000000000000000000000000000..d52799fc244bbe149d2d3d6060a0cb002c3ec249
--- /dev/null
+++ b/libnux/vx/v1/unittest.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "libnux/vx/unittest.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::test_write_string;
+using libnux::vx::test_write_int;
+using libnux::vx::test_write_termination;
+
+using libnux::vx::test_init;
+using libnux::vx::test_shutdown;
+
+using libnux::vx::test_action_type;
+
+using libnux::vx::test_get_passed;
+using libnux::vx::test_get_failed;
+
+using libnux::vx::testcase_get_passed;
+using libnux::vx::testcase_get_failed;
+
+using libnux::vx::test_set_action;
+using libnux::vx::test_get_action;
+
+using libnux::vx::test_inc_passed;
+using libnux::vx::test_inc_failed;
+
+using libnux::vx::test_equal;
+using libnux::vx::test_true;
+using libnux::vx::test_null;
+using libnux::vx::test_not_null;
+
+using libnux::vx::testcase_begin;
+using libnux::vx::testcase_end;
+using libnux::vx::test_summary;
+
+} // namespace libnux::vx::v1
diff --git a/libnux/vx/v1/vector.h b/libnux/vx/v1/vector.h
new file mode 100644
index 0000000000000000000000000000000000000000..ebde7f7280d50868c2a053e7afa5d7067c82f010
--- /dev/null
+++ b/libnux/vx/v1/vector.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "libnux/vx/vector.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::vector_type;
+using vector_row_t = libnux::vx::vector_row_t;
+
+using libnux::vx::get_row_via_vector;
+using libnux::vx::set_row_via_vector;
+using libnux::vx::set_row_via_vector_masked;
+using libnux::vx::get_row_via_omnibus;
+
+using libnux::vx::get_vector;
+using libnux::vx::set_vector;
+
+} // namespace libnux::vx::v1
diff --git a/libnux/vx/v1/vector_convert.h b/libnux/vx/v1/vector_convert.h
new file mode 100644
index 0000000000000000000000000000000000000000..6d0db31735c39a637b52f98dfb38efc6281da337
--- /dev/null
+++ b/libnux/vx/v1/vector_convert.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "libnux/vx/vector_convert.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::uint8_to_int8;
+
+} // namespace libnux::vx::v1
diff --git a/libnux/vx/v1/vector_math.h b/libnux/vx/v1/vector_math.h
new file mode 100644
index 0000000000000000000000000000000000000000..ad5a6bdca80193020e5973bfb34ef0ba99a16199
--- /dev/null
+++ b/libnux/vx/v1/vector_math.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "libnux/vx/vector_math.h"
+
+namespace libnux::vx::v1 {
+
+using libnux::vx::saturating_subtract;
+
+} // namespace libnux::vx::v1
diff --git a/libnux/vx/v2/bitformatting.h b/libnux/vx/v2/bitformatting.h
new file mode 100644
index 0000000000000000000000000000000000000000..55703c49bd063312356e9dd0ac8d50df78320cff
--- /dev/null
+++ b/libnux/vx/v2/bitformatting.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "libnux/vx/bitformatting.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::reverse_byte;
+using libnux::vx::vector_reverse_bytes;
+
+} // namespace libnux::vx:v2
diff --git a/libnux/vx/v2/correlation.h b/libnux/vx/v2/correlation.h
new file mode 100644
index 0000000000000000000000000000000000000000..53e6088699a306bb59c6427923fa87b8da91d13c
--- /dev/null
+++ b/libnux/vx/v2/correlation.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "libnux/vx/correlation.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::reset_all_correlations;
+using libnux::vx::get_correlation;
+using libnux::vx::get_causal_correlation;
+using libnux::vx::reset_correlation;
+
+} // namespace libnux::vx:v2
diff --git a/libnux/vx/v2/dls.h b/libnux/vx/v2/dls.h
new file mode 100644
index 0000000000000000000000000000000000000000..280ab90f64c13ec2c5db0abe2e43a57eda07604e
--- /dev/null
+++ b/libnux/vx/v2/dls.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <stdint.h>
+#include "libnux/vx/v2/omnibus.h"
+
+namespace libnux::vx::v2 {
+
+#include "libnux/vx/dls.tcc"
+
+} // namespace libnux::vx::v2
diff --git a/libnux/vx/v2/exp.h b/libnux/vx/v2/exp.h
new file mode 100644
index 0000000000000000000000000000000000000000..4357a49948e71d4b7eb789dbb716127c31e576a0
--- /dev/null
+++ b/libnux/vx/v2/exp.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "libnux/vx/exp.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::exp_6;
+using libnux::vx::exp_6b;
+using libnux::vx::exp_n;
+
+} // namespace libnux::vx:v2
diff --git a/libnux/vx/v2/fxv.h b/libnux/vx/v2/fxv.h
new file mode 100644
index 0000000000000000000000000000000000000000..03daa7d9b1d5ca9a26f45d0505120e37ef6100cc
--- /dev/null
+++ b/libnux/vx/v2/fxv.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "libnux/vx/fxv.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::fxv_array_t;
+using libnux::vx::fxv_cond_t;
+using libnux::vx::fxv_reorder_t;
+
+using libnux::vx::fxv_zero_vrf;
+
+} // namespace libnux::vx:v2
diff --git a/libnux/vx/v2/helper.h b/libnux/vx/v2/helper.h
new file mode 100644
index 0000000000000000000000000000000000000000..df9cf1b8c6ee27733cb260e1dde0bc8a47feb19a
--- /dev/null
+++ b/libnux/vx/v2/helper.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "libnux/vx/helper.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::abs_diff;
+using libnux::vx::find_max_amount;
+using libnux::vx::do_not_optimize_away;
+
+} // namespace libnux::vx:v2
diff --git a/libnux/vx/v2/location.h b/libnux/vx/v2/location.h
new file mode 100644
index 0000000000000000000000000000000000000000..55f524ff432bd2006dea7e483cbe9aa4eb143d12
--- /dev/null
+++ b/libnux/vx/v2/location.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "libnux/vx/location.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::get_location;
+
+} // namespace libnux::vx:v2
diff --git a/libnux/vx/v2/mailbox.h b/libnux/vx/v2/mailbox.h
new file mode 100644
index 0000000000000000000000000000000000000000..7b397e55e8d847592923ced2fdf3424560e41f03
--- /dev/null
+++ b/libnux/vx/v2/mailbox.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "libnux/vx/mailbox.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::mailbox_write;
+using libnux::vx::mailbox_read;
+
+using libnux::vx::mailbox_read_u8;
+using libnux::vx::mailbox_write_u8;
+
+using libnux::vx::mailbox_string_terminate;
+
+using libnux::vx::mailbox_write_string;
+using libnux::vx::mailbox_write_int;
+
+using libnux::vx::mailbox_write_vector;
+using libnux::vx::mailbox_write_signed_vector;
+
+} // namespace libnux::vx::v2
diff --git a/libnux/vx/v2/omnibus.h b/libnux/vx/v2/omnibus.h
new file mode 100644
index 0000000000000000000000000000000000000000..30c40aaddd019e9b76ffa8b8c755ebbf58745510
--- /dev/null
+++ b/libnux/vx/v2/omnibus.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "libnux/vx/omnibus.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::omnibus_address_t;
+using libnux::vx::omnibus_word_t;
+
+using libnux::vx::get_omnibus_pointer;
+
+using libnux::vx::omnibus_read;
+using libnux::vx::omnibus_write;
+
+} // namespace libnux::vx::v2
diff --git a/libnux/vx/v2/random.h b/libnux/vx/v2/random.h
new file mode 100644
index 0000000000000000000000000000000000000000..94935dd9ac25c88d25966975d498a8d2a9af850e
--- /dev/null
+++ b/libnux/vx/v2/random.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "libnux/vx/random.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::xorshift32;
+using libnux::vx::draw_poisson;
+using libnux::vx::random_lcg;
+
+} // namespace libnux::vx:v2
diff --git a/libnux/vx/v2/reset_neurons.h b/libnux/vx/v2/reset_neurons.h
new file mode 100644
index 0000000000000000000000000000000000000000..1999b530d798d09ddcaa4eb48c74e44171de5192
--- /dev/null
+++ b/libnux/vx/v2/reset_neurons.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "libnux/vx/reset_neurons.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::reset_neurons;
+
+} // namespace libnux::vx:v2
diff --git a/libnux/vx/v2/spikes.h b/libnux/vx/v2/spikes.h
new file mode 100644
index 0000000000000000000000000000000000000000..c8f060e3cb7205f0a33de0a76a767dcb8c16435d
--- /dev/null
+++ b/libnux/vx/v2/spikes.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "libnux/vx/spikes.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::spike_t;
+
+using libnux::vx::send_spike;
+using libnux::vx::send_uniform_spiketrain;
+
+} // namespace libnux::vx:v2
diff --git a/libnux/vx/v2/spr.h b/libnux/vx/v2/spr.h
new file mode 100644
index 0000000000000000000000000000000000000000..4ff84e8c8c5ce4da36c1bf37a840e08d8d28cc0e
--- /dev/null
+++ b/libnux/vx/v2/spr.h
@@ -0,0 +1,47 @@
+#pragma once
+
+#include "libnux/vx/spr.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::time_base_t;
+
+using libnux::vx::get_tbu;
+using libnux::vx::get_tbl;
+
+using libnux::vx::get_time_base;
+
+using libnux::vx::set_dec;
+using libnux::vx::get_dec;
+
+using libnux::vx::set_decar;
+using libnux::vx::get_decar;
+
+using libnux::vx::set_tcr;
+using libnux::vx::get_tcr;
+
+using libnux::vx::clear_tsr;
+using libnux::vx::get_tsr;
+
+using libnux::vx::set_msr;
+using libnux::vx::get_msr;
+
+using libnux::vx::get_esr;
+
+using libnux::vx::set_iccr;
+using libnux::vx::get_iccr;
+
+using libnux::vx::set_srr0;
+using libnux::vx::get_srr0;
+using libnux::vx::set_srr1;
+using libnux::vx::get_srr1;
+
+using libnux::vx::set_goe;
+using libnux::vx::get_goe;
+using libnux::vx::set_gout;
+using libnux::vx::get_gin;
+
+using libnux::vx::set_fit_period;
+using libnux::vx::get_fit_period;
+
+} // namespace libnux::vx:v2
diff --git a/libnux/vx/v2/syn.h b/libnux/vx/v2/syn.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa0c4c29e3f88acd3182080b7110b0cbdf1467e2
--- /dev/null
+++ b/libnux/vx/v2/syn.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "libnux/vx/syn.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::get_weights;
+using libnux::vx::set_weights;
+
+} // namespace libnux::vx:v2
diff --git a/libnux/vx/v2/time.h b/libnux/vx/v2/time.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe8d2d8f7bdee9a17d9d453e4e82a4d2e5f872cb
--- /dev/null
+++ b/libnux/vx/v2/time.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "libnux/vx/time.h"
+
+namespace libnux::vx::v2 {
+
+constexpr static uint32_t default_ppu_cycles_per_us =
+   libnux::vx::default_ppu_cycles_per_us;
+
+using libnux::vx::sleep_cycles;
+
+using libnux::vx::now;
+
+using time_pair = libnux::vx::time_pair;
+
+template <size_t N>
+using times = libnux::vx::times<N>;
+
+using libnux::vx::average;
+using libnux::vx::max;
+using libnux::vx::min;
+
+using libnux::vx::print_measurement;
+using libnux::vx::print_measurements_header;
+using libnux::vx::print_measurements_footer;
+using libnux::vx::measure_empty;
+
+} // namespace libnux::vx::v2
diff --git a/libnux/vx/v2/unittest.h b/libnux/vx/v2/unittest.h
new file mode 100644
index 0000000000000000000000000000000000000000..93c3f01e39fcfb8aa9fc791b9cc0809a3b747012
--- /dev/null
+++ b/libnux/vx/v2/unittest.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "libnux/vx/unittest.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::test_write_string;
+using libnux::vx::test_write_int;
+using libnux::vx::test_write_termination;
+
+using libnux::vx::test_init;
+using libnux::vx::test_shutdown;
+
+using libnux::vx::test_action_type;
+
+using libnux::vx::test_get_passed;
+using libnux::vx::test_get_failed;
+
+using libnux::vx::testcase_get_passed;
+using libnux::vx::testcase_get_failed;
+
+using libnux::vx::test_set_action;
+using libnux::vx::test_get_action;
+
+using libnux::vx::test_inc_passed;
+using libnux::vx::test_inc_failed;
+
+using libnux::vx::test_equal;
+using libnux::vx::test_true;
+using libnux::vx::test_null;
+using libnux::vx::test_not_null;
+
+using libnux::vx::testcase_begin;
+using libnux::vx::testcase_end;
+using libnux::vx::test_summary;
+
+} // namespace libnux::vx::v2
diff --git a/libnux/vx/v2/vector.h b/libnux/vx/v2/vector.h
new file mode 100644
index 0000000000000000000000000000000000000000..621fa28aa5b184da8e72018a9f9d0be87f7f9d30
--- /dev/null
+++ b/libnux/vx/v2/vector.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "libnux/vx/vector.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::vector_type;
+using vector_row_t = libnux::vx::vector_row_t;
+
+using libnux::vx::get_row_via_vector;
+using libnux::vx::set_row_via_vector;
+using libnux::vx::set_row_via_vector_masked;
+using libnux::vx::get_row_via_omnibus;
+
+using libnux::vx::get_vector;
+using libnux::vx::set_vector;
+
+} // namespace libnux::vx::v2
diff --git a/libnux/vx/v2/vector_convert.h b/libnux/vx/v2/vector_convert.h
new file mode 100644
index 0000000000000000000000000000000000000000..b491a801cc5504b0eeebfc250dea379c92c95d77
--- /dev/null
+++ b/libnux/vx/v2/vector_convert.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "libnux/vx/vector_convert.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::uint8_to_int8;
+
+} // namespace libnux::vx::v2
diff --git a/libnux/vx/v2/vector_math.h b/libnux/vx/v2/vector_math.h
new file mode 100644
index 0000000000000000000000000000000000000000..7dc19cb2fce8389b1b88ddb2b46d664e6cc5ef36
--- /dev/null
+++ b/libnux/vx/v2/vector_math.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "libnux/vx/vector_math.h"
+
+namespace libnux::vx::v2 {
+
+using libnux::vx::saturating_subtract;
+
+} // namespace libnux::vx::v2
diff --git a/libnux/vector.h b/libnux/vx/vector.h
similarity index 98%
rename from libnux/vector.h
rename to libnux/vx/vector.h
index ce39c870bbec1d4683328daf29a440329ed51306..1659b5ab15fd208d476e4935aff9cbd7c7c603c8 100644
--- a/libnux/vector.h
+++ b/libnux/vx/vector.h
@@ -3,10 +3,10 @@
 #include <array>
 #include <stddef.h>
 #include <stdint.h>
-#include "libnux/dls.h"
-#include "libnux/omnibus.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/omnibus.h"
 
-namespace libnux {
+namespace libnux::vx {
 
 /**
  * One vector as processed by the PPU's vector unit.
@@ -233,4 +233,4 @@ void set_vector(vector_type const& values, uint32_t base, uint32_t index)
 	);
 }
 
-} // namespace libnux
+} // namespace libnux::vx
diff --git a/libnux/vector_convert.h b/libnux/vx/vector_convert.h
similarity index 89%
rename from libnux/vector_convert.h
rename to libnux/vx/vector_convert.h
index 1f33b9f2d108442aa118ea285c799e0ecb5c58f5..05cb9eb147f1a3fa1b63da770cad62109471be58 100644
--- a/libnux/vector_convert.h
+++ b/libnux/vx/vector_convert.h
@@ -2,7 +2,7 @@
 
 #include <s2pp.h>
 
-namespace libnux {
+namespace libnux::vx {
 
 /**
  * Convert uint8_t to int8_t continuously such that 0 -> -128, 255 -> 127.
@@ -23,4 +23,4 @@ inline __vector int8_t uint8_to_int8(__vector uint8_t a)
 	return tmp;
 }
 
-} // namespace libnux
+} // namespace libnux::vx
diff --git a/libnux/vector_math.h b/libnux/vx/vector_math.h
similarity index 86%
rename from libnux/vector_math.h
rename to libnux/vx/vector_math.h
index 44ec8b02edbbaebd6440f44f59d4a1efa4087e24..ced51e4c84576e0f3d48cd951756a012f6aaf413 100644
--- a/libnux/vector_math.h
+++ b/libnux/vx/vector_math.h
@@ -2,7 +2,7 @@
 
 #include <s2pp.h>
 
-namespace libnux {
+namespace libnux::vx {
 
 inline __vector int8_t saturating_subtract(__vector int8_t a, __vector int8_t b)
 {
@@ -19,4 +19,4 @@ inline __vector int8_t saturating_subtract(__vector int8_t a, __vector int8_t b)
 	return tmp;
 }
 
-} // namespace libnux
+} // namespace libnux::vx
diff --git a/src/unittest.cpp b/src/unittest.cpp
deleted file mode 100644
index 5d226e46049fddfbbbd99f3a884e7582244103c3..0000000000000000000000000000000000000000
--- a/src/unittest.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-#include "libnux/system.h"
-#include "libnux/unittest.h"
-
-static uint32_t num_passed = 0;
-static uint32_t num_failed = 0;
-
-static uint32_t num_testcases_passed= 0;
-static uint32_t num_testcases_failed = 0;
-
-static uint32_t testcase_passed_offset = 0;
-static uint32_t testcase_failed_offset = 0;
-
-static libnux_test_action_type test_action = libnux_test_action_warning;
-
-
-void libnux_test_init(void) {
-}
-
-void libnux_test_shutdown(void) {
-	libnux_test_write_termination();
-	exit(num_testcases_failed != 0);
-}
-
-uint32_t libnux_test_get_passed(void) {
-	return num_passed;
-}
-
-uint32_t libnux_test_get_failed(void) {
-	return num_failed;
-}
-
-uint32_t libnux_testcase_get_passed(void) {
-	return num_testcases_passed;
-}
-
-uint32_t libnux_testcase_get_failed(void) {
-	return num_testcases_failed;
-}
-
-void libnux_test_set_action(libnux_test_action_type const action) {
-	test_action = action;
-}
-
-libnux_test_action_type libnux_test_get_action(void) {
-	return test_action;
-}
-
-void libnux_test_inc_passed(void) {
-	num_passed++;
-}
-
-void libnux_test_inc_failed(void) {
-	num_failed++;
-}
-
-uint32_t get_num_passed_in_testcase(void) {
-	return num_passed - testcase_passed_offset;
-}
-
-uint32_t get_num_failed_in_testcase(void) {
-	return num_failed - testcase_failed_offset;
-}
-
-void libnux_testcase_begin(char const * name) {
-	libnux_test_write_string("[ Run      ] ");
-	libnux_test_write_string(name);
-	libnux_test_write_string("\n");
-	testcase_passed_offset = num_passed;
-	testcase_failed_offset = num_failed;
-}
-
-void libnux_testcase_end(void) {
-	if(get_num_failed_in_testcase() == 0) {
-		libnux_test_write_string("[       Ok ] Passed ");
-		libnux_test_write_int(get_num_passed_in_testcase());
-		libnux_test_write_string(" tests\n");
-		num_testcases_passed++;
-	} else {
-		libnux_test_write_string("[  Failed  ]\n");
-		num_testcases_failed++;
-	}
-}
-
-void libnux_test_summary(void) {
-	libnux_test_write_string("\n[==========]\n");
-	libnux_test_write_string("[  Passed  ] ");
-	libnux_test_write_int(num_testcases_passed);
-	libnux_test_write_string(" test cases\n");
-	libnux_test_write_string("[  Failed  ] ");
-	libnux_test_write_int(num_testcases_failed);
-	libnux_test_write_string(" test cases\n");
-
-	libnux_test_write_string("\n[==========]\n");
-	libnux_test_write_string("[  Passed  ] ");
-	libnux_test_write_int(num_passed);
-	libnux_test_write_string(" tests\n");
-	libnux_test_write_string("[  Failed  ] ");
-	libnux_test_write_int(num_failed);
-	libnux_test_write_string(" tests\n");
-}
diff --git a/src/unittest_mailbox.cpp b/src/unittest_mailbox.cpp
deleted file mode 100644
index 907150c7375231d4287afe9cd9926c05cad9cf55..0000000000000000000000000000000000000000
--- a/src/unittest_mailbox.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "libnux/unittest.h"
-#include "libnux/mailbox.h"
-
-uint32_t libnux_test_write_string(char const * str) {
-	return libnux_mailbox_write_string(str);
-}
-
-uint32_t libnux_test_write_int(uint32_t const n) {
-	return libnux_mailbox_write_int(n);
-}
-
-void libnux_test_write_termination()
-{
-	libnux_mailbox_string_terminate();
-}
diff --git a/src/bitformatting.cpp b/src/vx/bitformatting.cpp
similarity index 86%
rename from src/bitformatting.cpp
rename to src/vx/bitformatting.cpp
index 66401d1e85b1e622402b3f40d9af9a05fd41a797..5de90aca847d01c7d53dcc796cf789ba5291e96e 100644
--- a/src/bitformatting.cpp
+++ b/src/vx/bitformatting.cpp
@@ -1,5 +1,7 @@
 #include <stddef.h>
-#include "libnux/bitformatting.h"
+#include "libnux/vx/bitformatting.h"
+
+namespace libnux::vx {
 
 uint8_t reverse_byte(uint8_t b)
 {
@@ -22,3 +24,5 @@ void vector_reverse_bytes(__vector uint8_t* data)
 		(*data)[i] = reverse_byte((*data)[i]);
 	}
 }
+
+} // namespace libnux::vx
diff --git a/src/correlation.cpp b/src/vx/correlation.cpp
similarity index 61%
rename from src/correlation.cpp
rename to src/vx/correlation.cpp
index 5190260be6c5beb83ca57b932c45079e80e4dc38..4bf8f70b9c5af12cd0056174a5f9502e08889c3c 100644
--- a/src/correlation.cpp
+++ b/src/vx/correlation.cpp
@@ -1,5 +1,7 @@
+#include "libnux/vx/correlation.h"
 #include <stddef.h>
-#include "libnux/correlation.h"
+
+namespace libnux::vx {
 
 void reset_all_correlations()
 {
@@ -7,3 +9,5 @@ void reset_all_correlations()
 		reset_correlation(row);
 	}
 }
+
+} // namespace libnux::vx
diff --git a/src/exp.cpp b/src/vx/exp.cpp
similarity index 96%
rename from src/exp.cpp
rename to src/vx/exp.cpp
index 32d8ae994336c7be52112bf6feeaf09303cc6996..408da6196fba5c9fdbc6c71ceb13e7dfe08fc9a0 100644
--- a/src/exp.cpp
+++ b/src/vx/exp.cpp
@@ -1,5 +1,8 @@
 #include <stdint.h>
-#include "libnux/fxdpt.h"
+#include "libnux/vx/exp.h"
+#include "libnux/vx/fxdpt.h"
+
+namespace libnux::vx {
 
 /** calculate the first 6 terms of the series expansion of the exponential
  * function.
@@ -109,7 +112,7 @@ int32_t exp_n(int32_t x, const uint32_t n)
 
 	for(i=2; i<n; i++) {
 		coeff = (i * coeff);  // factorial of i
-		
+
 		if( (x < FP(1.0)) && (x > FP(-1.0)) )
 			xto = (xto * x) / INV_SCALE;
 		else
@@ -117,6 +120,8 @@ int32_t exp_n(int32_t x, const uint32_t n)
 
 		rv += xto / coeff;
 	}
-			
+
 	return rv;
 }
+
+} // namespace libnux::vx
diff --git a/src/fxv.cpp b/src/vx/fxv.cpp
similarity index 88%
rename from src/fxv.cpp
rename to src/vx/fxv.cpp
index 52caf71b7d836f715333846fd0c68bfe19be55f5..1b53c780a4192844ecc9490023bc8906631960bc 100644
--- a/src/fxv.cpp
+++ b/src/vx/fxv.cpp
@@ -1,9 +1,11 @@
-#include "libnux/fxv.h"
-#include "libnux/dls.h"
-#include "libnux/sync.h"
+#include "libnux/vx/fxv.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/sync.h"
 #include <stddef.h>
 #include <stdint.h>
 
+namespace libnux::vx {
+
 void fxv_zero_vrf() {
 	volatile uint8_t zeros[dls_bytes_per_vector];
 	for (size_t i = 0; i < dls_bytes_per_vector; i++) {
@@ -49,3 +51,5 @@ void fxv_zero_vrf() {
 	);
 	sync();
 }
+
+} // namespace libnux::vx
diff --git a/src/mailbox.cpp b/src/vx/mailbox.cpp
similarity index 70%
rename from src/mailbox.cpp
rename to src/vx/mailbox.cpp
index 2980f46c506464f60985264f777ef5c1c8794588..87c9eba40fbc3983200f6d3fbc2f30950c676085 100644
--- a/src/mailbox.cpp
+++ b/src/vx/mailbox.cpp
@@ -1,5 +1,7 @@
 #include <stddef.h>
-#include "libnux/mailbox.h"
+#include "libnux/vx/mailbox.h"
+
+namespace libnux::vx {
 
 static uint32_t write_head_offset = 0;
 
@@ -46,7 +48,7 @@ uint32_t mailbox_read(uint8_t * dest, uint32_t const offset, uint32_t const size
 	return ptr - &mailbox_base + offset;
 }
 
-uint8_t libnux_mailbox_read_u8(uint32_t const offset) {
+uint8_t mailbox_read_u8(uint32_t const offset) {
 	if (reinterpret_cast<unsigned long>(&mailbox_base + offset) <
 	    reinterpret_cast<unsigned long>(&mailbox_end)) {
 		return *(&mailbox_base + offset);
@@ -56,7 +58,7 @@ uint8_t libnux_mailbox_read_u8(uint32_t const offset) {
 	}
 }
 
-void libnux_mailbox_write_u8(uint32_t const offset, uint8_t const byte) {
+void mailbox_write_u8(uint32_t const offset, uint8_t const byte) {
 	if (reinterpret_cast<unsigned long>(&mailbox_base + offset) <
 	    reinterpret_cast<unsigned long>(&mailbox_end)) {
 		*(&mailbox_base + offset) = byte;
@@ -65,12 +67,12 @@ void libnux_mailbox_write_u8(uint32_t const offset, uint8_t const byte) {
 	}
 }
 
-void libnux_mailbox_string_terminate()
+void mailbox_string_terminate()
 {
-	libnux_mailbox_write_u8(write_head_offset++, 0);
+	mailbox_write_u8(write_head_offset++, 0);
 }
 
-uint32_t libnux_mailbox_write_string(char const * str) {
+uint32_t mailbox_write_string(char const * str) {
 	char const * ptr = str;
 	for (; (*ptr != 0); write_head_offset++, ptr++) {
 		if (&mailbox_base + write_head_offset == &mailbox_end) {
@@ -82,39 +84,41 @@ uint32_t libnux_mailbox_write_string(char const * str) {
 	return ptr - str;
 }
 
-uint32_t libnux_mailbox_write_int(uint32_t const n) {
-	return libnux_mailbox_write_string(itoa(n, 10));
+uint32_t mailbox_write_int(uint32_t const n) {
+	return mailbox_write_string(itoa(n, 10));
 }
 
-uint32_t libnux_mailbox_write_signed_int(int32_t const n) {
+uint32_t mailbox_write_signed_int(int32_t const n) {
 	if (n < 0) {
-		uint32_t ret = libnux_mailbox_write_string("-");
+		uint32_t ret = mailbox_write_string("-");
 		if (n == INT32_MIN) {
-			return ret + libnux_mailbox_write_string("2147483648");
+			return ret + mailbox_write_string("2147483648");
 		} else {
-			return ret + libnux_mailbox_write_int(-n);
+			return ret + mailbox_write_int(-n);
 		}
 	}
-	return libnux_mailbox_write_int(n);
+	return mailbox_write_int(n);
 }
 
 #define LIBNUX_MAILBOX_WRITE_VECTOR(type, name, number_writer)                                     \
 	uint32_t libnux_mailbox_write_##name(__vector type const& vec)                                 \
 	{                                                                                              \
 		uint32_t ret = 0;                                                                          \
-		ret += libnux_mailbox_write_string("{");                                                   \
+		ret += mailbox_write_string("{");                                                          \
 		for (size_t i = 0; i < sizeof(__vector type) / sizeof(type); ++i) {                        \
 			ret += number_writer(vec[i]);                                                          \
 			if (i != sizeof(__vector type) / sizeof(type) - 1) {                                   \
-				ret += libnux_mailbox_write_string(",");                                           \
+				ret += mailbox_write_string(",");                                                  \
 			}                                                                                      \
 		}                                                                                          \
-		return ret + libnux_mailbox_write_string("}");                                             \
+		return ret + mailbox_write_string("}");                                                    \
 	}
 
-LIBNUX_MAILBOX_WRITE_VECTOR(uint8_t, vector, libnux_mailbox_write_int)
-LIBNUX_MAILBOX_WRITE_VECTOR(uint16_t, vector, libnux_mailbox_write_int)
-LIBNUX_MAILBOX_WRITE_VECTOR(int8_t, signed_vector, libnux_mailbox_write_signed_int)
-LIBNUX_MAILBOX_WRITE_VECTOR(int16_t, signed_vector, libnux_mailbox_write_signed_int)
+LIBNUX_MAILBOX_WRITE_VECTOR(uint8_t, vector, mailbox_write_int)
+LIBNUX_MAILBOX_WRITE_VECTOR(uint16_t, vector, mailbox_write_int)
+LIBNUX_MAILBOX_WRITE_VECTOR(int8_t, signed_vector, mailbox_write_signed_int)
+LIBNUX_MAILBOX_WRITE_VECTOR(int16_t, signed_vector, mailbox_write_signed_int)
 
 #undef LIBNUX_MAILBOX_WRITE_VECTOR
+
+} // namespace libnux::vx
diff --git a/src/malloc.cpp b/src/vx/malloc.cpp
similarity index 89%
rename from src/malloc.cpp
rename to src/vx/malloc.cpp
index 94355cb0df3efcddbec84c9b7c3a43052d50ffb8..84d307d189770adf830ee59238806d29690bae30 100644
--- a/src/malloc.cpp
+++ b/src/vx/malloc.cpp
@@ -1,10 +1,12 @@
-#include "libnux/malloc.h"
 #include <stdint.h>
+#include "libnux/vx/malloc.h"
 
 #ifdef MALLOC_DEBUG
-#include "libnux/mailbox.h"
+#include "libnux/vx/mailbox.h"
 #endif
 
+namespace libnux::vx {
+
 char* next_alloc = (char*) &heap_base;
 
 extern "C" void* malloc(size_t size)
@@ -36,3 +38,5 @@ extern "C" void free(void* ptr)
 	// do nothing; ever-growing heap...
 	(void) (ptr);
 }
+
+} // namespace libnux::vx
diff --git a/src/random.cpp b/src/vx/random.cpp
similarity index 86%
rename from src/random.cpp
rename to src/vx/random.cpp
index 24815569de5b9b8e008027d85d2cc0c44179b0c9..4b138203696b4f3e45d5f5b1991d929f363685b2 100644
--- a/src/random.cpp
+++ b/src/vx/random.cpp
@@ -1,4 +1,6 @@
-#include "libnux/random.h"
+#include "libnux/vx/random.h"
+
+namespace libnux::vx {
 
 uint32_t xorshift32(uint32_t* seed)
 {
@@ -29,3 +31,5 @@ uint32_t random_lcg(uint32_t *seed) {
   *seed = rv;
   return rv;
 }
+
+} // namespace libnux::vx
diff --git a/src/spikes.cpp b/src/vx/spikes.cpp
similarity index 73%
rename from src/spikes.cpp
rename to src/vx/spikes.cpp
index 76db0fe948d89fe2fb98051981aadcd2ea840a46..abc6617c47f31a0b913168c7f54802db03b789a8 100644
--- a/src/spikes.cpp
+++ b/src/vx/spikes.cpp
@@ -1,4 +1,6 @@
-#include "libnux/spikes.h"
+#include "libnux/vx/spikes.h"
+
+namespace libnux::vx {
 
 void send_uniform_spiketrain(spike_t* single_spike, uint32_t number, uint32_t isi_usec)
 {
@@ -8,3 +10,5 @@ void send_uniform_spiketrain(spike_t* single_spike, uint32_t number, uint32_t is
 		sleep_cycles(isi_usec * default_ppu_cycles_per_us);
 	}
 }
+
+} // namespace libnux::vx
diff --git a/src/stack_guards.cpp b/src/vx/stack_guards.cpp
similarity index 93%
rename from src/stack_guards.cpp
rename to src/vx/stack_guards.cpp
index 9dffe238e7f1c6913d2b1c09c6c1d91c56928f6a..54631366ab0d7eed6e0dd671ff571013993de8e0 100644
--- a/src/stack_guards.cpp
+++ b/src/vx/stack_guards.cpp
@@ -1,5 +1,7 @@
 #include <stdint.h>
 
+namespace libnux::vx {
+
 #ifdef LIBNUX_STACK_PROTECTOR
 
 #define STACK_GUARD_MAGIC 0xdeadbeef
@@ -38,3 +40,5 @@ asm(".globl isr_program\n"
 // clang-format on
 
 #endif
+
+} // namespace libnux
diff --git a/src/time.cpp b/src/vx/time.cpp
similarity index 55%
rename from src/time.cpp
rename to src/vx/time.cpp
index 8be5f72ec72c20a440b8e6b64411022b4f1cd1e7..402642b87c11abfeb9883209500ef91fe47a214d 100644
--- a/src/time.cpp
+++ b/src/vx/time.cpp
@@ -1,5 +1,7 @@
-#include "libnux/time.h"
-#include "libnux/spr.h"
+#include "libnux/vx/time.h"
+#include "libnux/vx/spr.h"
+
+namespace libnux::vx {
 
 /*
 	Idle for (approx.) `cycles` cycles.
@@ -19,18 +21,20 @@ time_base_t now()
 
 void print_measurement(char const* msg, time_pair const& t)
 {
-	libnux_mailbox_write_string(msg);
-	libnux_mailbox_write_string(": ");
-	libnux_mailbox_write_int(t.second - t.first);
-	libnux_mailbox_write_string("\n");
+	mailbox_write_string(msg);
+	mailbox_write_string(": ");
+	mailbox_write_int(t.second - t.first);
+	mailbox_write_string("\n");
 }
 
 void print_measurements_header()
 {
-	libnux_mailbox_write_string("begin time measurements [ppu cycles]\n\n");
+	mailbox_write_string("begin time measurements [ppu cycles]\n\n");
 }
 
 void print_measurements_footer()
 {
-	libnux_mailbox_write_string("\nstop time measurements [ppu cycles]");
+	mailbox_write_string("\nstop time measurements [ppu cycles]");
 }
+
+} // namespace libnux::vx
diff --git a/src/vx/unittest.cpp b/src/vx/unittest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ae10c284fbc4a4dce12f38bdc4ba1ba401609765
--- /dev/null
+++ b/src/vx/unittest.cpp
@@ -0,0 +1,104 @@
+#include "libnux/system.h"
+#include "libnux/vx/unittest.h"
+
+namespace libnux::vx {
+
+static uint32_t num_passed = 0;
+static uint32_t num_failed = 0;
+
+static uint32_t num_testcases_passed= 0;
+static uint32_t num_testcases_failed = 0;
+
+static uint32_t testcase_passed_offset = 0;
+static uint32_t testcase_failed_offset = 0;
+
+static test_action_type test_action = test_action_warning;
+
+
+void test_init(void) {
+}
+
+void test_shutdown(void) {
+	test_write_termination();
+	exit(num_testcases_failed != 0);
+}
+
+uint32_t test_get_passed(void) {
+	return num_passed;
+}
+
+uint32_t test_get_failed(void) {
+	return num_failed;
+}
+
+uint32_t testcase_get_passed(void) {
+	return num_testcases_passed;
+}
+
+uint32_t testcase_get_failed(void) {
+	return num_testcases_failed;
+}
+
+void test_set_action(test_action_type const action) {
+	test_action = action;
+}
+
+test_action_type test_get_action(void) {
+	return test_action;
+}
+
+void test_inc_passed(void) {
+	num_passed++;
+}
+
+void test_inc_failed(void) {
+	num_failed++;
+}
+
+uint32_t get_num_passed_in_testcase(void) {
+	return num_passed - testcase_passed_offset;
+}
+
+uint32_t get_num_failed_in_testcase(void) {
+	return num_failed - testcase_failed_offset;
+}
+
+void testcase_begin(char const * name) {
+	test_write_string("[ Run      ] ");
+	test_write_string(name);
+	test_write_string("\n");
+	testcase_passed_offset = num_passed;
+	testcase_failed_offset = num_failed;
+}
+
+void testcase_end(void) {
+	if(get_num_failed_in_testcase() == 0) {
+		test_write_string("[       Ok ] Passed ");
+		test_write_int(get_num_passed_in_testcase());
+		test_write_string(" tests\n");
+		num_testcases_passed++;
+	} else {
+		test_write_string("[  Failed  ]\n");
+		num_testcases_failed++;
+	}
+}
+
+void test_summary(void) {
+	test_write_string("\n[==========]\n");
+	test_write_string("[  Passed  ] ");
+	test_write_int(num_testcases_passed);
+	test_write_string(" test cases\n");
+	test_write_string("[  Failed  ] ");
+	test_write_int(num_testcases_failed);
+	test_write_string(" test cases\n");
+
+	test_write_string("\n[==========]\n");
+	test_write_string("[  Passed  ] ");
+	test_write_int(num_passed);
+	test_write_string(" tests\n");
+	test_write_string("[  Failed  ] ");
+	test_write_int(num_failed);
+	test_write_string(" tests\n");
+}
+
+} // namespace libnux::vx
diff --git a/src/vx/unittest_mailbox.cpp b/src/vx/unittest_mailbox.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e0f0bd0383f90b389659d68723467b3cdd5bfe3f
--- /dev/null
+++ b/src/vx/unittest_mailbox.cpp
@@ -0,0 +1,19 @@
+#include "libnux/vx/unittest.h"
+#include "libnux/vx/mailbox.h"
+
+namespace libnux::vx {
+
+uint32_t test_write_string(char const * str) {
+	return mailbox_write_string(str);
+}
+
+uint32_t test_write_int(uint32_t const n) {
+	return mailbox_write_int(n);
+}
+
+void test_write_termination()
+{
+	mailbox_string_terminate();
+}
+
+} // namespace libnux::vx
diff --git a/test/helpers/hwtest_common.py b/test/helpers/hwtest_common.py
index 36e13f52f47937e5f53d2de4b424a1c0aaf2873b..38126df5e7051c47328f1a59e55aa6a3baf6c0ea 100644
--- a/test/helpers/hwtest_common.py
+++ b/test/helpers/hwtest_common.py
@@ -69,7 +69,7 @@ class PpuHwTest(object):
         return hash(self.path)
 
 
-def find_binaries(dls_version: str) -> Set[PpuHwTest]:
+def find_binaries(chip_revision: str, chip_version: str) -> Set[PpuHwTest]:
     """
     Find test-binaries matching `(?:\b|_)[Tt]est`.
 
@@ -77,7 +77,7 @@ def find_binaries(dls_version: str) -> Set[PpuHwTest]:
     """
     ret = set()
 
-    test_regex = re.compile(r'(?:\b|_)[Tt]est.*' + dls_version + r'\.bin$')
+    test_regex = re.compile(r"(?:\b|_)[Tt]est.*" + chip_revision + r"_" + chip_version + r"\.bin$")
     for path, directories, files in os.walk(TEST_BINARY_PATH):
         for f in files:
             if test_regex.search(f):
@@ -87,7 +87,7 @@ def find_binaries(dls_version: str) -> Set[PpuHwTest]:
     return ret
 
 
-def get_special_binaries(dls_version: str) -> Set[PpuHwTest]:
+def get_special_binaries(chip_revision:str, chip_version: str) -> Set[PpuHwTest]:
     """
     Compile a set of "special" hardware tests. Tests are special, if the
     default constructor of :class:`PpuHwTest` does not apply.
@@ -100,30 +100,29 @@ def get_special_binaries(dls_version: str) -> Set[PpuHwTest]:
 
     test_list = {
         PpuHwTest(
-            join(TEST_BINARY_PATH, f"test_unittest_{dls_version}.bin"),
+            join(TEST_BINARY_PATH, chip_revision, f"test_unittest_{chip_revision}_{chip_version}.bin"),
             expected_exit_code=1),
         PpuHwTest(
-            join(TEST_BINARY_PATH, f"test_returncode_{dls_version}.bin"),
+            join(TEST_BINARY_PATH, chip_revision, f"test_returncode_{chip_revision}_{chip_version}.bin"),
             expected_exit_code=-559038737),
         PpuHwTest(
-            join(TEST_BINARY_PATH, f"test_stack_guard_{dls_version}.bin"),
+            join(TEST_BINARY_PATH, chip_revision, f"test_stack_guard_{chip_revision}_{chip_version}.bin"),
             expected_exit_code=stack_protection * -559038737),
         PpuHwTest(
-            join(TEST_BINARY_PATH, f"test_stack_redzone_{dls_version}.bin"),
+            join(TEST_BINARY_PATH, chip_revision, f"test_stack_redzone_{chip_revision}_{chip_version}.bin"),
             expected_exit_code=12 if stack_redzone else 2)
     }
 
-    if dls_version == 'vx':
-        simulation = os.environ.get("FLANGE_SIMULATION_RCF_PORT")
-        test_list.update({
-            PpuHwTest(
-                join(TEST_BINARY_PATH, f"test_cadc_static_{dls_version}.bin"),
-                expected_exit_code=0 if simulation is not None else 1,
-                supports_revision=lambda rev: rev >= 2),
-            PpuHwTest(
-                join(TEST_BINARY_PATH, f"test_synram_{dls_version}.bin"),
-                timeout=int(2e6),
-                supports_revision=lambda rev: rev >= 2),
-        })
+    simulation = os.environ.get("FLANGE_SIMULATION_RCF_PORT")
+    test_list.update({
+        PpuHwTest(
+            join(TEST_BINARY_PATH, chip_revision, f"test_cadc_static_{chip_revision}_{chip_version}.bin"),
+            expected_exit_code=0 if simulation is not None else 1,
+            supports_revision=lambda rev: rev >= 2),
+        PpuHwTest(
+            join(TEST_BINARY_PATH, chip_revision, f"test_synram_{chip_revision}_{chip_version}.bin"),
+            timeout=int(2e6),
+            supports_revision=lambda rev: rev >= 2),
+    })
 
     return test_list
diff --git a/test/test_empty.cpp b/test/helpers/test_empty.cpp
similarity index 100%
rename from test/test_empty.cpp
rename to test/helpers/test_empty.cpp
diff --git a/test/test_bool.cpp b/test/test_bool.cpp
deleted file mode 100644
index ba05abdd9cf19b5822871bab74cb76d1267ce054..0000000000000000000000000000000000000000
--- a/test/test_bool.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#include "libnux/unittest.h"
-#include <s2pp.h>
-#include <stddef.h>
-
-// needed for current gcc-nux
-#ifndef false
-// clang-format off
-#define false (bool) 0
-// clang-format on
-#endif
-#ifndef true
-#define true !false
-#endif
-
-void test_size()
-{
-	libnux_testcase_begin("size == 1B");
-	libnux_test_equal(sizeof(bool), static_cast<size_t>(1));
-	libnux_testcase_end();
-}
-
-void test_not()
-{
-	libnux_testcase_begin("not");
-	bool e1 = !true;
-	bool e2 = !false;
-	bool e3 = !!false;
-	bool e4 = !!true;
-	libnux_test_equal(e1, false);
-	libnux_test_equal(e2, true);
-	libnux_test_equal(e3, false);
-	libnux_test_equal(e4, true);
-	libnux_testcase_end();
-}
-
-void test_and()
-{
-	libnux_testcase_begin("and");
-	bool e1 = true && false;
-	bool e2 = true && true;
-	bool e3 = false && false;
-	libnux_test_equal(e1, false);
-	libnux_test_equal(e2, true);
-	libnux_test_equal(e3, false);
-	libnux_testcase_end();
-}
-
-void test_or()
-{
-	libnux_testcase_begin("or");
-	bool e1 = true || false;
-	bool e2 = true || true;
-	bool e3 = false || false;
-	libnux_test_equal(e1, true);
-	libnux_test_equal(e2, true);
-	libnux_test_equal(e3, false);
-	libnux_testcase_end();
-}
-
-void start()
-{
-	libnux_test_init();
-	test_size();
-	test_not();
-	test_and();
-	test_or();
-	libnux_test_summary();
-	libnux_test_shutdown();
-}
diff --git a/test/test_helper.cpp b/test/test_helper.cpp
deleted file mode 100644
index 2e5f8be865c6b409ae1b965fa8e7f81544f65cc0..0000000000000000000000000000000000000000
--- a/test/test_helper.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-#include <array>
-
-#include <s2pp.h>
-#include "libnux/helper.h"
-#include "libnux/unittest.h"
-
-void test_abs_diff()
-{
-	uint8_t u8bit_1 = 150;
-	uint8_t u8bit_2 = 15;
-	libnux_test_equal(abs_diff(u8bit_1, u8bit_2), static_cast<uint8_t>(135));
-
-	uint16_t u16bit_1 = 300;
-	uint16_t u16bit_2 = 3000;
-	libnux_test_equal(abs_diff(u16bit_1, u16bit_2), static_cast<uint16_t>(2700));
-
-	uint32_t u32bit_1 = 100;
-	uint32_t u32bit_2 = 100;
-	libnux_test_equal(abs_diff(u32bit_1, u32bit_2), static_cast<uint32_t>(0));
-
-	int8_t s8bit_1 = -10;
-	int8_t s8bit_2 = -20;
-	libnux_test_equal(abs_diff(s8bit_1, s8bit_2), static_cast<int8_t>(10));
-
-	int16_t s16bit_1 = -1000;
-	int16_t s16bit_2 = -100;
-	libnux_test_equal(abs_diff(s16bit_1, s16bit_2), static_cast<int16_t>(900));
-}
-
-void test_find_max_amount()
-{
-	std::array<uint8_t, 10> array_1{4, 17, 193, 4, 193, 10, 5, 3, 4, 0};
-	libnux_test_equal(find_max_amount(array_1), static_cast<uint8_t>(4));
-
-	std::array<uint16_t, 5> array_2{1600, 300, 1600, 300, 1600};
-	libnux_test_equal(find_max_amount(array_2), static_cast<uint16_t>(1600));
-}
-
-void start()
-{
-	libnux_test_init();
-	test_abs_diff();
-	test_find_max_amount();
-	libnux_test_summary();
-	libnux_test_shutdown();
-}
diff --git a/test/test_hwsimtests_vx.py b/test/test_hwsimtests_vx_v1.py
similarity index 96%
rename from test/test_hwsimtests_vx.py
rename to test/test_hwsimtests_vx_v1.py
index e236160ac952ad1cc83374891d9b2754ec40d6d5..7aef251636b8b0de7f23f118bae0907f63a83a6b 100644
--- a/test/test_hwsimtests_vx.py
+++ b/test/test_hwsimtests_vx_v1.py
@@ -80,8 +80,8 @@ class LibnuxHwSimTestsVx(unittest.TestCase):
             setattr(LibnuxHwSimTestsVx, test.name, test_method)
 
 
-LibnuxHwSimTestsVx.TESTS.update(get_special_binaries("vx"))
-LibnuxHwSimTestsVx.TESTS.update(find_binaries("vx"))
+LibnuxHwSimTestsVx.TESTS.update(get_special_binaries("vx", "v1"))
+LibnuxHwSimTestsVx.TESTS.update(find_binaries("vx", "v1"))
 LibnuxHwSimTestsVx.generate_cases()
 
 if __name__ == '__main__':
diff --git a/test/test_hwsimtests_vx_v2.py b/test/test_hwsimtests_vx_v2.py
new file mode 100644
index 0000000000000000000000000000000000000000..72db7a687bf47377be544cbfdcb4a68141ff3307
--- /dev/null
+++ b/test/test_hwsimtests_vx_v2.py
@@ -0,0 +1,88 @@
+import random
+import unittest
+from numbers import Integral
+from typing import Set, ClassVar
+
+from dlens_vx_v2.hxcomm import ManagedConnection
+from dlens_vx_v2.sta import generate, DigitalInit, run
+from dlens_vx_v2.halco import PPUOnDLS, iter_all, JTAGIdCodeOnDLS, TimerOnDLS
+from dlens_vx_v2.tools.run_ppu_program import load_and_start_program, \
+    stop_program, wait_until_ppu_finished, PPUTimeoutError
+from dlens_vx_v2 import logger
+from pyhaldls_vx_v2 import Timer
+from helpers.hwtest_common import get_special_binaries, find_binaries, \
+    PpuHwTest
+
+
+class LibnuxHwSimTestsVx(unittest.TestCase):
+    TESTS: Set[PpuHwTest] = set()
+    MANAGED_CONNECTION = ManagedConnection()
+    CONNECTION = None
+    CHIP_REVISION: ClassVar[Integral]
+
+    @classmethod
+    def setUpClass(cls) -> None:
+        # Initialize remote connection (to sim or hardware)
+        cls.CONNECTION = cls.MANAGED_CONNECTION.__enter__()
+
+        # Initialize the chip and find chip version
+        init_builder, _ = generate(DigitalInit())
+        jtag_id_ticket = init_builder.read(JTAGIdCodeOnDLS())
+        init_builder.write(TimerOnDLS(), Timer(0))
+        init_builder.wait_until(TimerOnDLS(), 1000)
+        run(cls.CONNECTION, init_builder.done())
+        jtag_id = jtag_id_ticket.get()
+        cls.CHIP_REVISION = jtag_id.version
+
+    @classmethod
+    def tearDownClass(cls) -> None:
+        # Disconnect the executor
+        cls.MANAGED_CONNECTION.__exit__()
+
+    @classmethod
+    def generate_cases(cls):
+        """
+        Augment this class by test cases for all tests defined in `cls.TESTS`.
+        """
+        for test in cls.TESTS:
+            def generate_test(ppu_test: PpuHwTest):
+                def test_func(self: LibnuxHwSimTestsVx):
+                    if not ppu_test.supports_revision(self.CHIP_REVISION):
+                        self.skipTest("Incompatible chip rev. "
+                                      "{self.CHIP_REVISION}")
+
+                    log = logger.get("LibnuxHwSimTestsVx.%s" % ppu_test.name)
+                    ppu = random.choice(list(iter_all(PPUOnDLS)))
+                    log.info("Running test on %s." % ppu)
+
+                    load_and_start_program(cls.CONNECTION, ppu_test.path, ppu)
+                    try:
+                        wait_until_ppu_finished(cls.CONNECTION,
+                                                timeout=ppu_test.timeout,
+                                                ppu=ppu)
+                        self.assertFalse(ppu_test.expect_timeout,
+                                         "Expected timeout did not happen.")
+                    except PPUTimeoutError:
+                        self.assertTrue(ppu_test.expect_timeout,
+                                        "Unexpected timeout.")
+                    finally:
+                        returncode = stop_program(cls.CONNECTION, ppu=ppu)
+
+                    self.assertEqual(ppu_test.expected_exit_code, returncode,
+                                     f"Exit code was {returncode}, expected "
+                                     f"{ppu_test.expected_exit_code}.")
+
+                return test_func
+
+            test_method = generate_test(test)
+            test_method.__name__ = test.name
+
+            setattr(LibnuxHwSimTestsVx, test.name, test_method)
+
+
+LibnuxHwSimTestsVx.TESTS.update(get_special_binaries("vx", "v2"))
+LibnuxHwSimTestsVx.TESTS.update(find_binaries("vx", "v2"))
+LibnuxHwSimTestsVx.generate_cases()
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/test/test_malloc.cpp b/test/test_malloc.cpp
deleted file mode 100644
index abf323112e8ec453c541a0b5471eeefca41e2940..0000000000000000000000000000000000000000
--- a/test/test_malloc.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "libnux/unittest.h"
-#include "libnux/mailbox.h"
-#include "libnux/malloc.h"
-
-void start(void) {
-	libnux_test_init();
-
-	libnux_testcase_begin("test malloc");
-	int* i = reinterpret_cast<int*>(malloc(sizeof(int)));
-	int* j = reinterpret_cast<int*>(malloc(sizeof(int)));
-	libnux_test_not_null(i);
-	libnux_test_not_null(j);
-	libnux_test_true((((intptr_t)i + (intptr_t)sizeof(int)) == (intptr_t)j));
-	libnux_testcase_end();
-
-	libnux_test_summary();
-	libnux_test_shutdown();
-}
diff --git a/test/test_unittest.cpp b/test/test_unittest.cpp
deleted file mode 100644
index a9f2a9880039d67c826ebf40d32efc85d875cb7c..0000000000000000000000000000000000000000
--- a/test/test_unittest.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include <libnux/unittest.h>
-
-void basic_test(void) {
-	libnux_testcase_begin("basic_checks");
-
-	char* s = reinterpret_cast<char*>(0);
-	int a = 0;
-	int b = 0;
-	int c = 0;
-
-	libnux_test_equal(0, a);
-	libnux_test_equal(0, b);
-	libnux_test_equal(0, c);
-
-	libnux_test_equal(0, 1-1);
-	libnux_test_equal(0, -1+1);
-	libnux_test_equal(-1, -2+1);
-
-	libnux_test_null(s);
-	libnux_test_true(1);
-
-	libnux_testcase_end();
-}
-
-void failing_test(void) {
-	libnux_testcase_begin("failing_test");
-
-	libnux_test_equal(0, 1+1);
-	libnux_test_equal(0, 1+2);
-
-	libnux_testcase_end();
-}
-
-void start(void) {
-	libnux_test_init();
-	basic_test();
-	failing_test();
-	libnux_test_summary();
-	libnux_test_shutdown();
-}
diff --git a/test/test_vector_convert.cpp b/test/test_vector_convert.cpp
deleted file mode 100644
index 812267e6fdafc161b550d8acf0271b32090fd4cf..0000000000000000000000000000000000000000
--- a/test/test_vector_convert.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "libnux/unittest.h"
-#include "libnux/vector_convert.h"
-
-void test_uint8_to_int8()
-{
-	libnux_testcase_begin("uint8_to_int8");
-
-	__vector uint8_t a = vec_splat_u8(0);
-	auto const ra = libnux::uint8_to_int8(a);
-	for (uint32_t index = 0; index < sizeof(__vector int8_t); index++) {
-		libnux_test_equal(ra[index], -128);
-	}
-
-	__vector uint8_t b = vec_splat_u8(255);
-	auto const rb = libnux::uint8_to_int8(b);
-	for (uint32_t index = 0; index < sizeof(__vector int8_t); index++) {
-		libnux_test_equal(rb[index], 127);
-	}
-
-	__vector uint8_t c = vec_splat_u8(123);
-	auto const rc = libnux::uint8_to_int8(c);
-	for (uint32_t index = 0; index < sizeof(__vector int8_t); index++) {
-		libnux_test_equal(rc[index], -128 + 123);
-	}
-
-	libnux_testcase_end();
-}
-
-void start(void)
-{
-	libnux_test_init();
-	test_uint8_to_int8();
-	libnux_test_summary();
-	libnux_test_shutdown();
-}
diff --git a/test/test_bitformatting.cpp b/test/vx/test_bitformatting.cpp
similarity index 56%
rename from test/test_bitformatting.cpp
rename to test/vx/test_bitformatting.cpp
index c1f2ce09b9de7399a422c919de2e85a572e94fb7..336a0b8977e72a4824a9164647db62b51d027b49 100644
--- a/test/test_bitformatting.cpp
+++ b/test/vx/test_bitformatting.cpp
@@ -1,16 +1,18 @@
-#include "libnux/unittest.h"
-#include "libnux/bitformatting.h"
+#include "libnux/vx/unittest.h"
+#include "libnux/vx/bitformatting.h"
+
+using namespace libnux::vx;
 
 void test_reverse_byte()
 {
 	uint8_t byte_1 = 170;
-	libnux_test_equal(reverse_byte(byte_1), 85);
+	test_equal(reverse_byte(byte_1), 85);
 
 	uint8_t byte_2 = 195;
-	libnux_test_equal(reverse_byte(byte_2), 195);
+	test_equal(reverse_byte(byte_2), 195);
 
 	uint8_t byte_3 = 0;
-	libnux_test_equal(reverse_byte(byte_3), 0);
+	test_equal(reverse_byte(byte_3), 0);
 }
 
 void test_vector_reverse_bytes()
@@ -24,15 +26,15 @@ void test_vector_reverse_bytes()
 	vector_reverse_bytes(&test_vector);
 
 	for (uint8_t i = 0; i < sizeof(__vector uint8_t); i++) {
-		libnux_test_equal(test_vector[i], reverse_byte(i));
+		test_equal(test_vector[i], reverse_byte(i));
 	}
 }
 
 void start()
 {
-	libnux_test_init();
+	test_init();
 	test_reverse_byte();
 	test_vector_reverse_bytes();
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/vx/test_bool.cpp b/test/vx/test_bool.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cd54328399ccfcb3dd9e6c3cebb2edaad2c6df6f
--- /dev/null
+++ b/test/vx/test_bool.cpp
@@ -0,0 +1,71 @@
+#include "libnux/vx/unittest.h"
+#include <s2pp.h>
+#include <stddef.h>
+
+using namespace libnux::vx;
+
+// needed for current gcc-nux
+#ifndef false
+// clang-format off
+#define false (bool) 0
+// clang-format on
+#endif
+#ifndef true
+#define true !false
+#endif
+
+void test_size()
+{
+	testcase_begin("size == 1B");
+	test_equal(sizeof(bool), static_cast<size_t>(1));
+	testcase_end();
+}
+
+void test_not()
+{
+	testcase_begin("not");
+	bool e1 = !true;
+	bool e2 = !false;
+	bool e3 = !!false;
+	bool e4 = !!true;
+	test_equal(e1, false);
+	test_equal(e2, true);
+	test_equal(e3, false);
+	test_equal(e4, true);
+	testcase_end();
+}
+
+void test_and()
+{
+	testcase_begin("and");
+	bool e1 = true && false;
+	bool e2 = true && true;
+	bool e3 = false && false;
+	test_equal(e1, false);
+	test_equal(e2, true);
+	test_equal(e3, false);
+	testcase_end();
+}
+
+void test_or()
+{
+	testcase_begin("or");
+	bool e1 = true || false;
+	bool e2 = true || true;
+	bool e3 = false || false;
+	test_equal(e1, true);
+	test_equal(e2, true);
+	test_equal(e3, false);
+	testcase_end();
+}
+
+void start()
+{
+	test_init();
+	test_size();
+	test_not();
+	test_and();
+	test_or();
+	test_summary();
+	test_shutdown();
+}
diff --git a/test/test_cadc_static.cpp b/test/vx/test_cadc_static.cpp
similarity index 71%
rename from test/test_cadc_static.cpp
rename to test/vx/test_cadc_static.cpp
index 6136ac7083d9c36e7f2fb6253ee10bfba8496391..a9433b4e0a7bc54348a3cf0bc96e006e4f14c321 100644
--- a/test/test_cadc_static.cpp
+++ b/test/vx/test_cadc_static.cpp
@@ -1,12 +1,12 @@
 #include <array>
 #include <stddef.h>
 #include <stdint.h>
-#include "libnux/dls.h"
-#include "libnux/omnibus.h"
-#include "libnux/unittest.h"
-#include "libnux/vector.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/omnibus.h"
+#include "libnux/vx/unittest.h"
+#include "libnux/vx/vector.h"
 
-using namespace libnux;
+using namespace libnux::vx;
 
 // generated in hx_top/**/anncore.sv
 vector_row_t get_expectation()
@@ -26,9 +26,9 @@ vector_row_t get_expectation()
 // program entry point
 void start(void)
 {
-	libnux_test_init();
+	test_init();
 
-	libnux_testcase_begin("cadc static pattern");
+	testcase_begin("cadc static pattern");
 	auto const expectation = get_expectation();
 	constexpr size_t row = 0; // arbitrary in [0,256)
 	std::array<bool, 2> is_causal = {false, true};
@@ -39,11 +39,11 @@ void start(void)
 		// is tested here
 		auto const cadc_omnibus = get_row_via_omnibus(
 		    row, causal ? cadc_top_causal_base_address : cadc_top_acausal_base_address);
-		libnux_test_equal(cadc_vector, cadc_omnibus);
-		libnux_test_equal(cadc_vector, expectation);
+		test_equal(cadc_vector, cadc_omnibus);
+		test_equal(cadc_vector, expectation);
 	}
-	libnux_testcase_end();
+	testcase_end();
 
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/test_ctors.cpp b/test/vx/test_ctors.cpp
similarity index 80%
rename from test/test_ctors.cpp
rename to test/vx/test_ctors.cpp
index 3bd16dcaa6734ed83daf23d7b349d8596e7ee0d0..59c510b519feb43b2b81a62e1781ada57b4481e3 100644
--- a/test/test_ctors.cpp
+++ b/test/vx/test_ctors.cpp
@@ -1,4 +1,6 @@
-#include "libnux/unittest.h"
+#include "libnux/vx/unittest.h"
+
+using namespace libnux::vx;
 
 volatile int global_value = 1;
 
diff --git a/test/test_fpga_memory_scalar_access.cpp b/test/vx/test_fpga_memory_scalar_access.cpp
similarity index 58%
rename from test/test_fpga_memory_scalar_access.cpp
rename to test/vx/test_fpga_memory_scalar_access.cpp
index a105a86ac94082e473f59fea2f4539e73de708d8..d87905248d94a44795e78a3fe09c66b7dd02ccf8 100644
--- a/test/test_fpga_memory_scalar_access.cpp
+++ b/test/vx/test_fpga_memory_scalar_access.cpp
@@ -1,10 +1,10 @@
 #include <array>
 #include <stddef.h>
 #include <stdint.h>
-#include "libnux/dls.h"
-#include "libnux/unittest.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/unittest.h"
 
-using namespace libnux;
+using namespace libnux::vx;
 
 template <typename T>
 void test_write_read(T const value, size_t const offset = 13)
@@ -13,19 +13,19 @@ void test_write_read(T const value, size_t const offset = 13)
 	*ptr = value;
 	// cf. issue #3739
 	asm volatile("nop");
-	libnux_test_equal(value, *ptr);
+	test_equal(value, *ptr);
 }
 
 void start(void)
 {
-	libnux_test_init();
+	test_init();
 
-	libnux_testcase_begin("external memory write read via scalar unit");
+	testcase_begin("external memory write read via scalar unit");
 	test_write_read<uint8_t>(123);
 	test_write_read<uint16_t>(12345);
 	test_write_read<uint32_t>(12345678);
-	libnux_testcase_end();
+	testcase_end();
 
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/test_fpga_memory_vector_access.cpp b/test/vx/test_fpga_memory_vector_access.cpp
similarity index 54%
rename from test/test_fpga_memory_vector_access.cpp
rename to test/vx/test_fpga_memory_vector_access.cpp
index 376ad9f03f1d7722526aa279f8e52b2f5a54cea2..d7e4f13bc53a68f9c5cc545af7a7c2455891fe91 100644
--- a/test/test_fpga_memory_vector_access.cpp
+++ b/test/vx/test_fpga_memory_vector_access.cpp
@@ -1,16 +1,16 @@
 #include <array>
 #include <stddef.h>
 #include <stdint.h>
-#include "libnux/dls.h"
-#include "libnux/unittest.h"
-#include "libnux/vector.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/unittest.h"
+#include "libnux/vx/vector.h"
 
-using namespace libnux;
+using namespace libnux::vx;
 
 void start(void) {
-	libnux_test_init();
+	test_init();
 
-	libnux_testcase_begin("external memory write read via vector unit");
+	testcase_begin("external memory write read via vector unit");
 	vector_type values;
 	for (size_t entry = 0; entry < dls_vector_size; ++entry) {
 		values[entry] = entry;
@@ -23,10 +23,10 @@ void start(void) {
 	auto const read = get_vector(dls_extmem_base, index);
 
 	for (size_t column = 0; column < 128; ++column) {
-		libnux_test_equal(read[column], values[column]);
+		test_equal(read[column], values[column]);
 	}
-	libnux_testcase_end();
+	testcase_end();
 
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/test_fxvadd.cpp b/test/vx/test_fxvadd.cpp
similarity index 65%
rename from test/test_fxvadd.cpp
rename to test/vx/test_fxvadd.cpp
index 7676b0acb10d1543b82376a77a50ff2ff2b37bc5..1e91c2ae6fc0de93ed6492f7972b6d92713a34a5 100644
--- a/test/test_fxvadd.cpp
+++ b/test/vx/test_fxvadd.cpp
@@ -1,42 +1,44 @@
 #include <s2pp.h>
-#include "libnux/mailbox.h"
-#include "libnux/unittest.h"
+#include "libnux/vx/mailbox.h"
+#include "libnux/vx/unittest.h"
+
+using namespace libnux::vx;
 
 void test_fxvadd()
 {
-	libnux_testcase_begin(__func__);
+	testcase_begin(__func__);
 	/* Addition should be modulo arithmetic by default */
 	{
 		__vector int8_t vec = fxv_splatb(0xff);
 		__vector int8_t const ones = fxv_splatb(1);
 		vec = fxv_add(vec, ones);
 		for (uint32_t i = 0; i < sizeof(__vector uint8_t); i++) {
-			libnux_test_equal(vec[i], 0);
+			test_equal(vec[i], 0);
 		}
 	}
-	libnux_testcase_end();
+	testcase_end();
 }
 
 void test_fxvaddfs()
 {
-	libnux_testcase_begin(__func__);
+	testcase_begin(__func__);
 	/* Check if saturating arithmetic works */
 	{
 		__vector int8_t vec = fxv_splatb(0x7f);
 		__vector int8_t const ones = fxv_splatb(1);
 		vec = fxv_addfs(vec, ones);
 		for (uint32_t i = 0; i < sizeof(__vector uint8_t); i++) {
-			libnux_test_equal(vec[i], 0x7f);
+			test_equal(vec[i], 0x7f);
 		}
 	}
-	libnux_testcase_end();
+	testcase_end();
 }
 
 void start(void)
 {
-	libnux_test_init();
+	test_init();
 	test_fxvadd();
 	test_fxvaddfs();
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/test_fxvsel.cpp b/test/vx/test_fxvsel.cpp
similarity index 87%
rename from test/test_fxvsel.cpp
rename to test/vx/test_fxvsel.cpp
index 1970fcb7bd8ee4d194c02cfab9525884770014b5..8df628921aa5bcbaf0358f540b7618b30b75b0af 100644
--- a/test/test_fxvsel.cpp
+++ b/test/vx/test_fxvsel.cpp
@@ -1,9 +1,11 @@
 #include <s2pp.h>
-#include "libnux/unittest.h"
-#include "libnux/mailbox.h"
+#include "libnux/vx/unittest.h"
+#include "libnux/vx/mailbox.h"
+
+using namespace libnux::vx;
 
 void test_fxvsel_inline_asm() {
-	libnux_testcase_begin(__func__);
+	testcase_begin(__func__);
 	// Create a vector with 0, +1, -1, 0, +1, -1, ... . The -1 is explicitely
 	// initialized as its two's complement, which is 0xff
 	__vector uint8_t cmp = {
@@ -46,7 +48,7 @@ void test_fxvsel_inline_asm() {
 				  [zero] "r" (0)
 				: "qv1", "memory");
 		for (uint32_t i = 0; i < sizeof(__vector uint8_t); i++) {
-			libnux_test_equal(res[i], rhs[i]);
+			test_equal(res[i], rhs[i]);
 		}
 	}
 	/* Condition gt */
@@ -66,9 +68,9 @@ void test_fxvsel_inline_asm() {
 				: "qv1", "memory");
 		for (uint32_t i = 0; i < sizeof(__vector uint8_t); i++) {
 			if ((int8_t)(cmp[i]) > 0) {
-				libnux_test_equal(res[i], rhs[i]);
+				test_equal(res[i], rhs[i]);
 			} else {
-				libnux_test_equal(res[i], lhs[i]);
+				test_equal(res[i], lhs[i]);
 			}
 		}
 	}
@@ -89,9 +91,9 @@ void test_fxvsel_inline_asm() {
 				: "qv1", "memory");
 		for (uint32_t i = 0; i < sizeof(__vector uint8_t); i++) {
 			if ((int8_t)(cmp[i]) < 0) {
-				libnux_test_equal(res[i], rhs[i]);
+				test_equal(res[i], rhs[i]);
 			} else {
-				libnux_test_equal(res[i], lhs[i]);
+				test_equal(res[i], lhs[i]);
 			}
 		}
 	}
@@ -112,19 +114,19 @@ void test_fxvsel_inline_asm() {
 				: "qv1", "memory");
 		for (uint32_t i = 0; i < sizeof(__vector uint8_t); i++) {
 			if ((int8_t)(cmp[i]) == 0) {
-				libnux_test_equal(res[i], rhs[i]);
+				test_equal(res[i], rhs[i]);
 			} else {
-				libnux_test_equal(res[i], lhs[i]);
+				test_equal(res[i], lhs[i]);
 			}
 		}
 	}
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 void start(void) {
-	libnux_test_init();
+	test_init();
 	test_fxvsel_inline_asm();
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/vx/test_helper.cpp b/test/vx/test_helper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5b3b98569a3d4004348937934ee66a749c84ed75
--- /dev/null
+++ b/test/vx/test_helper.cpp
@@ -0,0 +1,47 @@
+#include <array>
+#include <s2pp.h>
+#include "libnux/vx/helper.h"
+#include "libnux/vx/unittest.h"
+
+using namespace libnux::vx;
+
+void test_abs_diff()
+{
+	uint8_t u8bit_1 = 150;
+	uint8_t u8bit_2 = 15;
+	test_equal(abs_diff(u8bit_1, u8bit_2), static_cast<uint8_t>(135));
+
+	uint16_t u16bit_1 = 300;
+	uint16_t u16bit_2 = 3000;
+	test_equal(abs_diff(u16bit_1, u16bit_2), static_cast<uint16_t>(2700));
+
+	uint32_t u32bit_1 = 100;
+	uint32_t u32bit_2 = 100;
+	test_equal(abs_diff(u32bit_1, u32bit_2), static_cast<uint32_t>(0));
+
+	int8_t s8bit_1 = -10;
+	int8_t s8bit_2 = -20;
+	test_equal(abs_diff(s8bit_1, s8bit_2), static_cast<int8_t>(10));
+
+	int16_t s16bit_1 = -1000;
+	int16_t s16bit_2 = -100;
+	test_equal(abs_diff(s16bit_1, s16bit_2), static_cast<int16_t>(900));
+}
+
+void test_find_max_amount()
+{
+	std::array<uint8_t, 10> array_1{4, 17, 193, 4, 193, 10, 5, 3, 4, 0};
+	test_equal(find_max_amount(array_1), static_cast<uint8_t>(4));
+
+	std::array<uint16_t, 5> array_2{1600, 300, 1600, 300, 1600};
+	test_equal(find_max_amount(array_2), static_cast<uint16_t>(1600));
+}
+
+void start()
+{
+	test_init();
+	test_abs_diff();
+	test_find_max_amount();
+	test_summary();
+	test_shutdown();
+}
diff --git a/test/test_inline_vector_argument.cpp b/test/vx/test_inline_vector_argument.cpp
similarity index 89%
rename from test/test_inline_vector_argument.cpp
rename to test/vx/test_inline_vector_argument.cpp
index 23a3ed96860e81dafcdc6f1ca6ec6678e28ead1c..aa9acd91f6db2009c62d192d2254b78c8a8da944 100644
--- a/test/test_inline_vector_argument.cpp
+++ b/test/vx/test_inline_vector_argument.cpp
@@ -1,5 +1,7 @@
 #include <s2pp.h>
-#include "libnux/spr.h"
+#include "libnux/vx/spr.h"
+
+using namespace libnux::vx;
 
 // inlined function with vector argument
 inline __attribute__((always_inline)) void foo_inline(__vector uint8_t& y)
diff --git a/test/vx/test_malloc.cpp b/test/vx/test_malloc.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..256ee1a1738dd58f8e444d1c4e439c8d57a5625c
--- /dev/null
+++ b/test/vx/test_malloc.cpp
@@ -0,0 +1,20 @@
+#include "libnux/vx/unittest.h"
+#include "libnux/vx/mailbox.h"
+#include "libnux/vx/malloc.h"
+
+using namespace libnux::vx;
+
+void start(void) {
+	test_init();
+
+	testcase_begin("test malloc");
+	int* i = reinterpret_cast<int*>(malloc(sizeof(int)));
+	int* j = reinterpret_cast<int*>(malloc(sizeof(int)));
+	test_not_null(i);
+	test_not_null(j);
+	test_true((((intptr_t)i + (intptr_t)sizeof(int)) == (intptr_t)j));
+	testcase_end();
+
+	test_summary();
+	test_shutdown();
+}
diff --git a/test/test_many_vectors.cpp b/test/vx/test_many_vectors.cpp
similarity index 85%
rename from test/test_many_vectors.cpp
rename to test/vx/test_many_vectors.cpp
index 1fa52677b89a13c964f6208cb5d443f8cbaf09a2..613f06fd930902890b3ceaa8c02cb098e1f03286 100644
--- a/test/test_many_vectors.cpp
+++ b/test/vx/test_many_vectors.cpp
@@ -1,7 +1,9 @@
 #include <s2pp.h>
 
-#include "libnux/mailbox.h"
-#include "libnux/unittest.h"
+#include "libnux/vx/mailbox.h"
+#include "libnux/vx/unittest.h"
+
+using namespace libnux::vx;
 
 #define NUM_VECTOR_REGISTERS 32
 
@@ -12,7 +14,7 @@
 // test_many_vectors. This generates an easier to read assembly.
 void __attribute__((optimize("O0"))) test_equal(uint32_t a, uint32_t b)
 {
-	libnux_test_equal(a, b);
+	test_equal(a, b);
 }
 
 /*
@@ -25,7 +27,7 @@ void __attribute__((optimize("O0"))) test_equal(uint32_t a, uint32_t b)
  */
 void test_many_vectors()
 {
-	libnux_testcase_begin(__func__);
+	testcase_begin(__func__);
 
 	__vector uint8_t vectors[NUM_VECTORS_TO_USE];
 
@@ -40,15 +42,15 @@ void test_many_vectors()
 		}
 	}
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 int start()
 {
-	libnux_test_init();
+	test_init();
 	test_many_vectors();
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 
 	return 0;
 }
diff --git a/test/test_measure_time.cpp b/test/vx/test_measure_time.cpp
similarity index 79%
rename from test/test_measure_time.cpp
rename to test/vx/test_measure_time.cpp
index f080d808e59b8a2194d4030eaaab25ee0cdc65da..710ef9dd9033170bd23b6dd0a66d55456359dfd9 100644
--- a/test/test_measure_time.cpp
+++ b/test/vx/test_measure_time.cpp
@@ -1,7 +1,9 @@
-#include "libnux/attrib.h"
-#include "libnux/helper.h"
-#include "libnux/time.h"
-#include "libnux/unittest.h"
+#include "libnux/vx/attrib.h"
+#include "libnux/vx/helper.h"
+#include "libnux/vx/time.h"
+#include "libnux/vx/unittest.h"
+
+using namespace libnux::vx;
 
 template <size_t N>
 void test_sleep_cycles(char const* msg, times<N>& t, time_base_t sleep_time, time_base_t max_time)
@@ -22,8 +24,8 @@ void test_sleep_cycles(char const* msg, times<N>& t, time_base_t sleep_time, tim
 		pair.second = pair.first + (post_loop - pair.first) / inner_loop_count;
 	}
 	print_measurement(msg, t);
-	libnux_test_true(min(t) > sleep_time);
-	libnux_test_true(max(t) < max_time);
+	test_true(min(t) > sleep_time);
+	test_true(max(t) < max_time);
 }
 
 template <size_t N>
@@ -59,7 +61,7 @@ void measure_int_multiply_not_optimized_away(char const* msg, times<N>& t)
 
 int start()
 {
-	libnux_test_init();
+	test_init();
 
 	print_measurements_header();
 	time_pair global;
@@ -68,19 +70,19 @@ int start()
 	times<10> tentimes;
 	times<1> onetime;
 	/* Empty measurement using example measurement function. */
-	libnux_testcase_begin("empty");
+	testcase_begin("empty");
 	measure_empty(tentimes);
-	libnux_test_true(min(tentimes) > 0);
-	libnux_testcase_end();
+	test_true(min(tentimes) > 0);
+	testcase_end();
 
 	/* Measure sleep_cycles with different cycles. */
-	libnux_testcase_begin("sleep_cycles");
+	testcase_begin("sleep_cycles");
 	test_sleep_cycles("sleep_cycles 10", tentimes, 10, 600);
 	test_sleep_cycles("sleep_cycles 100", onetime, 100, 600);
 	test_sleep_cycles("sleep_cycles 1000", onetime, 1000, 1600);
-	libnux_testcase_end();
+	testcase_end();
 
-	libnux_testcase_begin("optimization");
+	testcase_begin("optimization");
 	/* Measure multiplication of two integer literals
 	   without prohibiting precalculation. */
 	measure_int_multiply("int operator*", tentimes);
@@ -89,14 +91,14 @@ int start()
 	   and have them not optimized away, i.e. precalculated. */
 	measure_int_multiply_not_optimized_away("int operator* not optimized away", tentimes);
 	auto min_not_optimized_away = min(tentimes);
-	libnux_test_true(min_optimized_away < min_not_optimized_away);
-	libnux_testcase_end();
+	test_true(min_optimized_away < min_not_optimized_away);
+	testcase_end();
 
 	global.second = now();
 	print_measurement("All measurements with evaluation time", global);
 	print_measurements_footer();
 
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 	return 0;
 }
diff --git a/test/test_noinline_vector_argument.cpp b/test/vx/test_noinline_vector_argument.cpp
similarity index 89%
rename from test/test_noinline_vector_argument.cpp
rename to test/vx/test_noinline_vector_argument.cpp
index 635c5acba69ccd63cc6d917667e5e7af7eae0f95..44f046aa07e34f79e2b19df9409ac785384a1278 100644
--- a/test/test_noinline_vector_argument.cpp
+++ b/test/vx/test_noinline_vector_argument.cpp
@@ -1,5 +1,7 @@
 #include <s2pp.h>
-#include "libnux/spr.h"
+#include "libnux/vx/spr.h"
+
+using namespace libnux::vx;
 
 // not inlined function with vector argument
 __attribute__((noinline)) void foo_noinline(__vector uint8_t& y)
diff --git a/test/test_omnibus.cpp b/test/vx/test_omnibus.cpp.bak
similarity index 55%
rename from test/test_omnibus.cpp
rename to test/vx/test_omnibus.cpp.bak
index 72230740b90194e64bba9f277aeb307d690a4c1d..12d3c89ebc5fbd6c15665963dc53eae9a6763d2b 100644
--- a/test/test_omnibus.cpp
+++ b/test/vx/test_omnibus.cpp.bak
@@ -1,8 +1,10 @@
-#include "libnux/dls.h"
-#include "libnux/unittest.h"
-#include "libnux/omnibus.h"
-#include "libnux/syn.h"
-#include "libnux/sync.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/unittest.h"
+#include "libnux/vx/omnibus.h"
+#include "libnux/vx/syn.h"
+#include "libnux/vx/sync.h"
+
+using namespace libnux::vx;
 
 /** Read first word from weight synram region. */
 uint32_t get_weights_vector_unit()
@@ -28,24 +30,24 @@ void set_weights_vector_unit(uint32_t const value)
 
 void test_omnibus()
 {
-	libnux_testcase_begin("test_omnibus");
+	testcase_begin("test_omnibus");
 	auto const omnibus_address = dls_synapse_array_base;
 
 	set_weights_vector_unit(0x20202020);
-	auto read_1 = libnux::omnibus_read(omnibus_address);
-	libnux_test_equal(read_1, 0x20202020);
+	auto read_1 = omnibus_read(omnibus_address);
+	test_equal(read_1, 0x20202020);
 
-	libnux::omnibus_write(omnibus_address, 0x20);
-	auto read_2 = libnux::omnibus_read(omnibus_address);
-	libnux_test_equal(read_2, 0x20);
-	libnux_test_equal(get_weights_vector_unit(), 0x20);
+	omnibus_write(omnibus_address, 0x20);
+	auto read_2 = omnibus_read(omnibus_address);
+	test_equal(read_2, 0x20);
+	test_equal(get_weights_vector_unit(), 0x20);
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 void start()
 {
-	libnux_test_init();
+	test_init();
 	test_omnibus();
-	libnux_test_shutdown();
+	test_shutdown();
 }
diff --git a/test/test_return_vector.cpp b/test/vx/test_return_vector.cpp
similarity index 56%
rename from test/test_return_vector.cpp
rename to test/vx/test_return_vector.cpp
index fbc747964c39d457d1b1906ba636113407e7d787..131a5c14f712aa62af10ff3ba0aca15b88905847 100644
--- a/test/test_return_vector.cpp
+++ b/test/vx/test_return_vector.cpp
@@ -1,5 +1,7 @@
 #include <s2pp.h>
-#include <libnux/unittest.h>
+#include <libnux/vx/unittest.h>
+
+using namespace libnux::vx;
 
 __vector uint8_t foo(__vector uint8_t* v)
 {
@@ -8,22 +10,22 @@ __vector uint8_t foo(__vector uint8_t* v)
 
 void test_return_vector()
 {
-	libnux_testcase_begin("return_vector");
+	testcase_begin("return_vector");
 	__vector uint8_t in = vec_splat_u8(1);
 	__vector uint8_t out;
 	out = foo(&in);
 
 	for (uint32_t i = 0; i < sizeof(__vector uint8_t); ++i) {
-		libnux_test_equal(in[i], 1);
-		libnux_test_equal(out[i], 1);
+		test_equal(in[i], 1);
+		test_equal(out[i], 1);
 	}
-	libnux_testcase_end();
+	testcase_end();
 }
 
 void start()
 {
-	libnux_test_init();
+	test_init();
 	test_return_vector();
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/test_returncode.cpp b/test/vx/test_returncode.cpp
similarity index 100%
rename from test/test_returncode.cpp
rename to test/vx/test_returncode.cpp
diff --git a/test/test_stack_guard.cpp b/test/vx/test_stack_guard.cpp
similarity index 100%
rename from test/test_stack_guard.cpp
rename to test/vx/test_stack_guard.cpp
diff --git a/test/test_stack_redzone.cpp b/test/vx/test_stack_redzone.cpp
similarity index 93%
rename from test/test_stack_redzone.cpp
rename to test/vx/test_stack_redzone.cpp
index 9788c72132719eb28108481065f5d18c47c27206..b69dd1759dfeb0a778ec2e2148b040a3e7b846e9 100644
--- a/test/test_stack_redzone.cpp
+++ b/test/vx/test_stack_redzone.cpp
@@ -1,5 +1,7 @@
 #include <stdint.h>
-#include "libnux/helper.h"
+#include "libnux/vx/helper.h"
+
+using namespace libnux::vx;
 
 extern uint8_t stack_redzone;
 
diff --git a/test/test_synram.cpp b/test/vx/test_synram.cpp
similarity index 77%
rename from test/test_synram.cpp
rename to test/vx/test_synram.cpp
index 5bc1bb6fcc6fafd233d2518e8b6fe25e2df6ea49..ac5bfc75a583e3bb9a74d897fca185e06f96e418 100644
--- a/test/test_synram.cpp
+++ b/test/vx/test_synram.cpp
@@ -1,12 +1,14 @@
 #include <array>
 #include <stddef.h>
 #include <stdint.h>
-#include "libnux/dls.h"
-#include "libnux/location.h"
-#include "libnux/omnibus.h"
-#include "libnux/sync.h"
-#include "libnux/unittest.h"
-#include "libnux/vector.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/location.h"
+#include "libnux/vx/omnibus.h"
+#include "libnux/vx/sync.h"
+#include "libnux/vx/unittest.h"
+#include "libnux/vx/vector.h"
+
+using namespace libnux::vx;
 
 // weight value which is the same value than written, when read from Omnibus
 constexpr uint8_t invariant_weight = 32;
@@ -29,15 +31,15 @@ void write_byte_vector_unit(uint32_t row, size_t index, uint8_t value)
 
 void start(void)
 {
-	libnux_test_init();
+	test_init();
 
-	libnux::PPUOnDLS ppu;
+	PPUOnDLS ppu;
 	bool const success = get_location(ppu);
 	if (!success) {
 		exit(1);
 	}
 	uint32_t synram_base =
-	    (ppu == libnux::PPUOnDLS::top) ? synram_top_base_address : synram_bottom_base_address;
+	    (ppu == PPUOnDLS::top) ? synram_top_base_address : synram_bottom_base_address;
 
 	// only use first row for now
 	constexpr uint32_t row = 0;
@@ -46,7 +48,7 @@ void start(void)
 	zero.fill(0);
 	set_row_via_vector(zero, row, dls_weight_base);
 
-	libnux_testcase_begin("synram fill linear");
+	testcase_begin("synram fill linear");
 	// write one weight at ascending index via byte-enables with a stride of 13,
 	// which should essentially lead to filling up of the weight matrix like
 	// t
@@ -62,7 +64,7 @@ void start(void)
 		// read-out via Omnibus
 		vector_row_t values = get_row_via_omnibus(row, synram_base);
 		// Compare to expectation from Omnibus access
-		libnux_test_equal(values, expectation);
+		test_equal(values, expectation);
 	}
 
 	// Test cornercase of last column
@@ -70,10 +72,10 @@ void start(void)
 	write_byte_vector_unit(row, last_column, invariant_weight);
 	expectation[last_column] = invariant_weight;
 	vector_row_t values = get_row_via_omnibus(row, synram_base);
-	libnux_test_equal(values, expectation);
+	test_equal(values, expectation);
 
-	libnux_testcase_end();
+	testcase_end();
 
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/test_synram_rw.cpp b/test/vx/test_synram_rw.cpp
similarity index 85%
rename from test/test_synram_rw.cpp
rename to test/vx/test_synram_rw.cpp
index 0048b9185fa6c4b0ab5e918ca1ce42df35c629f0..85cd924d58a438dcb6a03dc7d050e4fec9cc0032 100644
--- a/test/test_synram_rw.cpp
+++ b/test/vx/test_synram_rw.cpp
@@ -1,8 +1,9 @@
 #include <s2pp.h>
-#include "libnux/dls.h"
-#include "libnux/unittest.h"
-#include "libnux/random.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/unittest.h"
+#include "libnux/vx/random.h"
 
+using namespace libnux::vx;
 
 // Use 8 of 32 vectors on HX fitting in the vector registers
 // For more than 32 there is not enough memory
@@ -40,7 +41,7 @@ void set_synram_random(uint32_t const base_address, uint32_t const mask, uint32_
 
 
 void test_weight_read(uint32_t seed) {
-	libnux_testcase_begin("test_weight_read");
+	testcase_begin("test_weight_read");
 
 	for (uint32_t index = 0; index < SYNAPSE_ROW_ITERATIONS; index++) {
 		/* Explicitely load the weights, store to memory and synchronize */
@@ -56,16 +57,16 @@ void test_weight_read(uint32_t seed) {
 				  [addr] "r" (&data)
 				: /* no clobbers */);
 		for (uint32_t j = 0; j < sizeof(__vector uint8_t); j++) {
-			libnux_test_equal(data[j], xorshift32(&seed) & dls_weight_mask);
+			test_equal(data[j], xorshift32(&seed) & dls_weight_mask);
 		}
 	}
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 
 void test_decoder_read(uint32_t seed) {
-	libnux_testcase_begin("test_decoder_read");
+	testcase_begin("test_decoder_read");
 
 	for (uint32_t index = 0; index < SYNAPSE_ROW_ITERATIONS; index++) {
 		/* Explicitely load the weights, store to memory and synchronize */
@@ -81,20 +82,20 @@ void test_decoder_read(uint32_t seed) {
 				  [addr] "r" (&data)
 				: /* no clobbers */);
 		for (uint32_t j = 0; j < sizeof(__vector uint8_t); j++) {
-			libnux_test_equal(data[j], xorshift32(&seed) & dls_decoder_mask);
+			test_equal(data[j], xorshift32(&seed) & dls_decoder_mask);
 		}
 	}
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 
 void start(void) {
-	libnux_test_init();
+	test_init();
 	set_synram_random(dls_weight_base, dls_weight_mask, 42);
 	set_synram_random(dls_decoder_base, dls_decoder_mask, 1);
 	test_weight_read(42);
 	test_decoder_read(1);
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/vx/test_unittest.cpp b/test/vx/test_unittest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e353b422d6687a6c1c34430764b63b1091ce2a3f
--- /dev/null
+++ b/test/vx/test_unittest.cpp
@@ -0,0 +1,42 @@
+#include "libnux/vx/unittest.h"
+
+using namespace libnux::vx;
+
+void basic_test(void) {
+	testcase_begin("basic_checks");
+
+	char* s = reinterpret_cast<char*>(0);
+	int a = 0;
+	int b = 0;
+	int c = 0;
+
+	test_equal(0, a);
+	test_equal(0, b);
+	test_equal(0, c);
+
+	test_equal(0, 1-1);
+	test_equal(0, -1+1);
+	test_equal(-1, -2+1);
+
+	test_null(s);
+	test_true(1);
+
+	testcase_end();
+}
+
+void failing_test(void) {
+	testcase_begin("failing_test");
+
+	test_equal(0, 1+1);
+	test_equal(0, 1+2);
+
+	testcase_end();
+}
+
+void start(void) {
+	test_init();
+	basic_test();
+	failing_test();
+	test_summary();
+	test_shutdown();
+}
diff --git a/test/test_vector.cpp b/test/vx/test_vector.cpp
similarity index 67%
rename from test/test_vector.cpp
rename to test/vx/test_vector.cpp
index b489b3fef197757eb1a28a6549bc65e10e214614..6d4a34d8bc7073cc333b66b7567cf3fba2a7567c 100644
--- a/test/test_vector.cpp
+++ b/test/vx/test_vector.cpp
@@ -1,9 +1,11 @@
 #include <s2pp.h>
-#include <libnux/unittest.h>
-#include <libnux/mailbox.h>
+#include "libnux/vx/unittest.h"
+#include "libnux/vx/mailbox.h"
+
+using namespace libnux::vx;
 
 void test_vector_add() {
-	libnux_testcase_begin("vector_add");
+	testcase_begin("vector_add");
 
 	__vector uint8_t lhs = {
 		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
@@ -19,74 +21,74 @@ void test_vector_add() {
 	__vector uint8_t rhs = vec_splat_u8(1);
 	__vector uint8_t res = vec_add(lhs, rhs);
 	for (uint32_t index = 0; index < sizeof(__vector uint8_t); index++) {
-		libnux_test_equal(res[index], index + 1);
+		test_equal(res[index], index + 1);
 	}
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 void test_vector_addbfs() {
-	libnux_testcase_begin("vector_addbfs");
+	testcase_begin("vector_addbfs");
 
-	libnux_mailbox_write_string("Non saturating addition\n");
+	mailbox_write_string("Non saturating addition\n");
 	{
 		__vector int8_t lhs = vec_splat_s8(0);
 		__vector int8_t rhs = vec_splat_s8(1);
 		__vector int8_t res = fxv_addbfs_c(lhs, rhs, 0);
 		for (uint32_t index = 0; index < sizeof(__vector uint8_t); index++) {
-			libnux_test_equal(lhs[index], (int8_t)(0));
-			libnux_test_equal(rhs[index], (int8_t)(1));
-			libnux_test_equal(res[index], (int8_t)(1));
+			test_equal(lhs[index], (int8_t)(0));
+			test_equal(rhs[index], (int8_t)(1));
+			test_equal(res[index], (int8_t)(1));
 		}
 	}
-	libnux_mailbox_write_string("Saturating addition\n");
+	mailbox_write_string("Saturating addition\n");
 	{
 		__vector int8_t lhs = vec_splat_s8(127);
 		__vector int8_t rhs = vec_splat_s8(1);
 		__vector int8_t res = fxv_addbfs_c(lhs, rhs, 0);
 		for (uint32_t index = 0; index < sizeof(__vector uint8_t); index++) {
-			libnux_test_equal(res[index], (int8_t)(127));
+			test_equal(res[index], (int8_t)(127));
 		}
 	}
-	libnux_mailbox_write_string("Non saturating addition with signed\n");
+	mailbox_write_string("Non saturating addition with signed\n");
 	{
 		__vector int8_t lhs = vec_splat_s8(2);
 		__vector int8_t rhs = vec_splat_s8(-1);
 		__vector int8_t res = fxv_addbfs_c(lhs, rhs, 0);
 		for (uint32_t index = 0; index < sizeof(__vector uint8_t); index++) {
-			libnux_test_equal(res[index], (int8_t)(1));
+			test_equal(res[index], (int8_t)(1));
 		}
 	}
-	libnux_mailbox_write_string("Saturating addition with signed\n");
+	mailbox_write_string("Saturating addition with signed\n");
 	{
 		__vector int8_t lhs = vec_splat_s8(-128);
 		__vector int8_t rhs = vec_splat_s8(-1);
 		__vector int8_t res = fxv_addbfs_c(lhs, rhs, 0);
 		for (uint32_t index = 0; index < sizeof(__vector uint8_t); index++) {
-			libnux_test_equal(res[index], (int8_t)(-128));
+			test_equal(res[index], (int8_t)(-128));
 		}
 	}
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 void test_ptr_add() {
-	libnux_testcase_begin("ptr_add");
+	testcase_begin("ptr_add");
 
 	// Checks if the pointer to a vector is shifted by the size of the vector in
 	// bytes at an addition of 1.
 	__vector uint8_t* base = (__vector uint8_t*) (0x0);
 	__vector uint8_t* shifted = base + 1;
-	libnux_test_equal(shifted, (__vector uint8_t*) (sizeof(__vector uint8_t)));
+	test_equal(shifted, (__vector uint8_t*) (sizeof(__vector uint8_t)));
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 void start(void) {
-	libnux_test_init();
+	test_init();
 	test_ptr_add();
 	test_vector_add();
 	test_vector_addbfs();
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/test_vector_alignment.cpp b/test/vx/test_vector_alignment.cpp
similarity index 74%
rename from test/test_vector_alignment.cpp
rename to test/vx/test_vector_alignment.cpp
index 4d2d25e529f1953752dd4864092061b236cabdc9..70491148f54fb155e9d7124337c5a1d721fc5489 100644
--- a/test/test_vector_alignment.cpp
+++ b/test/vx/test_vector_alignment.cpp
@@ -1,8 +1,10 @@
-#include "libnux/mailbox.h"
-#include "libnux/unittest.h"
+#include "libnux/vx/mailbox.h"
+#include "libnux/vx/unittest.h"
 #include <s2pp.h>
 #include <stddef.h>
 
+using namespace libnux::vx;
+
 __vector uint8_t global_first = {
 	0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
 	0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
@@ -43,31 +45,31 @@ __vector uint8_t global_second = {
 
 void dump_vector(__vector uint8_t* ptr)
 {
-	libnux_mailbox_write_string("vector at ");
-	libnux_mailbox_write_int((uint32_t)ptr);
-	libnux_mailbox_write_string(": (");
+	mailbox_write_string("vector at ");
+	mailbox_write_int((uint32_t)ptr);
+	mailbox_write_string(": (");
 	for (uint32_t i = 0; i < sizeof(__vector uint8_t); i++) {
 		if (i > 0) {
-			libnux_mailbox_write_string(", ");
+			mailbox_write_string(", ");
 		}
-		libnux_mailbox_write_int((*ptr)[i]);
+		mailbox_write_int((*ptr)[i]);
 	}
-	libnux_mailbox_write_string(")\n");
+	mailbox_write_string(")\n");
 }
 
 template<typename T>
 void dump_integer(T* integer)
 {
-	libnux_mailbox_write_string("integer at ");
-	libnux_mailbox_write_int((uint32_t)integer);
-	libnux_mailbox_write_string(": ");
-	libnux_mailbox_write_int(*integer);
-	libnux_mailbox_write_string("\n");
+	mailbox_write_string("integer at ");
+	mailbox_write_int((uint32_t)integer);
+	mailbox_write_string(": ");
+	mailbox_write_int(*integer);
+	mailbox_write_string("\n");
 }
 
 
 void test_vector_alignment() {
-	libnux_testcase_begin(__func__);
+	testcase_begin(__func__);
 
 	__vector uint8_t local_first = {
 		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
@@ -107,20 +109,17 @@ void test_vector_alignment() {
 		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
 		0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f};
 
-	libnux_test_equal(global_first[0], 0);
-	libnux_test_equal(global_small, 0xff);
-	libnux_test_equal(global_second[0], 0x10);
-	libnux_test_equal(local_first[0], 0x20);
-	libnux_test_equal(local_small, 0xff);
-	libnux_test_equal(local_second[0], 0x30);
-
-	libnux_test_equal(
-	    ((uint32_t) &global_first) % sizeof(__vector uint8_t), static_cast<size_t>(0));
-	libnux_test_equal(
-	    ((uint32_t) &global_second) % sizeof(__vector uint8_t), static_cast<size_t>(0));
-	libnux_test_equal(((uint32_t) &local_first) % sizeof(__vector uint8_t), static_cast<size_t>(0));
-	libnux_test_equal(
-	    ((uint32_t) &local_second) % sizeof(__vector uint8_t), static_cast<size_t>(0));
+	test_equal(global_first[0], 0);
+	test_equal(global_small, 0xff);
+	test_equal(global_second[0], 0x10);
+	test_equal(local_first[0], 0x20);
+	test_equal(local_small, 0xff);
+	test_equal(local_second[0], 0x30);
+
+	test_equal(((uint32_t) &global_first) % sizeof(__vector uint8_t), static_cast<size_t>(0));
+	test_equal(((uint32_t) &global_second) % sizeof(__vector uint8_t), static_cast<size_t>(0));
+	test_equal(((uint32_t) &local_first) % sizeof(__vector uint8_t), static_cast<size_t>(0));
+	test_equal(((uint32_t) &local_second) % sizeof(__vector uint8_t), static_cast<size_t>(0));
 
 	dump_vector(&global_first);
 	dump_vector(&global_second);
@@ -130,15 +129,15 @@ void test_vector_alignment() {
 	dump_integer(&global_small);
 	dump_integer(&local_small);
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 
 int start(void) {
-	libnux_test_init();
+	test_init();
 	test_vector_alignment();
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 
 	return 0;
 }
diff --git a/test/test_vector_cc.cpp b/test/vx/test_vector_cc.cpp
similarity index 75%
rename from test/test_vector_cc.cpp
rename to test/vx/test_vector_cc.cpp
index 412cd28281be6c6c2b50be2d8eddaab76502112c..51462c04566e8067325d67d554235bcb7e019d7d 100644
--- a/test/test_vector_cc.cpp
+++ b/test/vx/test_vector_cc.cpp
@@ -1,16 +1,18 @@
 #include <s2pp.h>
-#include "libnux/mailbox.h"
-#include "libnux/new.h"
-#include "libnux/unittest.h"
+#include "libnux/vx/mailbox.h"
+#include "libnux/vx/new.h"
+#include "libnux/vx/unittest.h"
+
+using namespace libnux::vx;
 
 template<typename T>
 struct CRTP {
 	CRTP() {
-		libnux_testcase_begin(T::test_name);
+		testcase_begin(T::test_name);
 	}
 
 	~CRTP() {
-		libnux_testcase_end();
+		testcase_end();
 	}
 };
 
@@ -30,7 +32,7 @@ struct VectorTestCRTP : public CRTP<VectorTestCRTP> {
 		__vector uint8_t rhs = vec_splat_u8(1);
 		__vector uint8_t res = vec_add(lhs, rhs);
 		for (uint32_t index = 0; index < sizeof(__vector uint8_t); index++) {
-			libnux_test_equal(res[index], index + 1);
+			test_equal(res[index], index + 1);
 		}
 	}
 	constexpr static const char* test_name = "vector_add_CRTP";
@@ -38,11 +40,11 @@ struct VectorTestCRTP : public CRTP<VectorTestCRTP> {
 
 struct INHE {
 	INHE(const char* test_name) {
-		libnux_testcase_begin(test_name);
+		testcase_begin(test_name);
 	}
 
 	~INHE() {
-		libnux_testcase_end();
+		testcase_end();
 	}
 };
 
@@ -64,7 +66,7 @@ struct VectorTestINHE : public INHE {
 		__vector uint8_t rhs = vec_splat_u8(1);
 		__vector uint8_t res = vec_add(lhs, rhs);
 		for (uint32_t index = 0; index < sizeof(__vector uint8_t); index++) {
-			libnux_test_equal(res[index], index + 1);
+			test_equal(res[index], index + 1);
 		}
 	}
 };
@@ -73,12 +75,12 @@ struct VIRT {
 	VIRT() = default;
 
 	void operator()() {
-		libnux_testcase_begin(get_test_name());
+		testcase_begin(get_test_name());
 		test();
 	}
 
 	virtual ~VIRT() {
-		libnux_testcase_end();
+		testcase_end();
 	}
 
 	virtual void test() = 0;
@@ -101,7 +103,7 @@ struct VectorTestVIRT : public VIRT {
 		__vector uint8_t rhs = vec_splat_u8(1);
 		__vector uint8_t res = vec_add(lhs, rhs);
 		for (uint32_t index = 0; index < sizeof(__vector uint8_t); index++) {
-			libnux_test_equal(res[index], index + 1);
+			test_equal(res[index], index + 1);
 		}
 	}
 
@@ -112,7 +114,7 @@ struct VectorTestVIRT : public VIRT {
 
 struct VectorTestGLOB {
 	void test() {
-		libnux_testcase_begin(test_name);
+		testcase_begin(test_name);
 		__vector uint8_t lhs = {
 			0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
 			16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
@@ -127,14 +129,14 @@ struct VectorTestGLOB {
 		__vector uint8_t rhs = vec_splat_u8(1);
 		__vector uint8_t res = vec_add(lhs, rhs);
 		for (uint32_t index = 0; index < sizeof(__vector uint8_t); index++) {
-			libnux_test_equal(res[index], index + 1);
+			test_equal(res[index], index + 1);
 		}
 	}
 
 	VectorTestGLOB() = default;
 
 	~VectorTestGLOB() {
-		libnux_testcase_end();
+		testcase_end();
 	}
 
 	constexpr static const char* test_name = "vector_add_GLOB";
@@ -144,47 +146,47 @@ VectorTestGLOB test4;
 
 struct VectorTestNEW {
 	VectorTestNEW(char const* /*test_name*/) {
-		libnux_mailbox_write_string(__PRETTY_FUNCTION__);
-		libnux_mailbox_write_string("\n");
+		mailbox_write_string(__PRETTY_FUNCTION__);
+		mailbox_write_string("\n");
 	}
 
 	VectorTestNEW() : VectorTestNEW("VectorTestNEW_default")
 	{
-		libnux_mailbox_write_string(__PRETTY_FUNCTION__);
-		libnux_mailbox_write_string("\n");
+		mailbox_write_string(__PRETTY_FUNCTION__);
+		mailbox_write_string("\n");
 	}
 
 	~VectorTestNEW() {
-		libnux_mailbox_write_string(__PRETTY_FUNCTION__);
-		libnux_mailbox_write_string("\n");
+		mailbox_write_string(__PRETTY_FUNCTION__);
+		mailbox_write_string("\n");
 	}
 };
 
 struct TestInit {
 	TestInit() {
-		libnux_test_init();
+		test_init();
 	}
 
 	~TestInit() {
-		libnux_test_summary();
-		libnux_test_shutdown();
+		test_summary();
+		test_shutdown();
 	}
 };
 
 void print_memory_layout() {
 	void* p = 0;
-	libnux_mailbox_write_string("MEMORY LAYOUT:");
-	libnux_mailbox_write_string("\n\theap_base = ");
-	libnux_mailbox_write_int(reinterpret_cast<intptr_t>(&heap_base));
-	libnux_mailbox_write_string("\n\theap_end = ");
-	libnux_mailbox_write_int(reinterpret_cast<intptr_t>(&heap_end));
-	libnux_mailbox_write_string("\n\tcurrent stack ptr = ");
-	libnux_mailbox_write_int(reinterpret_cast<intptr_t>(&p));
-	libnux_mailbox_write_string("\n\tmailbox_base = ");
-	libnux_mailbox_write_int(reinterpret_cast<intptr_t>(&mailbox_base));
-	libnux_mailbox_write_string("\n\tmailbox_end = ");
-	libnux_mailbox_write_int(reinterpret_cast<intptr_t>(&mailbox_end));
-	libnux_mailbox_write_string("\n");
+	mailbox_write_string("MEMORY LAYOUT:");
+	mailbox_write_string("\n\theap_base = ");
+	mailbox_write_int(reinterpret_cast<intptr_t>(&heap_base));
+	mailbox_write_string("\n\theap_end = ");
+	mailbox_write_int(reinterpret_cast<intptr_t>(&heap_end));
+	mailbox_write_string("\n\tcurrent stack ptr = ");
+	mailbox_write_int(reinterpret_cast<intptr_t>(&p));
+	mailbox_write_string("\n\tmailbox_base = ");
+	mailbox_write_int(reinterpret_cast<intptr_t>(&mailbox_base));
+	mailbox_write_string("\n\tmailbox_end = ");
+	mailbox_write_int(reinterpret_cast<intptr_t>(&mailbox_end));
+	mailbox_write_string("\n");
 }
 
 void start(void) {
diff --git a/test/vx/test_vector_convert.cpp b/test/vx/test_vector_convert.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..779883dfe3d4de19ef9bf329af3793466e92b1b8
--- /dev/null
+++ b/test/vx/test_vector_convert.cpp
@@ -0,0 +1,37 @@
+#include "libnux/vx/unittest.h"
+#include "libnux/vx/vector_convert.h"
+
+using namespace libnux::vx;
+
+void test_uint8_to_int8()
+{
+	testcase_begin("uint8_to_int8");
+
+	__vector uint8_t a = vec_splat_u8(0);
+	auto const ra = uint8_to_int8(a);
+	for (uint32_t index = 0; index < sizeof(__vector int8_t); index++) {
+		test_equal(ra[index], -128);
+	}
+
+	__vector uint8_t b = vec_splat_u8(255);
+	auto const rb = uint8_to_int8(b);
+	for (uint32_t index = 0; index < sizeof(__vector int8_t); index++) {
+		test_equal(rb[index], 127);
+	}
+
+	__vector uint8_t c = vec_splat_u8(123);
+	auto const rc = uint8_to_int8(c);
+	for (uint32_t index = 0; index < sizeof(__vector int8_t); index++) {
+		test_equal(rc[index], -128 + 123);
+	}
+
+	testcase_end();
+}
+
+void start(void)
+{
+	test_init();
+	test_uint8_to_int8();
+	test_summary();
+	test_shutdown();
+}
diff --git a/test/test_vector_register_reusage.cpp b/test/vx/test_vector_register_reusage.cpp
similarity index 77%
rename from test/test_vector_register_reusage.cpp
rename to test/vx/test_vector_register_reusage.cpp
index b18376b2ac1636489d944884356a300fb276585f..486ca15782610192804fb193ea82640b028c8940 100644
--- a/test/test_vector_register_reusage.cpp
+++ b/test/vx/test_vector_register_reusage.cpp
@@ -1,5 +1,7 @@
 #include <s2pp.h>
-#include "libnux/unittest.h"
+#include "libnux/vx/unittest.h"
+
+using namespace libnux::vx;
 
 // some function doing something with vector registers
 uint8_t get_splatted_value(uint8_t const value)
@@ -13,8 +15,8 @@ volatile uint8_t value2 = 2;
 
 void start()
 {
-	libnux_test_init();
-	libnux_testcase_begin("vector register reusage");
+	test_init();
+	testcase_begin("vector register reusage");
 
 	// set vec to value1
 	__vector uint8_t vec;
@@ -40,11 +42,11 @@ void start()
 
 	uint8_t expected_value1 = vec[7];
 
-	libnux_test_equal(intermediate, value2);
+	test_equal(intermediate, value2);
 	// expect value1 after execution of nested function, since nothing should have changed
-	libnux_test_equal(expected_value1, value1);
-	libnux_testcase_end();
+	test_equal(expected_value1, value1);
+	testcase_end();
 
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/test_vector_saturating_subtract.cpp b/test/vx/test_vector_saturating_subtract.cpp
similarity index 51%
rename from test/test_vector_saturating_subtract.cpp
rename to test/vx/test_vector_saturating_subtract.cpp
index 86e29c971d0c769b678eb616f3c6dd652408624b..56581e49a4524ed2789bc16ef100963660d42b0f 100644
--- a/test/test_vector_saturating_subtract.cpp
+++ b/test/vx/test_vector_saturating_subtract.cpp
@@ -1,35 +1,37 @@
-#include "libnux/unittest.h"
-#include "libnux/vector_math.h"
+#include "libnux/vx/unittest.h"
+#include "libnux/vx/vector_math.h"
+
+using namespace libnux::vx;
 
 void test_saturating_subtract()
 {
-	libnux_testcase_begin("saturating_subtract");
+	testcase_begin("saturating_subtract");
 
 	{
 		__vector int8_t a = vec_splat_s8(-127);
 		__vector int8_t b = vec_splat_s8(2);
-		auto const rb = libnux::saturating_subtract(a, b);
+		auto const rb = saturating_subtract(a, b);
 		for (uint32_t index = 0; index < sizeof(__vector int8_t); index++) {
-			libnux_test_equal(rb[index], -128);
+			test_equal(rb[index], -128);
 		}
 	}
 
 	{
 		__vector int8_t a = vec_splat_s8(1);
 		__vector int8_t b = vec_splat_s8(-127);
-		auto const rb = libnux::saturating_subtract(a, b);
+		auto const rb = saturating_subtract(a, b);
 		for (uint32_t index = 0; index < sizeof(__vector int8_t); index++) {
-			libnux_test_equal(rb[index], 127);
+			test_equal(rb[index], 127);
 		}
 	}
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 void start(void)
 {
-	libnux_test_init();
+	test_init();
 	test_saturating_subtract();
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/test_vector_splat.cpp b/test/vx/test_vector_splat.cpp
similarity index 58%
rename from test/test_vector_splat.cpp
rename to test/vx/test_vector_splat.cpp
index 8202eabb8468b35c7f4ac7dab6ae9053c9c587c1..d6db188ecc020f7512dfd7ee9c81f3b533e3f071 100644
--- a/test/test_vector_splat.cpp
+++ b/test/vx/test_vector_splat.cpp
@@ -1,7 +1,8 @@
-#include <cstddef>
 #include <s2pp.h>
+#include <cstddef>
+#include "libnux/vx/unittest.h"
 
-#include "libnux/unittest.h"
+using namespace libnux::vx;
 
 volatile uint8_t u8_value = 5;
 constexpr uint8_t u8_constant = 7;
@@ -16,44 +17,44 @@ volatile int16_t s16_value = -13;
 constexpr int16_t s16_constant = -27;
 
 void start() {
-	libnux_test_init();
+	test_init();
 
-	libnux_testcase_begin("splat u8");
+	testcase_begin("splat u8");
 	__vector uint8_t u8_vec_from_variable = vec_splat_u8(u8_value);
 	__vector uint8_t u8_vec_from_constant = vec_splat_u8(u8_constant);
 	for (size_t i = 0; i < sizeof(__vector uint8_t); ++i) {
-		libnux_test_equal(u8_vec_from_variable[i], u8_value);
-		libnux_test_equal(u8_vec_from_constant[i], u8_constant);
+		test_equal(u8_vec_from_variable[i], u8_value);
+		test_equal(u8_vec_from_constant[i], u8_constant);
 	}
-	libnux_testcase_end();
+	testcase_end();
 
-	libnux_testcase_begin("splat s8");
+	testcase_begin("splat s8");
 	__vector int8_t s8_vec_from_variable = vec_splat_s8(s8_value);
 	__vector int8_t s8_vec_from_constant = vec_splat_s8(s8_constant);
 	for (size_t i = 0; i < sizeof(__vector int8_t); ++i) {
-		libnux_test_equal(s8_vec_from_variable[i], s8_value);
-		libnux_test_equal(s8_vec_from_constant[i], s8_constant);
+		test_equal(s8_vec_from_variable[i], s8_value);
+		test_equal(s8_vec_from_constant[i], s8_constant);
 	}
-	libnux_testcase_end();
+	testcase_end();
 
-	libnux_testcase_begin("splat u16");
+	testcase_begin("splat u16");
 	__vector uint16_t u16_vec_from_variable = vec_splat_u16(u16_value);
 	__vector uint16_t u16_vec_from_constant = vec_splat_u16(u16_constant);
 	for (size_t i = 0; i < sizeof(__vector uint16_t) / sizeof(uint16_t); ++i) {
-		libnux_test_equal(u16_vec_from_variable[i], u16_value);
-		libnux_test_equal(u16_vec_from_constant[i], u16_constant);
+		test_equal(u16_vec_from_variable[i], u16_value);
+		test_equal(u16_vec_from_constant[i], u16_constant);
 	}
-	libnux_testcase_end();
+	testcase_end();
 
-	libnux_testcase_begin("splat s16");
+	testcase_begin("splat s16");
 	__vector int16_t s16_vec_from_variable = vec_splat_s16(s16_value);
 	__vector int16_t s16_vec_from_constant = vec_splat_s16(s16_constant);
 	for (size_t i = 0; i < sizeof(__vector int16_t) / sizeof(uint16_t); ++i) {
-		libnux_test_equal(s16_vec_from_variable[i], s16_value);
-		libnux_test_equal(s16_vec_from_constant[i], s16_constant);
+		test_equal(s16_vec_from_variable[i], s16_value);
+		test_equal(s16_vec_from_constant[i], s16_constant);
 	}
-	libnux_testcase_end();
+	testcase_end();
 
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 }
diff --git a/test/test_vector_sync.cpp b/test/vx/test_vector_sync.cpp
similarity index 85%
rename from test/test_vector_sync.cpp
rename to test/vx/test_vector_sync.cpp
index f662e01fba3fcc5aa86c6abb288c2178cee7dd18..3103ddb0f1e579ee9bf10bf44a697490c764ab4c 100644
--- a/test/test_vector_sync.cpp
+++ b/test/vx/test_vector_sync.cpp
@@ -1,25 +1,27 @@
 #include <s2pp.h>
-#include "libnux/dls.h"
-#include "libnux/unittest.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/unittest.h"
+
+using namespace libnux::vx;
 
 void test_read_g_after_write_v(void)
 {
-	libnux_testcase_begin(__func__);
+	testcase_begin(__func__);
 
 	// Write with VX
 	__vector uint8_t vec = vec_splat_u8(0xff);
 
 	// Read with GPP
 	for (uint32_t i = 0; i < sizeof(__vector uint8_t); i++) {
-		libnux_test_equal(vec[i], 0xff);
+		test_equal(vec[i], 0xff);
 	}
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 void test_read_v_after_write_g(void)
 {
-	libnux_testcase_begin(__func__);
+	testcase_begin(__func__);
 
 	__vector uint8_t vec = {
 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -53,15 +55,15 @@ void test_read_v_after_write_g(void)
 
 	// Check the copy
 	for (uint32_t i = 0; i < sizeof(__vector uint8_t); i++) {
-		libnux_test_equal(copy[i], 1);
+		test_equal(copy[i], 1);
 	}
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 void test_write_g_after_read_v(void)
 {
-	libnux_testcase_begin(__func__);
+	testcase_begin(__func__);
 
 	__vector uint8_t vec = {
 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -97,15 +99,15 @@ void test_write_g_after_read_v(void)
 
 	// Check the copy
 	for (uint32_t i = 0; i < sizeof(__vector uint8_t); i++) {
-		libnux_test_equal(copy[i], 0);
+		test_equal(copy[i], 0);
 	}
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 void test_write_v_after_read_g(void)
 {
-	libnux_testcase_begin(__func__);
+	testcase_begin(__func__);
 
 	__vector uint8_t vec = {
 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -119,7 +121,7 @@ void test_write_v_after_read_g(void)
 
 	// Read with GPP
 	for (uint32_t i = 0; i < sizeof(__vector uint8_t); i++) {
-		libnux_test_equal(vec[i], 0);
+		test_equal(vec[i], 0);
 	}
 
 	// Write with VX
@@ -127,21 +129,21 @@ void test_write_v_after_read_g(void)
 
 	// Read with GPP
 	for (uint32_t i = 0; i < sizeof(__vector uint8_t); i++) {
-		libnux_test_equal(vec[i], 1);
+		test_equal(vec[i], 1);
 	}
 
-	libnux_testcase_end();
+	testcase_end();
 }
 
 int32_t start(void)
 {
-	libnux_test_init();
+	test_init();
 	test_read_g_after_write_v();
 	test_read_v_after_write_g();
 	test_write_g_after_read_v();
 	test_write_v_after_read_g();
-	libnux_test_summary();
-	libnux_test_shutdown();
+	test_summary();
+	test_shutdown();
 
 	return 0;
 }
diff --git a/test/with_hostcode/log_access_pattern_host.py b/test/with_hostcode/log_access_pattern_host_vx_v1.py
similarity index 97%
rename from test/with_hostcode/log_access_pattern_host.py
rename to test/with_hostcode/log_access_pattern_host_vx_v1.py
index d3d1d79094f43d4a650c7a642668b21dc2d017ce..b3491614559a24a3dba820330d608850ed765b45 100644
--- a/test/with_hostcode/log_access_pattern_host.py
+++ b/test/with_hostcode/log_access_pattern_host_vx_v1.py
@@ -100,7 +100,8 @@ class LibnuxAccessPatternTestVx(unittest.TestCase):
             self.skipTest(f"Incompatible chip rev. {self.CHIP_REVISION} (<2).")
 
         log = logger.get("LibnuxAccessPatternTestVx.test_refgen_access")
-        program = join(TEST_BINARY_PATH, "refgen_access_pattern-ppu.bin")
+        program = join(TEST_BINARY_PATH,
+                       "refgen_access_pattern-ppu_vx_v1.bin")
         initial_logsize = os.path.getsize(FLANGE_LOG_PATH)
         log.debug("Initial size of %s: %dbytes." % (FLANGE_LOG_PATH,
                                                     initial_logsize))
@@ -152,7 +153,8 @@ class LibnuxAccessPatternTestVx(unittest.TestCase):
             self.skipTest(f"Incompatible chip rev. {self.CHIP_REVISION} (<2).")
 
         log = logger.get("LibnuxAccessPatternTestVx.test_synram_access")
-        program = join(TEST_BINARY_PATH, "synram_access_pattern-ppu.bin")
+        program = join(TEST_BINARY_PATH,
+                       "synram_access_pattern-ppu_vx_v1.bin")
         initial_logsize = os.path.getsize(FLANGE_LOG_PATH)
         log.debug("Initial size of %s: %dbytes." % (FLANGE_LOG_PATH,
                                                     initial_logsize))
@@ -200,7 +202,8 @@ class LibnuxAccessPatternTestVx(unittest.TestCase):
 
         log = logger.get("LibnuxAccessPatternTestVx."
                          "test_correlation_reset_causal")
-        program = join(TEST_BINARY_PATH, "correlation_reset_causal-ppu.bin")
+        program = join(TEST_BINARY_PATH,
+                       "correlation_reset_causal-ppu_vx_v1.bin")
         initial_logsize = os.path.getsize(FLANGE_LOG_PATH)
         log.debug("Initial size of %s: %dbytes." % (FLANGE_LOG_PATH,
                                                     initial_logsize))
@@ -253,7 +256,8 @@ class LibnuxAccessPatternTestVx(unittest.TestCase):
             self.skipTest(f"Incompatible chip rev. {self.CHIP_REVISION} (<2).")
 
         log = logger.get("LibnuxAccessPatternTestVx.test_neuron_reset_global")
-        program = join(TEST_BINARY_PATH, "neuron_reset_global-ppu.bin")
+        program = join(TEST_BINARY_PATH,
+                       "neuron_reset_global-ppu_vx_v1.bin")
         initial_logsize = os.path.getsize(FLANGE_LOG_PATH)
         log.debug("Initial size of %s: %dbytes." % (FLANGE_LOG_PATH,
                                                     initial_logsize))
diff --git a/test/with_hostcode/log_access_pattern_host_vx_v2.py b/test/with_hostcode/log_access_pattern_host_vx_v2.py
new file mode 100644
index 0000000000000000000000000000000000000000..026c05772da57d571bcebd213befd07ef7d393aa
--- /dev/null
+++ b/test/with_hostcode/log_access_pattern_host_vx_v2.py
@@ -0,0 +1,390 @@
+import json
+import os
+from os.path import join
+import unittest
+from typing import List, Iterator, ClassVar
+
+from dlens_vx_v2.halco import iter_all, PPUOnDLS, SynapseRowOnSynram, \
+    SynapseOnSynapseRow, TimerOnDLS, JTAGIdCodeOnDLS
+from dlens_vx_v2.hxcomm import ManagedConnection
+from dlens_vx_v2.sta import generate, DigitalInit, run
+from dlens_vx_v2 import logger
+from dlens_vx_v2.tools.run_ppu_program import load_and_start_program, \
+    wait_until_ppu_finished, stop_program
+from pyhaldls_vx_v2 import SynapseQuad, Timer
+
+_THIS_DIR = os.path.dirname(os.path.realpath(__file__))
+TEST_BINARY_PATH = os.environ.get("TEST_BINARY_PATH",
+                                  join(_THIS_DIR,
+                                       os.pardir,
+                                       os.pardir,
+                                       os.pardir,
+                                       "build",
+                                       "libnux",
+                                       "test",
+                                       "with_hostcode")
+                                  )
+
+FLANGE_LOG_PATH = os.environ.get("FLANGE_LOG_PATH",
+                                 join(_THIS_DIR,
+                                      os.pardir,
+                                      os.pardir,
+                                      os.pardir,
+                                      "hxfpga",
+                                      "units",
+                                      "synplify_wrapper",
+                                      "sim",
+                                      "xrun.log")
+                                 )
+
+
+class LibnuxAccessPatternTestVx(unittest.TestCase):
+    MANAGED_CONNECTION = ManagedConnection()
+    CONNECTION = None
+    CHIP_REVISION: ClassVar[int]
+
+    class LogParser:
+        LOG_PREFIX = "HX_SIMULATION_LOG: "
+
+        def __init__(self, pattern: str, offset_bytes: int):
+            self.pattern = pattern
+            self.offset_bytes = offset_bytes
+            self.logfile = open(FLANGE_LOG_PATH, "rt")
+
+        def __iter__(self):
+            self.logfile.seek(self.offset_bytes)
+            return self
+
+        def __next__(self):
+            for line in self.logfile:
+                if line.startswith(self.LOG_PREFIX):
+                    event = json.loads(line[len(self.LOG_PREFIX):])
+                    if self.pattern in event:
+                        return event[self.pattern]
+
+            raise StopIteration
+
+        def __del__(self):
+            self.logfile.close()
+
+    @classmethod
+    def setUpClass(cls) -> None:
+        # Connect to some executor (sim or hardware)
+        cls.CONNECTION = cls.MANAGED_CONNECTION.__enter__()
+
+        # Initialize the chip and find chip version
+        init_builder, _ = generate(DigitalInit())
+        jtag_id_ticket = init_builder.read(JTAGIdCodeOnDLS())
+        init_builder.write(TimerOnDLS(), Timer(0))
+        init_builder.wait_until(TimerOnDLS(), 1000)
+        run(cls.CONNECTION, init_builder.done())
+        jtag_id = jtag_id_ticket.get()
+        cls.CHIP_REVISION = jtag_id.version
+
+    @classmethod
+    def tearDownClass(cls) -> None:
+        # Disconnect the executor
+        cls.MANAGED_CONNECTION.__exit__()
+
+    def run_ppu_program(self, ppu: PPUOnDLS, program_path: str, timeout: int):
+        load_and_start_program(self.CONNECTION, program_path, ppu)
+        wait_until_ppu_finished(self.CONNECTION, timeout=timeout, ppu=ppu)
+        ret_code = stop_program(self.CONNECTION, ppu=ppu,
+                                print_mailbox=False)
+
+        self.assertEqual(0, ret_code,
+                         f"PPU exit code was {ret_code}, expected 0.")
+
+    def test_refgen_access(self):
+        if self.CHIP_REVISION < 2:
+            self.skipTest(f"Incompatible chip rev. {self.CHIP_REVISION} (<2).")
+
+        log = logger.get("LibnuxAccessPatternTestVx.test_refgen_access")
+        program = join(TEST_BINARY_PATH,
+                       "refgen_access_pattern-ppu_vx_v2.bin")
+        initial_logsize = os.path.getsize(FLANGE_LOG_PATH)
+        log.debug("Initial size of %s: %dbytes." % (FLANGE_LOG_PATH,
+                                                    initial_logsize))
+
+        for ppu in iter_all(PPUOnDLS):
+            log.info("Running test on %s." % ppu)
+            self.run_ppu_program(ppu, program, int(5e5))
+
+        # Evaluate flange log
+        log_parser = self.LogParser("refgen_config_write", initial_logsize)
+        log_events = iter(log_parser)
+
+        initial_run = True
+        for _ in iter_all(PPUOnDLS):
+            # Reset by the first PPU has no effect, all values are already zero
+            if not initial_run:
+                self.assertDictEqual(next(log_events)["rg_i_amp_c"],
+                                     {'0': 0, '1': 0, '2': 15, '3': 20})
+                self.assertDictEqual(next(log_events)["rg_i_amp_c"],
+                                     {'0': 0, '1': 0, '2': 0, '3': 0})
+                self.assertDictEqual(next(log_events)["rg_i_offset_c"],
+                                     {'0': 0, '1': 0, '2': 35, '3': 40})
+                self.assertDictEqual(next(log_events)["rg_i_offset_c"],
+                                     {'0': 0, '1': 0, '2': 0, '3': 0})
+                self.assertDictEqual(next(log_events)["rg_i_slope_c"],
+                                     {'0': 0, '1': 0, '2': 55, '3': 60})
+                self.assertDictEqual(next(log_events)["rg_i_slope_c"],
+                                     {'0': 0, '1': 0, '2': 0, '3': 0})
+
+            initial_run = False
+            self.assertDictEqual(next(log_events)["rg_i_amp_c"],
+                                 {'0': 5, '1': 10, '2': 0, '3': 0})
+            self.assertDictEqual(next(log_events)["rg_i_amp_c"],
+                                 {'0': 5, '1': 10, '2': 15, '3': 20})
+            self.assertDictEqual(next(log_events)["rg_i_offset_c"],
+                                 {'0': 25, '1': 30, '2': 0, '3': 0})
+            self.assertDictEqual(next(log_events)["rg_i_offset_c"],
+                                 {'0': 25, '1': 30, '2': 35, '3': 40})
+            self.assertDictEqual(next(log_events)["rg_i_slope_c"],
+                                 {'0': 45, '1': 50, '2': 0, '3': 0})
+            self.assertDictEqual(next(log_events)["rg_i_slope_c"],
+                                 {'0': 45, '1': 50, '2': 55, '3': 60})
+
+        with self.assertRaises(StopIteration):
+            next(log_events)
+
+    def test_synram_access(self):
+        if self.CHIP_REVISION < 2:
+            self.skipTest(f"Incompatible chip rev. {self.CHIP_REVISION} (<2).")
+
+        log = logger.get("LibnuxAccessPatternTestVx.test_synram_access")
+        program = join(TEST_BINARY_PATH,
+                       "synram_access_pattern-ppu_vx_v2.bin")
+        initial_logsize = os.path.getsize(FLANGE_LOG_PATH)
+        log.debug("Initial size of %s: %dbytes." % (FLANGE_LOG_PATH,
+                                                    initial_logsize))
+
+        for ppu in iter_all(PPUOnDLS):
+            log.info("Running test on %s." % ppu)
+            self.run_ppu_program(ppu, program, int(5e7))
+
+        # Evaluate flange log
+        log_parser = self.LogParser("synram_write_access", initial_logsize)
+        log_events = iter(log_parser)
+
+        num_vectors_per_row = 2
+        vector_size = SynapseOnSynapseRow.size // num_vectors_per_row
+
+        for ppu in iter_all(PPUOnDLS):
+            diagonal_value = 1
+            for row in range(SynapseRowOnSynram.size):
+                for vec in range(num_vectors_per_row):
+                    for vector_element in range(vector_size):
+                        col = 2 * vector_element + vec
+
+                        self.assertDictEqual(
+                            next(log_events),
+                            {
+                                "data":
+                                    0 if row != col else
+                                    self.permute_weights(diagonal_value),
+                                "column":
+                                    col + SynapseOnSynapseRow.size
+                                    * ppu.toEnum().value()
+                            }
+                        )
+
+                diagonal_value += 1
+                if diagonal_value > SynapseQuad.Weight.max:
+                    diagonal_value = 1
+
+        with self.assertRaises(StopIteration):
+            next(log_events)
+
+    def test_correlation_reset_causal(self):
+        if self.CHIP_REVISION < 2:
+            self.skipTest(f"Incompatible chip rev. {self.CHIP_REVISION} (<2).")
+
+        log = logger.get("LibnuxAccessPatternTestVx."
+                         "test_correlation_reset_causal")
+        program = join(TEST_BINARY_PATH,
+                       "correlation_reset_causal-ppu_vx_v2.bin")
+        initial_logsize = os.path.getsize(FLANGE_LOG_PATH)
+        log.debug("Initial size of %s: %dbytes." % (FLANGE_LOG_PATH,
+                                                    initial_logsize))
+
+        for ppu in iter_all(PPUOnDLS):
+            log.info("Running test on %s." % ppu)
+            self.run_ppu_program(ppu, program, int(5e5))
+
+        # Evaluate flange log
+        log_parser = self.LogParser("correlation_reset_event", initial_logsize)
+        events = iter(log_parser)
+
+        for ppu in iter_all(PPUOnDLS):
+            # Test full reset
+            self.eval_creset(events, ppu, 0, [True] * 256, [True] * 256)
+            self.eval_creset(events, ppu, 10, [True] * 256, [True] * 256)
+            self.eval_creset(events, ppu, 255, [True] * 256, [True] * 256)
+
+            # Test causal-only reset
+            self.eval_creset(events, ppu, 0, [True] * 256, [False] * 256)
+            self.eval_creset(events, ppu, 20, [True] * 256, [False] * 256)
+            self.eval_creset(events, ppu, 255, [True] * 256, [False] * 256)
+
+            # Test acausal-only reset
+            self.eval_creset(events, ppu, 0, [False] * 256, [True] * 256)
+            self.eval_creset(events, ppu, 30, [False] * 256, [True] * 256)
+            self.eval_creset(events, ppu, 255, [False] * 256, [True] * 256)
+
+            # Test no reset at all
+            self.eval_creset(events, ppu, 0, [False] * 256, [False] * 256)
+            self.eval_creset(events, ppu, 40, [False] * 256, [False] * 256)
+            self.eval_creset(events, ppu, 255, [False] * 256, [False] * 256)
+
+            # Test specific odd column reset
+            causal_mask = [False] * 256
+            causal_mask[21] = True  # Column 21 is the 10th odd column
+            self.eval_creset(events, ppu, 0, causal_mask, [False] * 256)
+            self.eval_creset(events, ppu, 50, causal_mask, [False] * 256)
+            self.eval_creset(events, ppu, 255, causal_mask, [False] * 256)
+
+            # Test specific even column reset
+            causal_mask = [False] * 256
+            causal_mask[40] = True  # Column 40 is the 20th even column
+            self.eval_creset(events, ppu, 0, causal_mask, [False] * 256)
+            self.eval_creset(events, ppu, 60, causal_mask, [False] * 256)
+            self.eval_creset(events, ppu, 255, causal_mask, [False] * 256)
+
+    def test_neuron_reset_global(self):
+        if self.CHIP_REVISION < 2:
+            self.skipTest(f"Incompatible chip rev. {self.CHIP_REVISION} (<2).")
+
+        log = logger.get("LibnuxAccessPatternTestVx.test_neuron_reset_global")
+        program = join(TEST_BINARY_PATH,
+                       "neuron_reset_global-ppu_vx_v2.bin")
+        initial_logsize = os.path.getsize(FLANGE_LOG_PATH)
+        log.debug("Initial size of %s: %dbytes." % (FLANGE_LOG_PATH,
+                                                    initial_logsize))
+
+        for ppu in iter_all(PPUOnDLS):
+            log.info("Running test on %s." % ppu)
+            self.run_ppu_program(ppu, program, int(5e5))
+
+        # Evaluate flange log
+        parser = self.LogParser("global_neuron_reset_event", initial_logsize)
+        log_events = iter(parser)
+
+        for ppu in iter_all(PPUOnDLS):
+            # Test full reset
+            self.eval_neuron_reset(log_events, ppu, [True] * 256)
+
+            # Test no reset at all
+            # no edge at sa_corres_a => no output in log
+
+            # Test specific odd column reset
+            reset_mask = [False] * 256
+            reset_mask[21] = True  # Column 21 is the 10th odd column
+            self.eval_neuron_reset(log_events, ppu, reset_mask)
+
+            # Test specific even column reset
+            reset_mask = [False] * 256
+            reset_mask[40] = True  # Column 40 is the 20th even column
+            self.eval_neuron_reset(log_events, ppu, reset_mask)
+
+        with self.assertRaises(StopIteration):
+            next(log_events)
+
+    @staticmethod
+    def permute_weights(before: int):
+        after = 0
+        after |= (bool(before & (1 << 5))) << 5
+        after |= (bool(before & (1 << 0))) << 4
+        after |= (bool(before & (1 << 1))) << 3
+        after |= (bool(before & (1 << 2))) << 2
+        after |= (bool(before & (1 << 3))) << 1
+        after |= (bool(before & (1 << 4))) << 0
+        return after
+
+    # pylint: disable=too-many-arguments,too-many-locals
+    def eval_creset(self,
+                    events: Iterator[dict],
+                    ppu: PPUOnDLS,
+                    row: int,
+                    causal_mask: List[bool],
+                    acausal_mask: List[bool]):
+        """
+        Evaluate the next correlation reset events in an event stream against
+        abstract expectations.
+        """
+        expected_corenres_enable = 0b1100 if (ppu == PPUOnDLS.top) else 0b0011
+
+        expected_corenres_address = (row << 8) | row
+        if ppu == PPUOnDLS.top:
+            expected_corenres_address <<= 16
+
+        for vector_parity in range(2):
+            expected_corres_c = 0
+            for idx, val in enumerate(causal_mask):
+                if not val:
+                    continue
+                if idx % 2 == vector_parity:
+                    expected_corres_c |= 1 << (255 - idx)
+
+            expected_corres_a = 0
+            for idx, val in enumerate(acausal_mask):
+                if not val:
+                    continue
+                if idx % 2 == vector_parity:
+                    expected_corres_a |= 1 << (255 - idx)
+
+            if ppu == PPUOnDLS.top:
+                expected_corres_a <<= 256
+                expected_corres_c <<= 256
+
+            expectation = {
+                "sa_corenres_enable": expected_corenres_enable,
+                "sa_corres_c": expected_corres_c,
+                "sa_corres_a": expected_corres_a,
+                "sa_corenres_address": expected_corenres_address
+            }
+
+            # Two rising bit per event => two log outputs
+            for _ in range(2):
+                self.assertDictEqual(expectation, next(events))
+
+    def eval_neuron_reset(self,
+                          events: Iterator[dict],
+                          ppu: PPUOnDLS,
+                          reset_mask: List[bool]):
+        """
+        Evaluate the next global neuron reset events in an event stream against
+        abstract expectations.
+        """
+        expected_corenres_neuron = 0b1100 if (ppu == 0) else 0b0011
+
+        # Events are only visible if C is actually pulled
+        parities = list()
+        if any([val for idx, val in enumerate(reset_mask) if (idx % 2) == 0]):
+            parities.append(0)
+        if any([val for idx, val in enumerate(reset_mask) if (idx % 2) != 0]):
+            parities.append(1)
+
+        for vector_parity in parities:
+            expected_corres_a = 0
+            for idx, val in enumerate(reset_mask):
+                if not val:
+                    continue
+                if idx % 2 == vector_parity:
+                    expected_corres_a |= 1 << (255 - idx)
+
+            if ppu == PPUOnDLS.top:
+                expected_corres_a <<= 256
+
+            expectation = {
+                "sa_corenres_neuron": expected_corenres_neuron,
+                "sa_corres_c": 0,
+                "sa_corres_a": expected_corres_a,
+            }
+
+            self.assertDictEqual(expectation, next(events))
+            next(events)  # Drop falling sa_corres_a edge event
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/test/with_hostcode/neuron_reset_vector.py b/test/with_hostcode/neuron_reset_vector_vx_v2.py
similarity index 97%
rename from test/with_hostcode/neuron_reset_vector.py
rename to test/with_hostcode/neuron_reset_vector_vx_v2.py
index 770845fc19f390dd1ec185208e664cbeabb4e753..7fa28ab0c7f83089cf1c861915d6a7c5959afd20 100644
--- a/test/with_hostcode/neuron_reset_vector.py
+++ b/test/with_hostcode/neuron_reset_vector_vx_v2.py
@@ -65,7 +65,7 @@ class LibnuxNeuronResetVectorTestVx(unittest.TestCase):
             self.skipTest(f"Incompatible chip rev. {self.CHIP_REVISION} (<2).")
 
         log = logger.get("LibnuxAccessPatternTestVx.test_neuron_reset")
-        program = join(TEST_BINARY_PATH, "neuron_reset_vector-ppu.bin")
+        program = join(TEST_BINARY_PATH, "neuron_reset_vector-ppu_vx_v2.bin")
 
         builder = PlaybackProgramBuilder()
         config = NeuronConfig()
@@ -94,6 +94,8 @@ class LibnuxNeuronResetVectorTestVx(unittest.TestCase):
         tickets = []
         for ctr in iter_all(SpikeCounterReadOnDLS):
             tickets.append(builder.read(ctr))
+        builder.write(halco.TimerOnDLS(), hal.Timer(0))
+        builder.wait_until(halco.TimerOnDLS(), 10000)
         run(self.CONNECTION, builder.done())
 
         for i, ticket in enumerate(tickets):
diff --git a/test/with_hostcode/correlation_reset_causal-ppu.cpp b/test/with_hostcode/vx/correlation_reset_causal-ppu.cpp
similarity index 96%
rename from test/with_hostcode/correlation_reset_causal-ppu.cpp
rename to test/with_hostcode/vx/correlation_reset_causal-ppu.cpp
index 6a2a6e76a41210031d6eb8cdc8d28062d15dcd23..eac4bf7e5ccd5e083d1749505b764cf8d2a5be66 100644
--- a/test/with_hostcode/correlation_reset_causal-ppu.cpp
+++ b/test/with_hostcode/vx/correlation_reset_causal-ppu.cpp
@@ -1,10 +1,10 @@
 #include <array>
 #include <stddef.h>
 #include <stdint.h>
-#include "libnux/dls.h"
-#include "libnux/vector.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/vector.h"
 
-using namespace libnux;
+using namespace libnux::vx;
 
 void fill_array(vector_type& array, uint8_t target)
 {
diff --git a/test/with_hostcode/neuron_reset_global-ppu.cpp b/test/with_hostcode/vx/neuron_reset_global-ppu.cpp
similarity index 93%
rename from test/with_hostcode/neuron_reset_global-ppu.cpp
rename to test/with_hostcode/vx/neuron_reset_global-ppu.cpp
index aa83488449eda3e2703a26faa772d783919f2cb4..d5a31932efeddc997659b0f4caf457ab76184a45 100644
--- a/test/with_hostcode/neuron_reset_global-ppu.cpp
+++ b/test/with_hostcode/vx/neuron_reset_global-ppu.cpp
@@ -1,10 +1,10 @@
 #include <array>
 #include <stddef.h>
 #include <stdint.h>
-#include "libnux/dls.h"
-#include "libnux/vector.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/vector.h"
 
-using namespace libnux;
+using namespace libnux::vx;
 
 void fill_array(vector_type& array, uint8_t target)
 {
diff --git a/test/with_hostcode/neuron_reset_vector-ppu.cpp b/test/with_hostcode/vx/neuron_reset_vector-ppu.cpp
similarity index 53%
rename from test/with_hostcode/neuron_reset_vector-ppu.cpp
rename to test/with_hostcode/vx/neuron_reset_vector-ppu.cpp
index 1d7bcd5c561e6ec028735d7f38fd3a68657d5bbd..2bf25b6875255f996b98a40acbaf98e57c15d7d1 100644
--- a/test/with_hostcode/neuron_reset_vector-ppu.cpp
+++ b/test/with_hostcode/vx/neuron_reset_vector-ppu.cpp
@@ -1,15 +1,17 @@
-#include "libnux/reset_neurons.h"
-#include "libnux/time.h"
+#include "libnux/vx/reset_neurons.h"
+#include "libnux/vx/time.h"
+
+using namespace libnux::vx;
 
 int start()
 {
-	libnux::reset_neurons();
+	reset_neurons();
 
 	sleep_cycles(10 * default_ppu_cycles_per_us);
 
 	__vector uint8_t even = vec_splat_u8(1);
 	__vector uint8_t odd = vec_splat_u8(0);
-	libnux::reset_neurons(even, odd);
+	reset_neurons(even, odd);
 
 	return 0;
 }
diff --git a/test/with_hostcode/refgen_access_pattern-ppu.cpp b/test/with_hostcode/vx/refgen_access_pattern-ppu.cpp
similarity index 92%
rename from test/with_hostcode/refgen_access_pattern-ppu.cpp
rename to test/with_hostcode/vx/refgen_access_pattern-ppu.cpp
index 3edecf11683e82c79eb66fb1f86e61627a7e2079..b1c69e68f85b068ea3d1b702618d8b4b366e4c77 100644
--- a/test/with_hostcode/refgen_access_pattern-ppu.cpp
+++ b/test/with_hostcode/vx/refgen_access_pattern-ppu.cpp
@@ -1,8 +1,8 @@
 #include <array>
-#include "libnux/omnibus.h"
-#include "libnux/dls.h"
+#include "libnux/vx/omnibus.h"
+#include "libnux/vx/dls.h"
 
-using namespace libnux;
+using namespace libnux::vx;
 
 // Reference generator configuration values used within this test
 static constexpr std::array<unsigned int, 4> amp_values{5, 10, 15, 20};
diff --git a/test/with_hostcode/synram_access_pattern-ppu.cpp b/test/with_hostcode/vx/synram_access_pattern-ppu.cpp
similarity index 84%
rename from test/with_hostcode/synram_access_pattern-ppu.cpp
rename to test/with_hostcode/vx/synram_access_pattern-ppu.cpp
index f2c63e4ddf0ee5c747678f95e6512515eac2a664..6df5aaf34438e30ca79ab887aacb2611e91f6682 100644
--- a/test/with_hostcode/synram_access_pattern-ppu.cpp
+++ b/test/with_hostcode/vx/synram_access_pattern-ppu.cpp
@@ -1,7 +1,9 @@
 #include <stddef.h>
 #include <stdint.h>
-#include "libnux/dls.h"
-#include "libnux/vector.h"
+#include "libnux/vx/dls.h"
+#include "libnux/vx/vector.h"
+
+using namespace libnux::vx;
 
 void fill_array(vector_type& array, uint8_t target)
 {
@@ -27,7 +29,7 @@ int start(void)
 			tmp_row.odd_columns[row_id / 2] = diagonal_value;
 		}
 
-        set_row_via_vector(tmp_row, row_id, dls_weight_base);
+		set_row_via_vector(tmp_row, row_id, dls_weight_base);
 
 		diagonal_value++;
 		if (diagonal_value > dls_weight_mask) {
diff --git a/test/with_hostcode/wscript b/test/with_hostcode/wscript
index ef24dfe564f1e90f33df4523043d6664436e36d7..1fb2f264556f53e6894a17c0657e5ba7f01f6bb9 100644
--- a/test/with_hostcode/wscript
+++ b/test/with_hostcode/wscript
@@ -25,17 +25,22 @@ def build(bld):
     bld.env.DLSvx_HARDWARE_AVAILABLE = "cube" == os.environ.get("SLURM_JOB_PARTITION")
     bld.env.DLSvx_SIM_AVAILABLE = "FLANGE_SIMULATION_RCF_PORT" in os.environ
 
-    build_host_python(bld)
-    build_ppu_cpp(bld)
+    chip_revision_list = ["vx"]
+    chip_version_list = [["v1", "v2"]]
+
+    for chip_idx, chip_revision in enumerate(chip_revision_list):
+        for chip_version in chip_version_list[chip_idx]:
+            build_host_python(bld, chip_revision, chip_version)
+            build_ppu_cpp(bld, chip_revision, chip_version)
 
     bld.add_post_fun(summary)
 
 
-def build_host_python(bld):
-    bld(name="libnux-simtest-log_access_pattern",
-        tests="log_access_pattern_host.py",
+def build_host_python(bld, chip_revision, chip_version):
+    bld(name="libnux-simtest-log_access_pattern_" + chip_revision + "_" + chip_version,
+        tests="log_access_pattern_host_" + chip_revision + "_" + chip_version + ".py",
         features="use pytest pylint pycodestyle",
-        use="dlens_vx_v1",
+        use="dlens_" + chip_revision + "_" + chip_version,
         install_path="${PREFIX}/bin/tests/sim",
         pylint_config=join(get_toplevel_path(), "code-format", "pylintrc"),
         pycodestyle_config=join(get_toplevel_path(), "code-format", "pycodestyle"),
@@ -55,55 +60,62 @@ def build_host_python(bld):
         test_timeout=3600
         )
 
-    bld(name="libnux-test-neuron_reset_vector",
-        tests="neuron_reset_vector.py",
-        features="use pytest pylint pycodestyle",
-        use="dlens_vx_v2",
-        install_path="${PREFIX}/bin/tests/sim",
-        pylint_config=join(get_toplevel_path(), "code-format", "pylintrc"),
-        pycodestyle_config=join(get_toplevel_path(), "code-format", "pycodestyle"),
-        skip_run=not bld.env.DLSvx_HARDWARE_AVAILABLE,
-        test_environ=dict(
-            TEST_BINARY_PATH=os.path.join(get_toplevel_path(),
-                                          "build",
-                                          "libnux",
-                                          "test",
-                                          "with_hostcode")),
-        test_timeout=30
-        )
-
-
-def build_ppu_cpp(bld):
-    bld.program(name="libnux-test-refgen_access_pattern-ppu",
+    if chip_revision == "vx" and chip_version == "v1":
+        pass
+    else:
+        bld(name="libnux-test-neuron_reset_vector_" + chip_revision + "_" + chip_version,
+            tests="neuron_reset_vector_" + chip_revision + "_" + chip_version + ".py",
+            features="use pytest pylint pycodestyle",
+            use="dlens_" + chip_revision + "_" + chip_version,
+            install_path="${PREFIX}/bin/tests/sim",
+            pylint_config=join(get_toplevel_path(), "code-format", "pylintrc"),
+            pycodestyle_config=join(get_toplevel_path(), "code-format", "pycodestyle"),
+            skip_run=not bld.env.DLSvx_HARDWARE_AVAILABLE,
+            test_environ=dict(
+                TEST_BINARY_PATH=os.path.join(get_toplevel_path(),
+                                              "build",
+                                              "libnux",
+                                              "test",
+                                              "with_hostcode")),
+            test_timeout=30
+            )
+
+
+def build_ppu_cpp(bld, chip_revision, chip_version):
+    bld.program(name="libnux-test-refgen_access_pattern-ppu_" + chip_revision + "_" + chip_version,
                 features="cxx",
-                target="refgen_access_pattern-ppu.bin",
-                source="refgen_access_pattern-ppu.cpp",
-                use=["nux_runtime_vx"],
-                env=bld.all_envs["nux_vx"])
+                target="refgen_access_pattern-ppu_" + chip_revision + "_" + chip_version + ".bin",
+                source=chip_revision + "/refgen_access_pattern-ppu.cpp",
+                use=["nux_runtime_" + chip_revision + "_" + chip_version],
+                env=bld.all_envs["nux_" + chip_revision + "_" + chip_version])
 
-    bld.program(name="libnux-test-synram_access_pattern-ppu",
+    bld.program(name="libnux-test-synram_access_pattern-ppu_" + chip_revision + "_" + chip_version,
                 features="cxx",
-                target="synram_access_pattern-ppu.bin",
-                source="synram_access_pattern-ppu.cpp",
-                use=["nux_runtime_vx"],
-                env=bld.all_envs["nux_vx"])
+                target="synram_access_pattern-ppu_" + chip_revision + "_" + chip_version + ".bin",
+                source=chip_revision + "/synram_access_pattern-ppu.cpp",
+                use=["nux_runtime_" + chip_revision + "_" + chip_version],
+                env=bld.all_envs["nux_" + chip_revision + "_" + chip_version])
 
-    bld.program(name="libnux-test-correlation_reset_causal-ppu",
+    bld.program(name="libnux-test-correlation_reset_causal-ppu_" + chip_revision + "_" + chip_version,
                 features="cxx",
-                target="correlation_reset_causal-ppu.bin",
-                source="correlation_reset_causal-ppu.cpp",
-                use=["nux_runtime_vx"],
-                env=bld.all_envs["nux_vx"])
+                target="correlation_reset_causal-ppu_" + chip_revision + "_" + chip_version + ".bin",
+                source=chip_revision + "/correlation_reset_causal-ppu.cpp",
+                use=["nux_runtime_" + chip_revision + "_" + chip_version],
+                env=bld.all_envs["nux_" + chip_revision + "_" + chip_version])
 
-    bld.program(name="libnux-test-neuron_reset_global-ppu",
-                features="cxx",
-                target="neuron_reset_global-ppu.bin",
-                source="neuron_reset_global-ppu.cpp",
-                use=["nux_runtime_vx"],
-                env=bld.all_envs["nux_vx"])
-    bld.program(name="libnux-test-neuron_reset_vector-ppu",
+    bld.program(name="libnux-test-neuron_reset_global-ppu_" + chip_revision + "_" + chip_version,
                 features="cxx",
-                target="neuron_reset_vector-ppu.bin",
-                source="neuron_reset_vector-ppu.cpp",
-                use=["nux_runtime_vx"],
-                env=bld.all_envs["nux_vx"])
+                target="neuron_reset_global-ppu_" + chip_revision + "_" + chip_version + ".bin",
+                source=chip_revision + "/neuron_reset_global-ppu.cpp",
+                use=["nux_runtime_" + chip_revision + "_" + chip_version],
+                env=bld.all_envs["nux_" + chip_revision + "_" + chip_version])
+
+    if chip_revision == "vx" and chip_version == "v1":
+        pass
+    else:
+        bld.program(name="libnux-test-neuron_reset_vector-ppu_" + chip_revision + "_" + chip_version,
+                    features="cxx",
+                    target="neuron_reset_vector-ppu_" + chip_revision + "_" + chip_version + ".bin",
+                    source=chip_revision + "/neuron_reset_vector-ppu.cpp",
+                    use=["nux_runtime_" + chip_revision + "_" + chip_version],
+                    env=bld.all_envs["nux_" + chip_revision + "_" + chip_version])
diff --git a/wscript b/wscript
index 2d9700fbf07f086e708d34ba27164a57b04855ab..67a868da5d38f6ea3647e19e24dc59dc1c26680c 100644
--- a/wscript
+++ b/wscript
@@ -73,8 +73,12 @@ def configure(conf):
         conf.env.append_value('ASLINKFLAGS', '--defsym=mailbox_size=4096')
         conf.env.append_value('LINKFLAGS', '-Wl,--defsym=mailbox_size=4096')
 
-    # specialize for vx
-    conf.setenv('nux_vx', env=conf.all_envs['nux'])
+    # specialize for vx-v1
+    conf.setenv('nux_vx_v1', env=conf.all_envs['nux'])
+    conf.env.append_value('CXXFLAGS', '-mcpu=s2pp_hx')
+
+    # specialize for vx-v2
+    conf.setenv('nux_vx_v2', env=conf.all_envs['nux'])
     conf.env.append_value('CXXFLAGS', '-mcpu=s2pp_hx')
 
     # restore env
@@ -83,160 +87,127 @@ def configure(conf):
 def build(bld):
     bld.env.cube_partition = "cube" == os.environ.get("SLURM_JOB_PARTITION")
 
-    for dls_version in ['vx']:
-        env = bld.all_envs['nux_' + dls_version]
-
-        bld(
-            target = 'nux_inc_' + dls_version,
-            export_includes = ['.'],
-            env = env,
-        )
-
-        nux_sources = [
-            'src/bitformatting.cpp',
-            'src/correlation.cpp',
-            'src/exp.cpp',
-            'src/fxv.cpp',
-            'src/mailbox.cpp',
-            'src/malloc.cpp',
-            'src/random.cpp',
-            'src/stack_guards.cpp',
-            'src/spikes.cpp',
-            'src/time.cpp',
-            'src/unittest.cpp',
-            'src/unittest_mailbox.cpp',
-        ]
-
-        bld.stlib(
-            target = 'nux_' + dls_version,
-            source = nux_sources,
-            use = ['nux_inc_' + dls_version],
-            env = env,
-        )
-
-        bld(
-            features = 'cxx',
-            name = 'nux_runtime_obj_' + dls_version,
-            source = ['src/start.cpp',
-                      'src/initdeinit.cpp',
-                      'src/cxa_pure_virtual.cpp'],
-            use = 'nux_inc_' + dls_version,
-            env = env,
-        )
-
-        bld(
-            name='nux_runtime_shutdown_' + dls_version,
-            target='crt_shutdown.o',
-            source=['src/crt_shutdown.s'],
-            features='use asm',
-            env = env,
-        )
-
-        bld(
-            name='nux_runtime_' + dls_version,
-            target='crt.o',
-            source=['src/crt.s'],
-            features='use asm',
-            use=['nux_runtime_obj_' + dls_version,
-                 'nux_runtime_shutdown_' + dls_version],
-            env=env,
-        )
-
-        program_list = [
-            'examples/stdp.cpp',
-            'test/test_cadc_static.cpp',
-            'test/test_ctors.cpp',
-            'test/test_bitformatting.cpp',
-            'test/test_bool.cpp',
-            'test/test_fpga_memory_vector_access.cpp',
-            'test/test_fpga_memory_scalar_access.cpp',
-            'test/test_fxvadd.cpp',
-            'test/test_fxvsel.cpp',
-            'test/test_helper.cpp',
-            'test/test_inline_vector_argument.cpp',
-            'test/test_malloc.cpp',
-            'test/test_many_vectors.cpp',
-            'test/test_measure_time.cpp',
-            'test/test_noinline_vector_argument.cpp',
-            'test/test_return_vector.cpp',
-            'test/test_returncode.cpp',
-            'test/test_stack_guard.cpp',
-            'test/test_stack_redzone.cpp',
-            'test/test_synram.cpp',
-            'test/test_synram_rw.cpp',
-            'test/test_unittest.cpp',
-            'test/test_vector.cpp',
-            'test/test_vector_alignment.cpp',
-            'test/test_vector_cc.cpp',
-            'test/test_vector_convert.cpp',
-            'test/test_vector_saturating_subtract.cpp',
-            'test/test_vector_register_reusage.cpp',
-            'test/test_vector_splat.cpp',
-            'test/test_vector_sync.cpp',
-        ]
-
-        for program in program_list:
+    chip_revision_list = ["vx"]
+    chip_version_list = [["v1", "v2"]]
+
+    for chip_idx, chip_revision in enumerate(chip_revision_list):
+        for chip_version in chip_version_list[chip_idx]:
+
+            env = bld.all_envs["nux_" + chip_revision + "_" + chip_version]
+
+            bld(
+                target = "nux_inc_" + chip_revision + "_" + chip_version,
+                export_includes = ["."],
+                env = env,
+            )
+
+            bld.stlib(
+                target = "nux_" + chip_revision + "_" + chip_version,
+                source = bld.path.ant_glob("src/" + chip_revision + "/*.cpp")
+                       + bld.path.ant_glob("src/" + chip_revision + "/" + chip_version + "/*.cpp"),
+                use = ["nux_inc_" + chip_revision + "_" + chip_version],
+                env = env,
+            )
+
+            bld(
+                features = "cxx",
+                name = "nux_runtime_obj_" + chip_revision + "_" + chip_version,
+                source = ["src/start.cpp",
+                          "src/initdeinit.cpp",
+                          "src/cxa_pure_virtual.cpp"],
+                use = "nux_inc_" + chip_revision + "_" + chip_version,
+                env = env,
+            )
+
+            bld(
+                name = "nux_runtime_shutdown_" + chip_revision + "_" + chip_version,
+                target = "crt_shutdown.o",
+                source = ["src/crt_shutdown.s"],
+                features = "use asm",
+                env = env,
+            )
+
+            bld(
+                name = "nux_runtime_" + chip_revision + "_" + chip_version,
+                target = "crt.o",
+                source = ["src/crt.s"],
+                features = "use asm",
+                use = ["nux_runtime_obj_" + chip_revision + "_" + chip_version,
+                       "nux_runtime_shutdown_" + chip_revision + "_" + chip_version],
+                env=env,
+            )
+
+            program_list = []
+            program_list += ["test/" + chip_revision + "/" + os.path.basename(str(f)) 
+                             for f in bld.path.ant_glob("test/" + chip_revision + "/*.cpp")]
+            program_list += ["test/" + chip_revision + "/" + chip_version + "/" + os.path.basename(str(f))
+                             for f in bld.path.ant_glob("test/" + chip_revision + "/" + chip_version + "/*.cpp")]
+            program_list += ["examples/stdp.cpp"]
+
+            for program in program_list:
+                bld.program(
+                    features = "cxx",
+                    target = program.replace(".cpp", "") + "_" + chip_revision + "_" + chip_version + ".bin",
+                    source = [program],
+                    use = ["nux_" + chip_revision + "_" + chip_version,
+                           "nux_runtime_" + chip_revision + "_" + chip_version],
+                    env = bld.all_envs["nux_" + chip_revision + "_" + chip_version],
+                )
+
+            def max_size_empty():
+                stack_protector = env.LIBNUX_STACK_PROTECTOR_ENABLED[0].lower() == "true"
+                stack_redzone = env.LIBNUX_STACK_REDZONE_ENABLED[0].lower() == "true"
+                build_profile = bld.options.build_profile
+
+                if not stack_protector and not stack_redzone:
+                    if build_profile == 'release':
+                        return 400
+                    else:
+                        return 544
+
+                if stack_protector and not stack_redzone:
+                    if build_profile == 'release':
+                        return 816
+                    else:
+                        return 864
+
+                if not stack_protector and stack_redzone:
+                    if build_profile == 'release':
+                        return 496
+                    else:
+                        return 608
+
+                if stack_protector and stack_redzone:
+                    if build_profile == 'release':
+                        return 928
+                    else:
+                        return 1008
+
             bld.program(
-                features = 'cxx',
-                target = program.replace('.cpp', '') + '_' + dls_version + '.bin',
-                source = [program],
-                use = ['nux_' + dls_version, 'nux_runtime_' + dls_version],
-                env = bld.all_envs['nux_' + dls_version],
+                features = "cxx check_size",
+                check_size_max = max_size_empty(),
+                target = "test_empty_" + chip_revision + "_" + chip_version + ".bin",
+                source = ["test/helpers/test_empty.cpp"],
+                use = ["nux_" + chip_revision + "_" + chip_version,
+                       "nux_runtime_" + chip_revision + "_" + chip_version],
+                env = env,
             )
 
-        def max_size_empty():
-            stack_protector = env.LIBNUX_STACK_PROTECTOR_ENABLED[0].lower() == "true"
-            stack_redzone = env.LIBNUX_STACK_REDZONE_ENABLED[0].lower() == "true"
-            build_profile = bld.options.build_profile
-
-            if not stack_protector and not stack_redzone:
-                if build_profile == 'release':
-                    return 400
-                else:
-                    return 544
-
-            if stack_protector and not stack_redzone:
-                if build_profile == 'release':
-                    return 816
-                else:
-                    return 864
-
-            if not stack_protector and stack_redzone:
-                if build_profile == 'release':
-                    return 496
-                else:
-                    return 608
-
-            if stack_protector and stack_redzone:
-                if build_profile == 'release':
-                    return 928
-                else:
-                    return 1008
-
-        bld.program(
-            features = 'cxx check_size',
-            check_size_max = max_size_empty(),
-            target = 'test_empty_' + dls_version + '.bin',
-            source = ['test/test_empty.cpp'],
-            use = ['nux_' + dls_version, 'nux_runtime_' + dls_version],
-            env = env,
-        )
-
-    bld(
-        name='libnux_hwsimtests_vx',
-        tests='test/test_hwsimtests_vx.py',
-        features='use pytest pylint pycodestyle',
-        use='dlens_vx_v1',
-        install_path='${PREFIX}/bin/tests',
-        skip_run=not (bld.env.cube_partition or ("FLANGE_SIMULATION_RCF_PORT" in os.environ)),
-        env = bld.all_envs[''],
-        test_environ = dict(STACK_PROTECTION=env.LIBNUX_STACK_PROTECTOR_ENABLED[0],
-                            STACK_REDZONE=env.LIBNUX_STACK_REDZONE_ENABLED[0],
-                            TEST_BINARY_PATH=os.path.join(bld.env.PREFIX, 'build', 'libnux', 'test')),
-        pylint_config=join(get_toplevel_path(), "code-format", "pylintrc"),
-        pycodestyle_config=join(get_toplevel_path(), "code-format", "pycodestyle"),
-        test_timeout = 20000
-    )
+            bld(
+                name = "libnux_hwsimtests_" + chip_revision + "_" + chip_version,
+                tests = "test/test_hwsimtests_" + chip_revision + "_" + chip_version + ".py",
+                features = "use pytest pylint pycodestyle",
+                use = "dlens_" + chip_revision + "_" + chip_version,
+                install_path = "${PREFIX}/bin/tests",
+                skip_run = not (bld.env.cube_partition or ("FLANGE_SIMULATION_RCF_PORT" in os.environ)),
+                env = bld.all_envs[''],
+                test_environ = dict(STACK_PROTECTION=env.LIBNUX_STACK_PROTECTOR_ENABLED[0],
+                                    STACK_REDZONE=env.LIBNUX_STACK_REDZONE_ENABLED[0],
+                                    TEST_BINARY_PATH=os.path.join(bld.env.PREFIX, "build", "libnux", "test")),
+                pylint_config = join(get_toplevel_path(), "code-format", "pylintrc"),
+                pycodestyle_config = join(get_toplevel_path(), "code-format", "pycodestyle"),
+                test_timeout = 20000
+            )
 
     bld.add_post_fun(summary)