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