Added top files and config files for remaining peripherals.
diff --git a/openlane/Peripheral_GPIO/config.tcl b/openlane/Peripheral_GPIO/config.tcl
new file mode 100644
index 0000000..89f330d
--- /dev/null
+++ b/openlane/Peripheral_GPIO/config.tcl
@@ -0,0 +1,54 @@
+set ::env(PDK) "sky130A"
+set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd"
+
+set script_dir [file dirname [file normalize [info script]]]
+
+set ::env(ROUTING_CORES) "8"
+
+set ::env(DESIGN_NAME) GPIO
+
+set ::env(VERILOG_FILES) "\
+	$::env(CARAVEL_ROOT)/verilog/rtl/defines.v \
+	$script_dir/../../verilog/rtl/Utility/ConfigurationRegister.v \
+	$script_dir/../../verilog/rtl/PWM/PWMCounter.v \
+	$script_dir/../../verilog/rtl/PWM/PWMDevice.v \
+	$script_dir/../../verilog/rtl/PWM/PWM_top.v"
+
+set ::env(DESIGN_IS_CORE) 0
+set ::env(FP_PDN_CORE_RING) 0
+
+set ::env(CLOCK_PORT) "clk"
+set ::env(CLOCK_NET) "counter.clk"
+set ::env(CLOCK_PERIOD) "10"
+
+# Absolute module size
+# Modules should be bigger than 200x200
+# Also generally best to leave bottom left as 0,0
+set ::env(FP_SIZING) "absolute"
+set ::env(DIE_AREA) "0 0 500 350"
+
+# Alternatively use an adaptive size
+#set ::env(FP_SIZING) "relative"
+#set ::env(FP_CORE_UTIL) 20
+#set ::env(FP_ASPECT_RATIO) 1.0
+
+set ::env(FP_PIN_ORDER_CFG) $script_dir/pin_order.cfg
+
+set ::env(PL_BASIC_PLACEMENT) 0
+set ::env(PL_TARGET_DENSITY) 0.125
+
+# Maximum layer used for routing is metal 4.
+# This is because this macro will be inserted in a top level (user_project_wrapper) 
+# where the PDN is planned on metal 5. So, to avoid having shorts between routes
+# in this macro and the top level metal 5 stripes, we have to restrict routes to metal4.  
+# set ::env(GLB_RT_MAXLAYER) 5
+set ::env(RT_MAX_LAYER) {met4}
+
+# You can draw more power domains if you need to 
+set ::env(VDD_NETS) [list {vccd1}]
+set ::env(GND_NETS) [list {vssd1}]
+
+# If you're going to use multiple power domains, then disable cvc run.
+set ::env(RUN_CVC) 1
+
+set ::env(DIODE_INSERTION_STRATEGY) 4 
diff --git a/openlane/Peripheral_GPIO/pin_order.cfg b/openlane/Peripheral_GPIO/pin_order.cfg
new file mode 100644
index 0000000..798d831
--- /dev/null
+++ b/openlane/Peripheral_GPIO/pin_order.cfg
@@ -0,0 +1,11 @@
+#BUS_SORT
+
+#E
+gpio_.*
+
+#S
+clk
+rst
+
+#W
+peripheralBus_.*
diff --git a/openlane/Peripheral_UART/config.tcl b/openlane/Peripheral_UART/config.tcl
new file mode 100644
index 0000000..f6ea4ec
--- /dev/null
+++ b/openlane/Peripheral_UART/config.tcl
@@ -0,0 +1,54 @@
+set ::env(PDK) "sky130A"
+set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd"
+
+set script_dir [file dirname [file normalize [info script]]]
+
+set ::env(ROUTING_CORES) "8"
+
+set ::env(DESIGN_NAME) UART
+
+set ::env(VERILOG_FILES) "\
+	$::env(CARAVEL_ROOT)/verilog/rtl/defines.v \
+	$script_dir/../../verilog/rtl/Utility/ConfigurationRegister.v \
+	$script_dir/../../verilog/rtl/PWM/PWMCounter.v \
+	$script_dir/../../verilog/rtl/PWM/PWMDevice.v \
+	$script_dir/../../verilog/rtl/PWM/PWM_top.v"
+
+set ::env(DESIGN_IS_CORE) 0
+set ::env(FP_PDN_CORE_RING) 0
+
+set ::env(CLOCK_PORT) "clk"
+set ::env(CLOCK_NET) "counter.clk"
+set ::env(CLOCK_PERIOD) "10"
+
+# Absolute module size
+# Modules should be bigger than 200x200
+# Also generally best to leave bottom left as 0,0
+set ::env(FP_SIZING) "absolute"
+set ::env(DIE_AREA) "0 0 500 350"
+
+# Alternatively use an adaptive size
+#set ::env(FP_SIZING) "relative"
+#set ::env(FP_CORE_UTIL) 20
+#set ::env(FP_ASPECT_RATIO) 1.0
+
+set ::env(FP_PIN_ORDER_CFG) $script_dir/pin_order.cfg
+
+set ::env(PL_BASIC_PLACEMENT) 0
+set ::env(PL_TARGET_DENSITY) 0.125
+
+# Maximum layer used for routing is metal 4.
+# This is because this macro will be inserted in a top level (user_project_wrapper) 
+# where the PDN is planned on metal 5. So, to avoid having shorts between routes
+# in this macro and the top level metal 5 stripes, we have to restrict routes to metal4.  
+# set ::env(GLB_RT_MAXLAYER) 5
+set ::env(RT_MAX_LAYER) {met4}
+
+# You can draw more power domains if you need to 
+set ::env(VDD_NETS) [list {vccd1}]
+set ::env(GND_NETS) [list {vssd1}]
+
+# If you're going to use multiple power domains, then disable cvc run.
+set ::env(RUN_CVC) 1
+
+set ::env(DIODE_INSERTION_STRATEGY) 4 
diff --git a/openlane/Peripheral_UART/pin_order.cfg b/openlane/Peripheral_UART/pin_order.cfg
new file mode 100644
index 0000000..aabf6e5
--- /dev/null
+++ b/openlane/Peripheral_UART/pin_order.cfg
@@ -0,0 +1,11 @@
+#BUS_SORT
+
+#E
+uart_.*
+
+#S
+clk
+rst
+
+#W
+peripheralBus_.*
\ No newline at end of file
diff --git a/openlane/Peripheral_WBPeripheralBusInterface/config.tcl b/openlane/Peripheral_WBPeripheralBusInterface/config.tcl
new file mode 100644
index 0000000..6f504a4
--- /dev/null
+++ b/openlane/Peripheral_WBPeripheralBusInterface/config.tcl
@@ -0,0 +1,51 @@
+set ::env(PDK) "sky130A"
+set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd"
+
+set script_dir [file dirname [file normalize [info script]]]
+
+set ::env(ROUTING_CORES) "8"
+
+set ::env(DESIGN_NAME) WBPeripheralBusInterface
+
+set ::env(VERILOG_FILES) "\
+	$::env(CARAVEL_ROOT)/verilog/rtl/defines.v \
+	$script_dir/../../verilog/rtl/Peripherals/WBPeripheralBusInterface/WBPeripheralBusInterface_top.v"
+
+set ::env(DESIGN_IS_CORE) 0
+set ::env(FP_PDN_CORE_RING) 0
+
+set ::env(CLOCK_PORT) "clk"
+set ::env(CLOCK_NET) "counter.clk"
+set ::env(CLOCK_PERIOD) "10"
+
+# Absolute module size
+# Modules should be bigger than 200x200
+# Also generally best to leave bottom left as 0,0
+set ::env(FP_SIZING) "absolute"
+set ::env(DIE_AREA) "0 0 500 350"
+
+# Alternatively use an adaptive size
+#set ::env(FP_SIZING) "relative"
+#set ::env(FP_CORE_UTIL) 20
+#set ::env(FP_ASPECT_RATIO) 1.0
+
+set ::env(FP_PIN_ORDER_CFG) $script_dir/pin_order.cfg
+
+set ::env(PL_BASIC_PLACEMENT) 0
+set ::env(PL_TARGET_DENSITY) 0.125
+
+# Maximum layer used for routing is metal 4.
+# This is because this macro will be inserted in a top level (user_project_wrapper) 
+# where the PDN is planned on metal 5. So, to avoid having shorts between routes
+# in this macro and the top level metal 5 stripes, we have to restrict routes to metal4.  
+# set ::env(GLB_RT_MAXLAYER) 5
+set ::env(RT_MAX_LAYER) {met4}
+
+# You can draw more power domains if you need to 
+set ::env(VDD_NETS) [list {vccd1}]
+set ::env(GND_NETS) [list {vssd1}]
+
+# If you're going to use multiple power domains, then disable cvc run.
+set ::env(RUN_CVC) 1
+
+set ::env(DIODE_INSERTION_STRATEGY) 4 
diff --git a/openlane/Peripheral_WBPeripheralBusInterface/pin_order.cfg b/openlane/Peripheral_WBPeripheralBusInterface/pin_order.cfg
new file mode 100644
index 0000000..d04cfcc
--- /dev/null
+++ b/openlane/Peripheral_WBPeripheralBusInterface/pin_order.cfg
@@ -0,0 +1,11 @@
+#BUS_SORT
+
+#E
+peripheralBus_.*
+
+#N
+clk
+rst
+
+#W
+wb_.*
\ No newline at end of file
diff --git a/openlane/Peripherals/config.tcl b/openlane/Peripherals/config.tcl
new file mode 100644
index 0000000..26a5efe
--- /dev/null
+++ b/openlane/Peripherals/config.tcl
@@ -0,0 +1,90 @@
+set ::env(PDK) "sky130A"
+set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd"
+
+set script_dir [file dirname [file normalize [info script]]]
+
+set ::env(ROUTING_CORES) "8"
+
+set ::env(DESIGN_NAME) Peripherals
+
+set ::env(VERILOG_FILES) "\
+	$::env(CARAVEL_ROOT)/verilog/rtl/defines.v \
+	$script_dir/../../verilog/rtl/Peripherals/Peripherals_top.v"
+
+set ::env(DESIGN_IS_CORE) 0
+set ::env(FP_PDN_CORE_RING) 0
+
+set ::env(CLOCK_PORT) "clk"
+#set ::env(CLOCK_NET) "counter.clk"
+set ::env(CLOCK_PERIOD) "10"
+
+## Internal Macros
+### Macro PDN Connections
+set ::env(FP_PDN_MACRO_HOOKS) "\
+	wbPeripheralBusInterface vccd1 vssd1 \
+	gpio vccd1 vssd1 \
+	ioMux vccd1 vssd1 \
+	pwm vccd1 vssd1 \
+	spi vccd1 vssd1 \
+	uart vccd1 vssd1"
+
+### Macro Placement
+set ::env(MACRO_PLACEMENT_CFG) $script_dir/macro.cfg
+
+### Black-box verilog and views
+set ::env(VERILOG_FILES_BLACKBOX) "\
+	$::env(CARAVEL_ROOT)/verilog/rtl/defines.v \
+	$script_dir/../../verilog/rtl/Peripherals/WBPeripheralBusInterface/WBPeripheralBusInterface_top.v \
+	$script_dir/../../verilog/rtl/Peripherals/GPIO/GPIO_top.v \
+	$script_dir/../../verilog/rtl/Peripherals/IOMultiplexer/IOMultiplexer_top.v \
+	$script_dir/../../verilog/rtl/Peripherals/PWM/PWM_top.v \
+	$script_dir/../../verilog/rtl/Peripherals/SPI/SPI_top.v \
+	$script_dir/../../verilog/rtl/Peripherals/UART/UART_top.v"
+
+set ::env(EXTRA_LEFS) "\
+	$script_dir/../../lef/WBPeripheralBusInterface.lef \
+	$script_dir/../../lef/GPIO.lef \
+	$script_dir/../../lef/IOMultiplexer.lef \
+	$script_dir/../../lef/PWM.lef \
+	$script_dir/../../lef/SPI.lef \
+	$script_dir/../../lef/UART.lef \"
+
+set ::env(EXTRA_GDS_FILES) "\
+	$script_dir/../../gds/WBPeripheralBusInterface.gds \
+	$script_dir/../../gds/GPIO.gds \
+	$script_dir/../../gds/IOMultiplexer.gds \
+	$script_dir/../../gds/PWM.gds \
+	$script_dir/../../gds/SPI.gds \
+	$script_dir/../../gds/UART.gds"
+
+# Absolute module size
+# Modules should be bigger than 200x200
+# Also generally best to leave bottom left as 0,0
+set ::env(FP_SIZING) "absolute"
+set ::env(DIE_AREA) "0 0 1000 1500"
+
+# Alternatively use an adaptive size
+#set ::env(FP_SIZING) "relative"
+#set ::env(FP_CORE_UTIL) 20
+#set ::env(FP_ASPECT_RATIO) 1.0
+
+set ::env(FP_PIN_ORDER_CFG) $script_dir/pin_order.cfg
+
+set ::env(PL_BASIC_PLACEMENT) 0
+set ::env(PL_TARGET_DENSITY) 0.01
+
+# Maximum layer used for routing is metal 4.
+# This is because this macro will be inserted in a top level (user_project_wrapper) 
+# where the PDN is planned on metal 5. So, to avoid having shorts between routes
+# in this macro and the top level metal 5 stripes, we have to restrict routes to metal4.  
+# set ::env(GLB_RT_MAXLAYER) 5
+set ::env(RT_MAX_LAYER) {met4}
+
+# You can draw more power domains if you need to 
+set ::env(VDD_NETS) [list {vccd1}]
+set ::env(GND_NETS) [list {vssd1}]
+
+# If you're going to use multiple power domains, then disable cvc run.
+set ::env(RUN_CVC) 1
+
+set ::env(DIODE_INSERTION_STRATEGY) 4 
diff --git a/openlane/Peripherals/macro.cfg b/openlane/Peripherals/macro.cfg
new file mode 100644
index 0000000..2b971d5
--- /dev/null
+++ b/openlane/Peripherals/macro.cfg
@@ -0,0 +1,6 @@
+wbPeripheralBusInterface 100 100 N
+gpio 100 1000 N
+ioMux 650 1200 N
+pwm 550 575 N
+spi 100 575 N
+uart 550 100 N
\ No newline at end of file
diff --git a/openlane/Peripherals/pin_order.cfg b/openlane/Peripherals/pin_order.cfg
new file mode 100644
index 0000000..a378a76
--- /dev/null
+++ b/openlane/Peripherals/pin_order.cfg
@@ -0,0 +1,12 @@
+#BUS_SORT
+
+#N
+io_.*
+
+#E
+la_.*
+
+#W
+clk
+rst
+wb_.*
\ No newline at end of file
diff --git a/openlane/Peripherals_Flat/config.tcl b/openlane/Peripherals_Flat/config.tcl
new file mode 100644
index 0000000..9b92cad
--- /dev/null
+++ b/openlane/Peripherals_Flat/config.tcl
@@ -0,0 +1,68 @@
+set ::env(PDK) "sky130A"
+set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd"
+
+set script_dir [file dirname [file normalize [info script]]]
+
+set ::env(ROUTING_CORES) "8"
+
+set ::env(DESIGN_NAME) Peripherals
+
+set ::env(VERILOG_FILES) "\
+	$::env(CARAVEL_ROOT)/verilog/rtl/defines.v \
+	$script_dir/../../verilog/rtl/Peripherals/Peripherals_top.v \
+	$script_dir/../../verilog/rtl/Peripherals/WBPeripheralBusInterface/WBPeripheralBusInterface_top.v \
+	$script_dir/../../verilog/rtl/Peripherals/GPIO/GPIO_top.v \
+	$script_dir/../../verilog/rtl/Peripherals/IOMultiplexer/IOMultiplexer_top.v \
+	$script_dir/../../verilog/rtl/Peripherals/PWM/PWM_top.v \
+	$script_dir/../../verilog/rtl/Peripherals/PWM/PWMDevice.v \
+	$script_dir/../../verilog/rtl/Peripherals/PWM/PWMOutput.v \
+	$script_dir/../../verilog/rtl/Peripherals/SPI/SPI_top.v \
+	$script_dir/../../verilog/rtl/Peripherals/SPI/SPIDevice.v \
+	$script_dir/../../verilog/rtl/Peripherals/UART/UART_top.v \
+	$script_dir/../../verilog/rtl/Peripherals/UART/UART_Buffer.v \
+	$script_dir/../../verilog/rtl/Peripherals/UART/UART_rx.v \
+	$script_dir/../../verilog/rtl/Peripherals/UART/UART_tx.v \
+	$script_dir/../../verilog/rtl/Peripherals/Registers/ConfigurationRegister.v \
+	$script_dir/../../verilog/rtl/Peripherals/Registers/DataRegister.v \
+	$script_dir/../../verilog/rtl/Peripherals/Registers/DeviceSelect.v \
+	$script_dir/../../verilog/rtl/Peripherals/Registers/PeripheralSelect.v \
+	$script_dir/../../verilog/rtl/Utility/ShiftRegister.v"
+
+set ::env(DESIGN_IS_CORE) 0
+set ::env(FP_PDN_CORE_RING) 0
+
+set ::env(CLOCK_PORT) "clk"
+set ::env(CLOCK_NET) "counter.clk"
+set ::env(CLOCK_PERIOD) "10"
+
+# Absolute module size
+# Modules should be bigger than 200x200
+# Also generally best to leave bottom left as 0,0
+set ::env(FP_SIZING) "absolute"
+set ::env(DIE_AREA) "0 0 500 350"
+
+# Alternatively use an adaptive size
+#set ::env(FP_SIZING) "relative"
+#set ::env(FP_CORE_UTIL) 20
+#set ::env(FP_ASPECT_RATIO) 1.0
+
+set ::env(FP_PIN_ORDER_CFG) $script_dir/pin_order.cfg
+
+set ::env(PL_BASIC_PLACEMENT) 0
+set ::env(PL_TARGET_DENSITY) 0.01
+
+# Maximum layer used for routing is metal 4.
+# This is because this macro will be inserted in a top level (user_project_wrapper) 
+# where the PDN is planned on metal 5. So, to avoid having shorts between routes
+# in this macro and the top level metal 5 stripes, we have to restrict routes to metal4.  
+# set ::env(GLB_RT_MAXLAYER) 5
+set ::env(RT_MAX_LAYER) {met4}
+
+# You can draw more power domains if you need to 
+set ::env(VDD_NETS) [list {vccd1}]
+set ::env(GND_NETS) [list {vssd1}]
+
+# If you're going to use multiple power domains, then disable cvc run.
+set ::env(RUN_CVC) 1
+
+set ::env(DIODE_INSERTION_STRATEGY) 4 
diff --git a/openlane/Peripherals_Flat/pin_order.cfg b/openlane/Peripherals_Flat/pin_order.cfg
new file mode 100644
index 0000000..a378a76
--- /dev/null
+++ b/openlane/Peripherals_Flat/pin_order.cfg
@@ -0,0 +1,12 @@
+#BUS_SORT
+
+#N
+io_.*
+
+#E
+la_.*
+
+#W
+clk
+rst
+wb_.*
\ No newline at end of file
diff --git a/verilog/rtl/GPIO/GPIO_top.v b/verilog/rtl/GPIO/GPIO_top.v
deleted file mode 100644
index e69de29..0000000
--- a/verilog/rtl/GPIO/GPIO_top.v
+++ /dev/null
diff --git a/verilog/rtl/Peripherals/GPIO/GPIO_top.v b/verilog/rtl/Peripherals/GPIO/GPIO_top.v
new file mode 100644
index 0000000..0af1502
--- /dev/null
+++ b/verilog/rtl/Peripherals/GPIO/GPIO_top.v
@@ -0,0 +1,27 @@
+module GPIO #(
+		parameter ID = 8'h03
+	)(
+`ifdef USE_POWER_PINS
+		inout vccd1,	// User area 1 1.8V supply
+		inout vssd1,	// User area 1 digital ground
+`endif
+
+		input wire clk,
+		input wire rst,
+		
+		// Peripheral Bus
+		input wire peripheralBus_we,
+		input wire peripheralBus_oe,
+		output wire peripheralBus_busy,
+		input wire[23:0] peripheralBus_address,
+		inout wire[31:0] peripheralBus_data,
+
+		input wire[`MPRJ_IO_PADS_1-1:0] gpio0_input,
+		output wire[`MPRJ_IO_PADS_1-1:0] gpio0_output,
+		output wire[`MPRJ_IO_PADS_1-1:0] gpio0_oe,
+		input wire[`MPRJ_IO_PADS_2-1:0] gpio1_input,
+		output wire[`MPRJ_IO_PADS_2-1:0] gpio1_output,
+		output wire[`MPRJ_IO_PADS_2-1:0] gpio1_oe
+	);
+	
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/Peripherals/Peripherals_top.v b/verilog/rtl/Peripherals/Peripherals_top.v
new file mode 100644
index 0000000..cc172fe
--- /dev/null
+++ b/verilog/rtl/Peripherals/Peripherals_top.v
@@ -0,0 +1,193 @@
+module Peripherals (
+`ifdef USE_POWER_PINS
+		inout vccd1,	// User area 1 1.8V supply
+		inout vssd1,	// User area 1 digital ground
+`endif
+
+		input wire clk,
+		input wire rst,
+
+		// Wishbone Slave ports
+		input wire wb_clk,
+		input wire wb_rst,
+		input wire wb_stb,
+		input wire wb_cyc,
+		input wire wb_we,
+		input wire[3:0] wb_sel,
+		input wire[31:0] wb_dataIn,
+		input wire[31:0] wb_address,
+		output wire wb_ack,
+		output wire[31:0] wb_dataOut,
+
+		// IOs
+		input  [`MPRJ_IO_PADS-1:0] io_in,
+		output [`MPRJ_IO_PADS-1:0] io_out,
+		output [`MPRJ_IO_PADS-1:0] io_oeb,
+
+		// Logic Analyzer Signals
+		output wire[1:0] la_blink
+	);
+
+wire peripheralBus_we;
+wire peripheralBus_oe;
+wire peripheralBus_busy;
+wire[23:0] peripheralBus_address;
+wire[31:0] peripheralBus_data;
+WBPeripheralBusInterface wbPeripheralBusInterface #(
+	.ID(4'h3)
+)(
+`ifdef USE_POWER_PINS
+	.vccd1(vccd1),	// User area 1 1.8V power
+	.vssd1(vssd1),	// User area 1 digital ground
+`endif
+
+    .clk(clk),
+    .rst(rst),
+	.wb_clk(wb_clk),
+	.wb_rst(wb_rst),
+	.wb_stb(wb_stb),
+	.wb_cyc(wb_cyc),
+	.wb_we(wb_we),
+	.wb_sel(wb_sel),
+	.wb_dataIn(wb_dataIn),
+	.wb_address(wb_address),
+	.wb_ack(wb_ack),
+	.wb_dataOut(wb_dataOut),
+	.peripheralBus_we(peripheralBus_we),
+	.peripheralBus_oe(peripheralBus_oe),
+	.peripheralBus_busy(peripheralBus_busy),
+	.peripheralBus_address(peripheralBus_address),
+	.peripheralBus_data(peripheralBus_data),
+);
+
+wire[3:0] uart_en;	
+wire[3:0] uart_rx;
+wire[3:0] uart_tx;
+UART uart #(
+	.ID(8'h00)
+)(
+`ifdef USE_POWER_PINS
+	.vccd1(vccd1),	// User area 1 1.8V power
+	.vssd1(vssd1),	// User area 1 digital ground
+`endif
+
+    .clk(clk),
+    .rst(rst),
+	.peripheralBus_we(peripheralBus_we),
+	.peripheralBus_oe(peripheralBus_oe),
+	.peripheralBus_busy(peripheralBus_busy),
+	.peripheralBus_address(peripheralBus_address),
+	.peripheralBus_data(peripheralBus_data),
+	.uart_en(uart_en),
+	.uart_rx(uart_rx),
+	.uart_tx(uart_tx)
+);
+
+wire[1:0] spi_en;
+wire[1:0] spi_clk;
+wire[1:0] spi_mosi;
+wire[1:0] spi_miso;
+wire[1:0] spi_cs;
+SPI spi #(
+	.ID(8'h01)
+)(
+`ifdef USE_POWER_PINS
+	.vccd1(vccd1),	// User area 1 1.8V power
+	.vssd1(vssd1),	// User area 1 digital ground
+`endif
+
+    .clk(clk),
+    .rst(rst),
+	.peripheralBus_we(peripheralBus_we),
+	.peripheralBus_oe(peripheralBus_oe),
+	.peripheralBus_busy(peripheralBus_busy),
+	.peripheralBus_address(peripheralBus_address),
+	.peripheralBus_data(peripheralBus_data),
+	.spi_en(spi_en),
+	.spi_clk(spi_clk),
+	.spi_mosi(spi_mosi),
+	.spi_miso(spi_miso),
+	.spi_cs(spi_cs)
+);
+
+wire[15:0] pwm_en;
+wire[15:0] pwm_out;
+PWM pwm #(
+	.ID(8'h02)
+)(
+`ifdef USE_POWER_PINS
+	.vccd1(vccd1),	// User area 1 1.8V power
+	.vssd1(vssd1),	// User area 1 digital ground
+`endif
+
+    .clk(clk),
+    .rst(rst),
+	.peripheralBus_we(peripheralBus_we),
+	.peripheralBus_oe(peripheralBus_oe),
+	.peripheralBus_busy(peripheralBus_busy),
+	.peripheralBus_address(peripheralBus_address),
+	.peripheralBus_data(peripheralBus_data),
+	.pwm_out(pwm_en),
+	.pwm_out(pwm_out)
+);
+
+wire[`MPRJ_IO_PADS_1-1:0] gpio0_input;
+wire[`MPRJ_IO_PADS_1-1:0] gpio0_output;
+wire[`MPRJ_IO_PADS_1-1:0] gpio0_oe;
+wire[`MPRJ_IO_PADS_2-1:0] gpio1_input;
+wire[`MPRJ_IO_PADS_2-1:0] gpio1_output;
+wire[`MPRJ_IO_PADS_2-1:0] gpio1_oe;
+GPIO gpio #(
+	.ID(8'h03)
+)(
+`ifdef USE_POWER_PINS
+	.vccd1(vccd1),	// User area 1 1.8V power
+	.vssd1(vssd1),	// User area 1 digital ground
+`endif
+
+    .clk(clk),
+    .rst(rst),
+	.peripheralBus_we(peripheralBus_we),
+	.peripheralBus_oe(peripheralBus_oe),
+	.peripheralBus_busy(peripheralBus_busy),
+	.peripheralBus_address(peripheralBus_address),
+	.peripheralBus_data(peripheralBus_data),
+	.gpio0_input(gpio0_input),
+	.gpio0_output(gpio0_output),
+	.gpio0_oe(gpio0_oe),
+	.gpio1_input(gpio1_input),
+	.gpio1_output(gpio1_output),
+	.gpio1_oe(gpio1_oe)
+);
+
+IOMultiplexer ioMux(
+`ifdef USE_POWER_PINS
+	.vccd1(vccd1),	// User area 1 1.8V power
+	.vssd1(vssd1),	// User area 1 digital ground
+`endif
+
+    .clk(clk),
+    .rst(rst),
+	.uart_en(uart_en),
+	.uart_rx(uart_rx),
+	.uart_tx(uart_tx),
+	.spi_en(spi_en),
+	.spi_clk(spi_clk),
+	.spi_mosi(spi_mosi),
+	.spi_miso(spi_miso),
+	.spi_cs(spi_cs),
+	.pwm_en(pwm_en),
+	.pwm_out(pwm_out),
+	.gpio0_input(gpio0_input),
+	.gpio0_output(gpio0_output),
+	.gpio0_oe(gpio0_oe),
+	.gpio1_input(gpio1_input),
+	.gpio1_output(gpio1_output),
+	.gpio1_oe(gpio1_oe),
+    .io_in(io_in),
+    .io_out(io_out),
+    .io_oeb(io_oeb),
+	.la_blink(la_blink)
+);
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/Peripherals/SPI/SPIDevice.v b/verilog/rtl/Peripherals/SPI/SPIDevice.v
new file mode 100644
index 0000000..3529757
--- /dev/null
+++ b/verilog/rtl/Peripherals/SPI/SPIDevice.v
@@ -0,0 +1,207 @@
+module SPIDevice #(
+		parameter ID = 4'h0,
+		parameter WIDTH = 8,
+		parameter CLOCK_WIDTH = 8
+	)(
+		input wire clk,
+		input wire rst,
+
+		// Peripheral bus
+		input wire peripheralEnable,
+		input wire peripheralBus_we,
+		input wire peripheralBus_oe,
+		output wire peripheralBus_busy,
+		input wire[15:0] peripheralBus_address,
+		inout wire[31:0] peripheralBus_data,
+
+		// SPI interface
+		output wire spi_en,
+		output wire spi_clk,
+		output wire spi_mosi,
+		input  wire spi_miso,
+		output wire spi_cs
+	);
+
+	localparam WIDTH_BITS = $clog2(WIDTH);
+	localparam CLOCK_BITS = $clog2(CLOCK_WIDTH);
+
+	localparam STATE_IDLE  = 2'b00;
+	localparam STATE_SETUP = 2'b01;
+	localparam STATE_SHIFT = 2'b10;
+	localparam STATE_END   = 2'b11;
+
+	// Device select
+	wire[11:0] localAddress;
+	wire deviceEnable;
+	DeviceSelect #(.ID(ID)) select(
+		.peripheralEnable(peripheralEnable),
+		.peripheralBus_address(peripheralBus_address),
+		.localAddress(localAddress),
+		.deviceEnable(deviceEnable));
+
+	// Register
+	// Configuration register 	Default 0x64
+	// b00-b02: clockScale 		Default 0x4
+	// b03-04: spiMode 			Default 0x0
+	// b05: msbFirst 			Default 0x1
+	// b06: useCS 				Default 0x1
+	// b07: activeHighCS		Default 0x0
+	wire[7:0] configuration;
+	ConfigurationRegister #(.WIDTH(8), .ADDRESS(12'h000), .DEFAULT(8'h64)) configurationRegister(
+		.clk(clk),
+		.rst(rst),
+		.enable(deviceEnable),
+		.peripheralBus_we(peripheralBus_we),
+		.peripheralBus_oe(peripheralBus_oe),
+		.peripheralBus_address(localAddress),
+		.peripheralBus_data(peripheralBus_data),
+		.currentValue(configuration));
+
+	// Input and Output register
+	wire[WIDTH-1:0] readData;
+	wire[WIDTH-1:0] writeData;
+	wire writeData_en;
+	DataRegister #(.WIDTH(WIDTH), .ADDRESS(12'h004)) dataRegister(
+		.clk(clk),
+		.rst(rst),
+		.enable(deviceEnable),
+		.peripheralBus_we(peripheralBus_we),
+		.peripheralBus_oe(peripheralBus_oe),
+		.peripheralBus_busy(peripheralBus_busy),
+		.peripheralBus_address(localAddress),
+		.peripheralBus_data(peripheralBus_data),
+		.writeData(writeData),
+		.writeData_en(writeData_en),
+		.writeData_busy(),
+		.readData(readData),
+		.readData_en(),
+		.readData_busy());
+
+	wire[2:0] clockScale = configuration[2:0];
+	wire[1:0] spiMode = configuration[4:3];
+	wire msbFirst = configuration[5];
+	wire useCS = configuration[6];
+	wire activeHighCS = configuration[7];
+	wire spiClockPolarity = spiMode[1];
+	wire spiSampleMode = spiMode[0];
+
+	// State control
+	reg[1:0] state = STATE_IDLE;
+	wire busy = state != STATE_IDLE;
+	
+	reg[WIDTH_BITS-1:0] bitCounter = 'b0;
+	wire[WIDTH_BITS-1:0] nextBitCounter = bitCounter + 1;
+
+	reg[CLOCK_WIDTH-1:0] clockCounter = 'b0;
+	wire nextClockCounter = clockCounter + 1;
+	wire[CLOCK_WIDTH-1:0] clockScaleHalfMask = CLOCK_BITS'b1 << clockScale;
+	wire[CLOCK_WIDTH-1:0] clockScaleMask 	 = { clockScaleMask[CLOCK_WIDTH-2:0], 1'b0 };
+	wire spiHalfClock = clockCounter == (clockScaleHalfMask - 1);//|(clockCounter & clockScaleHalfMask);
+	wire spiClock 	  = clockCounter == (clockScaleMask - 1);
+
+	reg spiClockRise = 1'b0;
+	reg spiClockFall = 1'b0;
+
+	wire shiftInEnable  = spiSampleMode ? spiClockFall : spiClockRise;
+	wire shiftOutEnable = spiSampleMode ? spiClockRise : spiClockFall;
+
+	reg loadEnable;
+	ShiftRegister #(.WIDTH(WIDTH)) register (
+		.clk(clk),
+		.rst(rst),
+		.loadEnable(loadEnable),
+		.shiftInEnable(shiftInEnable),
+		.shiftOutEnable(shiftOutEnable),
+		.msbFirst(msbFirst),
+		.parallelIn(writeData),
+		.parallelOut(readData),
+		.serialIn(spi_miso),
+		.serialOut(spi_mosi));
+
+	always @(posedge clk) begin
+		if (rst) begin
+			state <= STATE_IDLE;
+			bitCounter <= 'b0;
+			clockCounter <= 1'b0;
+			loadEnable <= 1'b0;
+			spiClockRise <= 1'b0;
+			spiClockFall <= 1'b0;
+		end else begin
+			case (state)
+				STATE_IDLE: begin
+					bitCounter <= 'b0;
+					clockCounter <= 1'b0;
+					loadEnable <= 1'b0;
+
+					if (writeData_en) begin 
+						state <= STATE_SETUP;
+						loadEnable <= 1'b1;
+					end
+				end
+
+				STATE_SETUP: begin
+					loadEnable <= 1'b0;
+
+					if (spiHalfClock) begin
+						clockCounter <= 1'b0;
+						bitCounter <= 1'b0;
+						state <= STATE_SHIFT;
+					end else begin
+						clockCounter <= nextClockCounter;
+					end
+				end
+
+				STATE_SHIFT: begin
+					if (spiClock) begin
+						if (spiClockPolarity) begin
+							spiClockRise <= 1'b0;
+							spiClockFall <= 1'b1;
+						end else begin
+							spiClockRise <= 1'b1;
+							spiClockFall <= 1'b0;
+						end
+
+						clockCounter <= 1'b0;
+						if (bitCounter == (WIDTH_BITS - 1)) state <= STATE_END;
+						else bitCounter <= nextBitCounter;
+					end else if (spiHalfClock) begin
+						if (spiClockPolarity) begin
+							spiClockRise <= 1'b1;
+							spiClockFall <= 1'b0;
+						end else begin
+							spiClockRise <= 1'b0;
+							spiClockFall <= 1'b1;
+						end
+						
+					end else begin
+						spiClockRise <= 1'b0;
+						spiClockFall <= 1'b0;
+						clockCounter <= nextClockCounter;
+					end
+				end
+
+				STATE_END: begin
+					spiClockRise <= 1'b0;
+					spiClockFall <= 1'b0;
+					
+					if (spiClock) state <= STATE_IDLE;
+					else clockCounter <= nextClockCounter;
+				end
+
+				default: begin
+					state <= STATE_IDLE;
+					bitCounter <= 'b0;
+					clockCounter <= 1'b0;
+					loadEnable <= 1'b0;
+					spiClockRise <= 1'b0;
+					spiClockFall <= 1'b0;
+				end
+			endcase
+		end
+	end
+
+	assign peripheralBus_busy = busy;
+	assign spi_clk = spiClockPolarity ? !(spiClock && busy) : spiClock && busy;
+	assign spi_cs = useCS ? (activeHighCS ? busy : !busy) : 1'b0;
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/UART/UART_Buffer.v b/verilog/rtl/Peripherals/UART/UART_Buffer.v
similarity index 100%
rename from verilog/rtl/UART/UART_Buffer.v
rename to verilog/rtl/Peripherals/UART/UART_Buffer.v
diff --git a/verilog/rtl/UART/UART_rx.v b/verilog/rtl/Peripherals/UART/UART_rx.v
similarity index 100%
rename from verilog/rtl/UART/UART_rx.v
rename to verilog/rtl/Peripherals/UART/UART_rx.v
diff --git a/verilog/rtl/Peripherals/UART/UART_top.v b/verilog/rtl/Peripherals/UART/UART_top.v
new file mode 100644
index 0000000..39ca2fb
--- /dev/null
+++ b/verilog/rtl/Peripherals/UART/UART_top.v
@@ -0,0 +1,24 @@
+module UART #(
+		parameter ID = 8'h00
+	)(
+`ifdef USE_POWER_PINS
+		inout vccd1,	// User area 1 1.8V supply
+		inout vssd1,	// User area 1 digital ground
+`endif
+
+		input wire clk,
+		input wire rst,
+		
+		// Peripheral Bus
+		input wire peripheralBus_we,
+		input wire peripheralBus_oe,
+		output wire peripheralBus_busy,
+		input wire[23:0] peripheralBus_address,
+		inout wire[31:0] peripheralBus_data,
+
+		output wire[3:0] uart_en,	
+		output wire[3:0] uart_rx,
+		output wire[3:0] uart_tx
+	);
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/UART/UART_tx.v b/verilog/rtl/Peripherals/UART/UART_tx.v
similarity index 100%
rename from verilog/rtl/UART/UART_tx.v
rename to verilog/rtl/Peripherals/UART/UART_tx.v
diff --git a/verilog/rtl/Peripherals/WBPeripheralBusInterface/WBPeripheralBusInterface_top.v b/verilog/rtl/Peripherals/WBPeripheralBusInterface/WBPeripheralBusInterface_top.v
new file mode 100644
index 0000000..70e3a3c
--- /dev/null
+++ b/verilog/rtl/Peripherals/WBPeripheralBusInterface/WBPeripheralBusInterface_top.v
@@ -0,0 +1,32 @@
+module WBPeripheralBusInterface #(
+		parameter ID = 4'h1
+	)(
+`ifdef USE_POWER_PINS
+		inout vccd1,	// User area 1 1.8V supply
+		inout vssd1,	// User area 1 digital ground
+`endif
+
+		input wire clk,
+		input wire rst,
+
+		// Wishbone Slave ports
+		input wire wb_clk,
+		input wire wb_rst,
+		input wire wb_stb,
+		input wire wb_cyc,
+		input wire wb_we,
+		input wire[3:0] wb_sel,
+		input wire[31:0] wb_dataIn,
+		input wire[31:0] wb_address,
+		output wire wb_ack,
+		output wire[31:0] wb_dataOut,
+
+		// Peripheral Bus
+		output wire peripheralBus_we,
+		output wire peripheralBus_oe,
+		input wire peripheralBus_busy,
+		output wire[23:0] peripheralBus_address,
+		inout wire[31:0] peripheralBus_data
+	);
+	
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/UART/UART_top.v b/verilog/rtl/UART/UART_top.v
deleted file mode 100644
index e69de29..0000000
--- a/verilog/rtl/UART/UART_top.v
+++ /dev/null