initial commit
diff --git a/verilog/dv/dummy_slave.v b/verilog/dv/dummy_slave.v
new file mode 100644
index 0000000..857ce0e
--- /dev/null
+++ b/verilog/dv/dummy_slave.v
@@ -0,0 +1,33 @@
+module dummy_slave(
+    input wb_clk_i,
+    input wb_rst_i,
+    
+    input wb_stb_i,
+    input wb_cyc_i,
+    input wb_we_i,
+    input [3:0] wb_sel_i,
+    input [31:0] wb_adr_i,
+    input [31:0] wb_dat_i,
+    
+    output reg [31:0] wb_dat_o,
+    output reg wb_ack_o
+);
+    reg [31:0] store;
+
+    wire valid = wb_cyc_i & wb_stb_i;
+
+    always @(posedge wb_clk_i) begin
+        if (wb_rst_i == 1'b 1) begin
+            wb_ack_o <= 1'b 0;
+        end else begin
+            if (wb_we_i == 1'b 1) begin
+                if (wb_sel_i[0]) store[7:0]   <= wb_dat_i[7:0];
+                if (wb_sel_i[1]) store[15:8]  <= wb_dat_i[15:8];
+                if (wb_sel_i[2]) store[23:16] <= wb_dat_i[23:16];
+                if (wb_sel_i[3]) store[31:24] <= wb_dat_i[31:24];
+            end
+            wb_dat_o <= store;
+            wb_ack_o <= valid & !wb_ack_o;
+        end
+    end
+endmodule
\ No newline at end of file
diff --git a/verilog/dv/harness/mgmt_soc/Makefile b/verilog/dv/harness/mgmt_soc/Makefile
new file mode 100644
index 0000000..c934af3
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/Makefile
@@ -0,0 +1,18 @@
+# ---- Test patterns for project striVe ----
+
+.SUFFIXES:
+.SILENT: clean all
+
+PATTERNS = gpio mem uart perf hkspi sysctrl xbar
+
+all:  ${PATTERNS}
+	for i in ${PATTERNS}; do \
+		( cd $$i && make -f Makefile $${i}.vcd &> verify.log && grep Monitor verify.log) ; \
+	done
+
+clean:  ${PATTERNS}
+	for i in ${PATTERNS}; do \
+		( cd $$i && make clean ) ; \
+	done
+
+.PHONY: clean all
diff --git a/verilog/dv/harness/mgmt_soc/defs.h b/verilog/dv/harness/mgmt_soc/defs.h
new file mode 100644
index 0000000..e2d777f
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/defs.h
@@ -0,0 +1,96 @@
+#ifndef _STRIVE_H_
+#define _STRIVE_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+// a pointer to this is a null pointer, but the compiler does not
+// know that because "sram" is a linker symbol from sections.lds.
+extern uint32_t sram;
+
+// Pointer to firmware flash routines
+extern uint32_t flashio_worker_begin;
+extern uint32_t flashio_worker_end;
+
+// IOs: UART (0x2000_0000), GPIO (0x2100_0000), LA (0x2200_0000)
+#define reg_uart_clkdiv (*(volatile uint32_t*)0x20000000)
+#define reg_uart_data   (*(volatile uint32_t*)0x20000004)
+
+#define reg_gpio_data (*(volatile uint32_t*)0x21000000)
+#define reg_gpio_ena  (*(volatile uint32_t*)0x21000004)
+#define reg_gpio_pu   (*(volatile uint32_t*)0x21000008)
+#define reg_gpio_pd   (*(volatile uint32_t*)0x2100000c)
+
+#define reg_la0_data (*(volatile uint32_t*)0x22000000)
+#define reg_la1_data (*(volatile uint32_t*)0x22000004)
+#define reg_la2_data (*(volatile uint32_t*)0x22000008)
+#define reg_la3_data (*(volatile uint32_t*)0x2200000c)
+
+#define reg_la0_ena (*(volatile uint32_t*)0x22000010)
+#define reg_la1_ena (*(volatile uint32_t*)0x22000014)
+#define reg_la2_ena (*(volatile uint32_t*)0x22000018)
+#define reg_la3_ena (*(volatile uint32_t*)0x2200001c)
+
+// Flash Control SPI Configuration (2D00_0000)
+#define reg_spictrl (*(volatile uint32_t*)0x2D000000)         
+
+// House-Keeping SPI Read-Only Registers (0x2E00_0000)
+#define reg_spi_config     (*(volatile uint32_t*)0x2E000000)
+#define reg_spi_enables    (*(volatile uint32_t*)0x2E000004)
+#define reg_spi_pll_config (*(volatile uint32_t*)0x2E000008)
+#define reg_spi_mfgr_id    (*(volatile uint32_t*)0x2E00000c)
+#define reg_spi_prod_id    (*(volatile uint32_t*)0x2E000010)
+#define reg_spi_mask_rev   (*(volatile uint32_t*)0x2E000014)
+#define reg_spi_pll_bypass (*(volatile uint32_t*)0x2E000018)
+
+// System Area (0x2F00_0000)
+#define reg_rcosc_enable   (*(volatile uint32_t*)0x2F000000)
+#define reg_rcosc_out_dest (*(volatile uint32_t*)0x2F000004)
+
+#define reg_xtal_out_dest (*(volatile uint32_t*)0x2F000008)
+#define reg_pll_out_dest  (*(volatile uint32_t*)0x2F00000c)
+#define reg_trap_out_dest (*(volatile uint32_t*)0x2F000010)
+
+#define reg_irq7_source (*(volatile uint32_t*)0x2F000014)
+#define reg_irq8_source (*(volatile uint32_t*)0x2F000018)
+
+#define reg_overtemp_ena      (*(volatile uint32_t*)0x2F00001c)
+#define reg_overtemp_data     (*(volatile uint32_t*)0x2F000020)
+#define reg_overtemp_out_dest (*(volatile uint32_t*)0x2F000024)
+
+// Crosbbar Slave Addresses (0x8000_0000 - 0xB000_0000)
+#define qspi_ctrl_slave    (*(volatile uint32_t*)0x80000000)
+#define storage_area_slave (*(volatile uint32_t*)0x90000000)
+#define mega_any_slave1    (*(volatile uint32_t*)0xA0000000)
+#define mega_any_slave2    (*(volatile uint32_t*)0xB0000000)
+
+// #define reg_adc0_ena (*(volatile uint32_t*)0x21000010)
+// #define reg_adc0_data (*(volatile uint32_t*)0x21000014)
+// #define reg_adc0_done (*(volatile uint32_t*)0x21000018)
+// #define reg_adc0_convert (*(volatile uint32_t*)0x2100001c)
+// #define reg_adc0_clk_source (*(volatile uint32_t*)0x21000020)
+// #define reg_adc0_input_source (*(volatile uint32_t*)0x21000024)
+
+// #define reg_adc1_ena (*(volatile uint32_t*)0x21000030)
+// #define reg_adc1_data (*(volatile uint32_t*)0x21000034)
+// #define reg_adc1_done (*(volatile uint32_t*)0x21000038)
+// #define reg_adc1_convert (*(volatile uint32_t*)0x2100003c)
+// #define reg_adc1_clk_source (*(volatile uint32_t*)0x21000040)
+// #define reg_adc1_input_source (*(volatile uint32_t*)0x21000044)
+
+// #define reg_dac_ena (*(volatile uint32_t*)0x21000050)
+// #define reg_dac_data (*(volatile uint32_t*)0x21000054)
+
+// #define reg_comp_enable (*(volatile uint32_t*)0x21000060)
+// #define reg_comp_n_source (*(volatile uint32_t*)0x21000064)
+// #define reg_comp_p_source (*(volatile uint32_t*)0x21000068)
+// #define reg_comp_out_dest (*(volatile uint32_t*)0x2100006c)
+
+// #define reg_analog_out_sel (*(volatile uint32_t*)0x210000c0)
+// #define reg_analog_out_bias_ena (*(volatile uint32_t*)0x210000c4)
+// #define reg_analog_out_ena (*(volatile uint32_t*)0x210000c8)
+
+// #define reg_bandgap_ena (*(volatile uint32_t*)0x210000d0)
+
+// --------------------------------------------------------
+#endif
diff --git a/verilog/dv/harness/mgmt_soc/gpio/Makefile b/verilog/dv/harness/mgmt_soc/gpio/Makefile
new file mode 100644
index 0000000..e9253c0
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/gpio/Makefile
@@ -0,0 +1,33 @@
+.SUFFIXES:
+
+PATTERN = gpio
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+	iverilog -I ../ -I ../../../../ip -I ../../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c ../sections.lds ../start.s
+	/ef/apps/bin/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,../sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ ../start.s $<
+
+%.hex: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O verilog $< $@ 
+	# to fix flash base address
+	sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
+
diff --git a/verilog/dv/harness/mgmt_soc/gpio/gpio.c b/verilog/dv/harness/mgmt_soc/gpio/gpio.c
new file mode 100644
index 0000000..17a4885
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/gpio/gpio.c
@@ -0,0 +1,39 @@
+#include "../defs.h"
+
+// --------------------------------------------------------
+
+/*
+	GPIO Test
+		Tests PU and PD on the lower 8 pins while being driven from outside
+		Tests Writing to the upper 8 pins
+		Tests reading from the lower 8 pins
+*/
+void main()
+{
+	int i;
+
+	/* Lower 8 pins are input and upper 8 pins are o/p */
+	reg_gpio_data = 0;
+	reg_gpio_ena =  0x00ff;
+
+	// change the pull up and pull down (checked by the TB)
+	reg_gpio_data = 0xA000;
+	reg_gpio_pu = 0x000f;
+	reg_gpio_pd = 0x00f0;
+
+	reg_gpio_data = 0x0B00;
+	reg_gpio_pu = 0x00f0;
+	reg_gpio_pd = 0x000f;
+
+	reg_gpio_pu = 0x000f;
+	reg_gpio_pd = 0x00f0;
+
+	// read the lower 8 pins, add 1 then o/p the result
+	// checked by the TB
+	reg_gpio_data = 0xAB00;
+	while (1){
+		int x = reg_gpio_data & 0xff;
+		reg_gpio_data = (x+1) << 8;
+	}
+}
+
diff --git a/verilog/dv/harness/mgmt_soc/gpio/gpio_tb.v b/verilog/dv/harness/mgmt_soc/gpio/gpio_tb.v
new file mode 100644
index 0000000..c20ba26
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/gpio/gpio_tb.v
@@ -0,0 +1,194 @@
+/*
+ *  StriVe - A full example SoC using PicoRV32 in SkyWater s8
+ *
+ *  Copyright (C) 2017  Clifford Wolf <clifford@clifford.at>
+ *  Copyright (C) 2018  Tim Edwards <tim@efabless.com>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+`timescale 1 ns / 1 ps
+
+`include "harness.v"
+`include "spiflash.v"
+
+module gpio_tb;
+	reg XCLK;
+
+	wire VDD3V3;
+	assign VDD3V3 = 1'b1;
+
+	reg XI;
+
+	reg real adc_h, adc_l;
+	reg real adc_0, adc_1;
+	reg real comp_n, comp_p;
+
+	// External clock is used by default.  Make this artificially fast for the
+	// simulation.  Normally this would be a slow clock and the digital PLL
+	// would be the fast clock.
+
+	always #10 XCLK <= (XCLK === 1'b0);
+	always #220 XI <= (XI === 1'b0);
+
+	initial begin
+		XI = 0;
+		XCLK = 0;
+	end
+
+	initial begin
+		// Analog input pin values
+		adc_h = 0.0;
+		adc_l = 0.0;
+		adc_0 = 0.0;
+		adc_1 = 0.0;
+		comp_n = 0.0;
+		comp_p = 0.0;
+		#2000;
+		adc_h = 3.25;
+		adc_l = 0.05;
+		adc_0 = 1.0;
+		adc_1 = 1.5;
+		comp_n = 2.0;
+		comp_p = 2.5;
+	end
+
+	initial begin
+		$dumpfile("gpio.vcd");
+		$dumpvars(0, gpio_tb);
+
+		// Repeat cycles of 1000 XCLK edges as needed to complete testbench
+		repeat (25) begin
+			repeat (1000) @(posedge XCLK);
+			$display("+1000 cycles");
+		end
+		$display("%c[1;31m",27);
+		$display ("Monitor: Timeout, Test GPIO (RTL) Failed");
+		 $display("%c[0m",27);
+		$finish;
+	end
+
+	wire [15:0] gpio;
+
+	reg [7:0] gpio_lo;
+	wire [7:0] gpio_hi;
+
+	assign gpio[7:0] = gpio_lo;
+	assign gpio_hi = gpio[15:8];
+
+	wire flash_csb;
+	wire flash_clk;
+	wire flash_io0;
+	wire flash_io1;
+	wire flash_io2;
+	wire flash_io3;
+
+	reg SDI, CSB, SCK, RSTB;
+	wire SDO;
+
+	// Transactor
+	initial begin
+		gpio_lo = {8{1'bz}};
+		wait(gpio_hi==8'hA0);
+		gpio_lo = 8'hF0;
+		wait(gpio_hi==8'h0B);
+		gpio_lo = 8'h0F;
+		wait(gpio_hi==8'hAB);
+		gpio_lo = 8'h0;
+		repeat (1000) @(posedge XCLK);
+		gpio_lo = 8'h1;
+		repeat (1000) @(posedge XCLK);
+		gpio_lo = 8'h3;
+	end
+
+	// Monitor
+	initial begin
+		wait(gpio_hi==8'hA0);
+		wait(gpio[7:0]==8'hF0);
+		wait(gpio_hi==8'h0B);
+		wait(gpio[7:0]==8'h0F);
+		wait(gpio_hi==8'hAB);
+		wait(gpio[7:0]==8'h00);
+		wait(gpio_hi==8'h01);
+		wait(gpio[7:0]==8'h01);
+		wait(gpio_hi==8'h02);
+		wait(gpio[7:0]==8'h03);
+		wait(gpio_hi==8'h04);
+		$display("Monitor: Test GPIO (RTL) Passed");
+		$finish;
+	end
+
+	initial begin
+		CSB <= 1'b1;
+		SCK <= 1'b0;
+		SDI <= 1'b0;
+		RSTB <= 1'b0;
+		
+		#1000;
+		RSTB <= 1'b1;	    // Release reset
+		#2000;
+		CSB <= 1'b0;	    // Apply CSB to start transmission
+	end
+
+	always @(gpio) begin
+		#1 $display("GPIO state = %b (%d - %d)", gpio, gpio_hi, gpio_lo);
+	end
+
+	wire VDD1V8;
+	wire VSS;
+
+	assign VSS = 1'b0;
+	assign VDD1V8 = 1'b1;
+
+	harness uut (
+		.vdd	  (VDD3V3),
+		.vdd1v8	  (VDD1V8),
+		.vss	  (VSS),
+		.xi	  	  (XI),
+		.xclk	  (XCLK),
+		.SDI	  (SDI),
+		.SDO	  (SDO),
+		.CSB	  (CSB),
+		.SCK	  (SCK),
+		.ser_rx	  (1'b0),
+		.ser_tx	  (),
+		.irq	  (1'b0),
+		.gpio     (gpio),
+		.flash_csb(flash_csb),
+		.flash_clk(flash_clk),
+		.flash_io0(flash_io0),
+		.flash_io1(flash_io1),
+		.flash_io2(flash_io2),
+		.flash_io3(flash_io3),
+		.adc_high (adc_h),
+		.adc_low  (adc_l),
+		.adc0_in  (adc_0),
+		.adc1_in  (adc_1),
+		.RSTB	  (RSTB),
+		.comp_inp (comp_p),
+		.comp_inn (comp_n)
+	);
+
+	spiflash #(
+		.FILENAME("gpio.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(flash_io2),
+		.io3(flash_io3)
+	);
+
+endmodule
diff --git a/verilog/dv/harness/mgmt_soc/hkspi/Makefile b/verilog/dv/harness/mgmt_soc/hkspi/Makefile
new file mode 100644
index 0000000..2850baa
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/hkspi/Makefile
@@ -0,0 +1,31 @@
+.SUFFIXES:
+
+PATTERN = hkspi
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+	iverilog -I ../ -I ../../../../ip -I ../../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c ../sections.lds ../start.s
+	/ef/apps/bin/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,../sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ ../start.s $<
+
+%.hex: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O verilog $< /dev/stdout | sed -e '1 s/@10000000/@00000000/; 2,65537 d;' > $@
+
+%.bin: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
+
diff --git a/verilog/dv/harness/mgmt_soc/hkspi/hkspi.c b/verilog/dv/harness/mgmt_soc/hkspi/hkspi.c
new file mode 100644
index 0000000..d572727
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/hkspi/hkspi.c
@@ -0,0 +1,38 @@
+#include "../defs.h"
+
+// --------------------------------------------------------
+
+void putchar(char c)
+{
+	if (c == '\n')
+		putchar('\r');
+	reg_uart_data = c;
+}
+
+void print(const char *p)
+{
+	while (*p)
+		putchar(*(p++));
+}
+
+// --------------------------------------------------------
+
+void main()
+{
+	// Set clock to 64 kbaud
+	reg_uart_clkdiv = 625;
+
+	// NOTE: Crystal is running in simulation at 5MHz
+	// Internal clock is 8x crystal, or 40MHz
+	// Divided by clkdiv is 64 kHz
+	// So at this crystal rate, use clkdiv = 4167 for 9600 baud.
+
+	// This should appear at the output, received by the testbench UART.
+        print("\n");
+        print("  ____  _          ____         ____\n");
+        print(" |  _ \\(_) ___ ___/ ___|  ___  / ___|\n");
+        print(" | |_) | |/ __/ _ \\___ \\ / _ \\| |\n");
+        print(" |  __/| | (_| (_) |__) | (_) | |___\n");
+        print(" |_|   |_|\\___\\___/____/ \\___/ \\____|\n");
+}
+
diff --git a/verilog/dv/harness/mgmt_soc/hkspi/hkspi_tb.v b/verilog/dv/harness/mgmt_soc/hkspi/hkspi_tb.v
new file mode 100644
index 0000000..0edc43d
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/hkspi/hkspi_tb.v
@@ -0,0 +1,256 @@
+/*	
+	StriVe housekeeping SPI testbench.
+*/
+
+`timescale 1 ns / 1 ps
+
+`include "harness.v"
+`include "spiflash.v"
+`include "tbuart.v"
+
+module hkspi_tb;
+	reg XCLK;
+	reg XI;
+
+	reg real adc_h, adc_l;
+	reg real adc_0, adc_1;
+	reg real comp_n, comp_p;
+	reg SDI, CSB, SCK, RSTB;
+
+
+	wire [15:0] gpio;
+
+	wire flash_csb;
+	wire flash_clk;
+	wire flash_io0;
+	wire flash_io1;
+	wire flash_io2;
+	wire flash_io3;
+
+	wire SDO;
+
+	always #10 XCLK <= (XCLK === 1'b0);
+	always #220 XI <=  (XI === 1'b0);
+
+	initial begin
+		XI = 0;
+		XCLK = 0;
+	end
+
+	initial begin
+		// Analog input pin values (static)
+		adc_h = 0.0;
+		adc_l = 0.0;
+		adc_0 = 0.0;
+		adc_1 = 0.0;
+		comp_n = 0.0;
+		comp_p = 0.0;
+	end
+
+    // The main testbench is here.  Put the housekeeping SPI into
+    // pass-thru mode and read several bytes from the flash SPI.
+
+    // First define tasks for SPI functions
+
+	task start_csb;
+	    begin
+		SCK <= 1'b0;
+		SDI <= 1'b0;
+		CSB <= 1'b0;
+		#50;
+	    end
+	endtask
+
+	task end_csb;
+	    begin
+		SCK <= 1'b0;
+		SDI <= 1'b0;
+		CSB <= 1'b1;
+		#50;
+	    end
+	endtask
+
+	task write_byte;
+	    input [7:0] odata;
+	    begin
+		SCK <= 1'b0;
+		for (i=7; i >= 0; i--) begin
+		    #50;
+		    SDI <= odata[i];
+                    #50;
+		    SCK <= 1'b1;
+                    #100;
+		    SCK <= 1'b0;
+		end
+	    end
+	endtask
+
+	task read_byte;
+	    output [7:0] idata;
+	    begin
+		SCK <= 1'b0;
+		SDI <= 1'b0;
+		for (i=7; i >= 0; i--) begin
+		    #50;
+                    idata[i] = SDO;
+                    #50;
+		    SCK <= 1'b1;
+                    #100;
+		    SCK <= 1'b0;
+		end
+	    end
+	endtask
+
+	task read_write_byte
+	    (input [7:0] odata,
+	    output [7:0] idata);
+	    begin
+		SCK <= 1'b0;
+		for (i=7; i >= 0; i--) begin
+		    #50;
+		    SDI <= odata[i];
+                    idata[i] = SDO;
+                    #50;
+		    SCK <= 1'b1;
+                    #100;
+		    SCK <= 1'b0;
+		end
+	    end
+	endtask
+	
+	integer i;
+
+    // Now drive the digital signals on the housekeeping SPI
+	reg [7:0] tbdata;
+
+	initial begin
+	    $dumpfile("hkspi.vcd");
+	    $dumpvars(0, hkspi_tb);
+
+	    CSB <= 1'b1;
+	    SCK <= 1'b0;
+	    SDI <= 1'b0;
+	    RSTB <= 1'b0;
+
+	    // Delay, then bring chip out of reset
+	    #1000;
+	    RSTB <= 1'b1;
+	    #2000;
+
+        // First do a normal read from the housekeeping SPI to
+	    // make sure the housekeeping SPI works.
+
+		start_csb();
+		write_byte(8'h40);	// Read stream command
+		write_byte(8'h03);	// Address (register 3 = product ID)
+	    read_byte(tbdata);
+	    end_csb();
+	    #10;
+	    $display("Read data = 0x%02x (should be 0x05)", tbdata);
+
+	    // Toggle external reset
+		start_csb();
+		write_byte(8'h80);	// Write stream command
+		write_byte(8'h07);	// Address (register 7 = external reset)
+		write_byte(8'h01);	// Data = 0x01 (apply external reset)
+		end_csb();
+
+		start_csb();
+		write_byte(8'h80);	// Write stream command
+		write_byte(8'h07);	// Address (register 7 = external reset)
+		write_byte(8'h00);	// Data = 0x00 (release external reset)
+		end_csb();
+
+	    // Read all registers (0 to 8)
+		start_csb();
+		write_byte(8'h40);	// Read stream command
+		write_byte(8'h00);	// Address (register 3 = product ID)
+	    read_byte(tbdata);
+	    $display("Read register 0 = 0x%02x (should be 0x00)", tbdata);
+		if(tbdata != 8'h00) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read register 1 = 0x%02x (should be 0x04)", tbdata);
+		if(tbdata != 8'h14) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read register 2 = 0x%02x (should be 0x56)", tbdata);
+		if(tbdata != 8'h56) begin $display("Monitor: Test HK SPI (RTL) Failed, %02x", tbdata); $finish; end
+	    read_byte(tbdata);
+	    $display("Read register 3 = 0x%02x (should be 0x05)", tbdata);
+		if(tbdata != 8'h05) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read register 4 = 0x%02x (should be 0x07)", tbdata);
+		if(tbdata != 8'h07) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read register 5 = 0x%02x (should be 0x01)", tbdata);
+		if(tbdata != 8'h01) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read register 6 = 0x%02x (should be 0x00)", tbdata);
+		if(tbdata != 8'h00) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read register 7 = 0x%02x (should be 0x00)", tbdata);
+		if(tbdata != 8'h00) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read register 8 = 0x%02x (should be 0x00)", tbdata);
+		if(tbdata != 8'h00) begin $display("Monitor: Test HK SPI (RTL) Failed"); $finish; end
+		
+        end_csb();
+
+		$display("Monitor: Test HK SPI (RTL) Passed");
+
+	    #10000;
+ 	    $finish;
+	end
+
+	wire VDD3V3;
+	wire VDD1V8;
+	wire VSS;
+
+	assign VDD3V3 = 1'b1;
+	assign VSS = 1'b0;
+	assign VDD1V8 = 1'b1;
+
+	harness uut (
+		.vdd	  (VDD3V3),
+		.vdd1v8	  (VDD1V8),
+		.vss	  (VSS),
+		.xi	      (XI),
+		.xclk	  (XCLK),
+		.SDI	  (SDI),
+		.SDO	  (SDO),
+		.CSB	  (CSB),
+		.SCK	  (SCK),
+		.ser_rx	  (1'b0),
+		.ser_tx	  (tbuart_rx),
+		.irq	  (1'b0),
+		.gpio     (gpio),
+		.flash_csb(flash_csb),
+		.flash_clk(flash_clk),
+		.flash_io0(flash_io0),
+		.flash_io1(flash_io1),
+		.flash_io2(flash_io2),
+		.flash_io3(flash_io3),
+		.adc_high (adc_h),
+		.adc_low  (adc_l),
+		.adc0_in  (adc_0),
+		.adc1_in  (adc_1),
+		.RSTB	  (RSTB),
+		.comp_inp (comp_p),
+		.comp_inn (comp_n)
+	);
+
+	spiflash #(
+		.FILENAME("hkspi.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(flash_io2),
+		.io3(flash_io3)
+	);
+
+	tbuart tbuart (
+		.ser_rx(tbuart_rx)
+	);
+		
+endmodule
diff --git a/verilog/dv/harness/mgmt_soc/mem/Makefile b/verilog/dv/harness/mgmt_soc/mem/Makefile
new file mode 100644
index 0000000..d63df1b
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/mem/Makefile
@@ -0,0 +1,34 @@
+
+.SUFFIXES:
+
+PATTERN = mem
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+	iverilog -I ../ -I ../../../../ip -I ../../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c ../sections.lds ../start.s
+	/ef/apps/bin/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,../sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ ../start.s $<
+
+%.hex: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O verilog $< $@ 
+	# to fix flash base address
+	sed -i 's/@10000000/@00000000/g' $@                     
+
+%.bin: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
+
diff --git a/verilog/dv/harness/mgmt_soc/mem/mem.c b/verilog/dv/harness/mgmt_soc/mem/mem.c
new file mode 100644
index 0000000..0bff65d
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/mem/mem.c
@@ -0,0 +1,51 @@
+#include "../defs.h"
+
+// --------------------------------------------------------
+
+/*
+	Memory Test
+	It uses GPIO to flag the success or failure of the test
+*/
+unsigned int ints[10];
+unsigned short shorts[10];
+unsigned char bytes[10];
+
+void main()
+{
+	int i;
+
+	/* All GPIO pins are configured to be output */
+	reg_gpio_data = 0;
+	reg_gpio_ena =  0x0000;
+
+	// start test
+	reg_gpio_data = 0xA040;
+
+	// Test Word R/W
+	for(i=0; i<10; i++)
+		ints[i] = i*5000 + 10000;
+	
+	for(i=0; i<10; i++)
+		if((i*5000+10000) != ints[i]) reg_gpio_data = 0xAB40;
+	reg_gpio_data = 0xAB41;
+	
+	// Test Half Word R/W
+	reg_gpio_data = 0xA020;
+	for(i=0; i<10; i++)
+		shorts[i] = i*500 + 100;
+	
+	for(i=0; i<10; i++)
+		if((i*500+100) != shorts[i]) reg_gpio_data = 0xAB20;
+	reg_gpio_data = 0xAB21;
+
+	// Test byte R/W
+	reg_gpio_data = 0xA010;
+	for(i=0; i<10; i++)
+		bytes[i] = i*5 + 10;
+	
+	for(i=0; i<10; i++)
+		if((i*5+10) != bytes[i]) reg_gpio_data = 0xAB10;
+	reg_gpio_data = 0xAB11;
+
+}
+
diff --git a/verilog/dv/harness/mgmt_soc/mem/mem_tb.v b/verilog/dv/harness/mgmt_soc/mem/mem_tb.v
new file mode 100644
index 0000000..09bb0a7
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/mem/mem_tb.v
@@ -0,0 +1,189 @@
+/*
+ *  StriVe - A full example SoC using PicoRV32 in SkyWater s8
+ *
+ *  Copyright (C) 2017  Clifford Wolf <clifford@clifford.at>
+ *  Copyright (C) 2018  Tim Edwards <tim@efabless.com>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+`timescale 1 ns / 1 ps
+
+`include "harness.v"
+`include "spiflash.v"
+
+module mem_tb;
+	reg XCLK;
+	reg XI;
+
+	reg real adc_h, adc_l;
+	reg real adc_0, adc_1;
+	reg real comp_n, comp_p;
+	reg SDI, CSB, SCK, RSTB;
+
+	wire [15:0] gpio;
+	wire flash_csb;
+	wire flash_clk;
+	wire flash_io0;
+	wire flash_io1;
+	wire flash_io2;
+	wire flash_io3;
+	wire SDO;
+
+	// External clock is used by default.  Make this artificially fast for the
+	// simulation.  Normally this would be a slow clock and the digital PLL
+	// would be the fast clock.
+
+	always #10 XCLK <= (XCLK === 1'b0);
+	always #220 XI <= (XI === 1'b0);
+
+	initial begin
+		XI = 0;
+		XCLK = 0;
+	end
+
+	initial begin
+		// Analog input pin values
+		adc_h = 0.0;
+		adc_l = 0.0;
+		adc_0 = 0.0;
+		adc_1 = 0.0;
+		comp_n = 0.0;
+		comp_p = 0.0;
+		#2000;
+		adc_h = 3.25;
+		adc_l = 0.05;
+		adc_0 = 1.0;
+		adc_1 = 1.5;
+		comp_n = 2.0;
+		comp_p = 2.5;
+	end
+
+	initial begin
+		$dumpfile("mem.vcd");
+		$dumpvars(0, mem_tb);
+
+		// Repeat cycles of 1000 XCLK edges as needed to complete testbench
+		repeat (100) begin
+			repeat (1000) @(posedge XCLK);
+			//$display("+1000 cycles");
+		end
+		$display("%c[1;31m",27);
+		$display ("Monitor: Timeout, Test MEM (RTL) Failed");
+		$display("%c[0m",27);
+		$finish;
+	end
+
+	initial begin
+		CSB <= 1'b1;
+		SCK <= 1'b0;
+		SDI <= 1'b0;
+		RSTB <= 1'b0;
+		
+		#1000;
+		RSTB <= 1'b1;	    // Release reset
+		#2000;
+		CSB <= 1'b0;	    // Apply CSB to start transmission
+	end
+
+	always @(gpio) begin
+		if(gpio == 16'hA040) begin
+			$display("Mem Test (word rw) started");
+		end
+		else if(gpio == 16'hAB40) begin
+			$display("%c[1;31m",27);
+			$display("Monitor: Test MEM (RTL) [word rw] failed");
+			$display("%c[0m",27);
+			$finish;
+		end
+		else if(gpio == 16'hAB41) begin
+			$display("Monitor: Test MEM (RTL) [word rw]  passed");
+		end
+		else if(gpio == 16'hA020) begin
+			$display("Mem Test (short rw) started");
+		end
+		else if(gpio == 16'hAB20) begin
+			$display("%c[1;31m",27);
+			$display("Monitor: Test MEM (RTL) [short rw] failed");
+			$display("%c[0m",27);
+			$finish;
+		end
+		else if(gpio == 16'hAB21) begin
+			$display("Monitor: Test MEM (RTL) [short rw]  passed");
+		end
+		else if(gpio == 16'hA010) begin
+			$display("Mem Test (byte rw) started");
+		end
+		else if(gpio == 16'hAB10) begin
+			$display("%c[1;31m",27);
+			$display("Monitor: Test MEM (RTL) [byte rw] failed");
+			$display("%c[0m",27);
+			$finish;
+		end
+		else if(gpio == 16'hAB11) begin
+			$display("Monitor: Test MEM (RTL) [byte rw] passed");
+			$finish;
+		end
+
+	end
+
+	wire VDD3V3;
+	wire VDD1V8;
+	wire VSS;
+
+	assign VSS = 1'b0;
+	assign VDD3V3 = 1'b1;
+	assign VDD1V8 = 1'b1;
+
+	harness uut (
+		.vdd	  (VDD3V3),
+		.vdd1v8	  (VDD1V8),
+		.vss	  (VSS),
+		.xi	      (XI),
+		.xclk	  (XCLK),
+		.SDI	  (SDI),
+		.SDO	  (SDO),
+		.CSB	  (CSB),
+		.SCK	  (SCK),
+		.ser_rx	  (1'b0),
+		.ser_tx	  (),
+		.irq	  (1'b0),
+		.gpio     (gpio),
+		.flash_csb(flash_csb),
+		.flash_clk(flash_clk),
+		.flash_io0(flash_io0),
+		.flash_io1(flash_io1),
+		.flash_io2(flash_io2),
+		.flash_io3(flash_io3),
+		.adc_high (adc_h),
+		.adc_low  (adc_l),
+		.adc0_in  (adc_0),
+		.adc1_in  (adc_1),
+		.RSTB	  (RSTB),
+		.comp_inp (comp_p),
+		.comp_inn (comp_n)
+	);
+
+	spiflash #(
+		.FILENAME("mem.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(flash_io2),
+		.io3(flash_io3)
+	);
+
+endmodule
diff --git a/verilog/dv/harness/mgmt_soc/perf/Makefile b/verilog/dv/harness/mgmt_soc/perf/Makefile
new file mode 100644
index 0000000..dad371f
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/perf/Makefile
@@ -0,0 +1,34 @@
+.SUFFIXES:
+
+PATTERN = perf
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+	iverilog -I ../ -I ../../../../ip -I ../../../../rtl \
+	$< -o $@
+	
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c ../sections.lds ../start.s
+	/ef/apps/bin/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,../sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ ../start.s $<
+
+%.hex: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O verilog $< $@
+	# to fix flash base address
+	sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
+
diff --git a/verilog/dv/harness/mgmt_soc/perf/perf.c b/verilog/dv/harness/mgmt_soc/perf/perf.c
new file mode 100644
index 0000000..4dc34b1
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/perf/perf.c
@@ -0,0 +1,33 @@
+#include "../defs.h"
+
+// --------------------------------------------------------
+
+/*
+	Performance Test
+	It uses GPIO to flag the success or failure of the test
+*/
+unsigned int ints[50];
+unsigned short shorts[50];
+unsigned char bytes[50];
+
+int main()
+{
+	int i;
+    int sum = 0;
+
+	/* All GPIO pins are configured to be output */
+	reg_gpio_data = 0;
+	reg_gpio_ena =  0x0000;
+
+	// start test
+	reg_gpio_data = 0xA000;
+	
+    for(i=0; i<100; i++)
+        sum+=(sum + i);
+    
+    reg_gpio_data = 0xAB00;
+    
+    return sum;
+	
+}
+
diff --git a/verilog/dv/harness/mgmt_soc/perf/perf_tb.v b/verilog/dv/harness/mgmt_soc/perf/perf_tb.v
new file mode 100644
index 0000000..edd10ba
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/perf/perf_tb.v
@@ -0,0 +1,165 @@
+/*
+ *  StriVe - A full example SoC using PicoRV32 in SkyWater s8
+ *
+ *  Copyright (C) 2017  Clifford Wolf <clifford@clifford.at>
+ *  Copyright (C) 2018  Tim Edwards <tim@efabless.com>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+`timescale 1 ns / 1 ps
+
+`include "harness.v"
+`include "spiflash.v"
+
+module striVe_perf_tb;
+	reg XCLK;
+	reg XI;
+
+	reg real adc_h, adc_l;
+	reg real adc_0, adc_1;
+	reg real comp_n, comp_p;
+	reg SDI, CSB, SCK, RSTB;
+
+	wire [15:0] gpio;
+	wire flash_csb;
+	wire flash_clk;
+	wire flash_io0;
+	wire flash_io1;
+	wire flash_io2;
+	wire flash_io3;
+	wire SDO;
+
+	// External clock is used by default.  Make this artificially fast for the
+	// simulation.  Normally this would be a slow clock and the digital PLL
+	// would be the fast clock.
+
+	always #10 XCLK <= (XCLK === 1'b0);
+	always #220 XI <= (XI === 1'b0);
+
+	initial begin
+		XI = 0;
+		XCLK = 0;
+	end
+
+	initial begin
+		// Analog input pin values
+		adc_h = 0.0;
+		adc_l = 0.0;
+		adc_0 = 0.0;
+		adc_1 = 0.0;
+		comp_n = 0.0;
+		comp_p = 0.0;
+		#2000;
+		adc_h = 3.25;
+		adc_l = 0.05;
+		adc_0 = 1.0;
+		adc_1 = 1.5;
+		comp_n = 2.0;
+		comp_p = 2.5;
+	end
+
+	reg [31:0] kcycles;
+
+	initial begin
+		$dumpfile("striVe_perf.vcd");
+		$dumpvars(0, striVe_perf_tb);
+
+		kcycles = 0;
+		// Repeat cycles of 1000 XCLK edges as needed to complete testbench
+		repeat (150) begin
+			repeat (1000) @(posedge XCLK);
+			//$display("+1000 cycles");
+			kcycles<=kcycles+1;
+		end
+		$display("%c[1;31m",27);
+		$display ("Monitor: Timeout, Test Performance (RTL) Failed");
+		$display("%c[0m",27);
+		$finish;
+	end
+
+	initial begin
+		CSB <= 1'b1;
+		SCK <= 1'b0;
+		SDI <= 1'b0;
+		RSTB <= 1'b0;
+		
+		#1000;
+		RSTB <= 1'b1;	    // Release reset
+		#2000;
+		CSB <= 1'b0;	    // Apply CSB to start transmission
+	end
+
+	always @(gpio) begin
+		//#1 $display("GPIO state = %X ", gpio);
+		if(gpio == 16'hA000) begin
+			kcycles = 0;
+			$display("Performance Test started");
+		end
+		else if(gpio == 16'hAB00) begin
+			//$display("Monitor: number of cycles/100 iterations: %d KCycles", kcycles);
+			$display("Monitor: Test Performance (RTL) passed [%0d KCycles]", kcycles);
+			$finish;
+		end
+	end
+	
+	wire VDD3V3;
+	wire VDD1V8;
+	wire VSS;
+
+	assign VSS = 1'b0;
+	assign VDD1V8 = 1'b1;
+	assign VDD3V3 = 1'b1;
+
+	harness uut (
+		.vdd	  (VDD3V3  ),
+		.vdd1v8	  (VDD1V8),
+		.vss	  (VSS),
+		.xi	  (XI),
+		.xclk	  (XCLK),
+		.SDI	  (SDI),
+		.SDO	  (SDO),
+		.CSB	  (CSB),
+		.SCK	  (SCK),
+		.ser_rx	  (1'b0),
+		.ser_tx	  (	    ),
+		.irq	  (1'b0	    ),
+		.gpio     (gpio),
+		.flash_csb(flash_csb),
+		.flash_clk(flash_clk),
+		.flash_io0(flash_io0),
+		.flash_io1(flash_io1),
+		.flash_io2(flash_io2),
+		.flash_io3(flash_io3),
+		.adc_high (adc_h),
+		.adc_low  (adc_l),
+		.adc0_in  (adc_0),
+		.adc1_in  (adc_1),
+		.RSTB	  (RSTB),
+		.comp_inp (comp_p),
+		.comp_inn (comp_n)
+	);
+
+	spiflash #(
+		.FILENAME("perf.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(flash_io2),
+		.io3(flash_io3)
+	);
+
+endmodule
diff --git a/verilog/dv/harness/mgmt_soc/sections.lds b/verilog/dv/harness/mgmt_soc/sections.lds
new file mode 100644
index 0000000..4392c6d
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/sections.lds
@@ -0,0 +1,58 @@
+MEMORY {
+	FLASH (rx)	: ORIGIN = 0x10000000, LENGTH = 0x400000 	/* 4MB */
+	RAM(xrw)	: ORIGIN = 0x00000000, LENGTH = 0x400		/* 256 words ( 1024 ? ) */ 
+}
+
+SECTIONS {
+	/* The program code and other data goes into FLASH */
+	.text :
+	{
+		. = ALIGN(4);
+		*(.text)	/* .text sections (code) */
+		*(.text*)	/* .text* sections (code) */
+		*(.rodata)	/* .rodata sections (constants, strings, etc.) */
+		*(.rodata*)	/* .rodata* sections (constants, strings, etc.) */
+		*(.srodata)	/* .srodata sections (constants, strings, etc.) */
+		*(.srodata*)	/* .srodata*sections (constants, strings, etc.) */
+		. = ALIGN(4);
+		_etext = .;		/* define a global symbol at end of code */
+		_sidata = _etext;	/* This is used by the startup to initialize data */
+	} >FLASH
+
+	/* Initialized data section */
+	.data : AT ( _sidata )
+	{
+		. = ALIGN(4);
+		_sdata = .;
+		_ram_start = .;
+		. = ALIGN(4);
+		*(.data)
+		*(.data*)
+		*(.sdata)
+		*(.sdata*)
+		. = ALIGN(4);
+		_edata = .;
+	} >RAM
+
+	/* Uninitialized data section */
+	.bss :
+	{
+		. = ALIGN(4);
+		_sbss = .;
+		*(.bss)
+		*(.bss*)
+		*(.sbss)
+		*(.sbss*)
+		*(COMMON)
+
+		. = ALIGN(4);
+		_ebss = .;
+	} >RAM
+
+	/* Define the start of the heap */
+	.heap :
+	{
+		. = ALIGN(4);
+		_heap_start = .;
+	} >RAM
+}
diff --git a/verilog/rtl/spiflash.v b/verilog/dv/harness/mgmt_soc/spiflash.v
old mode 100755
new mode 100644
similarity index 100%
rename from verilog/rtl/spiflash.v
rename to verilog/dv/harness/mgmt_soc/spiflash.v
diff --git a/verilog/dv/harness/mgmt_soc/start.s b/verilog/dv/harness/mgmt_soc/start.s
new file mode 100644
index 0000000..62a6f42
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/start.s
@@ -0,0 +1,159 @@
+.section .text
+
+start:
+
+# zero-initialize register file
+addi x1, zero, 0
+# x2 (sp) is initialized by reset
+addi x3, zero, 0
+addi x4, zero, 0
+addi x5, zero, 0
+addi x6, zero, 0
+addi x7, zero, 0
+addi x8, zero, 0
+addi x9, zero, 0
+addi x10, zero, 0
+addi x11, zero, 0
+addi x12, zero, 0
+addi x13, zero, 0
+addi x14, zero, 0
+addi x15, zero, 0
+addi x16, zero, 0
+addi x17, zero, 0
+addi x18, zero, 0
+addi x19, zero, 0
+addi x20, zero, 0
+addi x21, zero, 0
+addi x22, zero, 0
+addi x23, zero, 0
+addi x24, zero, 0
+addi x25, zero, 0
+addi x26, zero, 0
+addi x27, zero, 0
+addi x28, zero, 0
+addi x29, zero, 0
+addi x30, zero, 0
+addi x31, zero, 0
+
+# zero initialize scratchpad memory
+# setmemloop:
+# sw zero, 0(x1)
+# addi x1, x1, 4
+# blt x1, sp, setmemloop
+
+# copy data section
+la a0, _sidata
+la a1, _sdata
+la a2, _edata
+bge a1, a2, end_init_data
+loop_init_data:
+lw a3, 0(a0)
+sw a3, 0(a1)
+addi a0, a0, 4
+addi a1, a1, 4
+blt a1, a2, loop_init_data
+end_init_data:
+
+# zero-init bss section
+la a0, _sbss
+la a1, _ebss
+bge a0, a1, end_init_bss
+loop_init_bss:
+sw zero, 0(a0)
+addi a0, a0, 4
+blt a0, a1, loop_init_bss
+end_init_bss:
+
+# call main
+call main
+loop:
+j loop
+
+.global flashio_worker_begin
+.global flashio_worker_end
+
+.balign 4
+
+flashio_worker_begin:
+# a0 ... data pointer
+# a1 ... data length
+# a2 ... optional WREN cmd (0 = disable)
+
+# address of SPI ctrl reg
+li   t0, 0x28000000
+
+# Set CS high, IO0 is output
+li   t1, 0x120
+sh   t1, 0(t0)
+
+# Enable Manual SPI Ctrl
+sb   zero, 3(t0)
+
+# Send optional WREN cmd
+beqz a2, flashio_worker_L1
+li   t5, 8
+andi t2, a2, 0xff
+flashio_worker_L4:
+srli t4, t2, 7
+sb   t4, 0(t0)
+ori  t4, t4, 0x10
+sb   t4, 0(t0)
+slli t2, t2, 1
+andi t2, t2, 0xff
+addi t5, t5, -1
+bnez t5, flashio_worker_L4
+sb   t1, 0(t0)
+
+# SPI transfer
+flashio_worker_L1:
+
+# If byte count is zero, we're done
+beqz a1, flashio_worker_L3
+
+# Set t5 to count down 32 bits
+li   t5, 32
+# Load t2 from address a0 (4 bytes)
+lw   t2, 0(a0)
+
+flashio_worker_LY:
+# Set t6 to count down 8 bits
+li   t6, 8
+
+flashio_worker_L2:
+# Clock out the bit (msb first) on IO0 and read bit in from IO1
+srli t4, t2, 31
+sb   t4, 0(t0)
+ori  t4, t4, 0x10
+sb   t4, 0(t0)
+lbu  t4, 0(t0)
+andi t4, t4, 2
+srli t4, t4, 1
+slli t2, t2, 1
+or   t2, t2, t4
+
+# Decrement 32 bit count
+addi t5, t5, -1
+bnez t5, flashio_worker_LX
+
+sw   t2, 0(a0)
+addi a0, a0, 4
+lw   t2, 0(a0)
+
+flashio_worker_LX:
+addi t6, t6, -1
+bnez t6, flashio_worker_L2
+addi a1, a1, -1
+bnez a1, flashio_worker_LY
+
+beqz t5, flashio_worker_L3
+sw   t2, 0(a0)
+
+flashio_worker_L3:
+# Back to MEMIO mode
+li   t1, 0x80
+sb   t1, 3(t0)
+
+ret
+.balign 4
+flashio_worker_end:
+
diff --git a/verilog/dv/harness/mgmt_soc/sysctrl/Makefile b/verilog/dv/harness/mgmt_soc/sysctrl/Makefile
new file mode 100644
index 0000000..0b43365
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/sysctrl/Makefile
@@ -0,0 +1,33 @@
+.SUFFIXES:
+
+PATTERN = sysctrl
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+	iverilog -I ../ -I ../../../../ip -I ../../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c ../sections.lds ../start.s
+	/ef/apps/bin/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,../sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ ../start.s $<
+
+%.hex: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O verilog $< $@ 
+	# to fix flash base address
+	sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
+
diff --git a/verilog/dv/harness/mgmt_soc/sysctrl/sysctrl.c b/verilog/dv/harness/mgmt_soc/sysctrl/sysctrl.c
new file mode 100644
index 0000000..a4a6762
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/sysctrl/sysctrl.c
@@ -0,0 +1,43 @@
+#include "../defs.h"
+
+// --------------------------------------------------------
+
+/*
+	System Control Test
+        - Reads default value of SPI-Controlled registers
+        - Flags failure/success using gpio
+*/
+void main()
+{
+	int i;
+
+    reg_gpio_data = 0;
+	reg_gpio_ena =  0x0000;
+
+	// start test
+	reg_gpio_data = 0xA040;
+
+    // Read Product ID value
+    if(0x05 != reg_spi_prod_id) reg_gpio_data = 0xAB40;
+	reg_gpio_data = 0xAB41;
+
+    // Read Manufacturer ID value
+    if(0x456 != reg_spi_mfgr_id) reg_gpio_data = 0xAB50;
+	reg_gpio_data = 0xAB51;
+
+    // Read Mask revision 
+    if(0x1 != reg_spi_mask_rev) reg_gpio_data = 0xAB60;
+	reg_gpio_data = 0xAB61;
+
+    // Read PLL-Bypass
+    if(0x1 != reg_spi_pll_bypass) reg_gpio_data = 0xAB70;
+	reg_gpio_data = 0xAB71;
+
+    if(0x7FFDFFF != reg_spi_pll_config) reg_gpio_data = 0xAB80;
+	reg_gpio_data = 0xAB81;
+
+    // Read spi enables
+    if(0x83 != reg_spi_enables) reg_gpio_data = 0xAB90;
+	reg_gpio_data = 0xAB91;
+}
+
diff --git a/verilog/dv/harness/mgmt_soc/sysctrl/sysctrl_tb.v b/verilog/dv/harness/mgmt_soc/sysctrl/sysctrl_tb.v
new file mode 100644
index 0000000..d1e4439
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/sysctrl/sysctrl_tb.v
@@ -0,0 +1,170 @@
+
+`timescale 1 ns / 1 ps
+
+`include "harness.v"
+`include "spiflash.v"
+
+module sysctrl_tb;
+	reg XCLK;
+	reg XI;
+
+	reg real adc_h, adc_l;
+	reg real adc_0, adc_1;
+	reg real comp_n, comp_p;
+	reg SDI, CSB, SCK, RSTB;
+
+	wire [15:0] gpio;
+	wire flash_csb;
+	wire flash_clk;
+	wire flash_io0;
+	wire flash_io1;
+	wire flash_io2;
+	wire flash_io3;
+	wire SDO;
+
+	// External clock is used by default.  Make this artificially fast for the
+	// simulation.  Normally this would be a slow clock and the digital PLL
+	// would be the fast clock.
+
+	always #10 XCLK <= (XCLK === 1'b0);
+	always #220 XI <= (XI === 1'b0);
+
+	initial begin
+		XI = 0;
+		XCLK = 0;
+	end
+
+	initial begin
+		$dumpfile("sysctrl_tb.vcd");
+		$dumpvars(0, sysctrl_tb);
+		repeat (25) begin
+			repeat (1000) @(posedge XCLK);
+			$display("+1000 cycles");
+		end
+		$display("%c[1;31m",27);
+		$display ("Monitor: Timeout, Test GPIO (RTL) Failed");
+		 $display("%c[0m",27);
+		$finish;
+	end
+
+	always @(gpio) begin
+		if(gpio == 16'hA040) begin
+			$display("System control Test started");
+		end
+		else if(gpio == 16'hAB40) begin
+			$display("%c[1;31m",27);
+			$display("Monitor: System control (RTL) Test failed");
+			$display("%c[0m",27);
+			$finish;
+		end
+		else if(gpio == 16'hAB41) begin
+			$display("Monitor: System control product ID read passed");
+		end
+        else if(gpio == 16'hAB50) begin
+            $display("%c[1;31m",27);
+			$display("Monitor: System control manufacture ID read failed");
+			$display("%c[0m",27);
+			$finish;
+        end else if(gpio == 16'hAB51) begin
+			$display("Monitor: System control manufacture ID read passed");
+        end
+        else if(gpio == 16'hAB60) begin
+            $display("%c[1;31m",27);
+			$display("Monitor: System control mask rev read failed");
+			$display("%c[0m",27);
+			$finish;
+        end else if(gpio == 16'hAB61) begin
+			$display("Monitor: System control mask rev read passed");
+        end
+        else if(gpio == 16'hAB70) begin
+            $display("%c[1;31m",27);
+			$display("Monitor: System control pll-bypass read failed");
+			$display("%c[0m",27);
+			$finish;
+        end else if(gpio == 16'hAB71) begin
+			$display("Monitor: System control pll-bypass read passed");
+        end
+        else if(gpio == 16'hAB80) begin
+            $display("%c[1;31m",27);
+			$display("Monitor: System control pll-config read failed");
+			$display("%c[0m",27);
+			$finish;
+        end else if(gpio == 16'hAB81) begin
+			$display("Monitor: System control pll-config read passed");
+        end
+        else if(gpio == 16'hAB90) begin
+            $display("%c[1;31m",27);
+			$display("Monitor: System control spi-enables read failed");
+			$display("%c[0m",27);
+			$finish;
+        end else if(gpio == 16'hAB91) begin
+			$display("Monitor: System control spi-enables read passed");
+			$display("Monitor: Sysctrl (RTL) test passed.");
+            $finish;
+        end
+	end
+
+	initial begin
+		CSB <= 1'b1;
+		SCK <= 1'b0;
+		SDI <= 1'b0;
+		RSTB <= 1'b0;
+		#1000;
+		RSTB <= 1'b1;	    // Release reset
+		#2000;
+		CSB <= 1'b0;	    // Apply CSB to start transmission
+	end
+
+	always @(gpio) begin
+		#1 $display("GPIO state = %b ", gpio);
+	end
+
+	wire VDD3V3;
+	wire VDD1V8;
+	wire VSS;
+	
+	assign VSS = 1'b0;
+	assign VDD1V8 = 1'b1;
+	assign VDD3V3 = 1'b1;
+
+	harness uut (
+		.vdd	  (VDD3V3),
+		.vdd1v8	  (VDD1V8),
+		.vss	  (VSS),
+		.xi	      (XI),
+		.xclk	  (XCLK),
+		.SDI	  (SDI),
+		.SDO	  (SDO),
+		.CSB	  (CSB),
+		.SCK	  (SCK),
+		.ser_rx	  (1'b0),
+		.ser_tx	  (),
+		.irq	  (1'b0),
+		.gpio     (gpio),
+		.flash_csb(flash_csb),
+		.flash_clk(flash_clk),
+		.flash_io0(flash_io0),
+		.flash_io1(flash_io1),
+		.flash_io2(flash_io2),
+		.flash_io3(flash_io3),
+		.adc_high (adc_h),
+		.adc_low  (adc_l),
+		.adc0_in  (adc_0),
+		.adc1_in  (adc_1),
+		.RSTB	  (RSTB),
+		.comp_inp (comp_p),
+		.comp_inn (comp_n)
+	);
+
+	spiflash #(
+		.FILENAME("sysctrl.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(flash_io2),
+		.io3(flash_io3)
+	);
+
+endmodule
diff --git a/verilog/dv/harness/mgmt_soc/tbuart.v b/verilog/dv/harness/mgmt_soc/tbuart.v
new file mode 100644
index 0000000..97c4283
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/tbuart.v
@@ -0,0 +1,89 @@
+/*
+ *  PicoSoC - A simple example SoC using PicoRV32
+ *
+ *  Copyright (C) 2017  Clifford Wolf <clifford@clifford.at>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+`timescale 1 ns / 1 ps
+
+/* tbuart --- mimic an external UART display, operating at 9600 baud	*/
+/* and accepting ASCII characters for display.				*/
+
+/* To do:  Match a known UART 3.3V 16x2 LCD display.  However, it	*/
+/* should be possible on a testing system to interface to the UART	*/
+/* pins on a Raspberry Pi, also running at 3.3V.			*/
+
+module tbuart (
+	input  ser_rx
+);
+	reg [3:0] recv_state;
+	reg [2:0] recv_divcnt;
+	reg [7:0] recv_pattern;
+	reg [8*50-1:0] recv_buf_data;	// 50 characters.  Increase as needed for tests.
+
+	reg clk;
+
+	initial begin
+		clk <= 1'b0;
+		recv_state <= 0;
+		recv_divcnt <= 0;
+		recv_pattern <= 0;
+		recv_buf_data <= 0;
+	end
+
+	// NOTE:  Running at 3.0us clock period @ 5 clocks per bit = 15.0us per
+	// bit ~= 64 kbaud. Not tuned to any particular UART.  Most run at
+	// 9600 baud default and will bounce up to higher baud rates when
+	// passed specific command words.
+
+	always #1500 clk <= (clk === 1'b0);
+
+	always @(posedge clk) begin
+		recv_divcnt <= recv_divcnt + 1;
+		case (recv_state)
+			0: begin
+				if (!ser_rx)
+					recv_state <= 1;
+				recv_divcnt <= 0;
+			end
+			1: begin
+				if (2*recv_divcnt > 3'd3) begin
+					recv_state <= 2;
+					recv_divcnt <= 0;
+				end
+			end
+			10: begin
+				if (recv_divcnt > 3'd3) begin
+					// 0x0a = '\n'
+					if (recv_pattern == 8'h0a) begin
+						$display("output: %s", recv_buf_data);
+					end else begin
+						recv_buf_data <= {recv_buf_data, recv_pattern};
+					end
+					recv_state <= 0;
+				end
+			end
+			default: begin
+				if (recv_divcnt > 3'd3) begin
+					recv_pattern <= {ser_rx, recv_pattern[7:1]};
+					recv_state <= recv_state + 1;
+					recv_divcnt <= 0;
+				end
+			end
+		endcase
+	end
+
+endmodule
diff --git a/verilog/dv/harness/mgmt_soc/uart/Makefile b/verilog/dv/harness/mgmt_soc/uart/Makefile
new file mode 100644
index 0000000..057be64
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/uart/Makefile
@@ -0,0 +1,35 @@
+# ---- Test patterns for project striVe ----
+
+.SUFFIXES:
+
+PATTERN = uart
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+	iverilog -I ../ -I ../../../../ip -I ../../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c ../sections.lds ../start.s
+	/ef/apps/bin/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,../sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ ../start.s $<
+
+%.hex: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O verilog $< $@
+	# to fix flash base address
+	sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
+
diff --git a/verilog/dv/harness/mgmt_soc/uart/uart.c b/verilog/dv/harness/mgmt_soc/uart/uart.c
new file mode 100644
index 0000000..fe362f8
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/uart/uart.c
@@ -0,0 +1,41 @@
+#include "../defs.h"
+
+// --------------------------------------------------------
+
+void putchar(char c)
+{
+	if (c == '\n')
+		putchar('\r');
+	reg_uart_data = c;
+}
+
+void print(const char *p)
+{
+	while (*p)
+		putchar(*(p++));
+}
+
+// --------------------------------------------------------
+
+void main()
+{
+	// Set clock to 64 kbaud
+	reg_uart_clkdiv = 625;
+
+	// NOTE: XCLK is running in simulation at 40MHz
+	// Divided by clkdiv is 64 kHz
+	// So at this crystal rate, use clkdiv = 4167 for 9600 baud.
+
+	/* All GPIO pins are configured to be output */
+	reg_gpio_data = 0;
+	reg_gpio_ena =  0x0000;
+
+	// start test
+	reg_gpio_data = 0xA000;
+
+	// This should appear at the output, received by the testbench UART.
+    print("\n");
+	print("Monitor: Test UART (RTL) passed\n\n");
+	reg_gpio_data = 0xAB00;
+}
+
diff --git a/verilog/dv/harness/mgmt_soc/uart/uart_tb.v b/verilog/dv/harness/mgmt_soc/uart/uart_tb.v
new file mode 100644
index 0000000..56c76f2
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/uart/uart_tb.v
@@ -0,0 +1,154 @@
+/*
+ *  StriVe - A full example SoC using PicoRV32 in SkyWater s8
+ *
+ *  Copyright (C) 2017  Clifford Wolf <clifford@clifford.at>
+ *  Copyright (C) 2018  Tim Edwards <tim@efabless.com>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+`timescale 1 ns / 1 ps
+
+`include "harness.v"
+`include "spiflash.v"
+`include "tbuart.v"
+
+module uart_tb;
+	reg XCLK;
+	reg XI;
+
+	reg real adc_h, adc_l;
+	reg real adc_0, adc_1;
+	reg real comp_n, comp_p;
+	reg SDI, CSB, SCK, RSTB;
+
+	wire [15:0] gpio;
+	wire flash_csb;
+	wire flash_clk;
+	wire flash_io0;
+	wire flash_io1;
+	wire flash_io2;
+	wire flash_io3;
+	wire SDO;
+
+	// External clock is used by default.  Make this artificially fast for the
+	// simulation.  Normally this would be a slow clock and the digital PLL
+	// would be the fast clock.
+
+	always #12.5 XCLK <= (XCLK === 1'b0);
+	always #220 XI <= (XI === 1'b0);
+
+	initial begin
+		XI = 0;
+		XCLK = 0;
+	end
+
+	initial begin
+		// Analog input pin values (static)
+		adc_h = 0.0;
+		adc_l = 0.0;
+		adc_0 = 0.0;
+		adc_1 = 0.0;
+		comp_n = 0.0;
+		comp_p = 0.0;
+	end
+
+	initial begin
+		$dumpfile("uart.vcd");
+		$dumpvars(0, uart_tb);
+
+		$display("Wait for UART o/p");
+		repeat (150) begin
+			repeat (10000) @(posedge XCLK);
+			// Diagnostic. . . interrupts output pattern.
+		end
+		$finish;
+	end
+
+	initial begin
+		CSB <= 1'b1;
+		SCK <= 1'b0;
+		SDI <= 1'b0;
+		RSTB <= 1'b0;
+		#1000;
+		RSTB <= 1'b1;	    // Release reset
+		#2000;
+		CSB <= 1'b0;
+	end
+
+	always @(gpio) begin
+		if(gpio == 16'hA000) begin
+			$display("UART Test started");
+		end
+		else if(gpio == 16'hAB00) begin
+			#1000;
+			$finish;
+		end
+	end
+
+	wire VDD3V3;
+	wire VDD1V8;
+	wire VSS;
+
+	assign VSS = 1'b0;
+	assign VDD1V8 = 1'b1;
+	assign VDD3V3 = 1'b1;
+
+	harness uut (
+		.vdd	  (VDD3V3),
+		.vdd1v8	  (VDD1V8),
+		.vss	  (VSS),
+		.xi	  	  (XI),
+		.xo	      (),
+		.xclk	  (XCLK),
+		.SDI	  (SDI),
+		.SDO	  (SDO),
+		.CSB	  (CSB),
+		.SCK	  (SCK),
+		.ser_rx	  (1'b0),
+		.ser_tx	  (tbuart_rx),
+		.irq	  (1'b0),
+		.gpio     (gpio),
+		.flash_csb(flash_csb),
+		.flash_clk(flash_clk),
+		.flash_io0(flash_io0),
+		.flash_io1(flash_io1),
+		.flash_io2(flash_io2),
+		.flash_io3(flash_io3),
+		.adc_high (adc_h),
+		.adc_low  (adc_l),
+		.adc0_in  (adc_0),
+		.adc1_in  (adc_1),
+		.RSTB	  (RSTB),
+		.comp_inp (comp_p),
+		.comp_inn (comp_n)
+	);
+
+	spiflash #(
+		.FILENAME("uart.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(flash_io2),
+		.io3(flash_io3)
+	);
+
+	// Testbench UART
+	tbuart tbuart (
+		.ser_rx(tbuart_rx)
+	);
+		
+endmodule
diff --git a/verilog/dv/harness/mgmt_soc/verify.log b/verilog/dv/harness/mgmt_soc/verify.log
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/verify.log
diff --git a/verilog/dv/harness/mgmt_soc/xbar/Makefile b/verilog/dv/harness/mgmt_soc/xbar/Makefile
new file mode 100644
index 0000000..5302d06
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/xbar/Makefile
@@ -0,0 +1,32 @@
+.SUFFIXES:
+
+PATTERN = xbar
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+	iverilog -I ../ -I ../../../../ip -I ../../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c ../sections.lds ../start.s
+	/ef/apps/bin/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,../sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ ../start.s $<
+
+%.hex: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O verilog $< $@
+	# to fix flash base address
+	sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+	/ef/apps/bin/riscv32-unknown-elf-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
diff --git a/verilog/dv/harness/mgmt_soc/xbar/xbar.c b/verilog/dv/harness/mgmt_soc/xbar/xbar.c
new file mode 100644
index 0000000..5565f1f
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/xbar/xbar.c
@@ -0,0 +1,41 @@
+#include "../defs.h"
+
+// --------------------------------------------------------
+
+/*
+	Crosbbar Switch Test
+        - Reads default value of SPI-Controlled registers
+        - Flags failure/success using gpio
+*/
+void main()
+{
+	int i;
+
+    reg_gpio_data = 0;
+	reg_gpio_ena =  0x0000;
+
+	// start test
+	reg_gpio_data = 0xA040;
+
+    // Write & Read from QSPI CTRL Slave
+    qspi_ctrl_slave = 0xA0A1; 
+    if(0xA0A1 != qspi_ctrl_slave) reg_gpio_data = 0xAB40;
+	reg_gpio_data = 0xAB41;
+
+    // Write & Read from storage area Slave
+    storage_area_slave = 0xB0B1; 
+    if(0xB0B1 != storage_area_slave) reg_gpio_data = 0xAB50;
+	reg_gpio_data = 0xAB51;
+
+    // Write & Read from Mega Project 1st slave
+    mega_any_slave1 = 0xC0C1; 
+    if(0xC0C1 != mega_any_slave1) reg_gpio_data = 0xAB60;
+	reg_gpio_data = 0xAB61;
+
+    // Write & Read from Mega Project 1st slave
+    mega_any_slave2 = 0xD0D1; 
+    if(0xD0D1 != mega_any_slave2) reg_gpio_data = 0xAB70;
+	reg_gpio_data = 0xAB71;
+
+}
+
diff --git a/verilog/dv/harness/mgmt_soc/xbar/xbar_tb.v b/verilog/dv/harness/mgmt_soc/xbar/xbar_tb.v
new file mode 100644
index 0000000..b9357f0
--- /dev/null
+++ b/verilog/dv/harness/mgmt_soc/xbar/xbar_tb.v
@@ -0,0 +1,150 @@
+
+`timescale 1 ns / 1 ps
+
+`include "harness.v"
+`include "spiflash.v"
+
+module xbar_tb;
+	reg XCLK;
+	reg XI;
+
+	reg real adc_h, adc_l;
+	reg real adc_0, adc_1;
+	reg real comp_n, comp_p;
+	reg SDI, CSB, SCK, RSTB;
+
+	wire [15:0] gpio;
+	wire flash_csb;
+	wire flash_clk;
+	wire flash_io0;
+	wire flash_io1;
+	wire flash_io2;
+	wire flash_io3;
+	wire SDO;
+
+	always #10 XCLK <= (XCLK === 1'b0);
+	always #220 XI <= (XI === 1'b0);
+
+	initial begin
+		XI = 0;
+		XCLK = 0;
+	end
+
+	initial begin
+		$dumpfile("xbar_tb.vcd");
+		$dumpvars(0, xbar_tb);
+		repeat (25) begin
+			repeat (1000) @(posedge XCLK);
+			$display("+1000 cycles");
+		end
+		$display("%c[1;31m",27);
+		$display ("Monitor: Timeout, Test Crossbar Switch (RTL) Failed");
+		 $display("%c[0m", 27);
+		$finish;
+	end
+
+	always @(gpio) begin
+		if(gpio == 16'hA040) begin
+			$display("Crossbar Switch Test started");
+		end
+		else if(gpio == 16'hAB40) begin
+			$display("%c[1;31m",27);
+			$display("Monitor: Crossbar test R/W from QSPI CTRL slave failed.");
+			$display("%c[0m",27);
+			$finish;
+		end
+		else if(gpio == 16'hAB41) begin
+			$display("Monitor: Crossbar test R/W from QSPI CTRL slave passed");
+		end
+        else if(gpio == 16'hAB50) begin
+            $display("%c[1;31m",27);
+			$display("Monitor: Crossbar test R/W from storage area failed.");
+			$display("%c[0m",27);
+			$finish;
+        end else if(gpio == 16'hAB51) begin
+			$display("Monitor: Crossbar test R/W from storage area passed.");
+        end
+        else if(gpio == 16'hAB60) begin
+            $display("%c[1;31m",27);
+			$display("Monitor: Crossbar test R/W from mega project 1st slave failed.");
+			$display("%c[0m",27);
+			$finish;
+        end else if(gpio == 16'hAB61) begin
+			$display("Monitor: Crossbar test R/W from mega project 1st slave passed.");
+        end
+        else if(gpio == 16'hAB70) begin
+            $display("%c[1;31m",27);
+			$display("Monitor: Crossbar test R/W from mega project 2nd slave passed.");
+			$display("%c[0m",27);
+			$finish;
+        end else if(gpio == 16'hAB71) begin
+			$display("Monitor: Crossbar test R/W from mega project 2nd slave passed.");
+		    $display("Monitor: Timeout, Test Crossbar Switch (RTL) Passed.");
+            $finish;
+        end
+	end
+
+	initial begin
+		CSB <= 1'b1;
+		SCK <= 1'b0;
+		SDI <= 1'b0;
+		RSTB <= 1'b0;
+		#1000;
+		RSTB <= 1'b1;	    // Release reset
+		#2000;
+		CSB <= 1'b0;	    // Apply CSB to start transmission
+	end
+
+	always @(gpio) begin
+		#1 $display("GPIO state = %b ", gpio);
+	end
+
+	wire VDD3V3;
+	wire VDD1V8;
+	wire VSS;
+	
+	assign VSS = 1'b0;
+	assign VDD1V8 = 1'b1;
+	assign VDD3V3 = 1'b1;
+
+	harness uut (
+		.vdd	  (VDD3V3),
+		.vdd1v8	  (VDD1V8),
+		.vss	  (VSS),
+		.xi	  (XI),
+		.xclk	  (XCLK),
+		.SDI	  (SDI),
+		.SDO	  (SDO),
+		.CSB	  (CSB),
+		.SCK	  (SCK),
+		.ser_rx	  (1'b0),
+		.ser_tx	  (),
+		.irq	  (1'b0),
+		.gpio     (gpio),
+		.flash_csb(flash_csb),
+		.flash_clk(flash_clk),
+		.flash_io0(flash_io0),
+		.flash_io1(flash_io1),
+		.flash_io2(flash_io2),
+		.flash_io3(flash_io3),
+		.adc_high (adc_h),
+		.adc_low  (adc_l),
+		.adc0_in  (adc_0),
+		.adc1_in  (adc_1),
+		.RSTB	  (RSTB),
+		.comp_inp (comp_p),
+		.comp_inn (comp_n)
+	);
+
+	spiflash #(
+		.FILENAME("xbar.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(flash_io2),
+		.io3(flash_io3)
+	);
+
+endmodule
diff --git a/verilog/dv/wb/Makefile b/verilog/dv/wb/Makefile
new file mode 100644
index 0000000..7b0e09b
--- /dev/null
+++ b/verilog/dv/wb/Makefile
@@ -0,0 +1,18 @@
+# ---- Test patterns for project striVe ----
+
+.SUFFIXES:
+.SILENT: clean all
+
+PATTERNS = gpio_wb intercon_wb  spimemio_wb uart_wb  crossbar_wb arbiter_wb
+
+all:  ${PATTERNS}
+	for i in ${PATTERNS}; do \
+		( cd $$i && make -f Makefile $${i}.vcd &> verify.log && grep Monitor verify.log) ; \
+	done
+
+clean:  ${PATTERNS}
+	for i in ${PATTERNS}; do \
+		( cd $$i && make clean ) ; \
+	done
+
+.PHONY: clean all
diff --git a/verilog/dv/wb/arbiter_wb/Makefile b/verilog/dv/wb/arbiter_wb/Makefile
new file mode 100644
index 0000000..e792a4d
--- /dev/null
+++ b/verilog/dv/wb/arbiter_wb/Makefile
@@ -0,0 +1,17 @@
+.SUFFIXES:
+
+PATTERN = arbiter_wb
+
+all:  ${PATTERN:=.vcd}
+
+%.vvp: %_tb.v
+	iverilog -I ../../../ip -I .. -I ../../ -I ../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+clean:
+	rm -f *.vvp *.vcd *.log
+
+.PHONY: clean all
diff --git a/verilog/dv/wb/arbiter_wb/arbiter_wb_tb.v b/verilog/dv/wb/arbiter_wb/arbiter_wb_tb.v
new file mode 100644
index 0000000..164d526
--- /dev/null
+++ b/verilog/dv/wb/arbiter_wb/arbiter_wb_tb.v
@@ -0,0 +1,232 @@
+
+`timescale 1 ns / 1 ps
+
+`include "arbiter.v"
+`include "dummy_slave.v"
+
+`ifndef AW
+`define AW 32
+`endif
+`ifndef DW
+`define DW 32
+`endif
+`ifndef NM
+`define NM 2
+`endif
+
+module arbiter_wb_tb;
+    
+    localparam SEL = `DW / 8;
+
+    reg wb_clk_i;
+    reg wb_rst_i;
+
+    // Masters Interface
+    reg [`NM-1:0] wbm_stb_i;
+    reg [`NM-1:0] wbm_cyc_i;
+    reg [`NM-1:0] wbm_we_i;
+    reg [`NM*SEL-1:0] wbm_sel_i;
+    reg [`NM*`DW-1:0] wbm_dat_i;
+    reg [`NM*`AW-1:0] wbm_adr_i;
+
+    wire [`NM-1:0] wbm_ack_o;
+    wire [`NM-1:0] wbm_err_o;
+    wire [`NM*`DW-1:0] wbm_dat_o;
+
+    // Slave Interface
+    reg  wbs_ack_i;
+    reg  wbs_err_i;               
+    wire [`DW-1:0] wbs_dat_i;      
+    wire wbs_stb_i;
+    wire wbs_cyc_i;           
+    wire wbs_we_i;    
+    wire [SEL-1:0] wbs_sel_i;      
+    wire [`AW-1:0] wbs_adr_i;   
+    wire [`DW-1:0] wbs_dat_o; 
+
+    wb_arbiter  #(
+        .AW(`AW),
+        .DW(`DW),
+        .NM(`NM)
+    ) uut (
+        .wb_clk_i(wb_clk_i),
+        .wb_rst_i(wb_rst_i),
+
+        // Masters Interface
+        .wbm_stb_i(wbm_stb_i),
+        .wbm_cyc_i(wbm_cyc_i),
+        .wbm_we_i(wbm_we_i),
+        .wbm_sel_i(wbm_sel_i),
+        .wbm_dat_i(wbm_dat_i),
+        .wbm_adr_i(wbm_adr_i),
+
+        .wbm_ack_o(wbm_ack_o),
+        .wbm_err_o(wbm_err_o),
+        .wbm_dat_o(wbm_dat_o),
+
+        // Slave Interface
+        .wbs_ack_i(wbs_ack_o), 
+        .wbs_err_i(wbs_err_o),               
+        .wbs_dat_i(wbs_dat_o),      
+        .wbs_stb_o(wbs_stb_i),   
+        .wbs_cyc_o(wbs_cyc_i),           
+        .wbs_we_o(wbs_we_i),     
+        .wbs_sel_o(wbs_sel_i),       
+        .wbs_adr_o(wbs_adr_i),   
+        .wbs_dat_o(wbs_dat_i)  
+    );
+    
+    // Instantiate one dummy slave for testing
+    dummy_slave dummy_slave (
+        .wb_clk_i(wb_clk_i),
+        .wb_rst_i(wb_rst_i),
+        .wb_stb_i(wbs_stb_i),
+        .wb_cyc_i(wbs_cyc_i),
+        .wb_we_i(wbs_we_i),
+        .wb_sel_i(wbs_sel_i),
+        .wb_adr_i(wbs_adr_i),
+        .wb_dat_i(wbs_dat_i),
+        .wb_dat_o(wbs_dat_o),
+        .wb_ack_o(wbs_ack_o)
+    );
+    
+    always #1 wb_clk_i = ~wb_clk_i;
+
+    initial begin
+        wb_clk_i  = 0;
+        wb_rst_i  = 0;
+        wbm_stb_i = 0;
+        wbm_cyc_i = 0;
+        wbm_we_i  = 0;
+        wbm_sel_i = 0;
+        wbm_dat_i = 0;
+        wbm_adr_i = 0;
+        wbs_ack_i = 0; 
+        wbs_err_i = 0;               
+    end
+
+    initial begin
+        $dumpfile("arbiter_wb_tb.vcd");
+        $dumpvars(0, arbiter_wb_tb);
+        repeat (50) begin
+            repeat (1000) @(posedge wb_clk_i);
+        end
+        $display("%c[1;31m",27);
+        $display ("Monitor: Timeout, Test Arbiter Failed");
+        $display("%c[0m",27);
+        $finish;
+    end
+
+
+    reg [`DW-1:0] data;
+    reg [`AW-1:0] address;
+
+    integer i;
+
+    initial begin
+        wb_rst_i = 1;
+        #2;
+        wb_rst_i = 0;
+        #2;
+
+        // Case 1: Initiate W/R requests from M0 -- MN
+        for (i=0; i<`NM; i=i+1) begin
+            data = $urandom_range(0, 255);
+            address = $urandom_range(0, 255);
+            write(address,data,i);
+            #2;
+            read(i);
+            if (wbm_dat_i[i*`DW +: `DW] !== data) begin
+                $display("Request Error from master %0b", i);
+                $finish;
+            end
+        end 
+
+        #10;
+
+        // Case 2: Initiate W/R requests from MN -- M0
+        for (i=`NM-1; i>=0; i=i-1) begin
+            data = $urandom_range(0, 255);
+            address = $urandom_range(0, 255);
+            write(address,data,i);
+            #2;
+            read(i);
+            if (wbm_dat_i[i*`DW +: `DW] !== data) begin
+                $display("Request Error from master %0b", i);
+                $finish;
+            end
+        end 
+
+        // Case 3: Initiate concurrent W/R requests from all masters
+        address = $urandom_range(0, 255);
+        wbm_stb_i = {`NM{1'b1}};
+        wbm_cyc_i = {`NM{1'b1}};
+        wbm_we_i  = {`NM{1'b1}};
+        wbm_sel_i = {`NM{4'hF}};
+        wbm_adr_i = {`NM{address}};
+        for (i=`NM-1; i>=0; i=i-1) begin
+            wbm_dat_i[i*`DW+: `DW] = $urandom_range(0, 2**32);
+        end
+
+        // Make sure that served request is master 0 (highest priority)      
+        wait(wbm_ack_o[0]);
+        if (wbm_ack_o[`NM-1:1] !== 0) begin
+          $display("Arbitration failed");
+          $finish;
+        end
+
+        // Read
+        wbm_we_i  = {`NM{1'b0}};
+        wait(wbm_ack_o[0]);
+       
+        // Make sure that the second master doesn't receive an ack
+        if (wbm_ack_o[`NM-1:1] !== 0) begin
+          $display("Arbitration failed");
+          $finish;
+        end        
+        #10;
+        $finish;
+    end
+
+    task read;
+        input mindex;
+        begin 
+            @(posedge wb_clk_i) begin
+                wbm_stb_i[mindex] = 1;
+                wbm_cyc_i[mindex] = 1;
+                wbm_we_i[mindex]  = 0;
+                $display("Read Cycle from master %0b started", mindex);
+            end
+            wait(wbm_ack_o[mindex]);
+            wait(!wbm_ack_o[mindex]);
+            wbm_stb_i[mindex] = 0;
+            wbm_cyc_i[mindex] = 0;
+            $display("Read Cycle from master %0b ended.", mindex);
+        end
+    endtask
+
+    task write;
+        input [`AW-1:0] adr;
+        input [`DW-1:0] data;
+        input integer mindex;
+
+        begin 
+            @(posedge wb_clk_i) begin
+                wbm_stb_i[mindex] = 1;
+                wbm_cyc_i[mindex] = 1;
+                wbm_we_i[mindex]  = 1;
+                wbm_sel_i[mindex*SEL+: SEL] = {SEL{1'b1}};
+                wbm_adr_i[mindex*`AW+: `AW] = adr;
+                wbm_dat_i[mindex*`DW+: `DW] = data;
+                $display("Write Cycle from master %0b started", mindex);
+            end
+           
+            wait(wbm_ack_o[mindex]);
+            wait(!wbm_ack_o[mindex]);
+            wbm_stb_i[mindex] = 0;
+            wbm_cyc_i[mindex] = 0;
+            $display("Write Cycle from master %0b ended.", mindex);
+        end
+    endtask
+
+endmodule
\ No newline at end of file
diff --git a/verilog/dv/wb/crossbar_wb/Makefile b/verilog/dv/wb/crossbar_wb/Makefile
new file mode 100644
index 0000000..fcd10cc
--- /dev/null
+++ b/verilog/dv/wb/crossbar_wb/Makefile
@@ -0,0 +1,17 @@
+.SUFFIXES:
+
+PATTERN = crossbar_wb
+
+all:  ${PATTERN:=.vcd}
+
+%.vvp: %_tb.v
+	iverilog  -I .. -I ../../ -I ../../../ip -I ../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+clean:
+	rm -f *.vvp *.vcd *.log
+
+.PHONY: clean all
diff --git a/verilog/dv/wb/crossbar_wb/crossbar_wb_tb.v b/verilog/dv/wb/crossbar_wb/crossbar_wb_tb.v
new file mode 100644
index 0000000..a9a35b4
--- /dev/null
+++ b/verilog/dv/wb/crossbar_wb/crossbar_wb_tb.v
@@ -0,0 +1,292 @@
+
+`timescale 1 ns / 1 ps
+
+`include "crossbar.v"
+`include "dummy_slave.v"
+
+`ifndef AW
+    `define AW 32
+`endif
+`ifndef DW
+    `define DW 32
+`endif
+`ifndef NM
+    `define NM 2
+`endif
+
+`ifndef NS
+    `define NS 4
+`endif
+
+`ifndef SLAVE_ADR
+    `define SLAVE_ADR { \
+        {8'hB0, {24{1'b0}}},\
+        {8'hA0, {24{1'b0}}},\
+        {8'h90, {24{1'b0}}},\
+        {8'h80, {24{1'b0}}}\
+    }\
+`endif
+
+`ifndef ADR_MASK
+    `define ADR_MASK { \
+        {8'hFF, {24{1'b0}}}, \
+        {8'hFF, {24{1'b0}}}, \
+        {8'hFF, {24{1'b0}}}, \
+        {8'hFF, {24{1'b0}}}  \
+    }\
+`endif
+
+module crossbar_wb_tb;
+
+    localparam SEL = `DW / 8;
+
+    reg wb_clk_i;           
+    reg wb_rst_i;     
+
+    // Masters interface
+    reg [`NM-1:0] wbm_cyc_i;       
+    reg [`NM-1:0] wbm_stb_i;       
+    reg [`NM-1:0] wbm_we_i;     
+    reg [(`NM*(`DW/8))-1:0] wbm_sel_i;     
+    reg [(`NM*`AW)-1:0] wbm_adr_i;        
+    reg [(`NM*`DW)-1:0] wbm_dat_i;       
+    wire [`NM-1:0] wbm_ack_o; 
+    wire [`NM-1:0] wbm_err_o;       
+    wire [(`NM*`DW)-1:0] wbm_dat_o;       
+
+    // Slaves interfaces
+    wire [`NS-1:0] wbs_ack_o;       
+    wire [(`NS*`DW)-1:0] wbs_dat_i;
+    wire [`NS-1:0] wbs_cyc_o;        
+    wire [`NS-1:0] wbs_stb_o;       
+    wire [`NS-1:0] wbs_we_o;        
+    wire [(`NS*(`DW/8))-1:0] wbs_sel_o;       
+    wire [(`NS*`AW)-1:0] wbs_adr_o;       
+    wire [(`NS*`DW)-1:0] wbs_dat_o;  
+    
+    wb_xbar #(
+        .NM(`NM),
+        .NS(`NS),
+        .AW(`AW),
+        .DW(`DW),
+        .SLAVE_ADR(`SLAVE_ADR),
+        .ADR_MASK(`ADR_MASK) 
+    )
+    wb_xbar(
+        .wb_clk_i(wb_clk_i),           
+        .wb_rst_i(wb_rst_i),     
+        // Masters interface
+        .wbm_cyc_i(wbm_cyc_i),       
+        .wbm_stb_i(wbm_stb_i),       
+        .wbm_we_i (wbm_we_i),     
+        .wbm_sel_i(wbm_sel_i),     
+        .wbm_adr_i(wbm_adr_i),        
+        .wbm_dat_i(wbm_dat_i),       
+        .wbm_ack_o(wbm_ack_o), 
+        .wbm_dat_o(wbm_dat_o),       
+        // Slaves interfaces
+        .wbs_ack_i(wbs_ack_o),       
+        .wbs_dat_i(wbs_dat_o),
+        .wbs_cyc_o(wbs_cyc_o),        
+        .wbs_stb_o(wbs_stb_o),       
+        .wbs_we_o(wbs_we_o),        
+        .wbs_sel_o(wbs_sel_o),       
+        .wbs_adr_o(wbs_adr_o),       
+        .wbs_dat_o(wbs_dat_i)     
+    );
+
+    // Instantiate four dummy slaves for testing
+    dummy_slave dummy_slaves [`NS-1:0](
+        .wb_clk_i({`NS{wb_clk_i}}),
+        .wb_rst_i({`NS{wb_rst_i}}),
+        .wb_stb_i(wbs_stb_o),
+        .wb_cyc_i(wbs_cyc_o),
+        .wb_we_i(wbs_we_o),
+        .wb_sel_i(wbs_sel_o),
+        .wb_adr_i(wbs_adr_o),
+        .wb_dat_i(wbs_dat_i),
+        .wb_dat_o(wbs_dat_o),
+        .wb_ack_o(wbs_ack_o)
+    );
+
+    initial begin
+        wb_clk_i  = 0;           
+        wb_rst_i  = 0;     
+        wbm_cyc_i = 0;       
+        wbm_stb_i = 0;       
+        wbm_we_i  = 0;     
+        wbm_sel_i = 0;     
+        wbm_adr_i = 0;        
+        wbm_dat_i = 0;  
+    end
+   
+    always #1 wb_clk_i = ~wb_clk_i;
+
+    initial begin
+        $dumpfile("crossbar_wb_tb.vcd");
+        $dumpvars(0, crossbar_wb_tb);
+        repeat (50) begin
+            repeat (1000) @(posedge wb_clk_i);
+        end
+        $display("%c[1;31m",27);
+        $display ("Monitor: Timeout, Test Crossbar Switch Failed");
+        $display("%c[0m",27);
+        $finish;
+    end
+
+    integer i;
+
+    reg [`AW*`NS-1:0] addresses = {
+        {8'hB0, {24{1'b0}}},
+        {8'hA0, {24{1'b0}}},
+        {8'h90, {24{1'b0}}},
+        {8'h80, {24{1'b0}}}
+    };
+
+    reg [`DW-1:0] m0_slave_data;
+    reg [`DW-1:0] m1_slave_data;
+    reg [`AW-1:0] slave_adr;
+
+    initial begin
+        wb_rst_i = 1;
+        #2;
+        wb_rst_i = 0;
+        #2;
+
+        // Case 1: Master0 addresses slave 0 and Master 2 Addresses slave 1
+        slave_adr = addresses[`AW-1:0];
+        m0_slave_data = $urandom_range(0, 2**(`DW-2));
+        write(slave_adr, m0_slave_data, 0);
+
+        #2;
+        read(slave_adr, 0);
+        if (wbm_dat_o[0*`DW+: `DW] !== m0_slave_data) begin
+            $display("Error reading from slave");
+            $finish;
+        end
+        
+        #10;
+        slave_adr = addresses[`AW*2-1:`AW*1];
+        m1_slave_data = $urandom_range(0, 2**(`DW-2));
+        write(slave_adr, m1_slave_data, 1);
+        #2;
+        read(slave_adr, 1);
+        #10;
+        if (wbm_dat_o[1*`DW+: `DW] !== m1_slave_data) begin
+            $display("Error reading from slave");
+            $finish;
+        end
+        #10;
+        // Case 2: Master0 addresses slave 0 and Master 2 Addresses slave 1 simultaenously
+        slave_adr = addresses[`AW-1:0];
+        m0_slave_data = $urandom_range(0, 2**(`DW-2));
+
+        wbm_stb_i[0] = 1;
+        wbm_cyc_i[0] = 1;
+        wbm_we_i [0]  = 1;
+        wbm_sel_i[0*SEL+: SEL] = {SEL{1'b1}};
+        wbm_adr_i[0*`AW+: `AW] = slave_adr;
+        wbm_dat_i[0*`DW+: `DW] = m0_slave_data;
+
+        slave_adr = addresses[`AW*2-1:`AW*1];
+        m1_slave_data = $urandom_range(0, 2**(`DW-2));
+
+        wbm_stb_i[1] = 1;
+        wbm_cyc_i[1] = 1;
+        wbm_we_i[1]  = 1;
+        wbm_sel_i[1*SEL+: SEL] = {SEL{1'b1}};
+        wbm_adr_i[1*`AW+: `AW] = slave_adr;
+        wbm_dat_i[1*`DW+: `DW] = m1_slave_data;
+
+        wait(wbm_ack_o[0] && wbm_ack_o[1]);
+        wait(!wbm_ack_o[0] && !wbm_ack_o[1]);
+        
+        // Read
+        wbm_we_i  = 2'b00;
+        wait(wbm_ack_o[0] && wbm_ack_o[1]);
+        wait(!wbm_ack_o[0] && !wbm_ack_o[1]);
+
+        if (wbm_dat_o[0*`DW+: `DW] !== m0_slave_data) begin
+            $display("Error reading from slave");
+            $finish;
+        end
+       
+        // Case 3: Master0 addresses slave 0 and Master 2 Addresses slave 1 simultaenously
+        slave_adr = addresses[`AW-1:0];
+        m0_slave_data = $urandom_range(0, 2**(`DW-2));
+
+        wbm_stb_i[0] = 1;
+        wbm_cyc_i[0] = 1;
+        wbm_we_i [0]  = 1;
+        wbm_sel_i[0*SEL+: SEL] = {SEL{1'b1}};
+        wbm_adr_i[0*`AW+: `AW] = slave_adr;
+        wbm_dat_i[0*`DW+: `DW] = m0_slave_data;
+
+        slave_adr = addresses[`AW-1:0];
+        m1_slave_data = $urandom_range(0, 2**(`DW-2));
+
+        wbm_stb_i[1] = 1;
+        wbm_cyc_i[1] = 1;
+        wbm_we_i [1]  = 1;
+        wbm_sel_i[1*SEL+: SEL] = {SEL{1'b1}};
+        wbm_adr_i[1*`AW+: `AW] = slave_adr;
+        wbm_dat_i[1*`DW+: `DW] = m1_slave_data;
+
+        wait(wbm_ack_o[0] && !wbm_ack_o[1]);
+        wait(!wbm_ack_o[0] && !wbm_ack_o[1]);
+        
+        // Read
+        wbm_we_i  = 2'b00;
+        wait(wbm_ack_o[0]);
+        wait(!wbm_ack_o[0]);
+        if (wbm_dat_o[0*`DW+: `DW] !== m0_slave_data) begin
+            $display("Error reading from slave");
+            $finish;
+        end
+
+        $finish;
+    end
+
+    task read;
+        input addr;
+        input mindex;
+        begin 
+            @(posedge wb_clk_i) begin
+                wbm_stb_i[mindex] = 1;
+                wbm_cyc_i[mindex] = 1;
+                wbm_we_i[mindex]  = 0;
+                $display("Read cycle from master %0b started", mindex);
+            end
+            wait(wbm_ack_o[mindex]);
+            wait(!wbm_ack_o[mindex]);
+            wbm_stb_i[mindex] = 0;
+            wbm_cyc_i[mindex] = 0;
+            $display("Read cycle from master %0b ended.", mindex);
+        end
+    endtask
+
+    task write;
+        input [`AW-1:0] adr;
+        input [`DW-1:0] data;
+        input integer mindex;
+
+        begin 
+            @(posedge wb_clk_i) begin
+                wbm_stb_i[mindex] = 1;
+                wbm_cyc_i[mindex] = 1;
+                wbm_we_i[mindex]  = 1;
+                wbm_sel_i[mindex*SEL+: SEL] = {SEL{1'b1}};
+                wbm_adr_i[mindex*`AW+: `AW] = adr;
+                wbm_dat_i[mindex*`DW+: `DW] = data;
+                $display("Write cycle from master %0b started", mindex);
+            end
+           
+            wait(wbm_ack_o[mindex]);
+            wait(!wbm_ack_o[mindex]);
+            wbm_stb_i[mindex] = 0;
+            wbm_cyc_i[mindex] = 0;
+            $display("Write cycle from master %0b ended.", mindex);
+        end
+    endtask
+
+endmodule
\ No newline at end of file
diff --git a/verilog/dv/wb/distributor/Makefile b/verilog/dv/wb/distributor/Makefile
new file mode 100644
index 0000000..f3a1273
--- /dev/null
+++ b/verilog/dv/wb/distributor/Makefile
@@ -0,0 +1,17 @@
+.SUFFIXES:
+
+PATTERN = distributor
+
+all:  ${PATTERN:=.vcd}
+
+%.vvp: %_tb.v
+	iverilog  -I .. -I ../../ -I ../../../ip -I ../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+clean:
+	rm -f *.vvp *.vcd *.log
+
+.PHONY: clean all
diff --git a/verilog/dv/wb/distributor/distributor_tb.v b/verilog/dv/wb/distributor/distributor_tb.v
new file mode 100644
index 0000000..ab8f929
--- /dev/null
+++ b/verilog/dv/wb/distributor/distributor_tb.v
@@ -0,0 +1,226 @@
+
+`timescale 1 ns / 1 ps
+
+`include "distributor.v"
+`include "dummy_slave.v"
+
+`ifndef AW
+    `define AW 32
+`endif
+`ifndef DW
+    `define DW 32
+`endif
+
+`ifndef NS
+    `define NS 4
+`endif
+
+`ifndef SLAVE_ADR
+    `define SLAVE_ADR { \
+        {8'hB0, {24{1'b0}}},\
+        {8'hA0, {24{1'b0}}},\
+        {8'h90, {24{1'b0}}},\
+        {8'h80, {24{1'b0}}}\
+    }\
+`endif
+
+`ifndef ADR_MASK
+    `define ADR_MASK { \
+        {8'hFF, {24{1'b0}}}, \
+        {8'hFF, {24{1'b0}}}, \
+        {8'hFF, {24{1'b0}}}, \
+        {8'hFF, {24{1'b0}}}  \
+    }\
+`endif
+
+module distributor_tb;
+
+    localparam SEL = `DW / 8;
+
+    reg wb_clk_i;           
+    reg wb_rst_i;     
+
+    // Masters interface
+    reg wbm_cyc_i;       
+    reg wbm_stb_i;       
+    reg wbm_we_i;     
+    reg [(`DW/8)-1:0] wbm_sel_i;     
+    reg [`AW-1:0] wbm_adr_i;        
+    reg [`DW-1:0] wbm_dat_i;       
+    wire wbm_ack_o; 
+    wire [`DW-1:0] wbm_dat_o;       
+
+    // Slaves interfaces
+    wire [`NS-1:0] wbs_ack_o;       
+    wire [(`NS*`DW)-1:0] wbs_dat_i;
+    wire [`NS-1:0] wbs_cyc_o;        
+    wire [`NS-1:0] wbs_stb_o;       
+    wire [`NS-1:0] wbs_we_o;        
+    wire [(`NS*(`DW/8))-1:0] wbs_sel_o;       
+    wire [(`NS*`AW)-1:0] wbs_adr_o;       
+    wire [(`NS*`DW)-1:0] wbs_dat_o;  
+    
+    distributor #(
+        .NS(`NS),
+        .AW(`AW),
+        .DW(`DW),
+        .ADR_MASK(`ADR_MASK),
+        .SLAVE_ADR(`SLAVE_ADR)
+    )
+    uut (
+        .wb_clk_i(wb_clk_i),           
+        .wb_rst_i(wb_rst_i),     
+        // Masters interface
+        .wbm_cyc_i(wbm_cyc_i),       
+        .wbm_stb_i(wbm_stb_i),       
+        .wbm_we_i (wbm_we_i),     
+        .wbm_sel_i(wbm_sel_i),     
+        .wbm_adr_i(wbm_adr_i),        
+        .wbm_dat_i(wbm_dat_i),       
+        .wbm_ack_o(wbm_ack_o), 
+        .wbm_dat_o(wbm_dat_o),
+
+        // Slaves interfaces
+        .wbs_ack_i(wbs_ack_o),       
+        .wbs_dat_i(wbs_dat_o),
+        .wbs_cyc_o(wbs_cyc_o),        
+        .wbs_stb_o(wbs_stb_o),       
+        .wbs_we_o(wbs_we_o),        
+        .wbs_sel_o(wbs_sel_o),       
+        .wbs_adr_o(wbs_adr_o),       
+        .wbs_dat_o(wbs_dat_i)     
+    );
+
+    // Instantiate four dummy slaves for testing
+    dummy_slave dummy_slaves [`NS-1:0](
+        .wb_clk_i({`NS{wb_clk_i}}),
+        .wb_rst_i({`NS{wb_rst_i}}),
+        .wb_stb_i(wbs_stb_o),
+        .wb_cyc_i(wbs_cyc_o),
+        .wb_we_i(wbs_we_o),
+        .wb_sel_i(wbs_sel_o),
+        .wb_adr_i(wbs_adr_o),
+        .wb_dat_i(wbs_dat_i),
+        .wb_dat_o(wbs_dat_o),
+        .wb_ack_o(wbs_ack_o)
+    );
+
+    initial begin
+        wb_clk_i  = 0;           
+        wb_rst_i  = 0;     
+        wbm_cyc_i = 0;       
+        wbm_stb_i = 0;       
+        wbm_we_i  = 0;     
+        wbm_sel_i = 0;     
+        wbm_adr_i = 0;        
+        wbm_dat_i = 0;  
+    end
+   
+    always #1 wb_clk_i = ~wb_clk_i;
+
+    initial begin
+        $dumpfile("distributor_tb.vcd");
+        $dumpvars(0, distributor_tb);
+        repeat (50) begin
+            repeat (1000) @(posedge wb_clk_i);
+        end
+        $display("%c[1;31m",27);
+        $display ("Monitor: Timeout, Test Distributor Failed");
+        $display("%c[0m",27);
+        $finish;
+    end
+
+    integer i;
+
+    reg [`DW-1:0] slave_data;
+    reg [`AW-1:0] slave_adr;
+
+    initial begin
+        wb_rst_i = 1;
+        #2;
+        wb_rst_i = 0;
+        #2;
+        
+        slave_adr = 32'h 8000_0000;
+        slave_data = $urandom_range(0, 2**(`DW-2));
+        write(slave_adr, slave_data);
+        #2;
+        read(slave_adr);
+        if (wbm_dat_i !== slave_data) begin
+          $display("Failed R/W from slave");
+        end
+        
+        #2;
+        slave_adr = 32'h 9000_0000;
+        slave_data = $urandom_range(0, 2**(`DW-2));
+        write(slave_adr, slave_data);
+        #2;
+        read(slave_adr);
+        if (wbm_dat_i !== slave_data) begin
+          $display("Failed R/W from slave");
+        end
+        #2;
+
+        slave_adr = 32'h A000_0000;
+        slave_data = $urandom_range(0, 2**(`DW-2));
+        write(slave_adr, slave_data);
+        #2;
+        read(slave_adr);
+        if (wbm_dat_i !== slave_data) begin
+          $display("Failed R/W from slave");
+        end
+        
+        #2;
+        slave_adr = 32'h B000_0000;
+        slave_data = $urandom_range(0, 2**(`DW-2));
+        write(slave_adr, slave_data);
+        #2;
+        read(slave_adr);
+        if (wbm_dat_i !== slave_data) begin
+          $display("Failed R/W from slave");
+        end
+
+
+        $finish;
+    end
+
+    task read;
+        input [`AW-1:0] addr;
+        begin 
+            @(posedge wb_clk_i) begin
+                wbm_stb_i = 1;
+                wbm_cyc_i = 1;
+                wbm_we_i  = 0;
+                wbm_adr_i = addr;
+                $display("Read Cycle Started");
+            end
+            wait(wbm_ack_o);
+            wait(!wbm_ack_o);
+            wbm_stb_i = 0;
+            wbm_cyc_i = 0;
+            $display("Read cycle Ended");
+        end
+    endtask
+
+    task write;
+        input [`AW-1:0] adr;
+        input [`DW-1:0] data;
+        begin 
+            @(posedge wb_clk_i) begin
+                wbm_stb_i = 1;
+                wbm_cyc_i = 1;
+                wbm_we_i  = 1;
+                wbm_sel_i = {SEL{1'b1}};
+                wbm_adr_i = adr;
+                wbm_dat_i = data;
+                $display("Write cycle started");
+            end
+            wait(wbm_ack_o);
+            wait(!wbm_ack_o);
+            wbm_stb_i = 0;
+            wbm_cyc_i = 0;
+            $display("Write cycle ended.");
+        end
+    endtask
+
+endmodule
\ No newline at end of file
diff --git a/verilog/dv/wb/distributor/distributor_tb.vcd b/verilog/dv/wb/distributor/distributor_tb.vcd
new file mode 100644
index 0000000..12f7ae8
--- /dev/null
+++ b/verilog/dv/wb/distributor/distributor_tb.vcd
@@ -0,0 +1,963 @@
+$date
+	Fri Aug 21 14:18:15 2020
+$end
+$version
+	Icarus Verilog
+$end
+$timescale
+	1ps
+$end
+$scope module distributor_tb $end
+$var wire 4 ! wbs_we_o [3:0] $end
+$var wire 4 " wbs_stb_o [3:0] $end
+$var wire 16 # wbs_sel_o [15:0] $end
+$var wire 128 $ wbs_dat_o [127:0] $end
+$var wire 128 % wbs_dat_i [127:0] $end
+$var wire 4 & wbs_cyc_o [3:0] $end
+$var wire 128 ' wbs_adr_o [127:0] $end
+$var wire 4 ( wbs_ack_o [3:0] $end
+$var wire 32 ) wbm_dat_o [31:0] $end
+$var wire 1 * wbm_ack_o $end
+$var reg 32 + slave_adr [31:0] $end
+$var reg 32 , slave_data [31:0] $end
+$var reg 1 - wb_clk_i $end
+$var reg 1 . wb_rst_i $end
+$var reg 32 / wbm_adr_i [31:0] $end
+$var reg 1 0 wbm_cyc_i $end
+$var reg 32 1 wbm_dat_i [31:0] $end
+$var reg 4 2 wbm_sel_i [3:0] $end
+$var reg 1 3 wbm_stb_i $end
+$var reg 1 4 wbm_we_i $end
+$scope module dummy_slaves[0] $end
+$var wire 1 5 valid $end
+$var wire 32 6 wb_adr_i [31:0] $end
+$var wire 1 7 wb_clk_i $end
+$var wire 1 8 wb_cyc_i $end
+$var wire 32 9 wb_dat_i [31:0] $end
+$var wire 1 : wb_rst_i $end
+$var wire 4 ; wb_sel_i [3:0] $end
+$var wire 1 < wb_stb_i $end
+$var wire 1 = wb_we_i $end
+$var reg 32 > store [31:0] $end
+$var reg 1 ? wb_ack_o $end
+$var reg 32 @ wb_dat_o [31:0] $end
+$upscope $end
+$scope module dummy_slaves[1] $end
+$var wire 1 A valid $end
+$var wire 32 B wb_adr_i [31:0] $end
+$var wire 1 C wb_clk_i $end
+$var wire 1 D wb_cyc_i $end
+$var wire 32 E wb_dat_i [31:0] $end
+$var wire 1 F wb_rst_i $end
+$var wire 4 G wb_sel_i [3:0] $end
+$var wire 1 H wb_stb_i $end
+$var wire 1 I wb_we_i $end
+$var reg 32 J store [31:0] $end
+$var reg 1 K wb_ack_o $end
+$var reg 32 L wb_dat_o [31:0] $end
+$upscope $end
+$scope module dummy_slaves[2] $end
+$var wire 1 M valid $end
+$var wire 32 N wb_adr_i [31:0] $end
+$var wire 1 O wb_clk_i $end
+$var wire 1 P wb_cyc_i $end
+$var wire 32 Q wb_dat_i [31:0] $end
+$var wire 1 R wb_rst_i $end
+$var wire 4 S wb_sel_i [3:0] $end
+$var wire 1 T wb_stb_i $end
+$var wire 1 U wb_we_i $end
+$var reg 32 V store [31:0] $end
+$var reg 1 W wb_ack_o $end
+$var reg 32 X wb_dat_o [31:0] $end
+$upscope $end
+$scope module dummy_slaves[3] $end
+$var wire 1 Y valid $end
+$var wire 32 Z wb_adr_i [31:0] $end
+$var wire 1 [ wb_clk_i $end
+$var wire 1 \ wb_cyc_i $end
+$var wire 32 ] wb_dat_i [31:0] $end
+$var wire 1 ^ wb_rst_i $end
+$var wire 4 _ wb_sel_i [3:0] $end
+$var wire 1 ` wb_stb_i $end
+$var wire 1 a wb_we_i $end
+$var reg 32 b store [31:0] $end
+$var reg 1 c wb_ack_o $end
+$var reg 32 d wb_dat_o [31:0] $end
+$upscope $end
+$scope module uut $end
+$var wire 1 - wb_clk_i $end
+$var wire 1 . wb_rst_i $end
+$var wire 32 e wbm_adr_i [31:0] $end
+$var wire 1 0 wbm_cyc_i $end
+$var wire 32 f wbm_dat_i [31:0] $end
+$var wire 4 g wbm_sel_i [3:0] $end
+$var wire 1 3 wbm_stb_i $end
+$var wire 1 4 wbm_we_i $end
+$var wire 4 h wbs_ack_i [3:0] $end
+$var wire 4 i wbs_cyc_o [3:0] $end
+$var wire 128 j wbs_dat_i [127:0] $end
+$var wire 4 k wbs_stb_o [3:0] $end
+$var wire 4 l wbs_we_o [3:0] $end
+$var wire 16 m wbs_sel_o [15:0] $end
+$var wire 128 n wbs_dat_o [127:0] $end
+$var wire 128 o wbs_adr_o [127:0] $end
+$var wire 1 * wbm_ack_o $end
+$var wire 4 p slave_sel [3:0] $end
+$var reg 32 q wbm_dat_o [31:0] $end
+$var integer 32 r i [31:0] $end
+$scope begin genblk1[0] $end
+$upscope $end
+$scope begin genblk1[1] $end
+$upscope $end
+$scope begin genblk1[2] $end
+$upscope $end
+$scope begin genblk1[3] $end
+$upscope $end
+$upscope $end
+$scope task read $end
+$var reg 32 s addr [31:0] $end
+$upscope $end
+$scope task write $end
+$var reg 32 t adr [31:0] $end
+$var reg 32 u data [31:0] $end
+$upscope $end
+$upscope $end
+$enddefinitions $end
+#0
+$dumpvars
+bx u
+bx t
+bx s
+b10000000 r
+b0 q
+b0 p
+b0 o
+b0 n
+b0 m
+b0 l
+b0 k
+bx j
+b0 i
+bx h
+b0 g
+b0 f
+b0 e
+bx d
+xc
+bx b
+0a
+0`
+b0 _
+1^
+b0 ]
+0\
+0[
+b0 Z
+0Y
+bx X
+xW
+bx V
+0U
+0T
+b0 S
+1R
+b0 Q
+0P
+0O
+b0 N
+0M
+bx L
+xK
+bx J
+0I
+0H
+b0 G
+1F
+b0 E
+0D
+0C
+b0 B
+0A
+bx @
+x?
+bx >
+0=
+0<
+b0 ;
+1:
+b0 9
+08
+07
+b0 6
+05
+04
+03
+b0 2
+b0 1
+00
+b0 /
+1.
+0-
+bx ,
+bx +
+0*
+b0 )
+bx (
+b0 '
+b0 &
+b0 %
+bx $
+b0 #
+b0 "
+b0 !
+$end
+#1000
+0?
+0K
+0W
+b0 (
+b0 h
+0c
+17
+1C
+1O
+1[
+1-
+#2000
+07
+0C
+0O
+0[
+0:
+0F
+0R
+0^
+0-
+0.
+#3000
+17
+1C
+1O
+1[
+1-
+#4000
+07
+0C
+0O
+0[
+0-
+b100100100001010100110101001001 u
+b10000000000000000000000000000000 t
+b100100100001010100110101001001 ,
+b10000000000000000000000000000000 +
+#5000
+b100100100001010100110101001001 >
+b100100100001010100110101001001 J
+b100100100001010100110101001001 V
+b100100100001010100110101001001 b
+15
+1<
+18
+b1 "
+b1 k
+b1 &
+b1 i
+bx )
+bx q
+b10000000 r
+b100100100001010100110101001001 9
+b100100100001010100110101001001 E
+b100100100001010100110101001001 Q
+b100100100001010100110101001001 ]
+b10000000000000000000000000000000 6
+b10000000000000000000000000000000 B
+b10000000000000000000000000000000 N
+b10000000000000000000000000000000 Z
+b1 p
+b1111 ;
+b1111 G
+b1111 S
+b1111 _
+1=
+1I
+1U
+1a
+17
+1C
+1O
+1[
+b100100100001010100110101001001001001001000010101001101010010010010010010000101010011010100100100100100100001010100110101001001 %
+b100100100001010100110101001001001001001000010101001101010010010010010010000101010011010100100100100100100001010100110101001001 n
+b100100100001010100110101001001 1
+b100100100001010100110101001001 f
+b10000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000 '
+b10000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000 o
+b10000000000000000000000000000000 /
+b10000000000000000000000000000000 e
+b1111111111111111 #
+b1111111111111111 m
+b1111 2
+b1111 g
+b1111 !
+b1111 l
+14
+10
+13
+1-
+#6000
+07
+0C
+0O
+0[
+0-
+#7000
+1*
+b10000000 r
+b100100100001010100110101001001 )
+b100100100001010100110101001001 q
+b1 (
+b1 h
+1?
+b100100100001010100110101001001 @
+b100100100001010100110101001001 L
+b100100100001010100110101001001 X
+b100100100001010100110101001001001001001000010101001101010010010010010010000101010011010100100100100100100001010100110101001001 $
+b100100100001010100110101001001001001001000010101001101010010010010010010000101010011010100100100100100100001010100110101001001 j
+b100100100001010100110101001001 d
+17
+1C
+1O
+1[
+1-
+#8000
+07
+0C
+0O
+0[
+0-
+#9000
+05
+08
+0<
+b0 &
+b0 i
+b0 "
+b0 k
+00
+03
+0*
+b0 (
+b0 h
+0?
+17
+1C
+1O
+1[
+1-
+#10000
+07
+0C
+0O
+0[
+0-
+#11000
+15
+18
+1<
+0=
+0I
+0U
+0a
+b1 &
+b1 i
+b1 "
+b1 k
+17
+1C
+1O
+1[
+b0 !
+b0 l
+04
+10
+13
+1-
+b10000000000000000000000000000000 s
+#12000
+07
+0C
+0O
+0[
+0-
+#13000
+1*
+b1 (
+b1 h
+1?
+17
+1C
+1O
+1[
+1-
+#14000
+07
+0C
+0O
+0[
+0-
+#15000
+05
+08
+0<
+b0 &
+b0 i
+b0 "
+b0 k
+00
+03
+0*
+b0 (
+b0 h
+0?
+17
+1C
+1O
+1[
+1-
+#16000
+07
+0C
+0O
+0[
+0-
+#17000
+b10000001000100101011110100000 >
+b10000001000100101011110100000 J
+b10000001000100101011110100000 V
+b10000001000100101011110100000 b
+1A
+1H
+1D
+05
+b10000000 r
+b100100100001010100110101001001 )
+b100100100001010100110101001001 q
+08
+0<
+b10000001000100101011110100000 9
+b10000001000100101011110100000 E
+b10000001000100101011110100000 Q
+b10000001000100101011110100000 ]
+b10010000000000000000000000000000 6
+b10010000000000000000000000000000 B
+b10010000000000000000000000000000 N
+b10010000000000000000000000000000 Z
+b10 p
+1=
+1I
+1U
+1a
+b10 &
+b10 i
+b10 "
+b10 k
+17
+1C
+1O
+1[
+b10000001000100101011110100000000100000010001001010111101000000001000000100010010101111010000000010000001000100101011110100000 %
+b10000001000100101011110100000000100000010001001010111101000000001000000100010010101111010000000010000001000100101011110100000 n
+b10000001000100101011110100000 1
+b10000001000100101011110100000 f
+b10010000000000000000000000000000100100000000000000000000000000001001000000000000000000000000000010010000000000000000000000000000 '
+b10010000000000000000000000000000100100000000000000000000000000001001000000000000000000000000000010010000000000000000000000000000 o
+b10010000000000000000000000000000 /
+b10010000000000000000000000000000 e
+b1111 !
+b1111 l
+14
+10
+13
+1-
+b10000001000100101011110100000 u
+b10010000000000000000000000000000 t
+b10000001000100101011110100000 ,
+b10010000000000000000000000000000 +
+#18000
+07
+0C
+0O
+0[
+0-
+#19000
+1*
+b10000000 r
+b10000001000100101011110100000 )
+b10000001000100101011110100000 q
+b10000001000100101011110100000 @
+b10 (
+b10 h
+1K
+b10000001000100101011110100000 L
+b10000001000100101011110100000 X
+b10000001000100101011110100000000100000010001001010111101000000001000000100010010101111010000000010000001000100101011110100000 $
+b10000001000100101011110100000000100000010001001010111101000000001000000100010010101111010000000010000001000100101011110100000 j
+b10000001000100101011110100000 d
+17
+1C
+1O
+1[
+1-
+#20000
+07
+0C
+0O
+0[
+0-
+#21000
+0A
+0D
+0H
+b0 &
+b0 i
+b0 "
+b0 k
+00
+03
+0*
+b0 (
+b0 h
+0K
+17
+1C
+1O
+1[
+1-
+#22000
+07
+0C
+0O
+0[
+0-
+#23000
+1A
+1D
+1H
+0=
+0I
+0U
+0a
+b10 &
+b10 i
+b10 "
+b10 k
+17
+1C
+1O
+1[
+b0 !
+b0 l
+04
+10
+13
+1-
+b10010000000000000000000000000000 s
+#24000
+07
+0C
+0O
+0[
+0-
+#25000
+1*
+b10 (
+b10 h
+1K
+17
+1C
+1O
+1[
+1-
+#26000
+07
+0C
+0O
+0[
+0-
+#27000
+0A
+0D
+0H
+b0 &
+b0 i
+b0 "
+b0 k
+00
+03
+0*
+b0 (
+b0 h
+0K
+17
+1C
+1O
+1[
+1-
+#28000
+07
+0C
+0O
+0[
+0-
+#29000
+b1001000010011010110000010 >
+b1001000010011010110000010 J
+b1001000010011010110000010 V
+b1001000010011010110000010 b
+1M
+1T
+1P
+0A
+b10000000 r
+b10000001000100101011110100000 )
+b10000001000100101011110100000 q
+0D
+0H
+b1001000010011010110000010 9
+b1001000010011010110000010 E
+b1001000010011010110000010 Q
+b1001000010011010110000010 ]
+b10100000000000000000000000000000 6
+b10100000000000000000000000000000 B
+b10100000000000000000000000000000 N
+b10100000000000000000000000000000 Z
+b100 p
+1=
+1I
+1U
+1a
+b100 &
+b100 i
+b100 "
+b100 k
+17
+1C
+1O
+1[
+b1001000010011010110000010000000010010000100110101100000100000000100100001001101011000001000000001001000010011010110000010 %
+b1001000010011010110000010000000010010000100110101100000100000000100100001001101011000001000000001001000010011010110000010 n
+b1001000010011010110000010 1
+b1001000010011010110000010 f
+b10100000000000000000000000000000101000000000000000000000000000001010000000000000000000000000000010100000000000000000000000000000 '
+b10100000000000000000000000000000101000000000000000000000000000001010000000000000000000000000000010100000000000000000000000000000 o
+b10100000000000000000000000000000 /
+b10100000000000000000000000000000 e
+b1111 !
+b1111 l
+14
+10
+13
+1-
+b1001000010011010110000010 u
+b10100000000000000000000000000000 t
+b1001000010011010110000010 ,
+b10100000000000000000000000000000 +
+#30000
+07
+0C
+0O
+0[
+0-
+#31000
+1*
+b10000000 r
+b1001000010011010110000010 )
+b1001000010011010110000010 q
+b1001000010011010110000010 @
+b1001000010011010110000010 L
+b100 (
+b100 h
+1W
+b1001000010011010110000010 X
+b1001000010011010110000010000000010010000100110101100000100000000100100001001101011000001000000001001000010011010110000010 $
+b1001000010011010110000010000000010010000100110101100000100000000100100001001101011000001000000001001000010011010110000010 j
+b1001000010011010110000010 d
+17
+1C
+1O
+1[
+1-
+#32000
+07
+0C
+0O
+0[
+0-
+#33000
+0M
+0P
+0T
+b0 &
+b0 i
+b0 "
+b0 k
+00
+03
+0*
+b0 (
+b0 h
+0W
+17
+1C
+1O
+1[
+1-
+#34000
+07
+0C
+0O
+0[
+0-
+#35000
+1M
+1P
+1T
+0=
+0I
+0U
+0a
+b100 &
+b100 i
+b100 "
+b100 k
+17
+1C
+1O
+1[
+b0 !
+b0 l
+04
+10
+13
+1-
+b10100000000000000000000000000000 s
+#36000
+07
+0C
+0O
+0[
+0-
+#37000
+1*
+b100 (
+b100 h
+1W
+17
+1C
+1O
+1[
+1-
+#38000
+07
+0C
+0O
+0[
+0-
+#39000
+0M
+0P
+0T
+b0 &
+b0 i
+b0 "
+b0 k
+00
+03
+0*
+b0 (
+b0 h
+0W
+17
+1C
+1O
+1[
+1-
+#40000
+07
+0C
+0O
+0[
+0-
+#41000
+b1100011111000001010110011001 >
+b1100011111000001010110011001 J
+b1100011111000001010110011001 V
+b1100011111000001010110011001 b
+1Y
+1`
+1\
+0M
+b10000000 r
+b1001000010011010110000010 )
+b1001000010011010110000010 q
+0P
+0T
+b1100011111000001010110011001 9
+b1100011111000001010110011001 E
+b1100011111000001010110011001 Q
+b1100011111000001010110011001 ]
+b10110000000000000000000000000000 6
+b10110000000000000000000000000000 B
+b10110000000000000000000000000000 N
+b10110000000000000000000000000000 Z
+b1000 p
+1=
+1I
+1U
+1a
+b1000 &
+b1000 i
+b1000 "
+b1000 k
+17
+1C
+1O
+1[
+b1100011111000001010110011001000011000111110000010101100110010000110001111100000101011001100100001100011111000001010110011001 %
+b1100011111000001010110011001000011000111110000010101100110010000110001111100000101011001100100001100011111000001010110011001 n
+b1100011111000001010110011001 1
+b1100011111000001010110011001 f
+b10110000000000000000000000000000101100000000000000000000000000001011000000000000000000000000000010110000000000000000000000000000 '
+b10110000000000000000000000000000101100000000000000000000000000001011000000000000000000000000000010110000000000000000000000000000 o
+b10110000000000000000000000000000 /
+b10110000000000000000000000000000 e
+b1111 !
+b1111 l
+14
+10
+13
+1-
+b1100011111000001010110011001 u
+b10110000000000000000000000000000 t
+b1100011111000001010110011001 ,
+b10110000000000000000000000000000 +
+#42000
+07
+0C
+0O
+0[
+0-
+#43000
+1*
+b10000000 r
+b1100011111000001010110011001 )
+b1100011111000001010110011001 q
+b1100011111000001010110011001 @
+b1100011111000001010110011001 L
+b1100011111000001010110011001 X
+b1000 (
+b1000 h
+1c
+b1100011111000001010110011001000011000111110000010101100110010000110001111100000101011001100100001100011111000001010110011001 $
+b1100011111000001010110011001000011000111110000010101100110010000110001111100000101011001100100001100011111000001010110011001 j
+b1100011111000001010110011001 d
+17
+1C
+1O
+1[
+1-
+#44000
+07
+0C
+0O
+0[
+0-
+#45000
+0Y
+0\
+0`
+b0 &
+b0 i
+b0 "
+b0 k
+00
+03
+0*
+b0 (
+b0 h
+0c
+17
+1C
+1O
+1[
+1-
+#46000
+07
+0C
+0O
+0[
+0-
+#47000
+1Y
+1\
+1`
+0=
+0I
+0U
+0a
+b1000 &
+b1000 i
+b1000 "
+b1000 k
+17
+1C
+1O
+1[
+b0 !
+b0 l
+04
+10
+13
+1-
+b10110000000000000000000000000000 s
+#48000
+07
+0C
+0O
+0[
+0-
+#49000
+1*
+b1000 (
+b1000 h
+1c
+17
+1C
+1O
+1[
+1-
+#50000
+07
+0C
+0O
+0[
+0-
+#51000
+0Y
+0\
+0`
+b0 &
+b0 i
+b0 "
+b0 k
+00
+03
+0*
+b0 (
+b0 h
+0c
+17
+1C
+1O
+1[
+1-
diff --git a/verilog/dv/wb/gpio_wb/Makefile b/verilog/dv/wb/gpio_wb/Makefile
new file mode 100644
index 0000000..d8d54e4
--- /dev/null
+++ b/verilog/dv/wb/gpio_wb/Makefile
@@ -0,0 +1,17 @@
+.SUFFIXES:
+
+PATTERN = gpio_wb
+
+all:  ${PATTERN:=.vcd}
+
+%.vvp: %_tb.v
+	iverilog -I .. -I ../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+clean:
+	rm -f *.vvp *.vcd
+
+.PHONY: clean all
diff --git a/verilog/dv/wb/gpio_wb/gpio_wb_tb.v b/verilog/dv/wb/gpio_wb/gpio_wb_tb.v
new file mode 100644
index 0000000..8db196c
--- /dev/null
+++ b/verilog/dv/wb/gpio_wb/gpio_wb_tb.v
@@ -0,0 +1,182 @@
+
+
+`timescale 1 ns / 1 ps
+
+`include "gpio_wb.v"
+
+module gpio_wb_tb;
+
+    reg wb_clk_i;
+	reg wb_rst_i;
+
+    reg wb_stb_i;
+    reg wb_cyc_i;
+	reg wb_we_i;
+	reg [3:0] wb_sel_i;
+
+	reg [31:0] wb_dat_i;
+	reg [31:0] wb_adr_i;
+    reg [15:0] gpio_in_pad;
+
+	wire wb_ack_o;
+	wire [31:0] wb_dat_o;
+
+    initial begin
+        wb_clk_i = 0; 
+        wb_rst_i = 0;
+        wb_stb_i = 0; 
+        wb_cyc_i = 0;  
+        wb_sel_i = 0;  
+        wb_we_i  = 0;  
+        wb_dat_i = 0; 
+        wb_adr_i = 0;  
+        gpio_in_pad = 0;
+    end
+
+    always #1 wb_clk_i = ~wb_clk_i;
+
+    initial begin
+        $dumpfile("gpio_wb_tb.vcd");
+        $dumpvars(0, gpio_wb_tb);
+        repeat (50) begin
+            repeat (1000) @(posedge wb_clk_i);
+        end
+        $display("%c[1;31m",27);
+        $display ("Monitor: Timeout, Test GPIO Wishbone Failed");
+        $display("%c[0m",27);
+        $finish;
+    end
+
+    integer i;
+    
+    // GPIO Internal Register Addresses
+    wire [31:0] gpio_adr     = uut.BASE_ADR | uut.GPIO_DATA;
+    wire [31:0] gpio_oeb_adr = uut.BASE_ADR | uut.GPIO_ENA;
+    wire [31:0] gpio_pu_adr  = uut.BASE_ADR | uut.GPIO_PU;
+    wire [31:0] gpio_pd_adr  = uut.BASE_ADR | uut.GPIO_PD;
+
+    reg [15:0] gpio_data;
+    reg [15:0] gpio_pu; 
+    reg [15:0] gpio_pd; 
+    reg [15:0] gpio_oeb;  
+
+    initial begin
+        // Reset Operation
+        wb_rst_i = 1;
+        #2;
+        wb_rst_i = 0; 
+        #2;
+
+        // Write to gpio_data reg
+        gpio_in_pad = 16'h FFFF;
+        gpio_data = 16'h A000;
+        write(gpio_adr, gpio_data);
+       
+        #2;
+        // Read from gpio_data reg
+        read(gpio_adr);
+        if (wb_dat_o !== {gpio_data, gpio_in_pad}) begin
+            $display("Monitor: Error reading from gpio reg");
+            $finish;
+        end
+        
+        #2;
+        // Write to pull-up reg
+        gpio_pu = 16'h 000f;
+        write(gpio_pu_adr, gpio_pu);
+        
+        #2;
+        // Read from pull-up reg
+        read(gpio_pu_adr);
+        if (wb_dat_o !== {16'd0, gpio_pu}) begin
+            $display("Monitor: Error reading from gpio pull-up reg");
+            $finish;
+        end
+
+        #2;
+        // Write to pull-down reg
+        gpio_pd = 16'h 00f0;
+        write(gpio_pd_adr, gpio_pd);
+        
+        #2;
+        // Read from pull-down reg
+        read(gpio_pd_adr);
+        if (wb_dat_o !== {16'd0, gpio_pd}) begin
+            $display("Monitor: Error reading from gpio pull-down reg");
+            $finish;
+        end
+
+        #2;
+        // Write to gpio enable reg
+        gpio_oeb = 16'h 00ff;
+        write(gpio_oeb_adr, gpio_oeb);
+        
+        #2;
+        // Read from gpio enable reg
+        read(gpio_oeb_adr);
+        if (wb_dat_o !== {16'd0, gpio_oeb}) begin
+            $display("Monitor: Error reading from gpio output enable reg");
+            $finish;
+        end
+        
+        #6;
+        $display("Monitor: GPIO WB Success!");
+        $finish;
+    end
+    
+    task write;
+        input [32:0] addr;
+        input [32:0] data;
+        begin 
+            @(posedge wb_clk_i) begin
+                wb_stb_i = 1;
+                wb_cyc_i = 1;
+                wb_sel_i = 4'hF; 
+                wb_we_i = 1;     
+                wb_adr_i = addr;
+                wb_dat_i = data;
+                $display("Write Cycle Started.");
+            end
+            // Wait for an ACK
+            wait(wb_ack_o == 1);
+            wait(wb_ack_o == 0);
+            wb_cyc_i = 0;
+            wb_stb_i = 0;
+            $display("Write Cycle Ended.");
+        end
+    endtask
+    
+    task read;
+        input [32:0] addr;
+        begin 
+            @(posedge wb_clk_i) begin
+                wb_stb_i = 1;
+                wb_cyc_i = 1;
+                wb_we_i = 0;
+                wb_adr_i = addr;
+                $display("Read Cycle Started.");
+            end
+            // Wait for an ACK
+            wait(wb_ack_o == 1);
+            wait(wb_ack_o == 0);
+            wb_cyc_i = 0;
+            wb_stb_i = 0;
+            $display("Read Cycle Ended.");
+        end
+    endtask
+    
+    gpio_wb uut(
+        .wb_clk_i(wb_clk_i),
+	    .wb_rst_i(wb_rst_i),
+        .wb_stb_i(wb_stb_i),
+	    .wb_cyc_i(wb_cyc_i),
+	    .wb_sel_i(wb_sel_i),
+	    .wb_we_i(wb_we_i),
+	    .wb_dat_i(wb_dat_i),
+	    .wb_adr_i(wb_adr_i), 
+        .wb_ack_o(wb_ack_o),
+	    .wb_dat_o(wb_dat_o),
+        .gpio_in_pad(gpio_in_pad)
+    );
+    
+endmodule
\ No newline at end of file
diff --git a/verilog/dv/wb/intercon_wb/Makefile b/verilog/dv/wb/intercon_wb/Makefile
new file mode 100644
index 0000000..e061e8d
--- /dev/null
+++ b/verilog/dv/wb/intercon_wb/Makefile
@@ -0,0 +1,17 @@
+.SUFFIXES:
+
+PATTERN = intercon_wb
+
+all:  ${PATTERN:=.vcd}
+
+%.vvp: %_tb.v
+	iverilog -I .. -I ../../ -I ../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+clean:
+	rm -f *.vvp *.vcd *.log
+
+.PHONY: clean all
diff --git a/verilog/dv/wb/intercon_wb/intercon_wb_tb.v b/verilog/dv/wb/intercon_wb/intercon_wb_tb.v
new file mode 100644
index 0000000..14702f9
--- /dev/null
+++ b/verilog/dv/wb/intercon_wb/intercon_wb_tb.v
@@ -0,0 +1,187 @@
+
+
+`timescale 1 ns / 1 ps
+
+`include "wb_intercon.v"
+`include "dummy_slave.v"
+
+`define AW 32
+`define DW 32
+`define NS 6
+
+`define SLAVE_ADR { \
+    {8'h28, {24{1'b0}} }, \   
+    {8'h23, {24{1'b0}} }, \     
+    {8'h21, {24{1'b0}} }, \    
+    {8'h20, {24{1'b0}} }, \    
+    {8'h10, {24{1'b0}} }, \    
+    {8'h00, {24{1'b0}} }  \
+}\
+
+`define ADR_MASK { \
+    {8'hFF, {24{1'b0}} }, \
+    {8'hFF, {24{1'b0}} }, \
+    {8'hFF, {24{1'b0}} }, \
+    {8'hFF, {24{1'b0}} }, \
+    {8'hFF, {24{1'b0}} }, \
+    {8'hFF, {24{1'b0}} }  \
+}\
+
+module intercon_wb_tb;
+
+    localparam SEL = `DW / 8;
+
+    reg wb_clk_i;
+	reg wb_rst_i;
+
+    // Master Interface
+    reg wbm_stb_i;
+    reg wbm_cyc_i;
+    reg wbm_we_i;
+    reg [SEL-1:0] wbm_sel_i;
+    reg [`AW-1:0] wbm_adr_i;
+    reg [`DW-1:0] wbm_dat_i;
+
+    wire [`DW-1:0] wbm_dat_o;
+    wire wbm_ack_o;
+
+    // Wishbone Slave Interface
+    wire [`NS-1:0] wbs_stb_i;
+    wire [`NS-1:0] wbs_ack_o;
+    wire [(`NS*`DW)-1:0] wbs_adr_i;
+    wire [(`NS*`AW)-1:0] wbs_dat_i;
+    wire [(`NS*`DW)-1:0] wbs_dat_o;
+
+    initial begin
+        wb_clk_i = 0; 
+        wb_rst_i = 0;
+        wbm_adr_i = 0;  
+        wbm_dat_i = 0;  
+        wbm_sel_i = 0;   
+        wbm_we_i  = 0;    
+        wbm_cyc_i = 0;   
+        wbm_stb_i = 0;  
+    end
+
+    always #1 wb_clk_i = ~wb_clk_i;
+
+    initial begin
+        $dumpfile("intercon_wb_tb.vcd");
+        $dumpvars(0, intercon_wb_tb);
+        repeat (50) begin
+            repeat (1000) @(posedge wb_clk_i);
+        end
+        $display("%c[1;31m",27);
+        $display ("Monitor: Timeout, Test Wishbone Interconnect Failed");
+        $display("%c[0m",27);
+        $finish;
+    end
+
+    integer i;
+
+    reg [`AW*`NS-1: 0] addr = `SLAVE_ADR;
+    reg [`DW:0] slave_data;
+    reg [`AW:0] slave_addr;
+
+    initial begin
+        // Reset Operation
+        wb_rst_i = 1;
+        #2;
+        wb_rst_i = 0; 
+        #2;
+
+        // W/R from all slaves
+        for (i=0; i<`NS; i=i+1) begin
+            slave_addr = addr[i*`AW +: `AW];
+            slave_data = $urandom_range(0, 2**32);
+            write(slave_addr, slave_data);
+            #2;
+            read(slave_addr);
+            if (wbm_dat_o !== slave_data) begin
+                $display("%c[1;31m",27);
+                $display ("Monitor: Reading from slave %0d failed", i);
+                $display("Monitor: Test Wishbone Interconnect failed");
+                $display("%c[0m",27);
+                $finish;
+            end
+        end
+        $display("Monitor: Test Wishbone Interconnect Success!");
+        $finish;
+    end
+    
+    task write;
+        input [`AW-1:0] addr;
+        input [`AW-1:0] data;
+        begin 
+            @(posedge wb_clk_i) begin
+                wbm_stb_i = 1;
+                wbm_cyc_i = 1;
+                wbm_sel_i = {SEL{1'b1}}; 
+                wbm_we_i = 1;    
+                wbm_adr_i = addr;
+                wbm_dat_i = data;
+                $display("Write Cycle Started.");
+            end
+            // Wait for an ACK
+            wait(wbm_ack_o == 1);
+            wait(wbm_ack_o == 0);
+            wbm_cyc_i = 0;
+            wbm_stb_i = 0;
+            $display("Write Cycle Ended.");
+        end
+    endtask
+    
+    task read;
+        input [`AW-1:0] addr;
+        begin 
+            @(posedge wb_clk_i) begin
+                wbm_stb_i = 1;
+                wbm_cyc_i = 1;
+                wbm_adr_i = addr;
+                wbm_we_i =  0;     
+                $display("Read Cycle Started.");
+            end
+            // Wait for an ACK
+            wait(wbm_ack_o == 1);
+            wait(wbm_ack_o == 0);
+            wbm_cyc_i = 0;
+            wbm_stb_i = 0;
+            $display("Read Cycle Ended.");
+        
+        end
+    endtask
+
+    wb_intercon #(
+        .AW(`AW),
+        .DW(`DW),
+        .NS(`NS),
+        .ADR_MASK(`ADR_MASK),
+        .SLAVE_ADR(`SLAVE_ADR)
+    ) uut(
+        // Master Interface
+        .wbm_adr_i(wbm_adr_i),
+        .wbm_stb_i(wbm_stb_i),
+        .wbm_dat_o(wbm_dat_o),
+        .wbm_ack_o(wbm_ack_o), 
+    
+        // Slave Interface
+        .wbs_stb_o(wbs_stb_i),
+        .wbs_dat_i(wbs_dat_o), 
+        .wbs_ack_i(wbs_ack_o)
+    );
+    
+    // Instantiate five dummy slaves for testing
+    dummy_slave dummy_slaves [`NS-1:0](
+        .wb_clk_i({`NS{wb_clk_i}}),
+        .wb_rst_i({`NS{wb_rst_i}}),
+        .wb_stb_i(wbs_stb_i),
+        .wb_cyc_i(wbm_cyc_i),
+        .wb_we_i(wbm_we_i),
+        .wb_sel_i(wbm_sel_i),
+        .wb_adr_i(wbm_adr_i),
+        .wb_dat_i(wbm_dat_i),
+        .wb_dat_o(wbs_dat_o),
+        .wb_ack_o(wbs_ack_o)
+    );
+
+endmodule
\ No newline at end of file
diff --git a/verilog/dv/wb/la_wb/Makefile b/verilog/dv/wb/la_wb/Makefile
new file mode 100644
index 0000000..216614f
--- /dev/null
+++ b/verilog/dv/wb/la_wb/Makefile
@@ -0,0 +1,17 @@
+.SUFFIXES:
+
+PATTERN = la_wb
+
+all:  ${PATTERN:=.vcd}
+
+%.vvp: %_tb.v
+	iverilog -I .. -I ../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+clean:
+	rm -f *.vvp *.vcd
+
+.PHONY: clean all
diff --git a/verilog/dv/wb/la_wb/la_wb_tb.v b/verilog/dv/wb/la_wb/la_wb_tb.v
new file mode 100644
index 0000000..2c50186
--- /dev/null
+++ b/verilog/dv/wb/la_wb/la_wb_tb.v
@@ -0,0 +1,208 @@
+`timescale 1 ns / 1 ps
+
+`include "la_wb.v"
+
+module la_wb_tb;
+
+    reg wb_clk_i;
+	reg wb_rst_i;
+
+    reg wb_stb_i;
+    reg wb_cyc_i;
+	reg wb_we_i;
+	reg [3:0] wb_sel_i;
+
+	reg [31:0] wb_dat_i;
+	reg [31:0] wb_adr_i;
+
+	wire wb_ack_o;
+	wire [31:0] wb_dat_o;
+
+    initial begin
+        wb_clk_i = 0; 
+        wb_rst_i = 0;
+        wb_stb_i = 0; 
+        wb_cyc_i = 0;  
+        wb_sel_i = 0;  
+        wb_we_i  = 0;  
+        wb_dat_i = 0; 
+        wb_adr_i = 0;  
+    end
+
+    always #1 wb_clk_i = ~wb_clk_i;
+    
+    initial begin
+        $dumpfile("la_wb_tb.vcd");
+        $dumpvars(0, la_wb_tb);
+        repeat (50) begin
+            repeat (1000) @(posedge wb_clk_i);
+        end
+        $display("%c[1;31m",27);
+        $display ("Monitor: Timeout, Test Wishbone LA Failed");
+        $display("%c[0m",27);
+        $finish;
+    end
+
+    integer i;
+    
+    // LA Wishbone Internal Register Addresses
+    wire [31:0] la_data_adr_0   = uut.BASE_ADR | uut.LA_DATA_0;
+    wire [31:0] la_data_adr_1   = uut.BASE_ADR | uut.LA_DATA_1;
+    wire [31:0] la_data_adr_2   = uut.BASE_ADR | uut.LA_DATA_2;
+    wire [31:0] la_data_adr_3   = uut.BASE_ADR | uut.LA_DATA_3;
+    
+    wire [31:0] la_ena_adr_0 = uut.BASE_ADR | uut.LA_ENA_0;
+    wire [31:0] la_ena_adr_1 = uut.BASE_ADR | uut.LA_ENA_1;
+    wire [31:0] la_ena_adr_2 = uut.BASE_ADR | uut.LA_ENA_2;
+    wire [31:0] la_ena_adr_3 = uut.BASE_ADR | uut.LA_ENA_3;
+
+    reg [31:0] la_data_0;
+    reg [31:0] la_data_1; 
+    reg [31:0] la_data_2;
+    reg [31:0] la_data_3; 
+
+    reg [31:0] la_ena_0;
+    reg [31:0] la_ena_1; 
+    reg [31:0] la_ena_2;
+    reg [31:0] la_ena_3; 
+
+    initial begin
+        // Reset Operation
+        wb_rst_i = 1;
+        #2;
+        wb_rst_i = 0; 
+        #2;
+
+        // Write to la data registers
+        la_data_0 = $urandom_range(0, 2**32);
+        la_data_1 = $urandom_range(0, 2**32);
+        la_data_2 = $urandom_range(0, 2**32);
+        la_data_3 = $urandom_range(0, 2**32);
+
+        write(la_data_adr_0, la_data_0);
+        write(la_data_adr_1, la_data_1);
+        write(la_data_adr_2, la_data_2);
+        write(la_data_adr_3, la_data_3);
+
+        #2;
+        // Read from la data registers
+        read(la_data_adr_0);
+        if (wb_dat_o !== la_data_0) begin
+            $display("Monitor: Error reading from la data_0 reg");
+            $finish;
+        end
+        
+        read(la_data_adr_1);
+        if (wb_dat_o !== la_data_1) begin
+            $display("Monitor: Error reading from la data_0 reg");
+            $finish;
+        end
+        
+        read(la_data_adr_2);
+        if (wb_dat_o !== la_data_1) begin
+            $display("Monitor: Error reading from la data_0 reg");
+            $finish;
+        end
+
+        read(la_data_adr_3);
+        if (wb_dat_o !== la_data_3) begin
+            $display("Monitor: Error reading from la data_0 reg");
+            $finish;
+        end
+
+        // Write to la emable registers
+        la_ena_0 = $urandom_range(0, 2**32);
+        la_ena_1 = $urandom_range(0, 2**32);
+        la_ena_2 = $urandom_range(0, 2**32);
+        la_ena_3 = $urandom_range(0, 2**32);
+
+        write(la_ena_adr_0, la_ena_0);
+        write(la_ena_adr_1, la_ena_1);
+        write(la_ena_adr_2, la_ena_2);
+        write(la_ena_adr_3, la_ena_3);
+
+        #2;
+        // Read from la data registers
+        read(la_ena_adr_0);
+        if (wb_dat_o !== la_ena_0) begin
+            $display("Monitor: Error reading from la data_0 reg");
+            $finish;
+        end
+        
+        read(la_ena_adr_1);
+        if (wb_dat_o !== la_ena_1) begin
+            $display("Monitor: Error reading from la data_0 reg");
+            $finish;
+        end
+        
+        read(la_ena_adr_2);
+        if (wb_dat_o !== la_ena_1) begin
+            $display("Monitor: Error reading from la data_0 reg");
+            $finish;
+        end
+
+        read(la_ena_adr_3);
+        if (wb_dat_o !== la_ena_3) begin
+            $display("Monitor: Error reading from la data_0 reg");
+            $finish;
+        end
+        #6;
+        $display("Monitor: Test LA Wishbone Success!");
+        $finish;
+    end
+    
+    task write;
+        input [32:0] addr;
+        input [32:0] data;
+        begin 
+            @(posedge wb_clk_i) begin
+                wb_stb_i = 1;
+                wb_cyc_i = 1;
+                wb_sel_i = 4'hF; 
+                wb_we_i = 1;     
+                wb_adr_i = addr;
+                wb_dat_i = data;
+                $display("Write Cycle Started.");
+            end
+            // Wait for an ACK
+            wait(wb_ack_o == 1);
+            wait(wb_ack_o == 0);
+            wb_cyc_i = 0;
+            wb_stb_i = 0;
+            $display("Write Cycle Ended.");
+        end
+    endtask
+    
+    task read;
+        input [32:0] addr;
+        begin 
+            @(posedge wb_clk_i) begin
+                wb_stb_i = 1;
+                wb_cyc_i = 1;
+                wb_we_i = 0;
+                wb_adr_i = addr;
+                $display("Read Cycle Started.");
+            end
+            // Wait for an ACK
+            wait(wb_ack_o == 1);
+            wait(wb_ack_o == 0);
+            wb_cyc_i = 0;
+            wb_stb_i = 0;
+            $display("Read Cycle Ended.");
+        end
+    endtask
+
+    la_wb uut(
+        .wb_clk_i(wb_clk_i),
+	    .wb_rst_i(wb_rst_i),
+        .wb_stb_i(wb_stb_i),
+	    .wb_cyc_i(wb_cyc_i),
+	    .wb_sel_i(wb_sel_i),
+	    .wb_we_i(wb_we_i),
+	    .wb_dat_i(wb_dat_i),
+	    .wb_adr_i(wb_adr_i), 
+        .wb_ack_o(wb_ack_o),
+	    .wb_dat_o(wb_dat_o)
+    );
+
+endmodule
\ No newline at end of file
diff --git a/verilog/dv/wb/la_wb/la_wb_tb.vcd b/verilog/dv/wb/la_wb/la_wb_tb.vcd
new file mode 100644
index 0000000..9a9969d
--- /dev/null
+++ b/verilog/dv/wb/la_wb/la_wb_tb.vcd
@@ -0,0 +1,635 @@
+$date
+	Fri Aug 21 14:19:50 2020
+$end
+$version
+	Icarus Verilog
+$end
+$timescale
+	1ps
+$end
+$scope module la_wb_tb $end
+$var wire 32 ! la_data_adr_0 [31:0] $end
+$var wire 32 " la_data_adr_1 [31:0] $end
+$var wire 32 # la_data_adr_2 [31:0] $end
+$var wire 32 $ la_data_adr_3 [31:0] $end
+$var wire 32 % la_ena_adr_0 [31:0] $end
+$var wire 32 & la_ena_adr_1 [31:0] $end
+$var wire 32 ' la_ena_adr_2 [31:0] $end
+$var wire 32 ( la_ena_adr_3 [31:0] $end
+$var wire 32 ) wb_dat_o [31:0] $end
+$var wire 1 * wb_ack_o $end
+$var reg 32 + la_data_0 [31:0] $end
+$var reg 32 , la_data_1 [31:0] $end
+$var reg 32 - la_data_2 [31:0] $end
+$var reg 32 . la_data_3 [31:0] $end
+$var reg 32 / la_ena_0 [31:0] $end
+$var reg 32 0 la_ena_1 [31:0] $end
+$var reg 32 1 la_ena_2 [31:0] $end
+$var reg 32 2 la_ena_3 [31:0] $end
+$var reg 32 3 wb_adr_i [31:0] $end
+$var reg 1 4 wb_clk_i $end
+$var reg 1 5 wb_cyc_i $end
+$var reg 32 6 wb_dat_i [31:0] $end
+$var reg 1 7 wb_rst_i $end
+$var reg 4 8 wb_sel_i [3:0] $end
+$var reg 1 9 wb_stb_i $end
+$var reg 1 : wb_we_i $end
+$scope module uut $end
+$var wire 4 ; iomem_we [3:0] $end
+$var wire 1 < resetn $end
+$var wire 1 = valid $end
+$var wire 1 * wb_ack_o $end
+$var wire 32 > wb_adr_i [31:0] $end
+$var wire 1 4 wb_clk_i $end
+$var wire 1 5 wb_cyc_i $end
+$var wire 32 ? wb_dat_i [31:0] $end
+$var wire 1 7 wb_rst_i $end
+$var wire 4 @ wb_sel_i [3:0] $end
+$var wire 1 9 wb_stb_i $end
+$var wire 1 : wb_we_i $end
+$var wire 32 A wb_dat_o [31:0] $end
+$var wire 1 B ready $end
+$var wire 128 C la_ena [127:0] $end
+$var wire 128 D la_data [127:0] $end
+$scope module la_ctrl $end
+$var wire 1 4 clk $end
+$var wire 32 E iomem_addr [31:0] $end
+$var wire 1 = iomem_valid $end
+$var wire 32 F iomem_wdata [31:0] $end
+$var wire 4 G iomem_wstrb [3:0] $end
+$var wire 1 < resetn $end
+$var wire 4 H la_ena_sel [3:0] $end
+$var wire 128 I la_ena [127:0] $end
+$var wire 4 J la_data_sel [3:0] $end
+$var wire 128 K la_data [127:0] $end
+$var reg 32 L iomem_rdata [31:0] $end
+$var reg 1 B iomem_ready $end
+$var reg 32 M la_data_0 [31:0] $end
+$var reg 32 N la_data_1 [31:0] $end
+$var reg 32 O la_data_2 [31:0] $end
+$var reg 32 P la_data_3 [31:0] $end
+$var reg 32 Q la_ena_0 [31:0] $end
+$var reg 32 R la_ena_1 [31:0] $end
+$var reg 32 S la_ena_2 [31:0] $end
+$var reg 32 T la_ena_3 [31:0] $end
+$upscope $end
+$upscope $end
+$scope task read $end
+$var reg 33 U addr [32:0] $end
+$upscope $end
+$scope task write $end
+$var reg 33 V addr [32:0] $end
+$var reg 33 W data [32:0] $end
+$upscope $end
+$upscope $end
+$enddefinitions $end
+#0
+$dumpvars
+bx W
+bx V
+bx U
+bx T
+bx S
+bx R
+bx Q
+bx P
+bx O
+bx N
+bx M
+bx L
+bx K
+b1 J
+bx I
+b0 H
+b0 G
+b0 F
+b0 E
+bx D
+bx C
+xB
+bx A
+b0 @
+b0 ?
+b0 >
+0=
+0<
+b0 ;
+0:
+09
+b0 8
+17
+b0 6
+05
+04
+b0 3
+bx 2
+bx 1
+bx 0
+bx /
+bx .
+bx -
+bx ,
+bx +
+x*
+bx )
+b100010000000000000000000011100 (
+b100010000000000000000000011000 '
+b100010000000000000000000010100 &
+b100010000000000000000000010000 %
+b100010000000000000000000001100 $
+b100010000000000000000000001000 #
+b100010000000000000000000000100 "
+b100010000000000000000000000000 !
+$end
+#1000
+b0 T
+b0 S
+b0 R
+b0 C
+b0 I
+b0 Q
+b0 P
+b0 O
+b0 N
+b0 D
+b0 K
+b0 M
+14
+#2000
+1<
+04
+07
+#3000
+0*
+0B
+14
+#4000
+04
+b0 W
+b100010000000000000000000000000 V
+b0 .
+b0 -
+b0 ,
+b0 +
+#5000
+b1111 ;
+b1111 G
+1=
+b100010000000000000000000000000 3
+b100010000000000000000000000000 >
+b100010000000000000000000000000 E
+1:
+b1111 8
+b1111 @
+15
+19
+14
+#6000
+04
+#7000
+b0 )
+b0 A
+b0 L
+1*
+1B
+14
+#8000
+04
+#9000
+0=
+b100010000000000000000000000100 V
+09
+05
+0*
+0B
+14
+#10000
+04
+#11000
+b10 J
+1=
+b100010000000000000000000000100 3
+b100010000000000000000000000100 >
+b100010000000000000000000000100 E
+15
+19
+14
+#12000
+04
+#13000
+1*
+1B
+14
+#14000
+04
+#15000
+0=
+b100010000000000000000000001000 V
+09
+05
+0*
+0B
+14
+#16000
+04
+#17000
+b100 J
+1=
+b100010000000000000000000001000 3
+b100010000000000000000000001000 >
+b100010000000000000000000001000 E
+15
+19
+14
+#18000
+04
+#19000
+1*
+1B
+14
+#20000
+04
+#21000
+0=
+b100010000000000000000000001100 V
+09
+05
+0*
+0B
+14
+#22000
+04
+#23000
+b1000 J
+1=
+b100010000000000000000000001100 3
+b100010000000000000000000001100 >
+b100010000000000000000000001100 E
+15
+19
+14
+#24000
+04
+#25000
+1*
+1B
+14
+#26000
+04
+#27000
+0=
+09
+05
+0*
+0B
+14
+#28000
+04
+#29000
+b1 J
+b0 ;
+b0 G
+1=
+b100010000000000000000000000000 3
+b100010000000000000000000000000 >
+b100010000000000000000000000000 E
+0:
+15
+19
+14
+b100010000000000000000000000000 U
+#30000
+04
+#31000
+1*
+1B
+14
+#32000
+04
+#33000
+0=
+b100010000000000000000000000100 U
+09
+05
+0*
+0B
+14
+#34000
+04
+#35000
+b10 J
+1=
+b100010000000000000000000000100 3
+b100010000000000000000000000100 >
+b100010000000000000000000000100 E
+15
+19
+14
+#36000
+04
+#37000
+1*
+1B
+14
+#38000
+04
+#39000
+0=
+b100010000000000000000000001000 U
+09
+05
+0*
+0B
+14
+#40000
+04
+#41000
+b100 J
+1=
+b100010000000000000000000001000 3
+b100010000000000000000000001000 >
+b100010000000000000000000001000 E
+15
+19
+14
+#42000
+04
+#43000
+1*
+1B
+14
+#44000
+04
+#45000
+0=
+b100010000000000000000000001100 U
+09
+05
+0*
+0B
+14
+#46000
+04
+#47000
+b1000 J
+1=
+b100010000000000000000000001100 3
+b100010000000000000000000001100 >
+b100010000000000000000000001100 E
+15
+19
+14
+#48000
+04
+#49000
+1*
+1B
+14
+#50000
+04
+#51000
+0=
+b100010000000000000000000010000 V
+b0 2
+b0 1
+b0 0
+b0 /
+09
+05
+0*
+0B
+14
+#52000
+04
+#53000
+b0 J
+b1 H
+b1111 ;
+b1111 G
+1=
+b100010000000000000000000010000 3
+b100010000000000000000000010000 >
+b100010000000000000000000010000 E
+1:
+15
+19
+14
+#54000
+04
+#55000
+1*
+1B
+14
+#56000
+04
+#57000
+0=
+b100010000000000000000000010100 V
+09
+05
+0*
+0B
+14
+#58000
+04
+#59000
+b10 H
+1=
+b100010000000000000000000010100 3
+b100010000000000000000000010100 >
+b100010000000000000000000010100 E
+15
+19
+14
+#60000
+04
+#61000
+1*
+1B
+14
+#62000
+04
+#63000
+0=
+b100010000000000000000000011000 V
+09
+05
+0*
+0B
+14
+#64000
+04
+#65000
+b100 H
+1=
+b100010000000000000000000011000 3
+b100010000000000000000000011000 >
+b100010000000000000000000011000 E
+15
+19
+14
+#66000
+04
+#67000
+1*
+1B
+14
+#68000
+04
+#69000
+0=
+b100010000000000000000000011100 V
+09
+05
+0*
+0B
+14
+#70000
+04
+#71000
+b1000 H
+1=
+b100010000000000000000000011100 3
+b100010000000000000000000011100 >
+b100010000000000000000000011100 E
+15
+19
+14
+#72000
+04
+#73000
+1*
+1B
+14
+#74000
+04
+#75000
+0=
+09
+05
+0*
+0B
+14
+#76000
+04
+#77000
+b1 H
+b0 ;
+b0 G
+1=
+b100010000000000000000000010000 3
+b100010000000000000000000010000 >
+b100010000000000000000000010000 E
+0:
+15
+19
+14
+b100010000000000000000000010000 U
+#78000
+04
+#79000
+1*
+1B
+14
+#80000
+04
+#81000
+0=
+b100010000000000000000000010100 U
+09
+05
+0*
+0B
+14
+#82000
+04
+#83000
+b10 H
+1=
+b100010000000000000000000010100 3
+b100010000000000000000000010100 >
+b100010000000000000000000010100 E
+15
+19
+14
+#84000
+04
+#85000
+1*
+1B
+14
+#86000
+04
+#87000
+0=
+b100010000000000000000000011000 U
+09
+05
+0*
+0B
+14
+#88000
+04
+#89000
+b100 H
+1=
+b100010000000000000000000011000 3
+b100010000000000000000000011000 >
+b100010000000000000000000011000 E
+15
+19
+14
+#90000
+04
+#91000
+1*
+1B
+14
+#92000
+04
+#93000
+0=
+b100010000000000000000000011100 U
+09
+05
+0*
+0B
+14
+#94000
+04
+#95000
+b1000 H
+1=
+b100010000000000000000000011100 3
+b100010000000000000000000011100 >
+b100010000000000000000000011100 E
+15
+19
+14
+#96000
+04
+#97000
+1*
+1B
+14
+#98000
+04
+#99000
+0=
+09
+05
+0*
+0B
+14
+#100000
+04
+#101000
+14
+#102000
+04
+#103000
+14
+#104000
+04
+#105000
+14
diff --git a/verilog/dv/wb/la_wb/ldo_wb_tb.vcd b/verilog/dv/wb/la_wb/ldo_wb_tb.vcd
new file mode 100644
index 0000000..a0e252e
--- /dev/null
+++ b/verilog/dv/wb/la_wb/ldo_wb_tb.vcd
@@ -0,0 +1,635 @@
+$date
+	Thu Aug 20 00:22:06 2020
+$end
+$version
+	Icarus Verilog
+$end
+$timescale
+	1ps
+$end
+$scope module ldo_wb_tb $end
+$var wire 32 ! ldo_data_adr_0 [31:0] $end
+$var wire 32 " ldo_data_adr_1 [31:0] $end
+$var wire 32 # ldo_data_adr_2 [31:0] $end
+$var wire 32 $ ldo_data_adr_3 [31:0] $end
+$var wire 32 % ldo_ena_adr_0 [31:0] $end
+$var wire 32 & ldo_ena_adr_1 [31:0] $end
+$var wire 32 ' ldo_ena_adr_2 [31:0] $end
+$var wire 32 ( ldo_ena_adr_3 [31:0] $end
+$var wire 32 ) wb_dat_o [31:0] $end
+$var wire 1 * wb_ack_o $end
+$var reg 32 + ldo_data_0 [31:0] $end
+$var reg 32 , ldo_data_1 [31:0] $end
+$var reg 32 - ldo_data_2 [31:0] $end
+$var reg 32 . ldo_data_3 [31:0] $end
+$var reg 32 / ldo_ena_0 [31:0] $end
+$var reg 32 0 ldo_ena_1 [31:0] $end
+$var reg 32 1 ldo_ena_2 [31:0] $end
+$var reg 32 2 ldo_ena_3 [31:0] $end
+$var reg 32 3 wb_adr_i [31:0] $end
+$var reg 1 4 wb_clk_i $end
+$var reg 1 5 wb_cyc_i $end
+$var reg 32 6 wb_dat_i [31:0] $end
+$var reg 1 7 wb_rst_i $end
+$var reg 4 8 wb_sel_i [3:0] $end
+$var reg 1 9 wb_stb_i $end
+$var reg 1 : wb_we_i $end
+$scope module uut $end
+$var wire 4 ; iomem_we [3:0] $end
+$var wire 1 < resetn $end
+$var wire 1 = valid $end
+$var wire 1 * wb_ack_o $end
+$var wire 32 > wb_adr_i [31:0] $end
+$var wire 1 4 wb_clk_i $end
+$var wire 1 5 wb_cyc_i $end
+$var wire 32 ? wb_dat_i [31:0] $end
+$var wire 1 7 wb_rst_i $end
+$var wire 4 @ wb_sel_i [3:0] $end
+$var wire 1 9 wb_stb_i $end
+$var wire 1 : wb_we_i $end
+$var wire 32 A wb_dat_o [31:0] $end
+$var wire 1 B ready $end
+$var wire 128 C ldo_ena [127:0] $end
+$var wire 128 D ldo_data [127:0] $end
+$scope module ldo_ctrl $end
+$var wire 1 4 clk $end
+$var wire 32 E iomem_addr [31:0] $end
+$var wire 1 = iomem_valid $end
+$var wire 32 F iomem_wdata [31:0] $end
+$var wire 4 G iomem_wstrb [3:0] $end
+$var wire 1 < resetn $end
+$var wire 4 H ldo_ena_sel [3:0] $end
+$var wire 128 I ldo_ena [127:0] $end
+$var wire 4 J ldo_data_sel [3:0] $end
+$var wire 128 K ldo_data [127:0] $end
+$var reg 32 L iomem_rdata [31:0] $end
+$var reg 1 B iomem_ready $end
+$var reg 32 M ldo_data_0 [31:0] $end
+$var reg 32 N ldo_data_1 [31:0] $end
+$var reg 32 O ldo_data_2 [31:0] $end
+$var reg 32 P ldo_data_3 [31:0] $end
+$var reg 32 Q ldo_ena_0 [31:0] $end
+$var reg 32 R ldo_ena_1 [31:0] $end
+$var reg 32 S ldo_ena_2 [31:0] $end
+$var reg 32 T ldo_ena_3 [31:0] $end
+$upscope $end
+$upscope $end
+$scope task read $end
+$var reg 33 U addr [32:0] $end
+$upscope $end
+$scope task write $end
+$var reg 33 V addr [32:0] $end
+$var reg 33 W data [32:0] $end
+$upscope $end
+$upscope $end
+$enddefinitions $end
+#0
+$dumpvars
+bx W
+bx V
+bx U
+bx T
+bx S
+bx R
+bx Q
+bx P
+bx O
+bx N
+bx M
+bx L
+bx K
+b1 J
+bx I
+b0 H
+b0 G
+b0 F
+b0 E
+bx D
+bx C
+xB
+bx A
+b0 @
+b0 ?
+b0 >
+0=
+0<
+b0 ;
+0:
+09
+b0 8
+17
+b0 6
+05
+04
+b0 3
+bx 2
+bx 1
+bx 0
+bx /
+bx .
+bx -
+bx ,
+bx +
+x*
+bx )
+b100010000000000000000000011100 (
+b100010000000000000000000011000 '
+b100010000000000000000000010100 &
+b100010000000000000000000010000 %
+b100010000000000000000000001100 $
+b100010000000000000000000001000 #
+b100010000000000000000000000100 "
+b100010000000000000000000000000 !
+$end
+#1000
+b0 T
+b0 S
+b0 R
+b0 C
+b0 I
+b0 Q
+b0 P
+b0 O
+b0 N
+b0 D
+b0 K
+b0 M
+14
+#2000
+1<
+04
+07
+#3000
+0*
+0B
+14
+#4000
+04
+b0 W
+b100010000000000000000000000000 V
+b0 .
+b0 -
+b0 ,
+b0 +
+#5000
+b1111 ;
+b1111 G
+1=
+b100010000000000000000000000000 3
+b100010000000000000000000000000 >
+b100010000000000000000000000000 E
+1:
+b1111 8
+b1111 @
+15
+19
+14
+#6000
+04
+#7000
+b0 )
+b0 A
+b0 L
+1*
+1B
+14
+#8000
+04
+#9000
+0=
+b100010000000000000000000000100 V
+09
+05
+0*
+0B
+14
+#10000
+04
+#11000
+b10 J
+1=
+b100010000000000000000000000100 3
+b100010000000000000000000000100 >
+b100010000000000000000000000100 E
+15
+19
+14
+#12000
+04
+#13000
+1*
+1B
+14
+#14000
+04
+#15000
+0=
+b100010000000000000000000001000 V
+09
+05
+0*
+0B
+14
+#16000
+04
+#17000
+b100 J
+1=
+b100010000000000000000000001000 3
+b100010000000000000000000001000 >
+b100010000000000000000000001000 E
+15
+19
+14
+#18000
+04
+#19000
+1*
+1B
+14
+#20000
+04
+#21000
+0=
+b100010000000000000000000001100 V
+09
+05
+0*
+0B
+14
+#22000
+04
+#23000
+b1000 J
+1=
+b100010000000000000000000001100 3
+b100010000000000000000000001100 >
+b100010000000000000000000001100 E
+15
+19
+14
+#24000
+04
+#25000
+1*
+1B
+14
+#26000
+04
+#27000
+0=
+09
+05
+0*
+0B
+14
+#28000
+04
+#29000
+b1 J
+b0 ;
+b0 G
+1=
+b100010000000000000000000000000 3
+b100010000000000000000000000000 >
+b100010000000000000000000000000 E
+0:
+15
+19
+14
+b100010000000000000000000000000 U
+#30000
+04
+#31000
+1*
+1B
+14
+#32000
+04
+#33000
+0=
+b100010000000000000000000000100 U
+09
+05
+0*
+0B
+14
+#34000
+04
+#35000
+b10 J
+1=
+b100010000000000000000000000100 3
+b100010000000000000000000000100 >
+b100010000000000000000000000100 E
+15
+19
+14
+#36000
+04
+#37000
+1*
+1B
+14
+#38000
+04
+#39000
+0=
+b100010000000000000000000001000 U
+09
+05
+0*
+0B
+14
+#40000
+04
+#41000
+b100 J
+1=
+b100010000000000000000000001000 3
+b100010000000000000000000001000 >
+b100010000000000000000000001000 E
+15
+19
+14
+#42000
+04
+#43000
+1*
+1B
+14
+#44000
+04
+#45000
+0=
+b100010000000000000000000001100 U
+09
+05
+0*
+0B
+14
+#46000
+04
+#47000
+b1000 J
+1=
+b100010000000000000000000001100 3
+b100010000000000000000000001100 >
+b100010000000000000000000001100 E
+15
+19
+14
+#48000
+04
+#49000
+1*
+1B
+14
+#50000
+04
+#51000
+0=
+b100010000000000000000000010000 V
+b0 2
+b0 1
+b0 0
+b0 /
+09
+05
+0*
+0B
+14
+#52000
+04
+#53000
+b0 J
+b1 H
+b1111 ;
+b1111 G
+1=
+b100010000000000000000000010000 3
+b100010000000000000000000010000 >
+b100010000000000000000000010000 E
+1:
+15
+19
+14
+#54000
+04
+#55000
+1*
+1B
+14
+#56000
+04
+#57000
+0=
+b100010000000000000000000010100 V
+09
+05
+0*
+0B
+14
+#58000
+04
+#59000
+b10 H
+1=
+b100010000000000000000000010100 3
+b100010000000000000000000010100 >
+b100010000000000000000000010100 E
+15
+19
+14
+#60000
+04
+#61000
+1*
+1B
+14
+#62000
+04
+#63000
+0=
+b100010000000000000000000011000 V
+09
+05
+0*
+0B
+14
+#64000
+04
+#65000
+b100 H
+1=
+b100010000000000000000000011000 3
+b100010000000000000000000011000 >
+b100010000000000000000000011000 E
+15
+19
+14
+#66000
+04
+#67000
+1*
+1B
+14
+#68000
+04
+#69000
+0=
+b100010000000000000000000011100 V
+09
+05
+0*
+0B
+14
+#70000
+04
+#71000
+b1000 H
+1=
+b100010000000000000000000011100 3
+b100010000000000000000000011100 >
+b100010000000000000000000011100 E
+15
+19
+14
+#72000
+04
+#73000
+1*
+1B
+14
+#74000
+04
+#75000
+0=
+09
+05
+0*
+0B
+14
+#76000
+04
+#77000
+b1 H
+b0 ;
+b0 G
+1=
+b100010000000000000000000010000 3
+b100010000000000000000000010000 >
+b100010000000000000000000010000 E
+0:
+15
+19
+14
+b100010000000000000000000010000 U
+#78000
+04
+#79000
+1*
+1B
+14
+#80000
+04
+#81000
+0=
+b100010000000000000000000010100 U
+09
+05
+0*
+0B
+14
+#82000
+04
+#83000
+b10 H
+1=
+b100010000000000000000000010100 3
+b100010000000000000000000010100 >
+b100010000000000000000000010100 E
+15
+19
+14
+#84000
+04
+#85000
+1*
+1B
+14
+#86000
+04
+#87000
+0=
+b100010000000000000000000011000 U
+09
+05
+0*
+0B
+14
+#88000
+04
+#89000
+b100 H
+1=
+b100010000000000000000000011000 3
+b100010000000000000000000011000 >
+b100010000000000000000000011000 E
+15
+19
+14
+#90000
+04
+#91000
+1*
+1B
+14
+#92000
+04
+#93000
+0=
+b100010000000000000000000011100 U
+09
+05
+0*
+0B
+14
+#94000
+04
+#95000
+b1000 H
+1=
+b100010000000000000000000011100 3
+b100010000000000000000000011100 >
+b100010000000000000000000011100 E
+15
+19
+14
+#96000
+04
+#97000
+1*
+1B
+14
+#98000
+04
+#99000
+0=
+09
+05
+0*
+0B
+14
+#100000
+04
+#101000
+14
+#102000
+04
+#103000
+14
+#104000
+04
+#105000
+14
diff --git a/verilog/dv/wb/mem_wb/Makefile b/verilog/dv/wb/mem_wb/Makefile
new file mode 100644
index 0000000..82b2235
--- /dev/null
+++ b/verilog/dv/wb/mem_wb/Makefile
@@ -0,0 +1,17 @@
+.SUFFIXES:
+
+PATTERN = mem_wb
+
+all:  ${PATTERN:=.vcd}
+
+%.vvp: %_tb.v
+	iverilog -I .. -I ../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+clean:
+	rm -f *.vvp *.vcd
+
+.PHONY: clean all
diff --git a/verilog/dv/wb/mem_wb/mem_wb_tb.v b/verilog/dv/wb/mem_wb/mem_wb_tb.v
new file mode 100644
index 0000000..eb45e22
--- /dev/null
+++ b/verilog/dv/wb/mem_wb/mem_wb_tb.v
@@ -0,0 +1,143 @@
+
+
+`timescale 1 ns / 1 ps
+
+`define USE_OPENRAM
+
+`include "sram_1rw1r_32_256_8_sky130.v"
+`include "mem_wb.v"
+
+module mem_wb_tb;
+
+    reg wb_clk_i;
+    reg wb_rst_i;
+
+    reg [31:0] wb_adr_i;
+    reg [31:0] wb_dat_i;
+    reg [3:0]  wb_sel_i;
+    reg wb_we_i;
+    reg wb_cyc_i;
+    reg wb_stb_i;
+
+    wire wb_ack_o;
+    wire [31:0] wb_dat_o;
+
+    initial begin
+        wb_clk_i = 0; 
+        wb_rst_i = 0;
+
+        wb_stb_i = 0;  // master select-signal for the slave
+        wb_we_i  = 0;  // R = 0 , W = 1
+        wb_cyc_i = 0;  // master is transferring
+        wb_adr_i = 0;  // input addr 32-bits
+        wb_dat_i = 0;  // input data 32-bits
+        wb_sel_i = 0;  // where data is available on data_i 4-bits
+    end
+
+    always #1 wb_clk_i = ~wb_clk_i;
+
+    initial begin
+        $dumpfile("mem_wb_tb.vcd");
+        $dumpvars(0, mem_wb_tb);
+        repeat (50) begin
+            repeat (1000) @(posedge wb_clk_i);
+        end
+        $display("%c[1;31m",27);
+        $display ("Monitor: Timeout, Test Wishbone Memory Failed");
+        $display("%c[0m",27);
+        $finish;
+    end
+
+    integer i;
+
+    reg [31:0] ref_data [255: 0];
+    reg [31: 0] read_data;
+
+    initial begin
+        // Reset Operation
+        wb_rst_i = 1;
+        #2;
+        wb_rst_i = 0; 
+        #2;
+
+        // Randomly Write to memory array
+        for ( i = 0; i < 1; i = i + 1) begin 
+            ref_data[i] = $urandom_range(0, 2**32);
+            write(i, ref_data[i]);
+            #2;
+        end
+
+        #6;
+        for ( i = 0; i < 1; i = i + 1) begin 
+            read(i);
+            if (wb_dat_o !== ref_data[i]) begin
+                $display("%c[1;31m",27);
+                $display("Expected %0b, but Got %0b ", ref_data[i], wb_dat_o);
+                $display("Monitor: Wishbone Memory Failed");
+                $display("%c[0m",27);
+                $finish;
+            end
+            #2;
+        end
+        #6;
+        $display("Success!");
+        $finish;
+    end
+     
+    task write;
+        input [32:0] addr;
+        input [32:0] data;
+        begin 
+            @(posedge wb_clk_i) begin
+                wb_stb_i = 1;
+                wb_cyc_i = 1;
+                wb_sel_i = 4'hF; 
+                wb_we_i = 1;     
+                wb_adr_i = addr;
+                wb_dat_i = data;
+                $display("Write Cycle Started.");
+            end
+            // Wait for an ACK
+            wait(wb_ack_o == 1);
+            wait(wb_ack_o == 0);
+            wb_cyc_i = 0;
+            wb_stb_i = 0;
+            $display("Write Cycle Ended.");
+        end
+    endtask
+    
+    task read;
+        input [32:0] addr;
+        begin 
+            @(posedge wb_clk_i) begin
+                wb_stb_i = 1;
+                wb_cyc_i = 1;
+                wb_we_i = 0;
+                wb_adr_i = addr;
+                $display("Read Cycle Started.");
+            end
+            // Wait for an ACK
+            wait(wb_ack_o == 1);
+            wait(wb_ack_o == 0);
+            wb_cyc_i = 0;
+            wb_stb_i = 0;
+            $display("Read Cycle Ended.");
+        end
+    endtask
+    
+    mem_wb uut(
+        .wb_clk_i(wb_clk_i),
+        .wb_rst_i(wb_rst_i),
+
+        .wb_adr_i(wb_adr_i), 
+        .wb_dat_i(wb_dat_i),
+        .wb_sel_i(wb_sel_i),
+        .wb_we_i(wb_we_i),
+        .wb_cyc_i(wb_cyc_i),
+        .wb_stb_i(wb_stb_i),
+
+        .wb_ack_o(wb_ack_o), 
+        .wb_dat_o(wb_dat_o)
+    );
+
+endmodule
\ No newline at end of file
diff --git a/verilog/dv/wb/spi_sysctrl_wb/Makefile b/verilog/dv/wb/spi_sysctrl_wb/Makefile
new file mode 100644
index 0000000..55b9235
--- /dev/null
+++ b/verilog/dv/wb/spi_sysctrl_wb/Makefile
@@ -0,0 +1,18 @@
+.SUFFIXES:
+
+PATTERN = spi_sysctrl_wb
+
+all:  ${PATTERN:=.vcd}
+
+%.vvp: %_tb.v
+	iverilog  -I ../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+clean:
+	rm -f *.vvp *.vcd *.log
+
+.PHONY: clean all
+
diff --git a/verilog/dv/wb/spi_sysctrl_wb/spi_sysctrl_wb_tb.v b/verilog/dv/wb/spi_sysctrl_wb/spi_sysctrl_wb_tb.v
new file mode 100644
index 0000000..0275a2c
--- /dev/null
+++ b/verilog/dv/wb/spi_sysctrl_wb/spi_sysctrl_wb_tb.v
@@ -0,0 +1,226 @@
+
+
+`timescale 1 ns / 1 ps
+
+`include "spi_sysctrl.v"
+`include "striVe_spi.v"
+
+module spi_sysctrl_wb_tb;
+
+    reg wb_clk_i;
+	reg wb_rst_i;
+
+    reg wb_stb_i;
+    reg wb_cyc_i;
+	reg wb_we_i;
+	reg [3:0] wb_sel_i;
+	reg [31:0] wb_dat_i;
+	reg [31:0] wb_adr_i;
+
+	wire wb_ack_o;
+	wire [31:0] wb_dat_o;
+
+    wire [7:0] spi_ro_config; // (verify) wire input to the core not connected to HKSPI, what should it be connected to ? 
+    wire [4:0] spi_ro_pll_div; 
+    wire [2:0] spi_ro_pll_sel;
+    wire spi_ro_xtal_ena;
+    wire spi_ro_reg_ena; 
+    wire [25:0] spi_ro_pll_trim;
+    wire spi_ro_pll_dco_ena;
+    wire [11:0] spi_ro_mfgr_id;
+    wire [7:0] spi_ro_prod_id;
+    wire [3:0] spi_ro_mask_rev;
+    wire spi_ro_pll_bypass;
+   
+    // HKSPI
+    reg RSTB;	    
+    reg SCK;	   
+    reg SDI;	    
+    reg CSB;	    
+    reg trap;
+    reg [3:0] mask_rev_in;	
+
+    wire SDO;	  
+    wire sdo_enb;
+    wire xtal_ena;
+    wire reg_ena;
+    wire pll_dco_ena;
+    wire [25:0] pll_trim;
+    wire [2:0] pll_sel;
+    wire [4:0] pll_div;
+    wire pll_bypass;
+    wire irq;
+    wire reset;
+    wire RST;
+    wire [11:0] mfgr_id;
+    wire [7:0] prod_id;
+    wire [3:0] mask_rev;
+
+    initial begin
+        wb_clk_i = 0; 
+        wb_rst_i = 0;
+        wb_stb_i = 0; 
+        wb_cyc_i = 0;  
+        wb_sel_i = 0;  
+        wb_we_i  = 0;  
+        wb_dat_i = 0; 
+        wb_adr_i = 0; 
+        CSB = 1;
+        SCK = 0;
+        SDI = 0;
+        RSTB = 0; 
+    end
+
+    always #1 wb_clk_i = ~wb_clk_i;
+
+    // System Control Default Register Addresses (Read-only reg)
+    wire [31:0] spi_cfg         = uut.BASE_ADR | uut.SPI_CFG; // unused & reserved ? 
+    wire [31:0] spi_ena         = uut.BASE_ADR | uut.SPI_ENA;
+    wire [31:0] spi_pll_cfg     = uut.BASE_ADR | uut.SPI_PLL_CFG;
+    wire [31:0] spi_mfgr_id     = uut.BASE_ADR | uut.SPI_MFGR_ID;
+    wire [31:0] spi_prod_id     = uut.BASE_ADR | uut.SPI_PROD_ID;
+    wire [31:0] spi_mask_rev    = uut.BASE_ADR | uut.SPI_MASK_REV;
+    wire [31:0] spi_pll_bypass  = uut.BASE_ADR | uut.SPI_PLL_BYPASS;
+
+    initial begin
+        $dumpfile("spi_sysctrl_wb_tb.vcd");
+        $dumpvars(0, spi_sysctrl_wb_tb);
+        repeat (50) begin
+            repeat (1000) @(posedge wb_clk_i);
+        end
+        $display("%c[1;31m",27);
+        $display ("Monitor: Timeout, Test SPI System Control Failed");
+        $display("%c[0m",27);
+        $finish;
+    end
+
+    integer i;
+
+    initial begin   
+        // Reset Operation
+        wb_rst_i = 1;
+        RSTB = 0;       // active low reset
+        #2;
+        wb_rst_i = 0;
+        RSTB = 1; 
+        #2;
+
+        // Read mask_rev register
+        mask_rev_in = 4'hF;
+        read(spi_mask_rev);
+        if (wb_dat_o !== {28'd0, mask_rev_in}) begin
+            $display("Error reading mask_rev reg");
+            $finish;
+        end
+
+        // Read manufacture id register
+        read(spi_mfgr_id);
+        if (wb_dat_o !== {20'd0, 12'h456}) begin
+            $display("Error reading manufacture id reg");
+            $finish;
+        end
+
+        // Read product id register
+        read(spi_prod_id);
+        if (wb_dat_o !== {24'd0, 8'h05}) begin
+            $display("Error reading product id reg");
+            $finish;
+        end
+
+        // Read PLL-Bypass register
+        read(spi_pll_bypass);
+        if (wb_dat_o !== {31'd0, 1'b1}) begin
+            $display("Error reading pll bypass id reg");
+            $finish;
+        end
+
+        // Read PLL-Configuration register
+        read(spi_pll_cfg);
+        if (wb_dat_o !== {5'd0, spi_ro_pll_trim, spi_ro_pll_dco_ena}) begin
+            $display("Error reading pll bypass id reg");
+            $finish;
+        end
+
+        // Read SPI Enables register
+        read(spi_ena);
+        if (wb_dat_o !== {22'd0, spi_ro_pll_div, spi_ro_pll_sel, spi_ro_xtal_ena, spi_ro_reg_ena}) begin
+            $display("Error reading pll bypass id reg");
+            $finish;
+        end                
+        $display("Success!");
+        $finish;
+    end
+
+    task read;
+        input [32:0] addr;
+        begin 
+            @(posedge wb_clk_i) begin
+                wb_stb_i = 1;
+                wb_cyc_i = 1;
+                wb_we_i = 0;
+                wb_adr_i = addr;
+                $display("Monitor: Read Cycle Started.");
+            end
+            // Wait for an ACK
+            wait(wb_ack_o == 1);
+            wait(wb_ack_o == 0);
+            wb_cyc_i = 0;
+            wb_stb_i = 0;
+            $display("Monitor: Read Cycle Ended.");
+        end
+    endtask
+
+    spi_sysctrl_wb uut(
+        .wb_clk_i(wb_clk_i),
+	    .wb_rst_i(wb_rst_i),
+
+        .wb_stb_i(wb_stb_i),
+	    .wb_cyc_i(wb_cyc_i),
+	    .wb_sel_i(wb_sel_i),
+	    .wb_we_i(wb_we_i),
+	    .wb_dat_i(wb_dat_i),
+	    .wb_adr_i(wb_adr_i), 
+        .wb_ack_o(wb_ack_o),
+	    .wb_dat_o(wb_dat_o),
+        
+        .spi_ro_config(spi_ro_config), // (verify) wire input to the core not connected to HKSPI, what should it be connected to ? 
+        .spi_ro_pll_div(spi_ro_pll_div), 
+        .spi_ro_pll_sel(spi_ro_pll_sel),
+        .spi_ro_xtal_ena(spi_ro_xtal_ena),
+        .spi_ro_reg_ena(spi_ro_reg_ena), 
+    
+        .spi_ro_pll_trim(spi_ro_pll_trim),
+        .spi_ro_pll_dco_ena(spi_ro_pll_dco_ena),  
+
+        .spi_ro_mfgr_id(spi_ro_mfgr_id),
+        .spi_ro_prod_id(spi_ro_prod_id), 
+        .spi_ro_mask_rev(spi_ro_mask_rev), 
+        .pll_bypass(spi_ro_pll_bypass)
+    );
+
+    striVe_spi hkspi (
+		.RSTB(RSTB),
+		.SCK(SCK),
+		.SDI(SDI),
+		.CSB(CSB),
+
+		.SDO(SDO),
+		.sdo_enb(SDO_enb),
+		.xtal_ena(spi_ro_xtal_ena),
+		.reg_ena(spi_ro_reg_ena),
+		.pll_dco_ena(spi_ro_pll_dco_ena),
+		.pll_sel(spi_ro_pll_sel),
+		.pll_div(spi_ro_pll_div),
+		.pll_trim(spi_ro_pll_trim),
+		.pll_bypass(spi_ro_pll_bypass),
+		.irq(irq_spi),
+		.RST(por),
+		.reset(ext_reset),
+		.trap(trap),
+		.mfgr_id(spi_ro_mfgr_id),
+		.prod_id(spi_ro_prod_id),
+		.mask_rev_in(mask_rev_in),
+		.mask_rev(spi_ro_mask_rev)
+    );
+
+endmodule
\ No newline at end of file
diff --git a/verilog/dv/wb/spi_sysctrl_wb/spi_sysctrl_wb_tb.vcd b/verilog/dv/wb/spi_sysctrl_wb/spi_sysctrl_wb_tb.vcd
new file mode 100644
index 0000000..3abe514
--- /dev/null
+++ b/verilog/dv/wb/spi_sysctrl_wb/spi_sysctrl_wb_tb.vcd
@@ -0,0 +1,460 @@
+$date
+	Fri Aug 21 14:21:00 2020
+$end
+$version
+	Icarus Verilog
+$end
+$timescale
+	1ps
+$end
+$scope module spi_sysctrl_wb_tb $end
+$var wire 32 ! spi_cfg [31:0] $end
+$var wire 32 " spi_ena [31:0] $end
+$var wire 32 # spi_mask_rev [31:0] $end
+$var wire 32 $ spi_mfgr_id [31:0] $end
+$var wire 32 % spi_pll_bypass [31:0] $end
+$var wire 32 & spi_pll_cfg [31:0] $end
+$var wire 32 ' spi_prod_id [31:0] $end
+$var wire 8 ( spi_ro_config [7:0] $end
+$var wire 12 ) spi_ro_mfgr_id [11:0] $end
+$var wire 8 * spi_ro_prod_id [7:0] $end
+$var wire 32 + wb_dat_o [31:0] $end
+$var wire 1 , wb_ack_o $end
+$var wire 1 - spi_ro_xtal_ena $end
+$var wire 1 . spi_ro_reg_ena $end
+$var wire 26 / spi_ro_pll_trim [25:0] $end
+$var wire 3 0 spi_ro_pll_sel [2:0] $end
+$var wire 5 1 spi_ro_pll_div [4:0] $end
+$var wire 1 2 spi_ro_pll_dco_ena $end
+$var wire 1 3 spi_ro_pll_bypass $end
+$var wire 4 4 spi_ro_mask_rev [3:0] $end
+$var wire 1 5 por $end
+$var wire 1 6 irq_spi $end
+$var wire 1 7 ext_reset $end
+$var wire 1 8 SDO_enb $end
+$var wire 1 9 SDO $end
+$var reg 1 : CSB $end
+$var reg 1 ; RSTB $end
+$var reg 1 < SCK $end
+$var reg 1 = SDI $end
+$var reg 4 > mask_rev_in [3:0] $end
+$var reg 1 ? trap $end
+$var reg 32 @ wb_adr_i [31:0] $end
+$var reg 1 A wb_clk_i $end
+$var reg 1 B wb_cyc_i $end
+$var reg 32 C wb_dat_i [31:0] $end
+$var reg 1 D wb_rst_i $end
+$var reg 4 E wb_sel_i [3:0] $end
+$var reg 1 F wb_stb_i $end
+$var reg 1 G wb_we_i $end
+$scope module hkspi $end
+$var wire 1 : CSB $end
+$var wire 1 5 RST $end
+$var wire 1 ; RSTB $end
+$var wire 1 < SCK $end
+$var wire 1 = SDI $end
+$var wire 4 H mask_rev [3:0] $end
+$var wire 4 I mask_rev_in [3:0] $end
+$var wire 12 J mfgr_id [11:0] $end
+$var wire 8 K prod_id [7:0] $end
+$var wire 1 ? trap $end
+$var wire 1 L wrstb $end
+$var wire 1 8 sdo_enb $end
+$var wire 1 M rdstb $end
+$var wire 8 N odata [7:0] $end
+$var wire 8 O idata [7:0] $end
+$var wire 8 P iaddr [7:0] $end
+$var wire 1 9 SDO $end
+$var reg 1 6 irq $end
+$var reg 1 3 pll_bypass $end
+$var reg 1 2 pll_dco_ena $end
+$var reg 5 Q pll_div [4:0] $end
+$var reg 3 R pll_sel [2:0] $end
+$var reg 26 S pll_trim [25:0] $end
+$var reg 1 . reg_ena $end
+$var reg 1 7 reset $end
+$var reg 1 - xtal_ena $end
+$scope module U1 $end
+$var wire 1 : CSB $end
+$var wire 1 < SCK $end
+$var wire 1 = SDI $end
+$var wire 8 T idata [7:0] $end
+$var wire 8 U odata [7:0] $end
+$var wire 8 V oaddr [7:0] $end
+$var wire 1 9 SDO $end
+$var reg 8 W addr [7:0] $end
+$var reg 3 X count [2:0] $end
+$var reg 3 Y fixed [2:0] $end
+$var reg 8 Z ldata [7:0] $end
+$var reg 7 [ predata [6:0] $end
+$var reg 1 M rdstb $end
+$var reg 1 \ readmode $end
+$var reg 1 8 sdoenb $end
+$var reg 2 ] state [1:0] $end
+$var reg 1 ^ writemode $end
+$var reg 1 L wrstb $end
+$upscope $end
+$upscope $end
+$scope module uut $end
+$var wire 4 _ iomem_we [3:0] $end
+$var wire 1 3 pll_bypass $end
+$var wire 1 ` resetn $end
+$var wire 8 a spi_ro_config [7:0] $end
+$var wire 4 b spi_ro_mask_rev [3:0] $end
+$var wire 12 c spi_ro_mfgr_id [11:0] $end
+$var wire 1 2 spi_ro_pll_dco_ena $end
+$var wire 5 d spi_ro_pll_div [4:0] $end
+$var wire 3 e spi_ro_pll_sel [2:0] $end
+$var wire 26 f spi_ro_pll_trim [25:0] $end
+$var wire 8 g spi_ro_prod_id [7:0] $end
+$var wire 1 . spi_ro_reg_ena $end
+$var wire 1 - spi_ro_xtal_ena $end
+$var wire 1 h valid $end
+$var wire 1 , wb_ack_o $end
+$var wire 32 i wb_adr_i [31:0] $end
+$var wire 1 A wb_clk_i $end
+$var wire 1 B wb_cyc_i $end
+$var wire 32 j wb_dat_i [31:0] $end
+$var wire 1 D wb_rst_i $end
+$var wire 4 k wb_sel_i [3:0] $end
+$var wire 1 F wb_stb_i $end
+$var wire 1 G wb_we_i $end
+$var wire 32 l wb_dat_o [31:0] $end
+$var wire 1 m ready $end
+$scope module spi_sysctrl $end
+$var wire 1 A clk $end
+$var wire 32 n iomem_addr [31:0] $end
+$var wire 1 h iomem_valid $end
+$var wire 32 o iomem_wdata [31:0] $end
+$var wire 4 p iomem_wstrb [3:0] $end
+$var wire 1 3 pll_bypass $end
+$var wire 1 ` resetn $end
+$var wire 8 q spi_ro_config [7:0] $end
+$var wire 4 r spi_ro_mask_rev [3:0] $end
+$var wire 12 s spi_ro_mfgr_id [11:0] $end
+$var wire 1 2 spi_ro_pll_dco_ena $end
+$var wire 5 t spi_ro_pll_div [4:0] $end
+$var wire 3 u spi_ro_pll_sel [2:0] $end
+$var wire 26 v spi_ro_pll_trim [25:0] $end
+$var wire 8 w spi_ro_prod_id [7:0] $end
+$var wire 1 . spi_ro_reg_ena $end
+$var wire 1 - spi_ro_xtal_ena $end
+$var wire 1 x spi_prod_sel $end
+$var wire 1 y spi_mfgr_sel $end
+$var wire 1 z spi_maskrev_sel $end
+$var wire 1 { spi_ena_sel $end
+$var wire 1 | spi_cfg_sel $end
+$var wire 1 } pll_cfg_sel $end
+$var wire 1 ~ pll_bypass_sel $end
+$var reg 32 !" iomem_rdata [31:0] $end
+$var reg 1 m iomem_ready $end
+$upscope $end
+$upscope $end
+$scope task read $end
+$var reg 33 "" addr [32:0] $end
+$upscope $end
+$upscope $end
+$enddefinitions $end
+#0
+$dumpvars
+bx ""
+bx !"
+0~
+0}
+1|
+0{
+0z
+0y
+0x
+b101 w
+b11111111111110111111111111 v
+b0 u
+b100 t
+b10001010110 s
+bx r
+bz q
+b0 p
+b0 o
+b0 n
+xm
+bx l
+b0 k
+b0 j
+b0 i
+0h
+b101 g
+b11111111111110111111111111 f
+b0 e
+b100 d
+b10001010110 c
+bx b
+bz a
+0`
+b0 _
+0^
+b0 ]
+0\
+b0 [
+b0 Z
+b0 Y
+b0 X
+b0 W
+b0 V
+b0 U
+b0 T
+b11111111111110111111111111 S
+b0 R
+b100 Q
+b0 P
+b0 O
+b0 N
+0M
+0L
+b101 K
+b10001010110 J
+bx I
+bx H
+0G
+0F
+b0 E
+1D
+b0 C
+0B
+0A
+b0 @
+x?
+bx >
+0=
+0<
+0;
+1:
+09
+18
+07
+06
+15
+bx 4
+13
+12
+b100 1
+b0 0
+b11111111111110111111111111 /
+1.
+1-
+x,
+bx +
+b101 *
+b10001010110 )
+bz (
+b101110000000000000000000010000 '
+b101110000000000000000000001000 &
+b101110000000000000000000011000 %
+b101110000000000000000000001100 $
+b101110000000000000000000010100 #
+b101110000000000000000000000100 "
+b101110000000000000000000000000 !
+$end
+#1000
+0,
+0m
+1A
+#2000
+05
+1`
+0A
+1;
+0D
+#3000
+1A
+#4000
+0A
+b101110000000000000000000010100 ""
+b1111 4
+b1111 H
+b1111 b
+b1111 r
+b1111 >
+b1111 I
+#5000
+0|
+1z
+1h
+b101110000000000000000000010100 @
+b101110000000000000000000010100 i
+b101110000000000000000000010100 n
+1B
+1F
+1A
+#6000
+0A
+#7000
+b1111 +
+b1111 l
+b1111 !"
+1,
+1m
+1A
+#8000
+0A
+#9000
+0h
+b101110000000000000000000001100 ""
+0F
+0B
+0,
+0m
+1A
+#10000
+0A
+#11000
+1y
+0z
+1h
+b101110000000000000000000001100 @
+b101110000000000000000000001100 i
+b101110000000000000000000001100 n
+1B
+1F
+1A
+#12000
+0A
+#13000
+b10001010110 +
+b10001010110 l
+b10001010110 !"
+1,
+1m
+1A
+#14000
+0A
+#15000
+0h
+b101110000000000000000000010000 ""
+0F
+0B
+0,
+0m
+1A
+#16000
+0A
+#17000
+0y
+1x
+1h
+b101110000000000000000000010000 @
+b101110000000000000000000010000 i
+b101110000000000000000000010000 n
+1B
+1F
+1A
+#18000
+0A
+#19000
+b101 +
+b101 l
+b101 !"
+1,
+1m
+1A
+#20000
+0A
+#21000
+0h
+b101110000000000000000000011000 ""
+0F
+0B
+0,
+0m
+1A
+#22000
+0A
+#23000
+0x
+1~
+1h
+b101110000000000000000000011000 @
+b101110000000000000000000011000 i
+b101110000000000000000000011000 n
+1B
+1F
+1A
+#24000
+0A
+#25000
+b1 +
+b1 l
+b1 !"
+1,
+1m
+1A
+#26000
+0A
+#27000
+0h
+b101110000000000000000000001000 ""
+0F
+0B
+0,
+0m
+1A
+#28000
+0A
+#29000
+1}
+0~
+1h
+b101110000000000000000000001000 @
+b101110000000000000000000001000 i
+b101110000000000000000000001000 n
+1B
+1F
+1A
+#30000
+0A
+#31000
+b111111111111101111111111111 +
+b111111111111101111111111111 l
+b111111111111101111111111111 !"
+1,
+1m
+1A
+#32000
+0A
+#33000
+0h
+b101110000000000000000000000100 ""
+0F
+0B
+0,
+0m
+1A
+#34000
+0A
+#35000
+1{
+0}
+1h
+b101110000000000000000000000100 @
+b101110000000000000000000000100 i
+b101110000000000000000000000100 n
+1B
+1F
+1A
+#36000
+0A
+#37000
+b10000011 +
+b10000011 l
+b10000011 !"
+1,
+1m
+1A
+#38000
+0A
+#39000
+0h
+0F
+0B
+0,
+0m
+1A
diff --git a/verilog/dv/wb/spimemio_wb/Makefile b/verilog/dv/wb/spimemio_wb/Makefile
new file mode 100644
index 0000000..075241d
--- /dev/null
+++ b/verilog/dv/wb/spimemio_wb/Makefile
@@ -0,0 +1,18 @@
+.SUFFIXES:
+
+PATTERN = spimemio_wb
+
+all:  ${PATTERN:=.vcd}
+
+%.vvp: %_tb.v
+	iverilog -I ../ -I ../../  -I ../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+clean:
+	rm -f *.vvp *.vcd *.log
+
+.PHONY: clean all
+
diff --git a/verilog/dv/wb/spimemio_wb/flash.hex b/verilog/dv/wb/spimemio_wb/flash.hex
new file mode 100644
index 0000000..23bd76d
--- /dev/null
+++ b/verilog/dv/wb/spimemio_wb/flash.hex
@@ -0,0 +1,6 @@
+@10000000
+a1
+b1
+c1
+d1
+f1
\ No newline at end of file
diff --git a/verilog/dv/wb/spimemio_wb/spimemio_wb_tb.v b/verilog/dv/wb/spimemio_wb/spimemio_wb_tb.v
new file mode 100644
index 0000000..b75e6fc
--- /dev/null
+++ b/verilog/dv/wb/spimemio_wb/spimemio_wb_tb.v
@@ -0,0 +1,217 @@
+
+
+`timescale 1 ns / 1 ps
+
+`define FLASH_BASE  32'h 1000_000
+
+`include "spimemio.v"
+// `include "spiflash.v"
+
+module spimemio_wb_tb;
+
+    reg wb_clk_i;
+	reg wb_rst_i;
+
+    reg wb_flash_stb_i;
+	reg wb_cfg_stb_i;
+	reg wb_cyc_i;
+	reg wb_we_i;
+	reg [3:0]  wb_sel_i;
+	reg [31:0] wb_adr_i;
+	reg [31:0] wb_dat_i;
+
+	wire wb_flash_ack_o;
+    wire wb_cfg_ack_o;
+	wire [31:0] wb_flash_dat_o;
+	wire [31:0] wb_cfg_dat_o;
+
+    wire flash_csb;
+    wire flash_clk;
+
+    wire flash_io0_oeb;
+    wire flash_io1_oeb;
+    wire flash_io2_oeb;
+    wire flash_io3_oeb;
+
+    wire flash_io0_di = 1'b 1;
+    wire flash_io1_di = 1'b 1;
+    wire flash_io2_di = 1'b 1;
+    wire flash_io3_di = 1'b 1;
+
+    initial begin
+        wb_clk_i = 0; 
+        wb_rst_i = 0;
+        wb_flash_stb_i = 0;  
+        wb_cfg_stb_i = 0; 
+        wb_cyc_i = 0;   
+        wb_we_i  = 0;
+        wb_sel_i = 0;    
+        wb_adr_i = 0;  
+        wb_dat_i = 0;  
+    end
+
+    always #1 wb_clk_i = ~wb_clk_i;
+
+    spimemio_wb uut(
+        .wb_clk_i(wb_clk_i),
+	    .wb_rst_i(wb_rst_i),
+        
+        .wb_flash_stb_i(wb_flash_stb_i),
+	    .wb_cfg_stb_i(wb_cfg_stb_i),
+	    .wb_cyc_i(wb_cyc_i),
+    	.wb_we_i(wb_we_i),
+	    .wb_sel_i(wb_sel_i),
+	    .wb_adr_i(wb_adr_i), 
+	    .wb_dat_i(wb_dat_i),
+	    .wb_flash_ack_o(wb_flash_ack_o),
+        .wb_cfg_ack_o(wb_cfg_ack_o),
+	    .wb_flash_dat_o(wb_flash_dat_o),
+	    .wb_cfg_dat_o(wb_cfg_dat_o),
+
+        .flash_clk(flash_clk),
+        .flash_csb(flash_csb),
+
+        .flash_io0_oeb(flash_io0_oeb),
+        .flash_io1_oeb(flash_io1_oeb),
+        .flash_io2_oeb(flash_io2_oeb),
+        .flash_io3_oeb(flash_io3_oeb),
+
+        .flash_io0_di(flash_io0_di),
+        .flash_io1_di(flash_io1_di),
+	    .flash_io2_di(flash_io2_di),
+	    .flash_io3_di(flash_io3_di)       
+    );
+
+    initial begin
+        $dumpfile("spimemio_wb_tb.vcd");
+        $dumpvars(0, spimemio_wb_tb);
+        repeat (50) begin
+            repeat (1000) @(posedge wb_clk_i);
+        end
+        $display("%c[1;31m",27);
+        $display ("Monitor: Timeout, Test spimmemio Failed");
+        $display("%c[0m",27);
+        $finish;
+    end
+
+    integer i;
+        
+    wire [31:0] cfgreg_data;
+    assign cfgreg_data = {
+        1'b 1,
+        8'b 0,
+        3'b 111,
+        4'b 1010,
+        4'b 0,             // make sure is it tied to zero in the module itself
+        {~flash_io3_oeb, ~flash_io2_oeb, ~flash_io1_oeb, ~flash_io0_oeb},
+        2'b 0,
+        flash_csb,
+        flash_clk,
+        {flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di}
+    };
+
+    initial begin
+        // Reset Operation
+        wb_rst_i = 1;
+        #2;
+        wb_rst_i = 0; 
+        #2;
+
+        // Read from flash
+        for (i = `FLASH_BASE; i < `FLASH_BASE + 100 ; i = i + 4) begin
+            read(i, 1, 0);
+            if (wb_flash_dat_o !== 32'hFFFF_FFFF) begin
+                $display("%c[1;31m",27);
+                $display("Expected %0b, but Got %0b ",  32'hFFFF_FFFF, wb_flash_dat_o);
+                $display("Monitor: Wishbone spimemio Failed");
+            	$display("%c[0m",27);
+                $finish;
+            end
+            #2;
+        end 
+
+        #6;
+        // Write to Configuration register
+        write(cfgreg_data, 0);
+        #2;
+        read(0, 0, 1);
+        if (wb_cfg_dat_o !== cfgreg_data) begin
+            $display("%c[1;31m",27);
+            $display("Expected %0b, but Got %0b ",  cfgreg_data, wb_cfg_dat_o);
+            $display("Monitor: Wishbone spimemio Failed");
+            $display("%c[0m",27);
+            $finish;
+        end
+        
+        $display("Success!");
+        $finish;
+    end
+    
+    task write;
+        input [32:0] data;
+        input [31:0] addr;
+        begin 
+            @(posedge wb_clk_i) begin
+                wb_cfg_stb_i = 1'b 1;
+                wb_flash_stb_i = 1'b 0;
+                wb_cyc_i = 1'b 1;
+                wb_sel_i = 4'b 1111; // complete word
+                wb_we_i = 1'b 1;     // write enable
+                wb_adr_i = addr;
+                wb_dat_i = data;
+            end
+
+            wait_ack();
+        end
+    endtask
+    
+    task read;
+        input [32:0] addr;
+        input flash_stb;
+        input cfg_stb;
+        begin 
+            wb_flash_stb_i = flash_stb;
+            wb_cfg_stb_i = cfg_stb;
+
+            wb_cyc_i = 1'b 1;
+            wb_adr_i = addr;
+            wb_dat_i = 24;
+            wb_sel_i = 4'b 1111; // complete word
+            wb_we_i = 1'b 0;     // read
+            $display("Initiated Read transaction...");
+            wait_ack();
+        end
+    endtask
+
+    task wait_ack;
+        // Wait for an ACK
+        if (wb_cfg_stb_i == 1) begin
+            @(posedge wb_cfg_ack_o) begin
+                #2;  // To end the transaction on the falling edge of ack 
+                wb_cyc_i = 1'b 0;
+                wb_cfg_stb_i = 1'b 0;
+                $display("Monitor: Received an ACK from slave");
+            end
+        end
+        else begin
+            @(posedge wb_flash_ack_o) begin
+                #2;  // To end the transaction on the falling edge of ack 
+                wb_cyc_i = 1'b 0;
+                wb_flash_stb_i = 1'b 0;
+                $display("Monitor: Received an ACK from slave");
+            end
+        end
+    endtask
+
+    // spiflash #(
+	// 	.FILENAME("flash.hex")
+	// ) spiflash (
+	// 	.csb(flash_csb),
+	// 	.clk(flash_clk),
+	// 	.io0(flash_io0),
+	// 	.io1(flash_io1),
+	// 	.io2(flash_io2),
+	// 	.io3(flash_io3)
+	// );
+    
+endmodule
\ No newline at end of file
diff --git a/verilog/dv/wb/sysctrl_wb/Makefile b/verilog/dv/wb/sysctrl_wb/Makefile
new file mode 100644
index 0000000..e1b0978
--- /dev/null
+++ b/verilog/dv/wb/sysctrl_wb/Makefile
@@ -0,0 +1,18 @@
+.SUFFIXES:
+
+PATTERN = sysctrl_wb
+
+all:  ${PATTERN:=.vcd}
+
+%.vvp: %_tb.v
+	iverilog  -I ../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+clean:
+	rm -f *.vvp *.vcd *.log
+
+.PHONY: clean all
+
diff --git a/verilog/dv/wb/sysctrl_wb/sysctrl_wb_tb.v b/verilog/dv/wb/sysctrl_wb/sysctrl_wb_tb.v
new file mode 100644
index 0000000..e0ec433
--- /dev/null
+++ b/verilog/dv/wb/sysctrl_wb/sysctrl_wb_tb.v
@@ -0,0 +1,222 @@
+
+`timescale 1 ns / 1 ps
+
+`include "sysctrl.v"
+
+module sysctrl_wb_tb;
+
+    reg wb_clk_i;
+	reg wb_rst_i;
+
+    reg wb_stb_i;
+    reg wb_cyc_i;
+	reg wb_we_i;
+	reg [3:0] wb_sel_i;
+	reg [31:0] wb_dat_i;
+	reg [31:0] wb_adr_i;
+
+	wire wb_ack_o;
+	wire [31:0] wb_dat_o;
+    
+    reg overtemp;
+
+    initial begin
+        wb_clk_i = 0; 
+        wb_rst_i = 0;
+        wb_stb_i = 0; 
+        wb_cyc_i = 0;  
+        wb_sel_i = 0;  
+        wb_we_i  = 0;  
+        wb_dat_i = 0; 
+        wb_adr_i = 0; 
+    end
+
+    always #1 wb_clk_i = ~wb_clk_i;
+    
+    initial begin
+        $dumpfile("sysctrl_wb_tb.vcd");
+        $dumpvars(0, sysctrl_wb_tb);
+        repeat (50) begin
+            repeat (1000) @(posedge wb_clk_i);
+        end
+        $display("%c[1;31m",27);
+        $display ("Monitor: Timeout, Test System Control Failed");
+        $display("%c[0m",27);
+        $finish;
+    end
+
+    integer i;
+    
+    // System Control Default Register Addresses 
+    wire [31:0] osc_ena_adr   = uut.BASE_ADR | uut.OSC_ENA;  
+    wire [31:0] osc_out_adr   = uut.BASE_ADR | uut.OSC_OUT;
+    wire [31:0] xtal_out_adr  = uut.BASE_ADR | uut.XTAL_OUT;
+    wire [31:0] pll_out_adr   = uut.BASE_ADR | uut.PLL_OUT;
+    wire [31:0] trap_out_adr  = uut.BASE_ADR | uut.TRAP_OUT;
+    wire [31:0] irq7_src_adr  = uut.BASE_ADR | uut.IRQ7_SRC;
+    wire [31:0] irq8_src_adr  = uut.BASE_ADR | uut.IRQ8_SRC;
+    wire [31:0] overtemp_adr  = uut.BASE_ADR | uut.OVERTEMP_DATA;
+    wire [31:0] overtemp_ena_adr  = uut.BASE_ADR | uut.OVERTEMP_ENA;
+    wire [31:0] ovetemp_out_adr   = uut.BASE_ADR | uut.OVERTEMP_OUT;
+
+    reg rcosc_ena;
+    reg [1:0] rcosc_output_dest;
+    reg [1:0] xtal_output_dest;
+    reg [1:0] pll_output_dest;
+    reg [1:0] trap_output_dest;
+    reg [1:0] irq_7_inputsrc;
+    reg [1:0] irq_8_inputsrc;
+    reg overtemp_ena;
+    reg [1:0] overtemp_dest;
+
+    initial begin
+        // Reset Operation
+        wb_rst_i = 1;
+        #2;
+        wb_rst_i = 0;
+        #2;
+        
+        overtemp  = 1'b1;
+        rcosc_ena = 1'b1;
+        rcosc_output_dest = 2'b10;
+        xtal_output_dest  = 2'b01;
+        pll_output_dest   = 2'b11;
+        trap_output_dest  = 2'b10;
+        irq_7_inputsrc    = 2'b01;
+        irq_8_inputsrc    = 2'b11;
+        overtemp_ena  = 1'b1;
+        overtemp_dest = 1'b1;
+
+        // Write to System Control Registers (except overtemp; read-only)
+        write(osc_ena_adr, rcosc_ena);
+        write(osc_out_adr, rcosc_output_dest);
+        write(xtal_out_adr, xtal_output_dest);
+        write(pll_out_adr, pll_output_dest);
+        write(trap_out_adr, trap_output_dest);
+        write(irq7_src_adr, irq_7_inputsrc);
+        write(irq8_src_adr, irq_8_inputsrc);
+        write(overtemp_ena_adr, overtemp_ena);
+        write(ovetemp_out_adr, overtemp_dest);
+        
+        #2;
+        // Read System Control Registers
+        read(overtemp_adr);
+        if (wb_dat_o !== overtemp) begin
+            $display("Error reading from overtemp reg");
+            $finish;
+        end
+
+        read(osc_ena_adr);
+        if (wb_dat_o !== rcosc_ena) begin
+            $display("Error reading oscillator enable register.");
+            $finish;
+        end
+
+        read(osc_out_adr);
+        if (wb_dat_o !== rcosc_output_dest) begin
+            $display("Error reading oscillator output destination register.");
+            $finish;
+        end
+        
+        read(xtal_out_adr);
+        if (wb_dat_o !== xtal_output_dest) begin
+            $display("Error reading XTAL output destination register.");
+            $finish;
+        end
+
+        read(pll_out_adr);
+        if (wb_dat_o !== pll_output_dest) begin
+            $display("Error reading PLL output destination register.");
+            $finish;
+        end
+
+        read(trap_out_adr);
+        if (wb_dat_o !== trap_output_dest) begin
+            $display("Error reading trap output destination register.");
+            $finish;
+        end
+
+        read(irq7_src_adr);
+        if (wb_dat_o !== irq_7_inputsrc) begin
+            $display("Error reading IRQ7 input source register.");
+            $finish;
+        end
+
+        read(irq8_src_adr);
+        if (wb_dat_o !== irq_8_inputsrc) begin
+            $display("Error reading IRQ7 input source register.");
+            $finish;
+        end
+
+        read(overtemp_ena_adr);
+        if (wb_dat_o !== overtemp_ena) begin
+            $display("Error reading over-temperature enable register.");
+            $finish;
+        end
+
+        read(ovetemp_out_adr);
+        if (wb_dat_o !== overtemp_dest) begin
+            $display("Error reading over-temperature output destination register.");
+            $finish;
+        end
+
+        $display("Success!");
+        $finish;
+    end
+    
+    task write;
+        input [32:0] addr;
+        input [32:0] data;
+        begin 
+            @(posedge wb_clk_i) begin
+                wb_stb_i = 1;
+                wb_cyc_i = 1;
+                wb_sel_i = 4'hF; 
+                wb_we_i = 1;     
+                wb_adr_i = addr;
+                wb_dat_i = data;
+                $display("Monitor: Write Cycle Started.");
+            end
+            // Wait for an ACK
+            wait(wb_ack_o == 1);
+            wait(wb_ack_o == 0);
+            wb_cyc_i = 0;
+            wb_stb_i = 0;
+            $display("Monitor: Write Cycle Ended.");
+        end
+    endtask
+    
+    task read;
+        input [32:0] addr;
+        begin 
+            @(posedge wb_clk_i) begin
+                wb_stb_i = 1;
+                wb_cyc_i = 1;
+                wb_we_i = 0;
+                wb_adr_i = addr;
+                $display("Monitor: Read Cycle Started.");
+            end
+            // Wait for an ACK
+            wait(wb_ack_o == 1);
+            wait(wb_ack_o == 0);
+            wb_cyc_i = 0;
+            wb_stb_i = 0;
+            $display("Monitor: Read Cycle Ended.");
+        end
+    endtask
+
+    sysctrl_wb uut(
+        .wb_clk_i(wb_clk_i),
+	    .wb_rst_i(wb_rst_i),
+        .wb_stb_i(wb_stb_i),
+	    .wb_cyc_i(wb_cyc_i),
+	    .wb_sel_i(wb_sel_i),
+	    .wb_we_i(wb_we_i),
+	    .wb_dat_i(wb_dat_i),
+	    .wb_adr_i(wb_adr_i), 
+        .wb_ack_o(wb_ack_o),
+	    .wb_dat_o(wb_dat_o),
+        .overtemp(overtemp)
+    );
+    
+endmodule
diff --git a/verilog/dv/wb/sysctrl_wb/sysctrl_wb_tb.vcd b/verilog/dv/wb/sysctrl_wb/sysctrl_wb_tb.vcd
new file mode 100644
index 0000000..31cad7c
--- /dev/null
+++ b/verilog/dv/wb/sysctrl_wb/sysctrl_wb_tb.vcd
@@ -0,0 +1,828 @@
+$date
+	Fri Aug 21 14:21:19 2020
+$end
+$version
+	Icarus Verilog
+$end
+$timescale
+	1ps
+$end
+$scope module sysctrl_wb_tb $end
+$var wire 32 ! irq7_src_adr [31:0] $end
+$var wire 32 " irq8_src_adr [31:0] $end
+$var wire 32 # osc_ena_adr [31:0] $end
+$var wire 32 $ osc_out_adr [31:0] $end
+$var wire 32 % overtemp_adr [31:0] $end
+$var wire 32 & overtemp_ena_adr [31:0] $end
+$var wire 32 ' ovetemp_out_adr [31:0] $end
+$var wire 32 ( pll_out_adr [31:0] $end
+$var wire 32 ) trap_out_adr [31:0] $end
+$var wire 32 * xtal_out_adr [31:0] $end
+$var wire 32 + wb_dat_o [31:0] $end
+$var wire 1 , wb_ack_o $end
+$var reg 2 - irq_7_inputsrc [1:0] $end
+$var reg 2 . irq_8_inputsrc [1:0] $end
+$var reg 1 / overtemp $end
+$var reg 2 0 overtemp_dest [1:0] $end
+$var reg 1 1 overtemp_ena $end
+$var reg 2 2 pll_output_dest [1:0] $end
+$var reg 1 3 rcosc_ena $end
+$var reg 2 4 rcosc_output_dest [1:0] $end
+$var reg 2 5 trap_output_dest [1:0] $end
+$var reg 32 6 wb_adr_i [31:0] $end
+$var reg 1 7 wb_clk_i $end
+$var reg 1 8 wb_cyc_i $end
+$var reg 32 9 wb_dat_i [31:0] $end
+$var reg 1 : wb_rst_i $end
+$var reg 4 ; wb_sel_i [3:0] $end
+$var reg 1 < wb_stb_i $end
+$var reg 1 = wb_we_i $end
+$var reg 2 > xtal_output_dest [1:0] $end
+$scope module uut $end
+$var wire 4 ? iomem_we [3:0] $end
+$var wire 1 / overtemp $end
+$var wire 1 @ resetn $end
+$var wire 1 A valid $end
+$var wire 1 , wb_ack_o $end
+$var wire 32 B wb_adr_i [31:0] $end
+$var wire 1 7 wb_clk_i $end
+$var wire 1 8 wb_cyc_i $end
+$var wire 32 C wb_dat_i [31:0] $end
+$var wire 1 : wb_rst_i $end
+$var wire 4 D wb_sel_i [3:0] $end
+$var wire 1 < wb_stb_i $end
+$var wire 1 = wb_we_i $end
+$var wire 2 E xtal_output_dest [1:0] $end
+$var wire 32 F wb_dat_o [31:0] $end
+$var wire 2 G trap_output_dest [1:0] $end
+$var wire 1 H ready $end
+$var wire 2 I rcosc_output_dest [1:0] $end
+$var wire 1 J rcosc_ena $end
+$var wire 2 K pll_output_dest [1:0] $end
+$var wire 1 L overtemp_ena $end
+$var wire 2 M overtemp_dest [1:0] $end
+$var wire 2 N irq_8_inputsrc [1:0] $end
+$var wire 2 O irq_7_inputsrc [1:0] $end
+$scope module sysctrl $end
+$var wire 1 7 clk $end
+$var wire 32 P iomem_addr [31:0] $end
+$var wire 1 A iomem_valid $end
+$var wire 32 Q iomem_wdata [31:0] $end
+$var wire 4 R iomem_wstrb [3:0] $end
+$var wire 1 / overtemp $end
+$var wire 1 @ resetn $end
+$var wire 1 S xtal_out_sel $end
+$var wire 1 T trap_out_sel $end
+$var wire 1 U pll_out_sel $end
+$var wire 1 V overtemp_sel $end
+$var wire 1 W overtemp_ena_sel $end
+$var wire 1 X overtemp_dest_sel $end
+$var wire 1 Y osc_out_sel $end
+$var wire 1 Z osc_ena_sel $end
+$var wire 1 [ irq8_sel $end
+$var wire 1 \ irq7_sel $end
+$var reg 32 ] iomem_rdata [31:0] $end
+$var reg 1 H iomem_ready $end
+$var reg 2 ^ irq_7_inputsrc [1:0] $end
+$var reg 2 _ irq_8_inputsrc [1:0] $end
+$var reg 2 ` overtemp_dest [1:0] $end
+$var reg 1 L overtemp_ena $end
+$var reg 2 a pll_output_dest [1:0] $end
+$var reg 1 J rcosc_ena $end
+$var reg 2 b rcosc_output_dest [1:0] $end
+$var reg 2 c trap_output_dest [1:0] $end
+$var reg 2 d xtal_output_dest [1:0] $end
+$upscope $end
+$upscope $end
+$scope task read $end
+$var reg 33 e addr [32:0] $end
+$upscope $end
+$scope task write $end
+$var reg 33 f addr [32:0] $end
+$var reg 33 g data [32:0] $end
+$upscope $end
+$upscope $end
+$enddefinitions $end
+#0
+$dumpvars
+bx g
+bx f
+bx e
+bx d
+bx c
+bx b
+bx a
+bx `
+bx _
+bx ^
+bx ]
+0\
+0[
+1Z
+0Y
+0X
+0W
+0V
+0U
+0T
+0S
+b0 R
+b0 Q
+b0 P
+bx O
+bx N
+bx M
+xL
+bx K
+xJ
+bx I
+xH
+bx G
+bx F
+bx E
+b0 D
+b0 C
+b0 B
+0A
+0@
+b0 ?
+bx >
+0=
+0<
+b0 ;
+1:
+b0 9
+08
+07
+b0 6
+bx 5
+bx 4
+x3
+bx 2
+x1
+bx 0
+x/
+bx .
+bx -
+x,
+bx +
+b101111000000000000000000001000 *
+b101111000000000000000000010000 )
+b101111000000000000000000001100 (
+b101111000000000000000000100100 '
+b101111000000000000000000011100 &
+b101111000000000000000000100000 %
+b101111000000000000000000000100 $
+b101111000000000000000000000000 #
+b101111000000000000000000011000 "
+b101111000000000000000000010100 !
+$end
+#1000
+0L
+b0 M
+b0 `
+b0 N
+b0 _
+b0 O
+b0 ^
+b0 G
+b0 c
+b0 E
+b0 d
+b0 K
+b0 a
+b0 I
+b0 b
+0J
+17
+#2000
+1@
+07
+0:
+#3000
+0,
+0H
+17
+#4000
+07
+b1 g
+b101111000000000000000000000000 f
+b1 0
+11
+b11 .
+b1 -
+b10 5
+b11 2
+b1 >
+b10 4
+13
+1/
+#5000
+b1111 ?
+b1111 R
+1A
+b1 9
+b1 C
+b1 Q
+b101111000000000000000000000000 6
+b101111000000000000000000000000 B
+b101111000000000000000000000000 P
+1=
+b1111 ;
+b1111 D
+18
+1<
+17
+#6000
+07
+#7000
+1J
+b0 +
+b0 F
+b0 ]
+1,
+1H
+17
+#8000
+07
+#9000
+0A
+b10 g
+b101111000000000000000000000100 f
+0<
+08
+0,
+0H
+17
+#10000
+07
+#11000
+0Z
+1Y
+1A
+b10 9
+b10 C
+b10 Q
+b101111000000000000000000000100 6
+b101111000000000000000000000100 B
+b101111000000000000000000000100 P
+18
+1<
+17
+#12000
+07
+#13000
+b10 I
+b10 b
+1,
+1H
+17
+#14000
+07
+#15000
+0A
+b1 g
+b101111000000000000000000001000 f
+0<
+08
+0,
+0H
+17
+#16000
+07
+#17000
+0Y
+1S
+1A
+b1 9
+b1 C
+b1 Q
+b101111000000000000000000001000 6
+b101111000000000000000000001000 B
+b101111000000000000000000001000 P
+18
+1<
+17
+#18000
+07
+#19000
+b1 E
+b1 d
+1,
+1H
+17
+#20000
+07
+#21000
+0A
+b11 g
+b101111000000000000000000001100 f
+0<
+08
+0,
+0H
+17
+#22000
+07
+#23000
+1U
+0S
+1A
+b11 9
+b11 C
+b11 Q
+b101111000000000000000000001100 6
+b101111000000000000000000001100 B
+b101111000000000000000000001100 P
+18
+1<
+17
+#24000
+07
+#25000
+b11 K
+b11 a
+1,
+1H
+17
+#26000
+07
+#27000
+0A
+b10 g
+b101111000000000000000000010000 f
+0<
+08
+0,
+0H
+17
+#28000
+07
+#29000
+0U
+1T
+1A
+b10 9
+b10 C
+b10 Q
+b101111000000000000000000010000 6
+b101111000000000000000000010000 B
+b101111000000000000000000010000 P
+18
+1<
+17
+#30000
+07
+#31000
+b10 G
+b10 c
+1,
+1H
+17
+#32000
+07
+#33000
+0A
+b1 g
+b101111000000000000000000010100 f
+0<
+08
+0,
+0H
+17
+#34000
+07
+#35000
+0T
+1\
+1A
+b1 9
+b1 C
+b1 Q
+b101111000000000000000000010100 6
+b101111000000000000000000010100 B
+b101111000000000000000000010100 P
+18
+1<
+17
+#36000
+07
+#37000
+b1 O
+b1 ^
+1,
+1H
+17
+#38000
+07
+#39000
+0A
+b11 g
+b101111000000000000000000011000 f
+0<
+08
+0,
+0H
+17
+#40000
+07
+#41000
+0\
+1[
+1A
+b11 9
+b11 C
+b11 Q
+b101111000000000000000000011000 6
+b101111000000000000000000011000 B
+b101111000000000000000000011000 P
+18
+1<
+17
+#42000
+07
+#43000
+b11 N
+b11 _
+1,
+1H
+17
+#44000
+07
+#45000
+0A
+b1 g
+b101111000000000000000000011100 f
+0<
+08
+0,
+0H
+17
+#46000
+07
+#47000
+0[
+1W
+1A
+b1 9
+b1 C
+b1 Q
+b101111000000000000000000011100 6
+b101111000000000000000000011100 B
+b101111000000000000000000011100 P
+18
+1<
+17
+#48000
+07
+#49000
+1L
+1,
+1H
+17
+#50000
+07
+#51000
+0A
+b101111000000000000000000100100 f
+0<
+08
+0,
+0H
+17
+#52000
+07
+#53000
+0W
+1X
+1A
+b101111000000000000000000100100 6
+b101111000000000000000000100100 B
+b101111000000000000000000100100 P
+18
+1<
+17
+#54000
+07
+#55000
+b1 M
+b1 `
+1,
+1H
+17
+#56000
+07
+#57000
+0A
+0<
+08
+0,
+0H
+17
+#58000
+07
+#59000
+1V
+0X
+b0 ?
+b0 R
+1A
+b101111000000000000000000100000 6
+b101111000000000000000000100000 B
+b101111000000000000000000100000 P
+0=
+18
+1<
+17
+b101111000000000000000000100000 e
+#60000
+07
+#61000
+b1 +
+b1 F
+b1 ]
+1,
+1H
+17
+#62000
+07
+#63000
+0A
+b101111000000000000000000000000 e
+0<
+08
+0,
+0H
+17
+#64000
+07
+#65000
+1Z
+0V
+1A
+b101111000000000000000000000000 6
+b101111000000000000000000000000 B
+b101111000000000000000000000000 P
+18
+1<
+17
+#66000
+07
+#67000
+1,
+1H
+17
+#68000
+07
+#69000
+0A
+b101111000000000000000000000100 e
+0<
+08
+0,
+0H
+17
+#70000
+07
+#71000
+0Z
+1Y
+1A
+b101111000000000000000000000100 6
+b101111000000000000000000000100 B
+b101111000000000000000000000100 P
+18
+1<
+17
+#72000
+07
+#73000
+b10 +
+b10 F
+b10 ]
+1,
+1H
+17
+#74000
+07
+#75000
+0A
+b101111000000000000000000001000 e
+0<
+08
+0,
+0H
+17
+#76000
+07
+#77000
+0Y
+1S
+1A
+b101111000000000000000000001000 6
+b101111000000000000000000001000 B
+b101111000000000000000000001000 P
+18
+1<
+17
+#78000
+07
+#79000
+b1 +
+b1 F
+b1 ]
+1,
+1H
+17
+#80000
+07
+#81000
+0A
+b101111000000000000000000001100 e
+0<
+08
+0,
+0H
+17
+#82000
+07
+#83000
+1U
+0S
+1A
+b101111000000000000000000001100 6
+b101111000000000000000000001100 B
+b101111000000000000000000001100 P
+18
+1<
+17
+#84000
+07
+#85000
+b11 +
+b11 F
+b11 ]
+1,
+1H
+17
+#86000
+07
+#87000
+0A
+b101111000000000000000000010000 e
+0<
+08
+0,
+0H
+17
+#88000
+07
+#89000
+0U
+1T
+1A
+b101111000000000000000000010000 6
+b101111000000000000000000010000 B
+b101111000000000000000000010000 P
+18
+1<
+17
+#90000
+07
+#91000
+b10 +
+b10 F
+b10 ]
+1,
+1H
+17
+#92000
+07
+#93000
+0A
+b101111000000000000000000010100 e
+0<
+08
+0,
+0H
+17
+#94000
+07
+#95000
+0T
+1\
+1A
+b101111000000000000000000010100 6
+b101111000000000000000000010100 B
+b101111000000000000000000010100 P
+18
+1<
+17
+#96000
+07
+#97000
+b1 +
+b1 F
+b1 ]
+1,
+1H
+17
+#98000
+07
+#99000
+0A
+b101111000000000000000000011000 e
+0<
+08
+0,
+0H
+17
+#100000
+07
+#101000
+0\
+1[
+1A
+b101111000000000000000000011000 6
+b101111000000000000000000011000 B
+b101111000000000000000000011000 P
+18
+1<
+17
+#102000
+07
+#103000
+b11 +
+b11 F
+b11 ]
+1,
+1H
+17
+#104000
+07
+#105000
+0A
+b101111000000000000000000011100 e
+0<
+08
+0,
+0H
+17
+#106000
+07
+#107000
+0[
+1W
+1A
+b101111000000000000000000011100 6
+b101111000000000000000000011100 B
+b101111000000000000000000011100 P
+18
+1<
+17
+#108000
+07
+#109000
+b1 +
+b1 F
+b1 ]
+1,
+1H
+17
+#110000
+07
+#111000
+0A
+b101111000000000000000000100100 e
+0<
+08
+0,
+0H
+17
+#112000
+07
+#113000
+0W
+1X
+1A
+b101111000000000000000000100100 6
+b101111000000000000000000100100 B
+b101111000000000000000000100100 P
+18
+1<
+17
+#114000
+07
+#115000
+1,
+1H
+17
+#116000
+07
+#117000
+0A
+0<
+08
+0,
+0H
+17
diff --git a/verilog/dv/wb/uart_wb/Makefile b/verilog/dv/wb/uart_wb/Makefile
new file mode 100644
index 0000000..a37bd82
--- /dev/null
+++ b/verilog/dv/wb/uart_wb/Makefile
@@ -0,0 +1,17 @@
+.SUFFIXES:
+
+PATTERN = uart_wb
+
+all:  ${PATTERN:=.vcd}
+
+%.vvp: %_tb.v
+	iverilog -I .. -I ../../ -I ../../../rtl \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+clean:
+	rm -f *.vvp *.vcd *.log
+
+.PHONY: clean all
diff --git a/verilog/dv/wb/uart_wb/uart_wb_tb.v b/verilog/dv/wb/uart_wb/uart_wb_tb.v
new file mode 100644
index 0000000..6063060
--- /dev/null
+++ b/verilog/dv/wb/uart_wb/uart_wb_tb.v
@@ -0,0 +1,149 @@
+
+
+`timescale 1 ns / 1 ps
+
+`include "simpleuart.v"
+
+module uart_wb_tb;
+    
+    reg wb_clk_i;
+	reg wb_rst_i;
+
+    reg wb_stb_i;
+	reg wb_cyc_i;
+	reg wb_we_i;
+	reg [3:0] wb_sel_i;
+	reg [31:0] wb_adr_i;
+	reg [31:0] wb_dat_i;
+
+	wire wb_ack_o;
+	wire [31:0] wb_dat_o;
+  
+    initial begin
+        wb_clk_i = 0; 
+        wb_rst_i = 0;
+        wb_stb_i = 0; 
+        wb_we_i  = 0;  
+        wb_cyc_i = 0;  
+        wb_adr_i = 0; 
+        wb_dat_i = 0; 
+        wb_sel_i = 0;  
+    end
+
+    always #1 wb_clk_i = ~wb_clk_i;
+
+    initial begin
+        $dumpfile("uart_wb_tb.vcd");
+        $dumpvars(0, uart_wb_tb);
+        repeat (500) begin
+            repeat (10000) @(posedge wb_clk_i);
+        end
+        $display("%c[1;31m",27);
+        $display("Monitor: Timeout, Test UART Failed");
+        $display("%c[0m",27);
+        $finish;
+    end
+
+    integer i;
+
+    wire [31:0] div_reg_addr = uut.BASE_ADR | uut.CLK_DIV;
+    wire [31:0] div_reg_data = 32'h FFFF_FFFF;
+    
+    wire [31:0] dat_reg_addr = uut.BASE_ADR | uut.DATA;
+    wire [31:0] dat_reg_data = 32'h FFFF_FFFF;
+
+    initial begin
+        // Reset Operation
+        wb_rst_i = 1;
+        #2;
+        wb_rst_i = 0; 
+        #2;
+
+        // Write to div register
+        write(div_reg_addr, div_reg_data);
+        #2;
+        read(div_reg_addr);
+        if (wb_dat_o !== div_reg_data) begin
+            $display("%c[1;31m",27);
+            $display("Expected %0b, but Got %0b ", div_reg_data, wb_dat_o);
+            $display("Monitor: Wishbone UART Failed");
+            $display("%c[0m",27);
+            $finish;
+        end
+        #6;
+
+        // Write Operation: writes to data register
+        write(dat_reg_addr, dat_reg_data);
+        #2;
+        read(dat_reg_addr);
+        if (wb_dat_o !== dat_reg_data) begin
+            $display("%c[1;31m",27);
+            $display("Expected %0b, but Got %0b ", dat_reg_data, wb_dat_o);
+            $display("Monitor: Wishbone UART Failed");
+            $display("%c[0m",27);
+            $finish;
+        end
+        $display("Success!");
+        $finish;
+    end
+    
+    task write;
+        input [32:0] addr;
+        input [32:0] data;
+        begin 
+            @(posedge wb_clk_i) begin
+                wb_stb_i = 1;
+                wb_cyc_i = 1;
+                wb_sel_i = 4'hF; 
+                wb_we_i = 1;     
+                wb_adr_i = addr;
+                wb_dat_i = data;
+                $display("Write Cycle Started.");
+            end
+            #2;
+            wb_we_i = 0;     
+            // Wait for an ACK
+            wait(wb_ack_o == 1);
+            #2;
+            wb_cyc_i = 0;
+            wb_stb_i = 0;
+            $display("Write Cycle Ended.");
+        end
+    endtask
+    
+    task read;
+        input [32:0] addr;
+        begin 
+            @(posedge wb_clk_i) begin
+                wb_stb_i = 1;
+                wb_cyc_i = 1;
+                wb_we_i = 0;
+                wb_adr_i = addr;
+                $display("Read Cycle Started.");
+            end
+            // Wait for an ACK
+            wait(wb_ack_o == 1);
+            #2;
+            // wait(wb_ack_o == 0);
+            wb_cyc_i = 0;
+            wb_stb_i = 0;
+            $display("Read Cycle Ended.");
+        end
+    endtask
+    
+    simpleuart_wb uut (
+		.wb_clk_i(wb_clk_i),
+		.wb_rst_i(wb_rst_i),
+    	.wb_stb_i(wb_stb_i),
+    	.wb_cyc_i(wb_cyc_i),
+    	.wb_sel_i(wb_sel_i),
+    	.wb_we_i(wb_we_i),
+        .wb_adr_i(wb_adr_i),      
+	    .wb_dat_i(wb_dat_i),
+	    .wb_ack_o(wb_ack_o),
+	    .wb_dat_o(wb_dat_o),
+        .ser_tx(tbuart_rx),
+		.ser_rx(ser_rx)
+	);
+
+endmodule
\ No newline at end of file
diff --git a/verilog/ip/arbiter.v b/verilog/ip/arbiter.v
new file mode 100644
index 0000000..f599173
--- /dev/null
+++ b/verilog/ip/arbiter.v
@@ -0,0 +1,135 @@
+module wb_arbiter #(
+    parameter AW = 32,
+    parameter DW = 32,
+    parameter NM = 2
+)(
+
+    input wb_clk_i,
+    input wb_rst_i,
+
+    // Masters Interface
+    input [NM-1:0] wbm_stb_i,
+    input [NM-1:0] wbm_cyc_i,
+    input [NM-1:0] wbm_we_i,
+    input [NM*(DW/8)-1:0] wbm_sel_i,
+    input [NM*DW-1:0] wbm_dat_i,
+    input [NM*AW-1:0] wbm_adr_i,
+
+    output [NM-1:0] wbm_ack_o,
+    output [NM-1:0] wbm_err_o,
+    output [NM*DW-1:0] wbm_dat_o,
+
+    // Slave Interface
+    input  wbs_ack_i, 
+    input  wbs_err_i,               
+    input  [DW-1:0] wbs_dat_i,      
+    output reg wbs_stb_o,   
+    output reg wbs_cyc_o,           
+    output wbs_we_o,     
+    output reg [(DW/8)-1:0] wbs_sel_o,       
+    output reg [AW-1:0]  wbs_adr_o,   
+    output reg [DW-1:0]  wbs_dat_o  
+);
+
+localparam SEL = DW / 8;
+
+//  Current elected master (one hot)
+reg [NM-1:0] cur_master;
+reg capture_req;         
+
+wire [NM-1:0] master_sel;  
+wire [NM-1:0] requests;
+wire any_req;
+wire any_acks;
+
+assign requests = wbm_cyc_i & wbm_stb_i;   
+assign any_req = |requests;
+assign any_ack = |{wbs_ack_i, wbs_err_i};
+
+genvar iM;
+generate 
+    assign master_sel[0] = requests[0];
+    for (iM=1; iM<NM; iM=iM+1) begin
+      assign master_sel[iM] = requests[iM] & (~master_sel[iM-1]);
+    end
+endgenerate
+
+// Current-elected master
+always @(posedge wb_clk_i)
+    if(wb_rst_i) begin
+        cur_master <= {NM{1'b0}};
+    end else if (capture_req) begin
+        cur_master <= master_sel;
+    end
+
+// Finite State Machine
+localparam IDLE = 1'b0;
+localparam BUSY = 1'b1;
+
+reg state = IDLE; 
+reg next_state;       
+
+always @(*)
+begin: FSM_COMB
+case (state)
+    IDLE: if (any_req) begin
+        wbs_stb_o = 1'b1;
+        wbs_cyc_o = 1'b1;
+        capture_req = 1'b1;
+        next_state = BUSY;
+    end else begin
+        wbs_stb_o = 1'b0;
+        wbs_cyc_o = 1'b0;
+        capture_req = 1'b0;
+        next_state = IDLE;
+    end
+    BUSY: begin
+        if (any_ack & !any_req) begin
+          next_state = IDLE;
+        end if (any_ack & any_req) begin
+           capture_req = 1'b1;
+        end 
+    end
+    default: next_state = IDLE;
+endcase
+end
+
+always @(posedge wb_clk_i)
+    if (wb_rst_i)                                                
+        state <= IDLE;
+    else                                            
+        state <= next_state;
+
+// Masters Output Assignment   
+assign wbm_dat_o = {NM{wbs_dat_i}};               
+assign wbm_ack_o = {NM{wbs_ack_i}} & cur_master; 
+assign wbm_err_o = {NM{wbs_err_i}} & cur_master; 
+
+// Multiplexed signal to the slave
+
+assign wbs_we_o = |(cur_master & wbm_we_i);    
+
+integer k;
+always @(*) begin
+    wbs_sel_o = {SEL{1'b0}};
+    for (k=0; k<(NM*SEL); k=k+1)
+        wbs_sel_o[k%SEL] = wbs_sel_o[k%SEL] | (cur_master[k/SEL] & wbm_sel_i[k]);
+end
+
+integer l;
+always @(*) begin
+    wbs_adr_o = {AW{1'b0}};
+    for (l=0; l<(NM*AW); l=l+1)
+        wbs_adr_o[l%AW] = wbs_adr_o[l%AW] | (cur_master[l/AW] & wbm_adr_i[l]);
+end
+
+integer o;
+always @(*) begin
+    wbs_dat_o = {DW{1'b0}};
+    for (o=0; o<(NM*DW); o=o+1)
+        wbs_dat_o[o%DW] = wbs_dat_o[o%DW] | (cur_master[o/DW] & wbm_dat_i[o]);
+end
+
+
+endmodule
+
diff --git a/verilog/ip/crossbar.v b/verilog/ip/crossbar.v
new file mode 100644
index 0000000..ee07d5e
--- /dev/null
+++ b/verilog/ip/crossbar.v
@@ -0,0 +1,172 @@
+
+`include "distributor.v"
+`include "arbiter.v"
+
+module wb_xbar #(
+    parameter NM = 2,  
+    parameter NS = 4,   
+    parameter AW = 32,  
+    parameter DW = 32      
+) (
+
+    input wb_clk_i,           
+    input wb_rst_i,     
+
+    // Masters interface
+    input [NM-1:0] wbm_cyc_i,       
+    input [NM-1:0] wbm_stb_i,       
+    input [NM-1:0] wbm_we_i,     
+    input [(NM*(DW/8))-1:0] wbm_sel_i,     
+    input [(NM*AW)-1:0] wbm_adr_i,        
+    input [(NM*DW)-1:0] wbm_dat_i,       
+    output [NM-1:0] wbm_ack_o, 
+    output [NM-1:0] wbm_err_o,       
+    output [(NM*DW)-1:0] wbm_dat_o,       
+
+    // Slaves interfaces
+    input [NS-1:0] wbs_ack_i,       
+    input [(NS*DW)-1:0]  wbs_dat_i,
+    output [NS-1:0] wbs_cyc_o,        
+    output [NS-1:0] wbs_stb_o,       
+    output [NS-1:0] wbs_we_o,        
+    output [(NS*(DW/8))-1:0] wbs_sel_o,       
+    output [(NS*AW)-1:0] wbs_adr_o,       
+    output [(NS*DW)-1:0] wbs_dat_o       
+);
+    parameter ADR_MASK = {
+        {8'hFF, {24{1'b0}}},
+        {8'hFF, {24{1'b0}}},
+        {8'hFF, {24{1'b0}}},
+        {8'hFF, {24{1'b0}}}
+    };
+
+    parameter SLAVE_ADR = {
+        {8'hB0, {24{1'b0}}},
+        {8'hA0, {24{1'b0}}},
+        {8'h90, {24{1'b0}}},
+        {8'h80, {24{1'b0}}}
+    };
+
+   localparam SEL = DW / 8;
+
+   wire [(NM*NS)-1:0] distributor_cyc_o;   
+   wire [(NM*NS)-1:0] distributor_stb_o;  
+   wire [(NM*NS)-1:0] distributor_we_o;    
+   wire [(NM*NS*SEL)-1:0] distributor_sel_o; 
+   wire [(NM*NS*AW)-1:0] distributor_adr_o;   
+   wire [(NM*NS*DW)-1:0] distributor_dat_o;   
+   wire [(NM*NS)-1:0]  distributor_ack_i;   
+   wire [(NM*NS)-1:0]  distributor_err_i; 
+   wire [(NM*NS)-1:0] distributor_rty_i;  
+   wire [(NM*NS*DW)-1:0] distributor_dat_i;   
+
+   //Arbiter busses:
+   wire [(NM*NS)-1:0] arbiter_cyc_i;       
+   wire [(NM*NS)-1:0] arbiter_stb_i;       
+   wire [(NM*NS)-1:0] arbiter_we_i;       
+   wire [(NM*NS*SEL)-1:0] arbiter_sel_i;       
+   wire [(NM*NS*AW)-1:0] arbiter_adr_i;      
+   wire [(NM*NS*DW)-1:0] arbiter_dat_i;      
+   wire [(NM*NS)-1:0] arbiter_ack_o;      
+   wire [(NM*NS)-1:0] arbiter_err_o;      
+   wire [(NM*NS*DW)-1:0] arbiter_dat_o;     
+
+   //Instantiate distributors
+   generate
+      genvar i;
+      for (i=0; i<NM; i=i+1)
+        begin
+        distributor #(
+            .NS(NS), 
+            .AW(AW),   
+            .DW(DW),
+            .SLAVE_ADR(SLAVE_ADR),
+            .ADR_MASK(ADR_MASK)
+        ) distributor (
+            .wb_clk_i(wb_clk_i),                                                                     
+            .wb_rst_i(wb_rst_i),   
+                                                                         
+            .wbm_cyc_i(wbm_cyc_i[i]),                                                              
+            .wbm_stb_i(wbm_stb_i[i]),                                                               
+            .wbm_we_i(wbm_we_i[i]),                                                                
+            .wbm_sel_i(wbm_sel_i[(SEL*(i+1))-1:(SEL*i)]),                              
+            .wbm_adr_i(wbm_adr_i[(AW*(i+1))-1:(AW*i)]),                               
+            .wbm_dat_i(wbm_dat_i[(DW*(i+1))-1:(DW*i)]),                               
+            .wbm_ack_o(wbm_ack_o[i]),                                                  
+            .wbm_dat_o(wbm_dat_o[(DW*(i+1))-1:(DW*i)]),                              
+            
+            // Slave interfaces
+            .wbs_cyc_o (distributor_cyc_o[(NS*(i+1))-1:NS*i]),                             
+            .wbs_stb_o (distributor_stb_o[(NS*(i+1))-1:NS*i]),                             
+            .wbs_we_o  (distributor_we_o [(NS*(i+1))-1:NS*i]),                              
+            .wbs_sel_o (distributor_sel_o[(NS*SEL*(i+1))-1:NS*SEL*i]),       
+            .wbs_adr_o (distributor_adr_o[(NS*AW*(i+1))-1:NS*AW*i]),         
+            .wbs_dat_o (distributor_dat_o[(NS*DW*(i+1))-1:NS*DW*i]),         
+            .wbs_ack_i (distributor_ack_i[(NS*(i+1))-1:NS*i]),                           
+            .wbs_dat_i (distributor_dat_i[(NS*DW*(i+1))-1:NS*DW*i])
+        );        
+        end
+   endgenerate
+
+   //Instantiate arbiters
+   generate
+      genvar j;
+      for (j=0; j<NS; j=j+1)
+        begin
+           wb_arbiter #(
+                .NM(NM),    
+                .AW(AW), 
+                .DW(DW)   
+            ) arbiter (
+                .wb_clk_i(wb_clk_i),                                                             
+                .wb_rst_i(wb_rst_i),                                                    
+                // Masters Interface
+                .wbm_cyc_i (arbiter_cyc_i[(NM*(j+1))-1:NM*j]),                        
+                .wbm_stb_i (arbiter_stb_i[(NM*(j+1))-1:NM*j]),                         
+                .wbm_we_i  (arbiter_we_i [(NM*(j+1))-1:NM*j]),                          
+                .wbm_sel_i (arbiter_sel_i[(NM*SEL*(j+1))-1:NM*SEL*j]),     
+                .wbm_adr_i (arbiter_adr_i[(NM*AW*(j+1))-1:NM*AW*j]),     
+                .wbm_dat_i (arbiter_dat_i[(NM*DW*(j+1))-1:NM*DW*j]),   
+                .wbm_ack_o (arbiter_ack_o[(NM*(j+1))-1:NM*j]),                        
+                .wbm_dat_o (arbiter_dat_o[(NM*DW*(j+1))-1:NM*DW*j]),    
+
+                // Slave interfaces
+                .wbs_cyc_o (wbs_cyc_o[j]),                                                       
+                .wbs_stb_o (wbs_stb_o[j]),                                                       
+                .wbs_we_o  (wbs_we_o[j]),                                                       
+                .wbs_sel_o (wbs_sel_o[(SEL*(j+1))-1:(SEL*j)]),                      
+                .wbs_adr_o (wbs_adr_o[(AW*(j+1))-1:(AW*j)]),                     
+                .wbs_dat_o (wbs_dat_o[(DW*(j+1))-1:(DW*j)]),                      
+                .wbs_ack_i (wbs_ack_i[j]),                                                      
+                .wbs_dat_i (wbs_dat_i[(DW*(j+1))-1:(DW*j)])                    
+            );
+        end 
+   endgenerate
+
+   //Crossbar connections
+   generate
+      genvar k, l, m, indx;
+      for (k=0; k<NM; k=k+1)
+      for (l=0; l<NS; l=l+1)
+        begin
+          assign arbiter_cyc_i[(NM*l)+k] = distributor_cyc_o[(NS*k)+l];               
+          assign arbiter_stb_i[(NM*l)+k] = distributor_stb_o[(NS*k)+l];               
+          assign arbiter_we_i [(NM*l)+k] = distributor_we_o [(NS*k)+l];               
+          
+          assign arbiter_sel_i[(((NM*l)+k)*SEL)+(SEL-1):((NM*l)+k)*SEL] = 
+                  distributor_sel_o[(((NS*k)+l)*SEL)+(SEL-1):((NS*k)+l)*SEL];            
+
+          assign arbiter_adr_i[(((NM*l)+k)*AW)+(AW-1) : ((NM*l)+k)*AW] = 
+                  distributor_adr_o[(((NS*k)+l)*AW)+(AW-1) : ((NS*k)+l)*AW];             
+          
+          assign arbiter_dat_i[(((NM*l)+k)*AW)+(AW-1) : ((NM*l)+k)*AW] = 
+                  distributor_dat_o[(((NS*k)+l)*AW)+(AW-1) : ((NS*k)+l)*AW]; 
+
+           assign distributor_dat_i[(((NS*k)+l)*DW)+(DW-1) : ((NS*k)+l)*DW] = 
+                  arbiter_dat_o[(((NM*l)+k)*DW)+(DW-1) : ((NM*l)+k)*DW];      
+          
+          assign distributor_ack_i[(NS*k)+l] = arbiter_ack_o[(NM*l)+k];                            
+        end
+      endgenerate
+
+endmodule 
\ No newline at end of file
diff --git a/verilog/ip/distributor.v b/verilog/ip/distributor.v
new file mode 100644
index 0000000..78aa374
--- /dev/null
+++ b/verilog/ip/distributor.v
@@ -0,0 +1,77 @@
+module distributor #(
+    parameter AW = 32,
+    parameter DW = 32,
+    parameter NS = 4
+) (
+    input wb_clk_i,            
+    input wb_rst_i,
+
+    // Master Interface
+    input  wbm_cyc_i,       
+    input  wbm_stb_i,        
+    input  wbm_we_i,         
+    input [(DW/8)-1:0] wbm_sel_i,       
+    input [AW-1:0] wbm_adr_i,        
+    input [DW-1:0] wbm_dat_i,       
+    output wbm_ack_o,       
+    output reg [DW-1:0] wbm_dat_o,        
+
+    // Slave interfaces
+    input [NS-1:0] wbs_ack_i,       
+    input [(NS*DW)-1:0] wbs_dat_i,      
+
+    output [NS-1:0] wbs_cyc_o,       
+    output [NS-1:0] wbs_stb_o,        
+    output [NS-1:0] wbs_we_o,         
+    output [(NS*(DW/8))-1:0]  wbs_sel_o,        
+    output [(NS*AW)-1:0]  wbs_adr_o,      
+    output [(NS*DW)-1:0]  wbs_dat_o
+
+);
+
+parameter ADR_MASK = {
+    {8'hFF, {24{1'b0}}},
+    {8'hFF, {24{1'b0}}},
+    {8'hFF, {24{1'b0}}},
+    {8'hFF, {24{1'b0}}}
+};
+    
+parameter SLAVE_ADR = {
+    {8'hB0, {24{1'b0}}},
+    {8'hA0, {24{1'b0}}},
+    {8'h90, {24{1'b0}}},
+    {8'h80, {24{1'b0}}}
+};
+
+wire [NS-1:0] slave_sel;
+
+// Decode Addresseses, then accordingly assign the slave signals
+genvar iS;
+generate
+    for (iS = 0; iS < NS; iS = iS + 1) begin
+        assign slave_sel[iS] = ((wbm_adr_i & ADR_MASK[(iS+1)*AW-1:iS*AW]) == SLAVE_ADR[(iS+1)*AW-1:iS*AW]);
+    end
+endgenerate
+
+// Plain signal propagation to all target busses
+assign wbs_we_o  = {NS{wbm_we_i}};                   //write enables
+assign wbs_sel_o = {NS{wbm_sel_i}};                  //write data selects
+assign wbs_adr_o = {NS{wbm_adr_i}};                  //address busses
+assign wbs_dat_o = {NS{wbm_dat_i}};                  //write data busses
+
+// Masked signal propagation to all target busses
+assign wbs_cyc_o  =  slave_sel & {NS{wbm_cyc_i}};               // bus cycle indicators
+assign wbs_stb_o  =  slave_sel & {NS{wbm_cyc_i}};               // access requests
+
+// Multiplexed signal propagation to the initiator bus
+assign wbm_ack_o = |{slave_sel & wbs_ack_i};         
+
+integer i;
+always @*                                                 
+    begin
+    wbm_dat_o = {DW{1'b0}};
+    for (i=0; i<(DW*NS); i=i+1)
+        wbm_dat_o[i%DW] = wbm_dat_o[i%DW] | (slave_sel[i/DW] & wbs_dat_i[i]);
+    end
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/caravel.v b/verilog/rtl/caravel.v
deleted file mode 100644
index bbe24ce..0000000
--- a/verilog/rtl/caravel.v
+++ /dev/null
@@ -1,919 +0,0 @@
-/*------------------------------------------------------*/
-/* caravel, a standard container for user projects on	*/
-/* the Google/SkyWater/efabless shuttle runs for the	*/
-/* SkyWater sky130 130nm process.			*/
-/*                                                      */
-/* Copyright 2020 efabless, Inc.                        */
-/* Written by Tim Edwards, August 2020                	*/
-/* This file is open source hardware released under the */
-/* Apache 2.0 license.  See file LICENSE.               */
-/*                                                      */
-/*------------------------------------------------------*/
-
-`timescale 1 ns / 1 ps
-
-/* Always define USE_PG_PIN (used by SkyWater cells) */
-/* But do not define SC_USE_PG_PIN */
-`define USE_PG_PIN
-
-/* Must define functional for now because otherwise the timing delays   */
-/* are assumed, but they have been stripped out because some are not    */
-/* parsed by iverilog.                                                  */
-
-`define functional
-
-// Define GL to use the gate-level netlists
-//`define GL
-
-// PDK IP
-
-// I/O padframe cells
-
-// Local IP
-`include "striVe.v"
-
-//`define     TOP_ROUTING
-
-`ifndef TOP_ROUTING 
-	`define ABUTMENT_PINS \
-	.amuxbus_a(analog_a),\
-	.amuxbus_b(analog_b),\
-	.vssa(vss),\
-	.vdda(vdd3v3),\
-	.vswitch(vdd3v3),\
-	.vddio_q(vddio_q),\
-	.vcchib(vdd1v8),\
-	.vddio(vdd3v3),\
-	.vccd(vdd1v8),\
-	.vssio(vss),\
-	.vssd(vss),\
-	.vssio_q(vssio_q),
-`else 
-	`define ABUTMENT_PINS 
-`endif
-
-module caravel (vdd3v3, vdd1v8, vss, gpio, cclk, ser_rx, ser_tx, irq,
-	RSTB, SDO, SDI, CSB, SCK,
-	flash_csb, flash_clk, flash_io0, flash_io1, flash_io2, flash_io3);
-    inout vdd3v3;
-    inout vdd1v8;
-    inout vss;
-    inout [15:0] gpio;
-    input cclk;		// CMOS clock input
-    input ser_rx;
-    output ser_tx;
-    input irq;
-    input RSTB;		// NOTE:  Replaces analog_out pin from raven chip
-    output SDO;
-    input SDI;
-    input CSB;
-    input SCK;
-    output flash_csb;
-    output flash_clk;
-    output flash_io0;
-    output flash_io1;
-    output flash_io2;
-    output flash_io3;
-
-    wire [15:0] gpio_out_core;
-    wire [15:0] gpio_in_core;
-    wire [15:0]	gpio_mode0_core;
-    wire [15:0]	gpio_mode1_core;
-    wire [15:0]	gpio_outenb_core;
-    wire [15:0]	gpio_inenb_core;
-
-    wire analog_a, analog_b;	    /* Placeholders for analog signals */
-
-    wire porb_h;
-    wire porb_l;
-    wire por_h;
-    wire por;
-    wire SCK_core;
-    wire SDI_core;
-    wire CSB_core;
-    wire SDO_core;
-    wire SDO_enb;
-    wire spi_ro_reg_ena_core;
-    wire spi_ro_pll_dco_ena_core;
-    wire [2:0] spi_ro_pll_sel_core;
-    wire [4:0] spi_ro_pll_div_core;
-    wire [25:0] spi_ro_pll_trim_core;
-    wire irq_spi_core;
-    wire ext_reset_core;
-    wire trap_core;
-    wire [11:0] spi_ro_mfgr_id_core;
-    wire [7:0] spi_ro_prod_id_core;
-    wire [3:0] spi_ro_mask_rev_core;
-
-    // Instantiate power cells for VDD3V3 domain (8 total; 4 high clamps and
-    // 4 low clamps)
-    s8iom0_vdda_hvc_pad vdd3v3hclamp [1:0] (
-		`ABUTMENT_PINS
-		.drn_hvc(),
-		.src_bdy_hvc()
-    );
-
-    s8iom0_vddio_hvc_pad vddiohclamp [1:0] (
-		`ABUTMENT_PINS
-		.drn_hvc(),
-		.src_bdy_hvc()
-    );
-
-
-    s8iom0_vdda_lvc_pad vdd3v3lclamp [3:0] (
-		`ABUTMENT_PINS
-		.bdy2_b2b(),
-		.drn_lvc1(),
-		.drn_lvc2(),
-		.src_bdy_lvc1(),
-		.src_bdy_lvc2()
-    );
-
-    // Instantiate the core voltage supply (since it is not generated on-chip)
-    // (1.8V) (4 total, 2 high and 2 low clamps)
-
-    s8iom0_vccd_hvc_pad vdd1v8hclamp [1:0] (
-		`ABUTMENT_PINS
-		.drn_hvc(),
-		.src_bdy_hvc()
-    );
-
-    s8iom0_vccd_lvc_pad vdd1v8lclamp [1:0] (
-		`ABUTMENT_PINS
-		.bdy2_b2b(),
-		.drn_lvc1(),
-		.drn_lvc2(),
-		.src_bdy_lvc1(),
-		.src_bdy_lvc2()
-    );
-
-    // Instantiate ground cells (7 total, 4 high clamps and 3 low clamps)
-
-    s8iom0_vssa_hvc_pad vsshclamp [3:0] (
-		`ABUTMENT_PINS
-		.drn_hvc(),
-		.src_bdy_hvc()
-    );
-
-    s8iom0_vssa_lvc_pad vssalclamp (
-		`ABUTMENT_PINS
-		.bdy2_b2b(),
-		.drn_lvc1(),
-		.drn_lvc2(),
-		.src_bdy_lvc1(),
-		.src_bdy_lvc2()
-    );
-
-    s8iom0_vssd_lvc_pad vssdlclamp (
-		`ABUTMENT_PINS
-		.bdy2_b2b(),
-		.drn_lvc1(),
-		.drn_lvc2(),
-		.src_bdy_lvc1(),
-		.src_bdy_lvc2()
-    );
-
-    s8iom0_vssio_lvc_pad vssiolclamp (
-		`ABUTMENT_PINS
-		.bdy2_b2b(),
-		.drn_lvc1(),
-		.drn_lvc2(),
-		.src_bdy_lvc1(),
-		.src_bdy_lvc2()
-    );
-
-
-
-    // Instantiate GPIO v2 cell.  These are used for both digital and analog
-    // functions, configured appropriately.
-    //
-    // GPIO pin description:
-    //
-    // general:  signals with _h suffix are in the vddio (3.3V) domain.  All
-    // other signals are in 1.8V domains (vccd or vcchib)
-
-    // out = Signal from core to pad (digital, 1.8V domain)
-    // oe_n = Output buffer enable (sense inverted)
-    // hld_h_n = Hold signals during deep sleep (sense inverted)
-    // enable_h = Power-on-reset (inverted)
-    // enable_inp_h = Defines state of input buffer output when disabled.
-    //	    Connect via loopback to tie_hi_esd or tie_lo_esd.
-    // enable_vdda_h = Power-on-reset (inverted) to analog section
-    // enable_vswitch_h = set to 0 if not using vswitch
-    // enable_vddio = set to 1 if vddio is up during deep sleep
-    // inp_dis = Disable input buffer
-    // ib_mode_sel = Input buffer mode select, 0 for 3.3V external signals, 1 for
-    //		1.8V external signals
-    // vtrip_se = Input buffer trip select, 0 for CMOS level, 1 for TTL level
-    // slow = 0 for fast slew, 1 for slow slew
-    // hld_ovr = override for pads that need to be enabled during deep sleep
-    // analog_en = enable analog functions
-    // analog_sel = select analog channel a or b
-    // analog_pol = analog select polarity
-    // dm = digital mode (3 bits) 000 = analog 001 = input only, 110 = output only
-    // vddio = Main 3.3V supply
-    // vddio_q = Quiet 3.3V supply
-    // vdda = Analog 3.3V supply
-    // vccd = Digital 1.8V supply
-    // vswitch = High-voltage supply for analog switches
-    // vcchib = Digital 1.8V supply live during deep sleep mode
-    // vssa = Analog ground
-    // vssd = Digital ground
-    // vssio_q = Quiet main ground
-    // vssio = Main ground
-    // pad = Signal on pad
-    // pad_a_noesd_h = Direct core connection to pad
-    // pad_a_esd_0_h = Core connection to pad through 150 ohms (primary)
-    // pad_a_esd_1_h = Core connection to pad through 150 ohms (secondary)
-    // amuxbus_a = Analog bus A
-    // amuxbus_b = Analog bus B
-    // in = Signal from pad to core (digital, 1.8V domain)
-    // in_h = Signal from pad to core (3.3V domain)
-    // tie_hi_esd = 3.3V output for loopback to enable_inp_h
-    // tie_lo_esd = ground output for loopback to enable_inp_h
-
-    // 37 instances:  16 general purpose digital, 2 for the crystal oscillator,
-    // 4 for the ADC, 1 for the analog out, 2 for the comparator inputs,
-    // one for the IRQ input, one for the xclk input, 6 for the SPI flash
-    // signals, and 4 for the housekeeping SPI signals.
-
-    // NOTE:  To pass a vector to array dm in an array of instances gpio_pad,
-    // the array needs to be rearranged.  Reconstruct the needed 48-bit vector
-    // (3 bit signal * 16 instances).
-    //
-    // Also note:  Preferable to use a generate block, but that is incompatible
-    // with the current version of padframe_generator. . .
-
-    wire [47:0] dm_all;
-
-    assign dm_all = {gpio_mode1_core[15], gpio_mode1_core[15], gpio_mode0_core[15],
-		 gpio_mode1_core[14], gpio_mode1_core[14], gpio_mode0_core[14],
-		 gpio_mode1_core[13], gpio_mode1_core[13], gpio_mode0_core[13],
-		 gpio_mode1_core[12], gpio_mode1_core[12], gpio_mode0_core[12],
-		 gpio_mode1_core[11], gpio_mode1_core[11], gpio_mode0_core[11],
-		 gpio_mode1_core[10], gpio_mode1_core[10], gpio_mode0_core[10],
-		 gpio_mode1_core[9], gpio_mode1_core[9], gpio_mode0_core[9],
-		 gpio_mode1_core[8], gpio_mode1_core[8], gpio_mode0_core[8],
-		 gpio_mode1_core[7], gpio_mode1_core[7], gpio_mode0_core[7],
-		 gpio_mode1_core[6], gpio_mode1_core[6], gpio_mode0_core[6],
-		 gpio_mode1_core[5], gpio_mode1_core[5], gpio_mode0_core[5],
-		 gpio_mode1_core[4], gpio_mode1_core[4], gpio_mode0_core[4],
-		 gpio_mode1_core[3], gpio_mode1_core[3], gpio_mode0_core[3],
-		 gpio_mode1_core[2], gpio_mode1_core[2], gpio_mode0_core[2],
-		 gpio_mode1_core[1], gpio_mode1_core[1], gpio_mode0_core[1],
-		 gpio_mode1_core[0], gpio_mode1_core[0], gpio_mode0_core[0]};
-
-    // GPIO pads (user space)
-    s8iom0_gpiov2_pad gpio_pad [31:0] (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(gpio),
-`endif
-		.out(gpio_out_core),	// Signal from core to pad
-		.oe_n(gpio_outenb_core), // Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold signals during deep sleep (sense inverted)
-		.enable_h(porb_h),	// Post-reset enable
-		.enable_inp_h(loopb0),	// Input buffer state when disabled
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(gpio_inenb_core),		// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm(dm_all), // (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(gpio_in_core),  // Signal from pad to core
-		.in_h(),	    // VDDA domain signal (unused)
-		.tie_hi_esd(),
-		.tie_lo_esd(loopb0)
-    );
-
-    s8iom0_gpiov2_pad cclk_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(cclk),
-`endif
-		.out(),			// Signal from core to pad
-		.oe_n(vdd1v8),		// Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold
-		.enable_h(porb_h),	// Enable
-		.enable_inp_h(loopb1),	// Enable input buffer
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(por),		// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm({vss, vss, vdd1v8}), // (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(cclk_core),	    // Signal from pad to core
-		.in_h(),
-		.tie_hi_esd(),
-		.tie_lo_esd(loopb1)
-    );
-
-    // NOTE:  The analog_out pad from the raven chip has been replaced by
-    // the digital reset input RSTB on striVe due to the lack of an on-board
-    // power-on-reset circuit.  The XRES pad is used for providing a glitch-
-    // free reset.
-
-    s8iom0s8_top_xres4v2 RSTB_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(RSTB),
-`endif
-		.tie_weak_hi_h(xresloop),   // Loop-back connection to pad through pad_a_esd_h
-		.tie_hi_esd(),
-		.tie_lo_esd(),
-		.pad_a_esd_h(xresloop),
-		.xres_h_n(porb_h),
-		.disable_pullup_h(vss),	    // 0 = enable pull-up on reset pad
-		.enable_h(vdd),		    // Power-on-reset to the power-on-reset input??
-		.en_vddio_sig_h(vss),	    // No idea.
-		.inp_sel_h(vss),	    // 1 = use filt_in_h else filter the pad input
-		.filt_in_h(vss),	    // Alternate input for glitch filter
-		.pullup_h(vss),		    // Pullup connection for alternate filter input
-		.enable_vddio(vdd1v8)
-    );
-
-    s8iom0_gpiov2_pad irq_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(irq),
-`endif
-		.out(vss),		// Signal from core to pad
-		.oe_n(vdd1v8),		// Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold
-		.enable_h(porb_h),	// Enable
-		.enable_inp_h(loopb10),	// Enable input buffer
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(por),		// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm({vss, vss, vdd1v8}),	// (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(irq_pin_core),		    // Signal from pad to core
-		.in_h(),
-		.tie_hi_esd(),
-		.tie_lo_esd(loopb10)
-    );
-
-    s8iom0_gpiov2_pad SDO_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(SDO),
-`endif
-		.out(SDO_core),		// Signal from core to pad
-		.oe_n(SDO_enb),		// Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold
-		.enable_h(porb_h),	// Enable
-		.enable_inp_h(loopb11),	// Enable input buffer
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(vdd1v8),	// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm({vdd1v8, vdd1v8, vss}),	// (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(),		    // Signal from pad to core
-		.in_h(),
-		.tie_hi_esd(),
-		.tie_lo_esd(loopb11)
-    );
-
-    s8iom0_gpiov2_pad SDI_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(SDI),
-`endif
-		.out(vss),		// Signal from core to pad
-		.oe_n(vdd1v8),		// Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold
-		.enable_h(porb_h),	// Enable
-		.enable_inp_h(loopb12),	// Enable input buffer
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(por),	// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm({vss, vss, vdd1v8}),	// (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(SDI_core),		    // Signal from pad to core
-		.in_h(SDI_core_h),
-		.tie_hi_esd(),
-		.tie_lo_esd()
-    );
-
-    s8iom0_gpiov2_pad CSB_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(CSB),
-`endif
-		.out(vss),		// Signal from core to pad
-		.oe_n(vdd1v8),		// Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold
-		.enable_h(porb_h),	// Enable
-		.enable_inp_h(loopb13),	// Enable input buffer
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(por),	// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm({vss, vss, vdd1v8}),	// (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(CSB_core),		    // Signal from pad to core
-		.in_h(CSB_core_h),
-		.tie_hi_esd(),
-		.tie_lo_esd(loopb13)
-    );
-
-    s8iom0_gpiov2_pad SCK_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(SCK),
-`endif
-		.out(vss),		// Signal from core to pad
-		.oe_n(vdd1v8),		// Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold
-		.enable_h(porb_h),	// Enable
-		.enable_inp_h(loopb14),	// Enable input buffer
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(por),	// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm({vss, vss, vdd1v8}),	// (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(SCK_core),		    // Signal from pad to core
-		.in_h(SCK_core_h),    // Signal in vdda domain (3.3V)
-		.tie_hi_esd(),
-		.tie_lo_esd(loopb14)
-    );
-
-    s8iom0_gpiov2_pad flash_csb_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(flash_csb),
-`endif
-		.out(flash_csb_core),			// Signal from core to pad
-		.oe_n(flash_csb_oeb_core),		// Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold
-		.enable_h(porb_h),	// Enable
-		.enable_inp_h(loopb16),	// Enable input buffer
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(flash_csb_ieb_core),	// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm({vdd1v8, vdd1v8, vss}),	// (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(),		    // Signal from pad to core
-		.in_h(),
-		.tie_hi_esd(),
-		.tie_lo_esd()
-    );
-
-    s8iom0_gpiov2_pad flash_clk_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(flash_clk),
-`endif
-		.out(flash_clk_core),			// Signal from core to pad
-		.oe_n(flash_clk_oeb_core),		// Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold
-		.enable_h(porb_h),	// Enable
-		.enable_inp_h(loopb17),	// Enable input buffer
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(flash_clk_ieb_core),	// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm({vdd1v8, vdd1v8, vss}),	// (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(),		    // Signal from pad to core
-		.in_h(),
-		.tie_hi_esd(),
-		.tie_lo_esd()
-    );
-
-    s8iom0_gpiov2_pad flash_io0_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(flash_io0),
-`endif
-		.out(flash_io0_do_core),			// Signal from core to pad
-		.oe_n(flash_io0_oeb_core),		// Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold
-		.enable_h(porb_h),	// Enable
-		.enable_inp_h(loopb18),	// Enable input buffer
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(flash_io0_ieb_core),		// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm({flash_io0_ieb_core, flash_io0_ieb_core, flash_io0_oeb_core}), // (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(flash_io0_di_core),		    // Signal from pad to core
-		.in_h(),
-		.tie_hi_esd(),
-		.tie_lo_esd(loopb18)
-    );
-
-    s8iom0_gpiov2_pad flash_io1_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(flash_io1),
-`endif
-		.out(flash_io1_do_core),			// Signal from core to pad
-		.oe_n(flash_io1_oeb_core),		// Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold
-		.enable_h(porb_h),	// Enable
-		.enable_inp_h(loopb19),	// Enable input buffer
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(flash_io1_ieb_core),		// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm({flash_io1_ieb_core, flash_io1_ieb_core, flash_io1_oeb_core}), // (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(flash_io1_di_core),		    // Signal from pad to core
-		.in_h(),
-		.tie_hi_esd(),
-		.tie_lo_esd(loopb19)
-    );
-
-    s8iom0_gpiov2_pad flash_io2_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(flash_io2),
-`endif
-		.out(flash_io2_do_core),			// Signal from core to pad
-		.oe_n(flash_io2_oeb_core),		// Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold
-		.enable_h(porb_h),	// Enable
-		.enable_inp_h(loopb20),	// Enable input buffer
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(flash_io2_ieb_core),		// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm({flash_io2_ieb_core, flash_io2_ieb_core, flash_io2_oeb_core}), // (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(flash_io2_di_core),		    // Signal from pad to core
-		.in_h(),
-		.tie_hi_esd(),
-		.tie_lo_esd(loopb20)
-    );
-
-    s8iom0_gpiov2_pad flash_io3_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(flash_io3),
-`endif
-		.out(flash_io3_do_core),			// Signal from core to pad
-		.oe_n(flash_io3_oeb_core),		// Output enable (sense inverted)
-		.hld_h_n(vdd),		// Hold
-		.enable_h(porb_h),	// Enable
-		.enable_inp_h(loopb21),	// Enable input buffer
-		.enable_vdda_h(porb_h),	// 
-		.enable_vswitch_h(vss),	// 
-		.enable_vddio(vdd1v8),	//
-		.inp_dis(flash_io3_ieb_core),		// Disable input buffer
-		.ib_mode_sel(vss),	//
-		.vtrip_sel(vss),	//
-		.slow(vss),		//
-		.hld_ovr(vss),		//
-		.analog_en(vss),	//
-		.analog_sel(vss),	//
-		.analog_pol(vss),	//
-		.dm({flash_io3_ieb_core, flash_io3_ieb_core, flash_io3_oeb_core}), // (3 bits) Mode control
-		.pad_a_noesd_h(),   // Direct pad connection
-		.pad_a_esd_0_h(),   // Pad connection through 150 ohms
-		.pad_a_esd_1_h(),   // Pad connection through 150 ohms
-		.in(flash_io3_di_core),		    // Signal from pad to core
-		.in_h(),
-		.tie_hi_esd(),
-		.tie_lo_esd(loopb21)
-    );
-
-    // Instantiate GPIO overvoltage (I2C) compliant cell
-    // (Use this for ser_rx and ser_tx;  no reason other than testing
-    // the use of the cell.) (Might be worth adding in the I2C IP from
-    // ravenna just to test on a proper I2C channel.)
-
-    s8iom0s8_top_gpio_ovtv2 ser_rx_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(ser_rx),
-`endif
-		.out(vss),
-		.oe_n(vdd1v8),
-		.hld_h_n(vdd),
-		.enable_h(porb_h),
-		.enable_inp_h(loopb22),
-		.enable_vdda_h(porb_h),
-		.enable_vddio(vdd1v8),
-		.enable_vswitch_h(vss),
-		.inp_dis(por),
-		.vtrip_sel(vss),
-		.hys_trim(vdd1v8),
-		.slow(vss),
-		.slew_ctl({vss, vss}),	// 2 bits
-		.hld_ovr(vss),
-		.analog_en(vss),
-		.analog_sel(vss),
-		.analog_pol(vss),
-		.dm({vss, vss, vdd1v8}),		// 3 bits
-		.ib_mode_sel({vss, vss}),	// 2 bits
-		.vinref(vdd1v8),
-		.pad_a_noesd_h(),
-		.pad_a_esd_0_h(),
-		.pad_a_esd_1_h(),
-		.in(ser_rx_core),
-		.in_h(),
-		.tie_hi_esd(),
-		.tie_lo_esd()
-    );
-
-    s8iom0s8_top_gpio_ovtv2 ser_tx_pad (
-		`ABUTMENT_PINS 
-`ifndef	TOP_ROUTING
-		.pad(ser_tx),
-`endif
-		.out(ser_tx_core),
-		.oe_n(vss),
-		.hld_h_n(vdd),
-		.enable_h(porb_h),
-		.enable_inp_h(loopb23),
-		.enable_vdda_h(porb_h),
-		.enable_vddio(vdd1v8),
-		.enable_vswitch_h(vss),
-		.inp_dis(vdd1v8),
-		.vtrip_sel(vss),
-		.hys_trim(vdd1v8),
-		.slow(vss),
-		.slew_ctl({vss, vss}),	// 2 bits
-		.hld_ovr(vss),
-		.analog_en(vss),
-		.analog_sel(vss),
-		.analog_pol(vss),
-		.dm({vdd1v8, vdd1v8, vss}),		// 3 bits
-		.ib_mode_sel({vss, vss}),	// 2 bits
-		.vinref(vdd1v8),
-		.pad_a_noesd_h(),
-		.pad_a_esd_0_h(),
-		.pad_a_esd_1_h(),
-		.in(),
-		.in_h(),
-		.tie_hi_esd(),
-		.tie_lo_esd()
-    );
-
-    // Corner cells
- `ifndef TOP_ROUTING   
-	s8iom0_corner_pad corner [3:0] (
-		.vssio(vss),
-		.vddio(vdd),
-		.vddio_q(vddio_q),
-		.vssio_q(vssio_q),
-		.amuxbus_a(analog_a),
-		.amuxbus_b(analog_b),
-		.vssd(vss),
-		.vssa(vss),
-		.vswitch(vdd),
-		.vdda(vdd),
-		.vccd(vdd1v8),
-		.vcchib(vdd1v8)
-		//`ABUTMENT_PINS 
-    );
-`endif
-    // SoC core
-
-	wire striVe_clk, striVe_rstn;
-
-    striVe_clkrst clkrst(
-`ifdef LVS
-	.vdd1v8(vdd1v8),
-	.vss(vss),
-`endif		
-	.ext_clk_sel(ext_clk_sel_core),
-	.ext_clk(ext_clk_core),
-	.pll_clk(pll_clk_core),
-	.reset(por), 
-	.ext_reset(ext_reset_core),
-	.clk(striVe_clk),
-	.resetn(striVe_rstn)
-);
-
-    striVe_soc core (
-`ifdef LVS
-	.vdd1v8(vdd1v8),
-	.vss(vss),
-`endif
-    
-	.pll_clk(pll_clk_core),
-    	.clk(striVe_clk),
-    	.resetn(striVe_rstn),
-	.gpio_out_pad(gpio_out_core),
-	.gpio_in_pad(gpio_in_core),
-	.gpio_mode0_pad(gpio_mode0_core),
-	.gpio_mode1_pad(gpio_mode1_core),
-	.gpio_outenb_pad(gpio_outenb_core),
-	.gpio_inenb_pad(gpio_inenb_core),
-	.spi_sck(SCK_core),
-	.spi_ro_config(spi_ro_config_core),
-	.spi_ro_pll_dco_ena(spi_ro_pll_dco_ena_core),
-	.spi_ro_pll_div(spi_ro_pll_div_core),
-	.spi_ro_pll_sel(spi_ro_pll_sel_core),
-	.spi_ro_pll_trim(spi_ro_pll_trim_core),
-	.spi_ro_mfgr_id(spi_ro_mfgr_id_core),
-	.spi_ro_prod_id(spi_ro_prod_id_core),
-	.spi_ro_mask_rev(spi_ro_mask_rev_core),
-	.ser_tx(ser_tx_core),
-	.ser_rx(ser_rx_core),
-	.irq_pin(irq_pin_core),
-	.irq_spi(irq_spi_core),
-	.trap(trap_core),
-	.flash_csb(flash_csb_core),
-	.flash_clk(flash_clk_core),
-	.flash_csb_oeb(flash_csb_oeb_core),
-	.flash_clk_oeb(flash_clk_oeb_core),
-	.flash_io0_oeb(flash_io0_oeb_core),
-	.flash_io1_oeb(flash_io1_oeb_core),
-	.flash_io2_oeb(flash_io2_oeb_core),
-	.flash_io3_oeb(flash_io3_oeb_core),
-	.flash_csb_ieb(flash_csb_ieb_core),
-	.flash_clk_ieb(flash_clk_ieb_core),
-	.flash_io0_ieb(flash_io0_ieb_core),
-	.flash_io1_ieb(flash_io1_ieb_core),
-	.flash_io2_ieb(flash_io2_ieb_core),
-	.flash_io3_ieb(flash_io3_ieb_core),
-	.flash_io0_do(flash_io0_do_core),
-	.flash_io1_do(flash_io1_do_core),
-	.flash_io2_do(flash_io2_do_core),
-	.flash_io3_do(flash_io3_do_core),
-	.flash_io0_di(flash_io0_di_core),
-	.flash_io1_di(flash_io1_di_core),
-	.flash_io2_di(flash_io2_di_core),
-	.flash_io3_di(flash_io3_di_core)
-    );
-
-    // For the mask revision input, use an array of digital constant logic cells
-    wire [3:0] mask_rev_h;
-    wire [3:0] no_connect;
-
-    sky130_fd_sc_hvl__conb_1 mask_rev_value [3:0] (
-`ifdef LVS
-        .vpwr(vdd3v3),
-        .vpb(vdd3v3),
-        .vnb(vss),
-        .vgnd(vss),
-`endif
-        .HI({no_connect[3:1], mask_rev[0]}),
-        .LO({mask_rev[3:1], no_connect[0]})
-     );
-
-    // Housekeeping SPI at 3.3V.
-
-    striVe_spi housekeeping (
-`ifdef LVS
-	.vdd(vdd3v3),
-	.vss(vss),
-`endif
-	.RSTB(porb_h),
-	.SCK(SCK_core_h),
-	.SDI(SDI_core_h),
-	.CSB(CSB_core_h),
-	.SDO(SDO_core_h),
-	.sdo_enb(SDO_enb_h),
-	.reg_ena(spi_ro_reg_ena_core_h),
-	.pll_dco_ena(spi_ro_pll_dco_ena_core_h),
-	.pll_sel(spi_ro_pll_sel_core_h),
-	.pll_div(spi_ro_pll_div_core_h),
-        .pll_trim(spi_ro_pll_trim_core_h),
-	.irq(irq_spi_core_h),
-	.RST(por_h),
-	.reset(ext_reset_core_h),
-	.trap(trap_core_h),
-        .mfgr_id(spi_ro_mfgr_id_core_h),
-	.prod_id(spi_ro_prod_id_core_h),
-	.mask_rev_in(mask_rev_h),
-	.mask_rev(spi_ro_mask_rev_core_h)
-    );
-
-    // Level shifters from the HVL library
-
-    // On-board digital PLL
-
-    digital_pll pll (
-`ifdef LVS
-	.vdd(vdd1v8),
-	.vss(vss),
-`endif
-	.reset(por),
-	.osc(cclk_core),
-	.clockc(pll_clk_core),
-	.clockp({pll_clk_core0, pll_clk_core90}),
-	.clockd({pll_clk2, pll_clk4, pll_clk8, pll_clk16}),
-	.div(spi_ro_pll_div_core),
-	.sel(spi_ro_pll_sel_core),
-	.dco(spi_ro_pll_dco_ena_core),
-	.ext_trim(spi_ro_pll_trim_core)
-    );
-	
-endmodule
diff --git a/verilog/rtl/digital_pll.v b/verilog/rtl/digital_pll.v
index fe564cb..d7dc839 100644
--- a/verilog/rtl/digital_pll.v
+++ b/verilog/rtl/digital_pll.v
@@ -4,7 +4,17 @@
 `include "digital_pll_controller.v"
 `include "ring_osc2x13.v"
 
-module digital_pll(reset, extclk_sel, osc, clockc, clockp, clockd, div, sel, dco, ext_trim);
+module digital_pll(
+`ifdef LVS
+    vdd,
+    vss,
+`endif
+    reset, extclk_sel, osc, clockc, clockp, clockd, div, sel, dco, ext_trim);
+
+`ifdef LVS
+    input vdd;
+    input vss;
+`endif
 
     input	reset;		// Sense positive reset
     input	extclk_sel;	// External clock select (acts as 2nd reset)
@@ -32,66 +42,66 @@
     assign creset = (dco == 1'b0) ? ireset : 1'b1;
 
     ring_osc2x13 ringosc (
-	.reset(ireset),
-	.trim(itrim),
-	.clockp(clockp)
+    .reset(ireset),
+    .trim(itrim),
+    .clockp(clockp)
     );
 
     digital_pll_controller pll_control (
-	.reset(creset),
-	.clock(clockp[0]),
-	.osc(osc),
-	.div(div),
-	.trim(otrim)
+    .reset(creset),
+    .clock(clockp[0]),
+    .osc(osc),
+    .div(div),
+    .trim(otrim)
     );
 
     // Select core clock output
     assign clockc = (sel == 3'b000) ? clockp[0] :
-		    (sel == 3'b001) ? clockd[0] :
-		    (sel == 3'b010) ? clockd[1] :
-		    (sel == 3'b011) ? clockd[2] :
-		    		      clockd[3];
+            (sel == 3'b001) ? clockd[0] :
+            (sel == 3'b010) ? clockd[1] :
+            (sel == 3'b011) ? clockd[2] :
+                          clockd[3];
 
     // Derive negative-sense reset from the input positive-sense reset
 
-    sky130_fd_sc_hd__inv_4 irb (
-	.A(reset),
-	.Y(resetb)
+    scs8hd_inv_4 irb (
+    .A(reset),
+    .Y(resetb)
     );
 
     // Create divided down clocks.  The inverted output only comes
     // with digital standard cells with inverted resets, so the
     // reset has to be inverted as well.
  
-    sky130_fd_sc_hd__dfrbp_1 idiv2 (
-	.CLK(clockp[1]),
-	.D(clockd[0]),
-	.Q(nint[0]),
-	.QN(clockd[0]),
-	.RESETB(resetb)
+    scs8hd_dfrbp_1 idiv2 (
+    .CLK(clockp[1]),
+    .D(clockd[0]),
+    .Q(nint[0]),
+    .QN(clockd[0]),
+    .RESETB(resetb)
     );
 
-    sky130_fd_sc_hd__dfrbp_1 idiv4 (
-	.CLK(clockd[0]),
-	.D(clockd[1]),
-	.Q(nint[1]),
-	.QN(clockd[1]),
-	.RESETB(resetb)
+    scs8hd_dfrbp_1 idiv4 (
+    .CLK(clockd[0]),
+    .D(clockd[1]),
+    .Q(nint[1]),
+    .QN(clockd[1]),
+    .RESETB(resetb)
     );
 
-    sky130_fd_sc_hd__dfrbp_1 idiv8 (
-	.CLK(clockd[1]),
-	.D(clockd[2]),
-	.Q(nint[2]),
-	.QN(clockd[2]),
-	.RESETB(resetb)
+    scs8hd_dfrbp_1 idiv8 (
+    .CLK(clockd[1]),
+    .D(clockd[2]),
+    .Q(nint[2]),
+    .QN(clockd[2]),
+    .RESETB(resetb)
     );
 
-    sky130_fd_sc_hd__dfrbp_1 idiv16 (
-	.CLK(clockd[2]),
-	.D(clockd[3]),
-	.Q(nint[3]),
-	.QN(clockd[3]),
-	.RESETB(resetb)
+    scs8hd_dfrbp_1 idiv16 (
+    .CLK(clockd[2]),
+    .D(clockd[3]),
+    .Q(nint[3]),
+    .QN(clockd[3]),
+    .RESETB(resetb)
     );
 endmodule
diff --git a/verilog/rtl/digital_pll_controller.v b/verilog/rtl/digital_pll_controller.v
index b88cc33..ddc553d 100644
--- a/verilog/rtl/digital_pll_controller.v
+++ b/verilog/rtl/digital_pll_controller.v
@@ -54,62 +54,62 @@
     assign tint = tval[6:2];
                                      // |<--second-->|<-- first-->|
     assign trim = (tint == 5'd0)  ? 26'b0000000000000_0000000000000 :
-		  (tint == 5'd1)  ? 26'b0000000000000_0000000000001 :
-		  (tint == 5'd2)  ? 26'b0000000000000_0000001000001 :
-		  (tint == 5'd3)  ? 26'b0000000000000_0010001000001 :
-		  (tint == 5'd4)  ? 26'b0000000000000_0010001001001 :
-		  (tint == 5'd5)  ? 26'b0000000000000_0010101001001 :
-		  (tint == 5'd6)  ? 26'b0000000000000_1010101001001 :
-		  (tint == 5'd7)  ? 26'b0000000000000_1010101101001 :
-		  (tint == 5'd8)  ? 26'b0000000000000_1010101101101 :
-		  (tint == 5'd9)  ? 26'b0000000000000_1011101101101 :
-		  (tint == 5'd10) ? 26'b0000000000000_1011101111101 :
-		  (tint == 5'd11) ? 26'b0000000000000_1111101111101 :
-		  (tint == 5'd12) ? 26'b0000000000000_1111101111111 :
-		  (tint == 5'd13) ? 26'b0000000000000_1111111111111 :
-		  (tint == 5'd14) ? 26'b0000000000001_1111111111111 :
-		  (tint == 5'd15) ? 26'b0000001000001_1111111111111 :
-		  (tint == 5'd16) ? 26'b0010001000001_1111111111111 :
-		  (tint == 5'd17) ? 26'b0010001001001_1111111111111 :
-		  (tint == 5'd18) ? 26'b0010101001001_1111111111111 :
-		  (tint == 5'd19) ? 26'b1010101001001_1111111111111 :
-		  (tint == 5'd20) ? 26'b1010101101001_1111111111111 :
-		  (tint == 5'd21) ? 26'b1010101101101_1111111111111 :
-		  (tint == 5'd22) ? 26'b1011101101101_1111111111111 :
-		  (tint == 5'd23) ? 26'b1011101111101_1111111111111 :
-		  (tint == 5'd24) ? 26'b1111101111101_1111111111111 :
-		  (tint == 5'd25) ? 26'b1111101111111_1111111111111 :
-				    26'b1111111111111_1111111111111;
+          (tint == 5'd1)  ? 26'b0000000000000_0000000000001 :
+          (tint == 5'd2)  ? 26'b0000000000000_0000001000001 :
+          (tint == 5'd3)  ? 26'b0000000000000_0010001000001 :
+          (tint == 5'd4)  ? 26'b0000000000000_0010001001001 :
+          (tint == 5'd5)  ? 26'b0000000000000_0010101001001 :
+          (tint == 5'd6)  ? 26'b0000000000000_1010101001001 :
+          (tint == 5'd7)  ? 26'b0000000000000_1010101101001 :
+          (tint == 5'd8)  ? 26'b0000000000000_1010101101101 :
+          (tint == 5'd9)  ? 26'b0000000000000_1011101101101 :
+          (tint == 5'd10) ? 26'b0000000000000_1011101111101 :
+          (tint == 5'd11) ? 26'b0000000000000_1111101111101 :
+          (tint == 5'd12) ? 26'b0000000000000_1111101111111 :
+          (tint == 5'd13) ? 26'b0000000000000_1111111111111 :
+          (tint == 5'd14) ? 26'b0000000000001_1111111111111 :
+          (tint == 5'd15) ? 26'b0000001000001_1111111111111 :
+          (tint == 5'd16) ? 26'b0010001000001_1111111111111 :
+          (tint == 5'd17) ? 26'b0010001001001_1111111111111 :
+          (tint == 5'd18) ? 26'b0010101001001_1111111111111 :
+          (tint == 5'd19) ? 26'b1010101001001_1111111111111 :
+          (tint == 5'd20) ? 26'b1010101101001_1111111111111 :
+          (tint == 5'd21) ? 26'b1010101101101_1111111111111 :
+          (tint == 5'd22) ? 26'b1011101101101_1111111111111 :
+          (tint == 5'd23) ? 26'b1011101111101_1111111111111 :
+          (tint == 5'd24) ? 26'b1111101111101_1111111111111 :
+          (tint == 5'd25) ? 26'b1111101111111_1111111111111 :
+                    26'b1111111111111_1111111111111;
    
     always @(posedge clock or posedge reset) begin
-	if (reset == 1'b1) begin
-	    tval <= 7'd0;	// Note:  trim[0] must be zero for startup to work.
-	    oscbuf <= 3'd0;
-	    prep <= 3'd0;
-	    count0 <= 5'd0;
-	    count1 <= 5'd0;
+    if (reset == 1'b1) begin
+        tval <= 7'd0;	// Note:  trim[0] must be zero for startup to work.
+        oscbuf <= 3'd0;
+        prep <= 3'd0;
+        count0 <= 5'd0;
+        count1 <= 5'd0;
 
-	end else begin
-	    oscbuf <= {oscbuf[1:0], osc};
+    end else begin
+        oscbuf <= {oscbuf[1:0], osc};
 
-	    if (oscbuf[2] != oscbuf[1]) begin
-		count1 <= count0;
-		count0 <= 5'b00001;
-		prep <= {prep[1:0], 1'b1};
+        if (oscbuf[2] != oscbuf[1]) begin
+        count1 <= count0;
+        count0 <= 5'b00001;
+        prep <= {prep[1:0], 1'b1};
 
-		if (prep == 3'b111) begin
-		    if (sum > div) begin
-			tval <= tval + 1;
-		    end else if (sum < div) begin
-			tval <= tval - 1;
-		    end
-		end
-	    end else begin
-		if (count0 != 5'b11111) begin
-	            count0 <= count0 + 1;
-		end
-	    end
-	end
+        if (prep == 3'b111) begin
+            if (sum > div) begin
+            tval <= tval + 1;
+            end else if (sum < div) begin
+            tval <= tval - 1;
+            end
+        end
+        end else begin
+        if (count0 != 5'b11111) begin
+                count0 <= count0 + 1;
+        end
+        end
+    end
     end
 
 endmodule	// digital_pll_controller
diff --git a/verilog/rtl/gpio_wb.v b/verilog/rtl/gpio_wb.v
new file mode 100644
index 0000000..5f014ce
--- /dev/null
+++ b/verilog/rtl/gpio_wb.v
@@ -0,0 +1,147 @@
+module gpio_wb # (
+    parameter BASE_ADR  = 32'h 2100_0000,
+    parameter GPIO_DATA = 8'h 00,
+    parameter GPIO_ENA  = 8'h 04,
+    parameter GPIO_PU   = 8'h 08,
+    parameter GPIO_PD   = 8'h 0c
+) (
+    input wb_clk_i,
+    input wb_rst_i,
+
+    input [31:0] wb_dat_i,
+    input [31:0] wb_adr_i,
+    input [3:0] wb_sel_i,
+    input wb_cyc_i,
+    input wb_stb_i,
+    input wb_we_i,
+
+    output [31:0] wb_dat_o,
+    output wb_ack_o,
+
+    input [15:0] gpio_in_pad,
+    output [15:0] gpio,
+    output [15:0] gpio_oeb,
+    output [15:0] gpio_pu,
+    output [15:0] gpio_pd
+);
+
+    wire resetn;
+    wire valid;
+    wire ready;
+    wire [3:0] iomem_we;
+
+    assign resetn = ~wb_rst_i;
+    assign valid = wb_stb_i && wb_cyc_i; 
+
+    assign iomem_we = wb_sel_i & {4{wb_we_i}};
+    assign wb_ack_o = ready;
+
+    gpio #(
+        .BASE_ADR(BASE_ADR),
+        .GPIO_DATA(GPIO_DATA),
+        .GPIO_ENA(GPIO_ENA),
+        .GPIO_PD(GPIO_PD),
+        .GPIO_PU(GPIO_PU)
+    ) gpio_ctrl (
+        .clk(wb_clk_i),
+        .resetn(resetn),
+
+        .gpio_in_pad(gpio_in_pad),
+
+        .iomem_addr(wb_adr_i),
+        .iomem_valid(valid),
+        .iomem_wstrb(iomem_we),
+        .iomem_wdata(wb_dat_i),
+        .iomem_rdata(wb_dat_o),
+        .iomem_ready(ready),
+
+        .gpio(gpio),
+        .gpio_oeb(gpio_oeb),
+        .gpio_pu(gpio_pu),
+        .gpio_pd(gpio_pd)
+    );
+    
+endmodule
+
+module gpio #(
+    parameter BASE_ADR  = 32'h 2100_0000,
+    parameter GPIO_DATA = 8'h 00,
+    parameter GPIO_ENA  = 8'h 04,
+    parameter GPIO_PU   = 8'h 08,
+    parameter GPIO_PD   = 8'h 0c
+) (
+    input clk,
+    input resetn,
+
+    input [15:0] gpio_in_pad,
+
+    input [31:0] iomem_addr,
+    input iomem_valid,
+    input [3:0] iomem_wstrb,
+    input [31:0] iomem_wdata,
+    output reg [31:0] iomem_rdata,
+    output reg iomem_ready,
+
+    output [15:0] gpio,
+    output [15:0] gpio_oeb,
+    output [15:0] gpio_pu,
+    output [15:0] gpio_pd
+);
+
+    reg [15:0] gpio;		// GPIO output data
+    reg [15:0] gpio_pu;		// GPIO pull-up enable
+    reg [15:0] gpio_pd;		// GPIO pull-down enable
+    reg [15:0] gpio_oeb;    // GPIO output enable (sense negative)
+    
+    wire gpio_sel;
+    wire gpio_oeb_sel;
+    wire gpio_pu_sel;  
+    wire gpio_pd_sel;
+
+    assign gpio_sel     = (iomem_addr[7:0] == GPIO_DATA);
+    assign gpio_oeb_sel = (iomem_addr[7:0] == GPIO_ENA);
+    assign gpio_pu_sel  = (iomem_addr[7:0] == GPIO_PU);
+    assign gpio_pd_sel  = (iomem_addr[7:0] == GPIO_PD);
+
+    always @(posedge clk) begin
+        if (!resetn) begin
+            gpio <= 0;
+            gpio_oeb <= 16'hffff;
+            gpio_pu <= 0;
+            gpio_pd <= 0;
+        end else begin
+            iomem_ready <= 0;
+            if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin
+                iomem_ready <= 1'b 1;
+                
+                if (gpio_sel) begin
+                    iomem_rdata <= {gpio, gpio_in_pad};
+
+                    if (iomem_wstrb[0]) gpio[ 7: 0] <= iomem_wdata[ 7: 0];
+                    if (iomem_wstrb[1]) gpio[15: 8] <= iomem_wdata[15: 8];
+
+                end else if (gpio_oeb_sel) begin
+                    iomem_rdata <= {16'd0, gpio_oeb};
+
+                    if (iomem_wstrb[0]) gpio_oeb[ 7: 0] <= iomem_wdata[ 7: 0];
+                    if (iomem_wstrb[1]) gpio_oeb[15: 8] <= iomem_wdata[15: 8];
+
+                end else if (gpio_pu_sel) begin
+                    iomem_rdata <= {16'd0, gpio_pu};
+
+                    if (iomem_wstrb[0]) gpio_pu[ 7: 0] <= iomem_wdata[ 7: 0];
+                    if (iomem_wstrb[1]) gpio_pu[15: 8] <= iomem_wdata[15: 8];
+
+                end else if (gpio_pd_sel) begin
+                    iomem_rdata <= {16'd0, gpio_pd};          
+
+                    if (iomem_wstrb[0]) gpio_pd[ 7: 0] <= iomem_wdata[ 7: 0];
+                    if (iomem_wstrb[1]) gpio_pd[15: 8] <= iomem_wdata[15: 8];
+
+                end
+
+            end
+        end
+    end
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/harness.v b/verilog/rtl/harness.v
new file mode 100644
index 0000000..b8403e1
--- /dev/null
+++ b/verilog/rtl/harness.v
@@ -0,0 +1,1303 @@
+/*----------------------------------------------------------*/
+/* striVe, a raven/ravenna-like architecture in SkyWater s8 */
+/*                                                          */
+/* 1st edition, test of SkyWater s8 process                 */
+/* This version is missing all analog functionality,        */
+/* including crystal oscillator, voltage regulator, and PLL */
+/* For simplicity, the pad arrangement of Raven has been    */
+/* retained, even though many pads have no internal         */
+/* connection.                                              */
+/*                                                          */
+/* Copyright 2020 efabless, Inc.                            */
+/* Written by Tim Edwards, December 2019                    */
+/* This file is open source hardware released under the     */
+/* Apache 2.0 license.  See file LICENSE.                   */
+/*                                                          */
+/*----------------------------------------------------------*/
+
+`timescale 1 ns / 1 ps
+
+`define USE_OPENRAM
+`define USE_PG_PIN
+`define functional
+
+`ifdef SYNTH_OPENLANE
+        `include "../stubs/scs8hd_conb_1.v"
+        `include "../stubs/s8iom0s8.v"
+        `include "../stubs/power_pads_lib.v"
+`else
+
+    `ifndef LVS
+        `include "/ef/tech/SW/EFS8A/libs.ref/verilog/s8iom0s8/s8iom0s8.v"
+        `include "/ef/tech/SW/EFS8A/libs.ref/verilog/s8iom0s8/power_pads_lib.v"
+        `include "/ef/tech/SW/EFS8A/libs.ref/verilog/scs8hd/scs8hd.v"
+
+        `include "lvlshiftdown.v"
+        `include "mgmt_soc.v"
+        `include "striVe_spi.v"
+        `include "digital_pll.v"
+        `include "striVe_clkrst.v"
+        `include "../ip/crossbar.v"
+        `include "../dv/dummy_slave.v"
+
+    `endif
+`endif
+
+`ifdef USE_OPENRAM
+        `include "sram_1rw1r_32_256_8_sky130.v"
+`endif
+
+//`define     TOP_ROUTING
+`ifndef TOP_ROUTING 
+    `define ABUTMENT_PINS \
+    .amuxbus_a(analog_a),\
+    .amuxbus_b(analog_b),\
+    .vssa(vss),\
+    .vdda(vdd),\
+    .vswitch(vdd),\
+    .vddio_q(vddio_q),\
+    .vcchib(vdd1v8),\
+    .vddio(vdd),\
+    .vccd(vdd1v8),\
+    .vssio(vss),\
+    .vssd(vss),\
+    .vssio_q(vssio_q),
+`else 
+    `define ABUTMENT_PINS 
+`endif
+
+// Crossbar Slaves
+`ifndef SLAVE_ADR
+    `define SLAVE_ADR { \
+        {8'hB0, {24{1'b0}}},\
+        {8'hA0, {24{1'b0}}},\
+        {8'h90, {24{1'b0}}},\
+        {8'h80, {24{1'b0}}}\
+    }\
+`endif
+
+`ifndef ADR_MASK
+    `define ADR_MASK { \
+        {8'hFF, {24{1'b0}}}, \
+        {8'hFF, {24{1'b0}}}, \
+        {8'hFF, {24{1'b0}}}, \
+        {8'hFF, {24{1'b0}}}  \
+    }\
+`endif
+
+`define NM 2    // Crossbar switch number of masters
+`define NS 4    // Crossbar switch number of slaves 
+`define DW 32
+`define AW 32
+
+module harness (vdd, vdd1v8, vss, gpio, xi, xo, adc0_in, adc1_in, adc_high, adc_low,
+    comp_inn, comp_inp, RSTB, ser_rx, ser_tx, irq, SDO, SDI, CSB, SCK,
+    xclk, flash_csb, flash_clk, flash_io0, flash_io1, flash_io2, flash_io3);
+
+    inout vdd;
+    inout vdd1v8;
+    inout vss;
+    inout [15:0] gpio;
+    input xi;		// CMOS clock input, not a crystal
+    output xo;		// divide-by-16 clock output
+    input adc0_in;
+    input adc1_in;
+    input adc_high;
+    input adc_low;
+    input comp_inn;
+    input comp_inp;
+    input RSTB;		// NOTE:  Replaces analog_out pin from raven chip
+    input ser_rx;
+    output ser_tx;
+    input irq;
+    output SDO;
+    input SDI;
+    input CSB;
+    input SCK;
+    input xclk;
+    output flash_csb;
+    output flash_clk;
+    output flash_io0;
+    output flash_io1;
+    output flash_io2;
+    output flash_io3;
+
+    wire [15:0] gpio_out_core;
+    wire [15:0] gpio_in_core;
+    wire [15:0]	gpio_mode0_core;
+    wire [15:0]	gpio_mode1_core;
+    wire [15:0]	gpio_outenb_core;
+    wire [15:0]	gpio_inenb_core;
+
+    wire analog_a, analog_b;	    /* Placeholders for analog signals */
+
+    wire porb_h;
+    wire porb_l;
+    wire por_h;
+    wire por;
+    wire SCK_core;
+    wire SDI_core;
+    wire CSB_core;
+    wire SDO_core;
+    wire SDO_enb;
+    wire spi_ro_xtal_ena_core;
+    wire spi_ro_reg_ena_core;
+    wire spi_ro_pll_dco_ena_core;
+    wire [2:0] spi_ro_pll_sel_core;
+    wire [4:0] spi_ro_pll_div_core;
+    wire [25:0] spi_ro_pll_trim_core;
+    wire ext_clk_sel_core;
+    wire irq_spi_core;
+    wire ext_reset_core;
+    wire trap_core;
+    wire [11:0] spi_ro_mfgr_id_core;
+    wire [7:0] spi_ro_prod_id_core;
+    wire [3:0] spi_ro_mask_rev_core;
+
+    // Instantiate power cells for VDD3V3 domain (8 total; 4 high clamps and
+    // 4 low clamps)
+    s8iom0_vdda_hvc_pad vdd3v3hclamp [1:0] (
+        `ABUTMENT_PINS
+        .drn_hvc(),
+        .src_bdy_hvc()
+    );
+
+    s8iom0_vddio_hvc_pad vddiohclamp [1:0] (
+        `ABUTMENT_PINS
+        .drn_hvc(),
+        .src_bdy_hvc()
+    );
+
+
+    s8iom0_vdda_lvc_pad vdd3v3lclamp [3:0] (
+        `ABUTMENT_PINS
+        .bdy2_b2b(),
+        .drn_lvc1(),
+        .drn_lvc2(),
+        .src_bdy_lvc1(),
+        .src_bdy_lvc2()
+    );
+
+    // Instantiate the core voltage supply (since it is not generated on-chip)
+    // (1.8V) (4 total, 2 high and 2 low clamps)
+
+    s8iom0_vccd_hvc_pad vdd1v8hclamp [1:0] (
+        `ABUTMENT_PINS
+        .drn_hvc(),
+        .src_bdy_hvc()
+    );
+
+    s8iom0_vccd_lvc_pad vdd1v8lclamp [1:0] (
+        `ABUTMENT_PINS
+        .bdy2_b2b(),
+        .drn_lvc1(),
+        .drn_lvc2(),
+        .src_bdy_lvc1(),
+        .src_bdy_lvc2()
+    );
+
+    // Instantiate ground cells (7 total, 4 high clamps and 3 low clamps)
+
+    s8iom0_vssa_hvc_pad vsshclamp [3:0] (
+        `ABUTMENT_PINS
+        .drn_hvc(),
+        .src_bdy_hvc()
+    );
+
+    s8iom0_vssa_lvc_pad vssalclamp (
+        `ABUTMENT_PINS
+        .bdy2_b2b(),
+        .drn_lvc1(),
+        .drn_lvc2(),
+        .src_bdy_lvc1(),
+        .src_bdy_lvc2()
+    );
+
+    s8iom0_vssd_lvc_pad vssdlclamp (
+        `ABUTMENT_PINS
+        .bdy2_b2b(),
+        .drn_lvc1(),
+        .drn_lvc2(),
+        .src_bdy_lvc1(),
+        .src_bdy_lvc2()
+    );
+
+    s8iom0_vssio_lvc_pad vssiolclamp (
+        `ABUTMENT_PINS
+        .bdy2_b2b(),
+        .drn_lvc1(),
+        .drn_lvc2(),
+        .src_bdy_lvc1(),
+        .src_bdy_lvc2()
+    );
+
+    wire [47:0] dm_all;
+
+    assign dm_all = {gpio_mode1_core[15], gpio_mode1_core[15], gpio_mode0_core[15],
+         gpio_mode1_core[14], gpio_mode1_core[14], gpio_mode0_core[14],
+         gpio_mode1_core[13], gpio_mode1_core[13], gpio_mode0_core[13],
+         gpio_mode1_core[12], gpio_mode1_core[12], gpio_mode0_core[12],
+         gpio_mode1_core[11], gpio_mode1_core[11], gpio_mode0_core[11],
+         gpio_mode1_core[10], gpio_mode1_core[10], gpio_mode0_core[10],
+         gpio_mode1_core[9], gpio_mode1_core[9], gpio_mode0_core[9],
+         gpio_mode1_core[8], gpio_mode1_core[8], gpio_mode0_core[8],
+         gpio_mode1_core[7], gpio_mode1_core[7], gpio_mode0_core[7],
+         gpio_mode1_core[6], gpio_mode1_core[6], gpio_mode0_core[6],
+         gpio_mode1_core[5], gpio_mode1_core[5], gpio_mode0_core[5],
+         gpio_mode1_core[4], gpio_mode1_core[4], gpio_mode0_core[4],
+         gpio_mode1_core[3], gpio_mode1_core[3], gpio_mode0_core[3],
+         gpio_mode1_core[2], gpio_mode1_core[2], gpio_mode0_core[2],
+         gpio_mode1_core[1], gpio_mode1_core[1], gpio_mode0_core[1],
+         gpio_mode1_core[0], gpio_mode1_core[0], gpio_mode0_core[0]};
+
+    // GPIO pads
+    s8iom0_gpiov2_pad gpio_pad [15:0] (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(gpio),
+`endif
+        .out(gpio_out_core),	// Signal from core to pad
+        .oe_n(gpio_outenb_core), // Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold signals during deep sleep (sense inverted)
+        .enable_h(porb_h),	// Post-reset enable
+        .enable_inp_h(loopb0),	// Input buffer state when disabled
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(gpio_inenb_core),		// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm(dm_all), // (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(gpio_in_core),  // Signal from pad to core
+        .in_h(),	    // VDDA domain signal (unused)
+        .tie_hi_esd(),
+        .tie_lo_esd(loopb0)
+    );
+
+    s8iom0_gpiov2_pad xi_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(xi),
+`endif
+        .out(),			// Signal from core to pad
+        .oe_n(vdd1v8),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb1),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(por),		// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vss, vss, vdd1v8}), // (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(xi_core),	    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd(loopb1)
+    );
+
+    s8iom0_gpiov2_pad xo_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(xo),
+`endif
+        .out(pll_clk16),	// Signal from core to pad
+        .oe_n(vss),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb2),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(vdd1v8),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vdd1v8, vdd1v8, vss}),	// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(),	    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd(loopb2)
+    );
+
+    s8iom0_gpiov2_pad adc0_in_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(adc0_in),
+`endif
+        .out(vss),		// Signal from core to pad
+        .oe_n(vdd1v8),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb3),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(vdd1v8),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vdd1v8),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vss, vss, vss}),			// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd()
+    );
+
+    s8iom0_gpiov2_pad adc1_in_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(adc1_in),
+`endif
+        .pad_a_noesd_h(),   // Direct pad connection
+        .out(vss),		// Signal from core to pad
+        .oe_n(vdd1v8),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb4),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(vdd1v8),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vdd1v8),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vss, vss, vss}),			// (3 bits) Mode control
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd()
+    );
+
+    s8iom0_gpiov2_pad adc_high_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(adc_high),
+`endif
+        .out(vss),		// Signal from core to pad
+        .oe_n(vdd1v8),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb5),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(vdd1v8),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vdd1v8),	//
+        .analog_sel(vdd1v8),	//
+        .analog_pol(vdd1v8),	//
+        .dm({vss, vss, vss}),			// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd()
+    );
+
+    s8iom0_gpiov2_pad adc_low_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(adc_low),
+`endif
+        .out(vss),		// Signal from core to pad
+        .oe_n(vdd1v8),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb6),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(vdd1v8),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vdd1v8),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vss, vss, vss}),			// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd()
+    );
+
+    s8iom0_gpiov2_pad comp_inn_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(comp_inn),
+`endif
+        .out(vss),		// Signal from core to pad
+        .oe_n(vdd1v8),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb7),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(vdd1v8),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vdd1v8),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vss, vss, vss}),			// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd()
+    );
+
+    s8iom0_gpiov2_pad comp_inp_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(comp_inp),
+`endif
+        .out(vss),		// Signal from core to pad
+        .oe_n(vdd1v8),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb8),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(vdd1v8),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vdd1v8),	//
+        .analog_sel(vdd1v8),	//
+        .analog_pol(vss),	//
+        .dm({vss, vss, vss}),			// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd()
+    );
+
+    // NOTE:  The analog_out pad from the raven chip has been replaced by
+    // the digital reset input RSTB on striVe due to the lack of an on-board
+    // power-on-reset circuit.  The XRES pad is used for providing a glitch-
+    // free reset.
+
+    s8iom0s8_top_xres4v2 RSTB_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(RSTB),
+`endif
+        .tie_weak_hi_h(xresloop),   // Loop-back connection to pad through pad_a_esd_h
+        .tie_hi_esd(),
+        .tie_lo_esd(),
+        .pad_a_esd_h(xresloop),
+        .xres_h_n(porb_h),
+        .disable_pullup_h(vss),	    // 0 = enable pull-up on reset pad
+        .enable_h(vdd),		    // Power-on-reset to the power-on-reset input??
+        .en_vddio_sig_h(vss),	    // No idea.
+        .inp_sel_h(vss),	    // 1 = use filt_in_h else filter the pad input
+        .filt_in_h(vss),	    // Alternate input for glitch filter
+        .pullup_h(vss),		    // Pullup connection for alternate filter input
+        .enable_vddio(vdd1v8)
+    );
+
+    s8iom0_gpiov2_pad irq_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(irq),
+`endif
+        .out(vss),		// Signal from core to pad
+        .oe_n(vdd1v8),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb10),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(por),		// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vss, vss, vdd1v8}),	// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(irq_pin_core),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd(loopb10)
+    );
+
+    s8iom0_gpiov2_pad SDO_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(SDO),
+`endif
+        .out(SDO_core),		// Signal from core to pad
+        .oe_n(SDO_enb),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb11),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(vdd1v8),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vdd1v8, vdd1v8, vss}),	// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd(loopb11)
+    );
+
+    s8iom0_gpiov2_pad SDI_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(SDI),
+`endif
+        .out(vss),			// Signal from core to pad
+        .oe_n(vdd1v8),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb12),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(por),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vss, vss, vdd1v8}),	// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(SDI_core),		    // Signal from pad to core
+        .in_h(SDI_core_h),
+        .tie_hi_esd(),
+        .tie_lo_esd()
+    );
+
+    s8iom0_gpiov2_pad CSB_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(CSB),
+`endif
+        .out(vss),		// Signal from core to pad
+        .oe_n(vdd1v8),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb13),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(por),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vss, vss, vdd1v8}),	// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(CSB_core),		    // Signal from pad to core
+        .in_h(CSB_core_h),
+        .tie_hi_esd(),
+        .tie_lo_esd(loopb13)
+    );
+
+    s8iom0_gpiov2_pad SCK_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(SCK),
+`endif
+        .out(vss),		// Signal from core to pad
+        .oe_n(vdd1v8),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb14),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(por),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vss, vss, vdd1v8}),	// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(SCK_core),		    // Signal from pad to core
+        .in_h(SCK_core_h),    // Signal in vdda domain (3.3V)
+        .tie_hi_esd(),
+        .tie_lo_esd(loopb14)
+    );
+
+    s8iom0_gpiov2_pad xclk_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(xclk),
+`endif
+        .out(vss),		// Signal from core to pad
+        .oe_n(vdd1v8),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb15),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(por),		// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vss, vss, vdd1v8}), // (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(ext_clk_core),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd(loopb15)
+    );
+
+    // assign flash_csb = (input) ? 
+    s8iom0_gpiov2_pad flash_csb_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(flash_csb),
+`endif
+        .out(flash_csb_core),			// Signal from core to pad
+        .oe_n(flash_csb_oeb_core),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb16),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(flash_csb_ieb_core),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vdd1v8, vdd1v8, vss}),	// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd()
+    );
+
+    s8iom0_gpiov2_pad flash_clk_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(flash_clk),
+`endif
+        .out(flash_clk_core),			// Signal from core to pad
+        .oe_n(flash_clk_oeb_core),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb17),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(flash_clk_ieb_core),	// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({vdd1v8, vdd1v8, vss}),	// (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd()
+    );
+
+    s8iom0_gpiov2_pad flash_io0_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(flash_io0),
+`endif
+        .out(flash_io0_do_core),			// Signal from core to pad
+        .oe_n(flash_io0_oeb_core),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb18),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(flash_io0_ieb_core),		// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({flash_io0_ieb_core, flash_io0_ieb_core, flash_io0_oeb_core}), // (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(flash_io0_di_core),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd(loopb18)
+    );
+
+    s8iom0_gpiov2_pad flash_io1_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(flash_io1),
+`endif
+        .out(flash_io1_do_core),			// Signal from core to pad
+        .oe_n(flash_io1_oeb_core),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb19),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(flash_io1_ieb_core),		// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({flash_io1_ieb_core, flash_io1_ieb_core, flash_io1_oeb_core}), // (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(flash_io1_di_core),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd(loopb19)
+    );
+
+    s8iom0_gpiov2_pad flash_io2_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(flash_io2),
+`endif
+        .out(flash_io2_do_core),			// Signal from core to pad
+        .oe_n(flash_io2_oeb_core),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb20),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(flash_io2_ieb_core),		// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({flash_io2_ieb_core, flash_io2_ieb_core, flash_io2_oeb_core}), // (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(flash_io2_di_core),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd(loopb20)
+    );
+
+    s8iom0_gpiov2_pad flash_io3_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(flash_io3),
+`endif
+        .out(flash_io3_do_core),			// Signal from core to pad
+        .oe_n(flash_io3_oeb_core),		// Output enable (sense inverted)
+        .hld_h_n(vdd),		// Hold
+        .enable_h(porb_h),	// Enable
+        .enable_inp_h(loopb21),	// Enable input buffer
+        .enable_vdda_h(porb_h),	// 
+        .enable_vswitch_h(vss),	// 
+        .enable_vddio(vdd1v8),	//
+        .inp_dis(flash_io3_ieb_core),		// Disable input buffer
+        .ib_mode_sel(vss),	//
+        .vtrip_sel(vss),	//
+        .slow(vss),		//
+        .hld_ovr(vss),		//
+        .analog_en(vss),	//
+        .analog_sel(vss),	//
+        .analog_pol(vss),	//
+        .dm({flash_io3_ieb_core, flash_io3_ieb_core, flash_io3_oeb_core}), // (3 bits) Mode control
+        .pad_a_noesd_h(),   // Direct pad connection
+        .pad_a_esd_0_h(),   // Pad connection through 150 ohms
+        .pad_a_esd_1_h(),   // Pad connection through 150 ohms
+        .in(flash_io3_di_core),		    // Signal from pad to core
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd(loopb21)
+    );
+
+    // Instantiate GPIO overvoltage (I2C) compliant cell
+    // (Use this for ser_rx and ser_tx;  no reason other than testing
+    // the use of the cell.) (Might be worth adding in the I2C IP from
+    // ravenna just to test on a proper I2C channel.)
+
+    s8iom0s8_top_gpio_ovtv2 ser_rx_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(ser_rx),
+`endif
+        .out(vss),
+        .oe_n(vdd1v8),
+        .hld_h_n(vdd),
+        .enable_h(porb_h),
+        .enable_inp_h(loopb22),
+        .enable_vdda_h(porb_h),
+        .enable_vddio(vdd1v8),
+        .enable_vswitch_h(vss),
+        .inp_dis(por),
+        .vtrip_sel(vss),
+        .hys_trim(vdd1v8),
+        .slow(vss),
+        .slew_ctl({vss, vss}),	// 2 bits
+        .hld_ovr(vss),
+        .analog_en(vss),
+        .analog_sel(vss),
+        .analog_pol(vss),
+        .dm({vss, vss, vdd1v8}),		// 3 bits
+        .ib_mode_sel({vss, vss}),	// 2 bits
+        .vinref(vdd1v8),
+        .pad_a_noesd_h(),
+        .pad_a_esd_0_h(),
+        .pad_a_esd_1_h(),
+        .in(ser_rx_core),
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd()
+    );
+
+    s8iom0s8_top_gpio_ovtv2 ser_tx_pad (
+        `ABUTMENT_PINS 
+`ifndef	TOP_ROUTING
+        .pad(ser_tx),
+`endif
+        .out(ser_tx_core),
+        .oe_n(vss),
+        .hld_h_n(vdd),
+        .enable_h(porb_h),
+        .enable_inp_h(loopb23),
+        .enable_vdda_h(porb_h),
+        .enable_vddio(vdd1v8),
+        .enable_vswitch_h(vss),
+        .inp_dis(vdd1v8),
+        .vtrip_sel(vss),
+        .hys_trim(vdd1v8),
+        .slow(vss),
+        .slew_ctl({vss, vss}),	// 2 bits
+        .hld_ovr(vss),
+        .analog_en(vss),
+        .analog_sel(vss),
+        .analog_pol(vss),
+        .dm({vdd1v8, vdd1v8, vss}),		// 3 bits
+        .ib_mode_sel({vss, vss}),	// 2 bits
+        .vinref(vdd1v8),
+        .pad_a_noesd_h(),
+        .pad_a_esd_0_h(),
+        .pad_a_esd_1_h(),
+        .in(),
+        .in_h(),
+        .tie_hi_esd(),
+        .tie_lo_esd()
+    );
+
+    // Corner cells (These are overlay cells;  it is not clear what is normally
+    // supposed to go under them.)
+ `ifndef TOP_ROUTING   
+    s8iom0_corner_pad corner [3:0] (
+        .vssio(vss),
+        .vddio(vdd),
+        .vddio_q(vddio_q),
+        .vssio_q(vssio_q),
+        .amuxbus_a(analog_a),
+        .amuxbus_b(analog_b),
+        .vssd(vss),
+        .vssa(vss),
+        .vswitch(vdd),
+        .vdda(vdd),
+        .vccd(vdd1v8),
+        .vcchib(vdd1v8)
+        //`ABUTMENT_PINS 
+    );
+`endif
+
+    // SoC core
+    wire [9:0]  adc0_data_core;
+    wire [1:0]  adc0_inputsrc_core;
+    wire [9:0]  adc1_data_core;
+    wire [1:0]  adc1_inputsrc_core;
+    wire [9:0]  dac_value_core;
+    wire [1:0]  comp_ninputsrc_core;
+    wire [1:0]  comp_pinputsrc_core;
+    wire [7:0]  spi_ro_config_core;
+
+    wire xbar_cyc_o_core;
+    wire xbar_stb_o_core;
+    wire xbar_we_o_core;
+    wire [3:0] xbar_sel_o_core;
+    wire [31:0] xbar_adr_o_core;
+    wire [31:0] xbar_dat_o_core;
+    wire xbar_ack_i_core;
+    wire [31:0] xbar_dat_i_core;
+
+    wire striVe_clk, striVe_rstn;
+    
+    striVe_clkrst clkrst(
+    `ifdef LVS
+        .vdd1v8(vdd1v8),
+        .vss(vss),
+    `endif		
+        .ext_clk_sel(ext_clk_sel_core),
+        .ext_clk(ext_clk_core),
+        .pll_clk(pll_clk_core),
+        .reset(por), 
+        .ext_reset(ext_reset_core),
+        .clk(striVe_clk),
+        .resetn(striVe_rstn)
+    );
+
+    mgmt_soc core (
+    `ifdef LVS
+        .vdd1v8(vdd1v8),
+        .vss(vss),
+    `endif
+        .pll_clk(pll_clk_core),
+        .ext_clk(ext_clk_core),
+        .ext_clk_sel(ext_clk_sel_core),
+        .clk(striVe_clk),
+        .resetn(striVe_rstn),
+        .gpio_out_pad(gpio_out_core),
+        .gpio_in_pad(gpio_in_core),
+        .gpio_mode0_pad(gpio_mode0_core),
+        .gpio_mode1_pad(gpio_mode1_core),
+        .gpio_outenb_pad(gpio_outenb_core),
+        .gpio_inenb_pad(gpio_inenb_core),
+        .adc0_ena(adc0_ena_core),
+        .adc0_convert(adc0_convert_core),
+        .adc0_data(adc0_data_core),
+        .adc0_done(adc0_done_core),
+        .adc0_clk(adc0_clk_core),
+        .adc0_inputsrc(adc0_inputsrc_core),
+        .adc1_ena(adc1_ena_core),
+        .adc1_convert(adc1_convert_core),
+        .adc1_clk(adc1_clk_core),
+        .adc1_inputsrc(adc1_inputsrc_core),
+        .adc1_data(adc1_data_core),
+        .adc1_done(adc1_done_core),
+        .xtal_in(xtal_in_core),
+        .comp_in(comp_in_core),
+        .spi_sck(SCK_core),
+        .spi_ro_config(spi_ro_config_core),
+        .spi_ro_xtal_ena(spi_ro_xtal_ena_core),
+        .spi_ro_reg_ena(spi_ro_reg_ena_core),
+        .spi_ro_pll_dco_ena(spi_ro_pll_dco_ena_core),
+        .spi_ro_pll_div(spi_ro_pll_div_core),
+        .spi_ro_pll_sel(spi_ro_pll_sel_core),
+        .spi_ro_pll_trim(spi_ro_pll_trim_core),
+        .spi_ro_mfgr_id(spi_ro_mfgr_id_core),
+        .spi_ro_prod_id(spi_ro_prod_id_core),
+        .spi_ro_mask_rev(spi_ro_mask_rev_core),
+        .ser_tx(ser_tx_core),
+        .ser_rx(ser_rx_core),
+        .irq_pin(irq_pin_core),
+        .irq_spi(irq_spi_core),
+        .trap(trap_core),
+        .flash_csb(flash_csb_core),
+        .flash_clk(flash_clk_core),
+        .flash_csb_oeb(flash_csb_oeb_core),
+        .flash_clk_oeb(flash_clk_oeb_core),
+        .flash_io0_oeb(flash_io0_oeb_core),
+        .flash_io1_oeb(flash_io1_oeb_core),
+        .flash_io2_oeb(flash_io2_oeb_core),
+        .flash_io3_oeb(flash_io3_oeb_core),
+        .flash_csb_ieb(flash_csb_ieb_core),
+        .flash_clk_ieb(flash_clk_ieb_core),
+        .flash_io0_ieb(flash_io0_ieb_core),
+        .flash_io1_ieb(flash_io1_ieb_core),
+        .flash_io2_ieb(flash_io2_ieb_core),
+        .flash_io3_ieb(flash_io3_ieb_core),
+        .flash_io0_do(flash_io0_do_core),
+        .flash_io1_do(flash_io1_do_core),
+        .flash_io2_do(flash_io2_do_core),
+        .flash_io3_do(flash_io3_do_core),
+        .flash_io0_di(flash_io0_di_core),
+        .flash_io1_di(flash_io1_di_core),
+        .flash_io2_di(flash_io2_di_core),
+        .flash_io3_di(flash_io3_di_core),
+        .xbar_cyc_o(xbar_cyc_o_core),
+        .xbar_stb_o(xbar_stb_o_core),
+        .xbar_we_o (xbar_we_o_core),
+        .xbar_sel_o(xbar_sel_o_core),
+        .xbar_adr_o(xbar_adr_o_core),
+        .xbar_dat_o(xbar_dat_o_core),
+        .xbar_ack_i(xbar_ack_i_core),
+        .xbar_dat_i(xbar_dat_i_core)
+    );
+    
+    // Mega-Project
+    wire mega_cyc_o;
+    wire mega_stb_o;
+    wire mega_we_o;
+    wire [3:0] mega_sel_o;
+    wire [31:0] mega_adr_o;
+    wire [31:0] mega_dat_o;
+    wire mega_ack_i;
+    wire [31:0] mega_dat_i;
+
+    // Masters interface
+    wire [`NM-1:0] wbm_cyc_i;       
+    wire [`NM-1:0] wbm_stb_i;       
+    wire [`NM-1:0] wbm_we_i;     
+    wire [(`NM*(`DW/8))-1:0] wbm_sel_i;     
+    wire [(`NM*`AW)-1:0] wbm_adr_i;        
+    wire [(`NM*`DW)-1:0] wbm_dat_i; 
+
+    wire [`NM-1:0] wbm_ack_o; 
+    wire [(`NM*`DW)-1:0] wbm_dat_o;       
+
+    // Slaves interfaces
+    wire [`NS-1:0] wbs_ack_o;       
+    wire [(`NS*`DW)-1:0] wbs_dat_i;
+    wire [`NS-1:0] wbs_cyc_o;        
+    wire [`NS-1:0] wbs_stb_o;       
+    wire [`NS-1:0] wbs_we_o;        
+    wire [(`NS*(`DW/8))-1:0] wbs_sel_o;       
+    wire [(`NS*`AW)-1:0] wbs_adr_o;       
+    wire [(`NS*`DW)-1:0] wbs_dat_o;  
+
+    assign wbm_cyc_i = {mega_cyc_o, xbar_cyc_o_core};
+    assign wbm_stb_i = {mega_stb_o, xbar_stb_o_core};
+    assign wbm_we_i  = {mega_we_o , xbar_we_o_core};
+    assign wbm_sel_i = {mega_sel_o, xbar_sel_o_core};
+    assign wbm_adr_i = {mega_adr_o, xbar_adr_o_core};
+    assign wbm_dat_i = {mega_dat_o, xbar_dat_o_core};
+
+    assign xbar_ack_i_core = wbm_ack_o[0];
+    assign mega_ack_i = wbm_ack_o[1];
+    assign xbar_dat_i_core = wbm_dat_o[`DW-1:0];
+    assign mega_dat_i = wbm_dat_o[`DW*2-1:`DW];
+    
+     // Instantiate four dummy slaves for testing (TO-BE-REMOVED)
+    dummy_slave dummy_slaves [`NS-1:0](
+        .wb_clk_i({`NS{striVe_clk}}),
+        .wb_rst_i({`NS{~striVe_rstn}}),
+        .wb_stb_i(wbs_stb_o),
+        .wb_cyc_i(wbs_cyc_o),
+        .wb_we_i(wbs_we_o),
+        .wb_sel_i(wbs_sel_o),
+        .wb_adr_i(wbs_adr_o),
+        .wb_dat_i(wbs_dat_i),
+        .wb_dat_o(wbs_dat_o),
+        .wb_ack_o(wbs_ack_o)
+    );
+    // Crossbar Switch
+    wb_xbar #(
+        .NM(`NM),
+        .NS(`NS),
+        .AW(`AW),
+        .DW(`DW),
+        .SLAVE_ADR(`SLAVE_ADR),
+        .ADR_MASK(`ADR_MASK) 
+    )
+    wb_xbar(
+        .wb_clk_i(striVe_clk),           
+        .wb_rst_i(~striVe_rstn), 
+
+        // Masters interface
+        .wbm_cyc_i(wbm_cyc_i),       
+        .wbm_stb_i(wbm_stb_i),       
+        .wbm_we_i (wbm_we_i),     
+        .wbm_sel_i(wbm_sel_i),     
+        .wbm_adr_i(wbm_adr_i),        
+        .wbm_dat_i(wbm_dat_i),       
+        .wbm_ack_o(wbm_ack_o), 
+        .wbm_dat_o(wbm_dat_o),       
+
+        // Slaves interfaces
+        .wbs_ack_i(wbs_ack_o),       
+        .wbs_dat_i(wbs_dat_o),
+        .wbs_cyc_o(wbs_cyc_o),        
+        .wbs_stb_o(wbs_stb_o),       
+        .wbs_we_o (wbs_we_o),        
+        .wbs_sel_o(wbs_sel_o),       
+        .wbs_adr_o(wbs_adr_o),       
+        .wbs_dat_o(wbs_dat_i)     
+    );
+
+    // For the mask revision input, use an array of digital constant logic cells
+    wire [3:0] mask_rev;
+    wire [3:0] no_connect;
+    scs8hd_conb_1 mask_rev_value [3:0] (
+    `ifdef LVS
+        .vpwr(vdd1v8),
+        .vpb(vdd1v8),
+        .vnb(vss),
+        .vgnd(vss),
+    `endif
+        .HI({no_connect[3:1], mask_rev[0]}),
+        .LO({mask_rev[3:1], no_connect[0]})
+    );
+
+    // Housekeeping SPI at 1.8V.
+
+    striVe_spi housekeeping (
+    `ifdef LVS
+        .vdd(vdd1v8),
+        .vss(vss),
+    `endif
+        .RSTB(porb_l),
+        .SCK(SCK_core),
+        .SDI(SDI_core),
+        .CSB(CSB_core),
+        .SDO(SDO_core),
+        .sdo_enb(SDO_enb),
+        
+        .xtal_ena(spi_ro_xtal_ena_core),
+        .reg_ena(spi_ro_reg_ena_core),
+        .pll_dco_ena(spi_ro_pll_dco_ena_core),
+        .pll_sel(spi_ro_pll_sel_core),
+        .pll_div(spi_ro_pll_div_core),
+        .pll_trim(spi_ro_pll_trim_core),
+        .pll_bypass(ext_clk_sel_core),
+        .irq(irq_spi_core),
+        .RST(por),
+        .reset(ext_reset_core),
+        .trap(trap_core),
+        .mfgr_id(spi_ro_mfgr_id_core),
+        .prod_id(spi_ro_prod_id_core),
+        .mask_rev_in(mask_rev),
+        .mask_rev(spi_ro_mask_rev_core)
+    );
+
+    lvlshiftdown porb_level_shift (
+    `ifdef LVS
+        .vpwr(vdd1v8),
+        .vpb(vdd1v8),
+        .vnb(vss),
+        .vgnd(vss),
+    `endif
+        .A(porb_h),
+        .X(porb_l)
+    );
+
+    // On-board experimental digital PLL
+    // Use xi_core, assumed to be a CMOS digital clock signal.  xo_core
+    // is used as an output and set from pll_clk16.
+
+    digital_pll pll (
+    `ifdef LVS
+        .vdd(vdd1v8),
+        .vss(vss),
+    `endif
+        .reset(por),
+        .extclk_sel(ext_clk_sel_core),
+        .osc(xi_core),
+        .clockc(pll_clk_core),
+        .clockp({pll_clk_core0, pll_clk_core90}),
+        .clockd({pll_clk2, pll_clk4, pll_clk8, pll_clk16}),
+        .div(spi_ro_pll_div_core),
+        .sel(spi_ro_pll_sel_core),
+        .dco(spi_ro_pll_dco_ena_core),
+        .ext_trim(spi_ro_pll_trim_core)
+    );
+    
+endmodule
diff --git a/verilog/rtl/la_wb.v b/verilog/rtl/la_wb.v
new file mode 100644
index 0000000..fd713a4
--- /dev/null
+++ b/verilog/rtl/la_wb.v
@@ -0,0 +1,201 @@
+module la_wb # (
+    parameter BASE_ADR  = 32'h 2200_0000,
+    parameter LA_DATA_0 = 8'h00,
+    parameter LA_DATA_1 = 8'h04,
+    parameter LA_DATA_2 = 8'h08,
+    parameter LA_DATA_3 = 8'h0c,
+    parameter LA_ENA_0 = 8'h10,
+    parameter LA_ENA_1 = 8'h14,
+    parameter LA_ENA_2 = 8'h18,
+    parameter LA_ENA_3 = 8'h1c
+) (
+    input wb_clk_i,
+    input wb_rst_i,
+
+    input [31:0] wb_dat_i,
+    input [31:0] wb_adr_i,
+    input [3:0] wb_sel_i,
+    input wb_cyc_i,
+    input wb_stb_i,
+    input wb_we_i,
+
+    output [31:0] wb_dat_o,
+    output wb_ack_o,
+
+    output [127:0] la_data,
+    output [127:0] la_ena
+);
+
+    wire resetn;
+    wire valid;
+    wire ready;
+    wire [3:0] iomem_we;
+
+    assign resetn = ~wb_rst_i;
+    assign valid = wb_stb_i && wb_cyc_i; 
+
+    assign iomem_we = wb_sel_i & {4{wb_we_i}};
+    assign wb_ack_o = ready;
+
+    la #(
+        .BASE_ADR(BASE_ADR),
+        .LA_DATA_0(LA_DATA_0),
+        .LA_DATA_1(LA_DATA_1),
+        .LA_DATA_2(LA_DATA_2),
+        .LA_DATA_3(LA_DATA_3),
+        .LA_ENA_0(LA_ENA_0),
+        .LA_ENA_1(LA_ENA_1),
+        .LA_ENA_2(LA_ENA_2),
+        .LA_ENA_3(LA_ENA_3)
+    ) la_ctrl (
+        .clk(wb_clk_i),
+        .resetn(resetn),
+        .iomem_addr(wb_adr_i),
+        .iomem_valid(valid),
+        .iomem_wstrb(iomem_we),
+        .iomem_wdata(wb_dat_i),
+        .iomem_rdata(wb_dat_o),
+        .iomem_ready(ready),
+        .la_data(la_data),
+        .la_ena(la_ena)
+    );
+    
+endmodule
+
+module la #(
+    parameter BASE_ADR  = 32'h 2200_0000,
+    parameter LA_DATA_0 = 8'h00,
+    parameter LA_DATA_1 = 8'h04,
+    parameter LA_DATA_2 = 8'h08,
+    parameter LA_DATA_3 = 8'h0c,
+    parameter LA_ENA_0  = 8'h10,
+    parameter LA_ENA_1  = 8'h14,
+    parameter LA_ENA_2  = 8'h18,
+    parameter LA_ENA_3  = 8'h1c
+) (
+    input clk,
+    input resetn,
+
+    input [31:0] iomem_addr,
+    input iomem_valid,
+    input [3:0] iomem_wstrb,
+    input [31:0] iomem_wdata,
+
+    output reg [31:0] iomem_rdata,
+    output reg iomem_ready,
+
+    output [127:0] la_data,
+    output [127:0] la_ena
+);
+
+    reg [31:0] la_data_0;		
+    reg [31:0] la_data_1;		
+    reg [31:0] la_data_2;		
+    reg [31:0] la_data_3; 
+
+    reg [31:0] la_ena_0;		
+    reg [31:0] la_ena_1;		
+    reg [31:0] la_ena_2;		
+    reg [31:0] la_ena_3;    
+    
+    wire [3:0] la_data_sel;
+    wire [3:0] la_ena_sel;
+
+    assign la_data = {la_data_3, la_data_2, la_data_1, la_data_0};
+    assign la_ena  = {la_ena_3, la_ena_2, la_ena_1, la_ena_0};
+
+    assign la_data_sel = {
+        (iomem_addr[7:0] == LA_DATA_3),
+        (iomem_addr[7:0] == LA_DATA_2),
+        (iomem_addr[7:0] == LA_DATA_1),
+        (iomem_addr[7:0] == LA_DATA_0)
+    };
+
+    assign la_ena_sel = {
+        (iomem_addr[7:0] == LA_ENA_3),
+        (iomem_addr[7:0] == LA_ENA_2),
+        (iomem_addr[7:0] == LA_ENA_1),
+        (iomem_addr[7:0] == LA_ENA_0)
+    };
+
+
+    always @(posedge clk) begin
+        if (!resetn) begin
+            la_data_0 <= 0;
+            la_data_1 <= 0;
+            la_data_2 <= 0;
+            la_data_3 <= 0;
+            la_ena_0 <= 0;
+            la_ena_1 <= 0;
+            la_ena_2 <= 0;
+            la_ena_3 <= 0;
+        end else begin
+            iomem_ready <= 0;
+            if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin
+                iomem_ready <= 1'b 1;
+                
+                if (la_data_sel[0]) begin
+                    iomem_rdata <= la_data_0;
+
+                    if (iomem_wstrb[0]) la_data_0[ 7: 0] <= iomem_wdata[ 7: 0];
+                    if (iomem_wstrb[1]) la_data_0[15: 8] <= iomem_wdata[15: 8];
+                    if (iomem_wstrb[2]) la_data_0[23:16] <= iomem_wdata[23:16];
+                    if (iomem_wstrb[3]) la_data_0[31:24] <= iomem_wdata[31:24];
+
+                end else if (la_data_sel[1]) begin
+                    iomem_rdata <= la_data_1;
+
+                    if (iomem_wstrb[0]) la_data_1[ 7: 0] <= iomem_wdata[ 7: 0];
+                    if (iomem_wstrb[1]) la_data_1[15: 8] <= iomem_wdata[15: 8];
+                    if (iomem_wstrb[2]) la_data_1[23:16] <= iomem_wdata[23:16];
+                    if (iomem_wstrb[3]) la_data_1[31:24] <= iomem_wdata[31:24];
+
+                end else if (la_data_sel[2]) begin
+                    iomem_rdata <= la_data_2;
+
+                    if (iomem_wstrb[0]) la_data_2[ 7: 0] <= iomem_wdata[ 7: 0];
+                    if (iomem_wstrb[1]) la_data_2[15: 8] <= iomem_wdata[15: 8];
+                    if (iomem_wstrb[2]) la_data_2[23:16] <= iomem_wdata[23:16];
+                    if (iomem_wstrb[3]) la_data_2[31:24] <= iomem_wdata[31:24];
+
+                end else if (la_data_sel[3]) begin
+                    iomem_rdata <= la_data_3;
+
+                    if (iomem_wstrb[0]) la_data_3[ 7: 0] <= iomem_wdata[ 7: 0];
+                    if (iomem_wstrb[1]) la_data_3[15: 8] <= iomem_wdata[15: 8];
+                    if (iomem_wstrb[2]) la_data_3[23:16] <= iomem_wdata[23:16];
+                    if (iomem_wstrb[3]) la_data_3[31:24] <= iomem_wdata[31:24];
+                end else if (la_ena_sel[0]) begin
+                    iomem_rdata <= la_ena_0;
+
+                    if (iomem_wstrb[0]) la_ena_0[ 7: 0] <= iomem_wdata[ 7: 0];
+                    if (iomem_wstrb[1]) la_ena_0[15: 8] <= iomem_wdata[15: 8];
+                    if (iomem_wstrb[2]) la_ena_0[23:16] <= iomem_wdata[23:16];
+                    if (iomem_wstrb[3]) la_ena_0[31:24] <= iomem_wdata[31:24];
+                end else if (la_ena_sel[1]) begin
+                    iomem_rdata <= la_ena_1;
+
+                    if (iomem_wstrb[0]) la_ena_1[ 7: 0] <= iomem_wdata[ 7: 0];
+                    if (iomem_wstrb[1]) la_ena_1[15: 8] <= iomem_wdata[15: 8];
+                    if (iomem_wstrb[2]) la_ena_1[23:16] <= iomem_wdata[23:16];
+                    if (iomem_wstrb[3]) la_ena_1[31:24] <= iomem_wdata[31:24];
+                end else if (la_ena_sel[2]) begin
+                    iomem_rdata <= la_ena_2;
+
+                    if (iomem_wstrb[0]) la_ena_2[ 7: 0] <= iomem_wdata[ 7: 0];
+                    if (iomem_wstrb[1]) la_ena_2[15: 8] <= iomem_wdata[15: 8];
+                    if (iomem_wstrb[2]) la_ena_2[23:16] <= iomem_wdata[23:16];
+                    if (iomem_wstrb[3]) la_ena_2[31:24] <= iomem_wdata[31:24];
+                end else if (la_ena_sel[3]) begin
+                    iomem_rdata <= la_ena_3;
+
+                    if (iomem_wstrb[0]) la_ena_3[ 7: 0] <= iomem_wdata[ 7: 0];
+                    if (iomem_wstrb[1]) la_ena_3[15: 8] <= iomem_wdata[15: 8];
+                    if (iomem_wstrb[2]) la_ena_3[23:16] <= iomem_wdata[23:16];
+                    if (iomem_wstrb[3]) la_ena_3[31:24] <= iomem_wdata[31:24];
+                end 
+            end
+        end
+    end
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/lvlshiftdown.v b/verilog/rtl/lvlshiftdown.v
new file mode 100644
index 0000000..a647cf6
--- /dev/null
+++ b/verilog/rtl/lvlshiftdown.v
@@ -0,0 +1,30 @@
+/* Level shifter (simplified model, as buffer only) */
+
+module lvlshiftdown (
+`ifdef LVS
+        vpwr, vpb, vnb, vgnd,
+`endif
+        A,
+        X
+    );
+
+
+`ifdef LVS
+    input vpwr;
+    input vpb;
+    input vnb;
+    input vgnd;
+`endif
+
+input A;
+output X;
+
+`ifdef LVS
+    wire vpwr, vpb, vnb, vgnd;
+`endif
+
+wire A, X;
+
+assign X = A;
+
+endmodule   // lvlshiftdown
diff --git a/verilog/rtl/mem_wb.v b/verilog/rtl/mem_wb.v
new file mode 100644
index 0000000..e0b6599
--- /dev/null
+++ b/verilog/rtl/mem_wb.v
@@ -0,0 +1,106 @@
+module mem_wb # (
+    parameter integer MEM_WORDS = 256
+) (
+    input wb_clk_i,
+    input wb_rst_i,
+
+    input [31:0] wb_adr_i,
+    input [31:0] wb_dat_i,
+    input [3:0] wb_sel_i,
+    input wb_we_i,
+    input wb_cyc_i,
+    input wb_stb_i,
+
+    output wb_ack_o,
+    output [31:0] wb_dat_o
+    
+);
+    wire valid;
+    wire ram_wen;
+    wire [3:0] wen; // write enable
+
+    assign valid = wb_cyc_i & wb_stb_i;
+    assign ram_wen = wb_we_i && valid;
+
+    assign wen = wb_sel_i & {4{ram_wen}} ;
+
+`ifndef USE_OPENRAM
+    assign wb_ack_o = valid;
+`else
+
+    /*
+        Ack Generation
+            - write transaction: asserted upon receiving adr_i & dat_i 
+            - read transaction : asserted one clock cycle after receiving the adr_i & dat_i
+    */ 
+
+    reg [2:0] wb_ack_read;
+   
+    assign wb_ack_o = wb_we_i ? valid : &wb_ack_read;
+
+    always @(posedge wb_clk_i) begin
+        if (wb_rst_i == 1'b 1) begin
+            wb_ack_read <= 3'b 00;
+        end else begin
+            wb_ack_read <= {3{valid}} & {1'b1, wb_ack_read[2:1]};
+        end
+    end
+
+`endif
+
+    soc_mem mem(
+        .clk(wb_clk_i),
+        .ena(valid),
+        .wen(wen),
+        .addr(wb_adr_i[23:2]),
+        .wdata(wb_dat_i),
+        .rdata(wb_dat_o)
+    );
+
+endmodule
+
+module soc_mem 
+`ifndef USE_OPENRAM
+#(
+    parameter integer WORDS = 256
+)
+`endif
+ ( 
+    input clk,
+    input ena,
+    input [3:0] wen,
+    input [21:0] addr,
+    input [31:0] wdata,
+    output[31:0] rdata
+);
+
+`ifndef USE_OPENRAM
+    reg [31:0] rdata;
+    reg [31:0] mem [0:WORDS-1];
+
+    always @(posedge clk) begin
+        if (ena == 1'b1) begin
+            rdata <= mem[addr];
+            if (wen[0]) mem[addr][ 7: 0] <= wdata[ 7: 0];
+            if (wen[1]) mem[addr][15: 8] <= wdata[15: 8];
+            if (wen[2]) mem[addr][23:16] <= wdata[23:16];
+            if (wen[3]) mem[addr][31:24] <= wdata[31:24];
+        end
+    end
+`else
+    
+    /* Using Port 0 Only - Size: 1KB, 256x32 bits */
+    //sram_1rw1r_32_256_8_scn4m_subm 
+    sram_1rw1r_32_256_8_sky130 SRAM(
+            .clk0(clk), 
+            .csb0(~ena), 
+            .web0(~|wen),
+            .wmask0(wen),
+            .addr0(addr[7:0]),
+            .din0(wdata),
+            .dout0(rdata)
+      );
+
+`endif
+
+endmodule
diff --git a/verilog/rtl/mgmt_soc.v b/verilog/rtl/mgmt_soc.v
new file mode 100644
index 0000000..007ca0f
--- /dev/null
+++ b/verilog/rtl/mgmt_soc.v
@@ -0,0 +1,876 @@
+/*
+ *  PicoSoC - A simple example SoC using PicoRV32
+ *
+ *  Copyright (C) 2017  Clifford Wolf <clifford@clifford.at>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ *  Revision 1,  July 2019:  Added signals to drive flash_clk and flash_csb
+ *  output enable (inverted), tied to reset so that the flash is completely
+ *  isolated from the processor when the processor is in reset.
+ *
+ *  Also: Made ram_wenb a 4-bit bus so that the memory access can be made
+ *  byte-wide for byte-wide instructions.
+ */
+
+`ifdef PICORV32_V
+`error "openstriVe_soc.v must be read before picorv32.v!"
+`endif
+
+`define PICORV32_REGS openstriVe_soc_regs
+
+`include "picorv32.v"
+`include "spimemio.v"
+`include "simpleuart.v"
+`include "wb_intercon.v"
+`include "mem_wb.v"
+`include "gpio_wb.v"
+`include "spi_sysctrl.v"
+`include "sysctrl.v"
+`include "la_wb.v"
+
+module mgmt_soc (
+`ifdef LVS
+    inout vdd1v8,	    /* 1.8V domain */
+    inout vss,
+`endif
+    input pll_clk,
+    input ext_clk,
+    input ext_clk_sel,
+
+    input clk,
+    input resetn,
+
+    // Memory mapped I/O signals
+    output [15:0] gpio_out_pad,			// Connect to out on gpio pad
+    input  [15:0] gpio_in_pad,			// Connect to in on gpio pad
+    output [15:0] gpio_mode0_pad,		// Connect to dm[0] on gpio pad
+    output [15:0] gpio_mode1_pad,		// Connect to dm[2] on gpio pad
+    output [15:0] gpio_outenb_pad,		// Connect to oe_n on gpio pad
+    output [15:0] gpio_inenb_pad,		// Connect to inp_dis on gpio pad
+
+    // LA signals
+    input  [127:0] la_input,           	// From Mega-Project to cpu
+    output [127:0] la_output,          	// From CPU to Mega-Project
+    output [127:0] la_oe,              	// LA output enable (sensitiviy according to tri-state ?) 
+
+    output 	      adc0_ena,
+    output 	      adc0_convert,
+    input  [9:0]  adc0_data,
+    input  	      adc0_done,
+    output	      adc0_clk,
+    output [1:0]  adc0_inputsrc,
+    output 	      adc1_ena,
+    output 	      adc1_convert,
+    output	      adc1_clk,
+    output [1:0]  adc1_inputsrc,
+    input  [9:0]  adc1_data,
+    input  	      adc1_done,
+
+    output	      dac_ena,
+    output [9:0]  dac_value,
+
+    output	      analog_out_sel,	// Analog output select (DAC or bandgap)
+    output	      opamp_ena,		// Op-amp enable for analog output
+    output	      opamp_bias_ena,	// Op-amp bias enable for analog output
+    output	      bg_ena,			// Bandgap enable
+
+    output	      comp_ena,
+    output [1:0]  comp_ninputsrc,
+    output [1:0]  comp_pinputsrc,
+    output	      rcosc_ena,
+
+    output	      overtemp_ena,
+    input	      overtemp,
+    input	      rcosc_in,		// RC oscillator output
+    input	      xtal_in,		// crystal oscillator output
+    input	      comp_in,		// comparator output
+    input	      spi_sck,
+
+    input [7:0]   spi_ro_config,
+    input 	      spi_ro_xtal_ena,
+    input 	      spi_ro_reg_ena,
+    input 	      spi_ro_pll_dco_ena,
+    input [4:0]   spi_ro_pll_div,
+    input [2:0]   spi_ro_pll_sel,
+    input [25:0]  spi_ro_pll_trim,
+
+    input [11:0]  spi_ro_mfgr_id,
+    input [7:0]   spi_ro_prod_id,
+    input [3:0]   spi_ro_mask_rev,
+
+    output ser_tx,
+    input  ser_rx,
+
+    // IRQ
+    input  irq_pin,		// dedicated IRQ pin
+    input  irq_spi,		// IRQ from standalone SPI
+
+    // trap
+    output trap,
+
+    // Flash memory control (SPI master)
+    output flash_csb,
+    output flash_clk,
+
+    output flash_csb_oeb,
+    output flash_clk_oeb,
+
+    output flash_io0_oeb,
+    output flash_io1_oeb,
+    output flash_io2_oeb,
+    output flash_io3_oeb,
+
+    output flash_csb_ieb,
+    output flash_clk_ieb,
+
+    output flash_io0_ieb,
+    output flash_io1_ieb,
+    output flash_io2_ieb,
+    output flash_io3_ieb,
+
+    output flash_io0_do,
+    output flash_io1_do,
+    output flash_io2_do,
+    output flash_io3_do,
+
+    input  flash_io0_di,
+    input  flash_io1_di,
+    input  flash_io2_di,
+    input  flash_io3_di,
+
+    // Crossbar Switch Slaves
+    input [31:0] xbar_dat_i,
+    input xbar_ack_i,
+    output xbar_cyc_o,	
+    output xbar_stb_o,
+    output xbar_we_o,
+    output [3:0] xbar_sel_o,
+    output [31:0] xbar_adr_o,
+    output [31:0] xbar_dat_o
+);
+    /* Memory reverted back to 256 words while memory has to be synthesized */
+    parameter integer MEM_WORDS = 256;
+    parameter [31:0] STACKADDR = (4*MEM_WORDS);       // end of memory
+    parameter [31:0] PROGADDR_RESET = 32'h 1000_0000; 
+    parameter [31:0] PROGADDR_IRQ   = 32'h 0000_0000;
+
+    // Slaves Base Addresses
+    parameter RAM_BASE_ADR   = 32'h 0000_0000;
+    parameter FLASH_BASE_ADR = 32'h 1000_0000;
+    parameter UART_BASE_ADR  = 32'h 2000_0000;
+    parameter GPIO_BASE_ADR  = 32'h 2100_0000;
+    parameter LA_BASE_ADR   = 32'h 2200_0000;
+    parameter SYS_BASE_ADR   = 32'h 2F00_0000;
+    parameter SPI_BASE_ADR   = 32'h 2E00_0000;
+    parameter FLASH_CTRL_CFG = 32'h 2D00_0000;
+    parameter XBAR_BASE_ADR  = 32'h 8000_0000;
+
+    // UART
+    parameter UART_CLK_DIV = 8'h00;
+    parameter UART_DATA    = 8'h04;
+    
+    // SOC GPIO
+    parameter GPIO_DATA = 8'h00;
+    parameter GPIO_ENA  = 8'h04;
+    parameter GPIO_PU   = 8'h08;
+    parameter GPIO_PD   = 8'h0c;
+    
+    // LDO
+    parameter LA_DATA_0 = 8'h00;
+    parameter LA_DATA_1 = 8'h04;
+    parameter LA_DATA_2 = 8'h08;
+    parameter LA_DATA_3 = 8'h0c;
+    parameter LA_ENA_0  = 8'h10;
+    parameter LA_ENA_1  = 8'h14;
+    parameter LA_ENA_2  = 8'h18;
+    parameter LA_ENA_3  = 8'h1c;
+    
+    // SPI-Controlled Registers 
+    parameter SPI_CFG        = 8'h00;
+    parameter SPI_ENA        = 8'h04;
+    parameter SPI_PLL_CFG    = 8'h08;
+    parameter SPI_MFGR_ID    = 8'h0c;
+    parameter SPI_PROD_ID    = 8'h10;
+    parameter SPI_MASK_REV   = 8'h14;
+    parameter SPI_PLL_BYPASS = 8'h18;
+    
+    // System Control Registers
+    parameter OSC_ENA       = 8'h00;
+    parameter OSC_OUT       = 8'h04;
+    parameter XTAL_OUT      = 8'h08;
+    parameter PLL_OUT       = 8'h0c;
+    parameter TRAP_OUT      = 8'h10;
+    parameter IRQ7_SRC      = 8'h14;
+    parameter IRQ8_SRC      = 8'h18;
+    parameter OVERTEMP_ENA  = 8'h1c;
+    parameter OVERTEMP_DATA = 8'h20;
+    parameter OVERTEMP_OUT  = 8'h24;
+
+    // Wishbone Interconnect 
+    localparam ADR_WIDTH = 32;
+    localparam DAT_WIDTH = 32;
+    localparam NUM_SLAVES = 9;
+
+    parameter [NUM_SLAVES*ADR_WIDTH-1: 0] ADR_MASK = {
+        {8'h80, {ADR_WIDTH-8{1'b0}}},
+        {8'hFF, {ADR_WIDTH-8{1'b0}}},
+        {8'hFF, {ADR_WIDTH-8{1'b0}}},
+        {8'hFF, {ADR_WIDTH-8{1'b0}}},
+        {8'hFF, {ADR_WIDTH-8{1'b0}}},
+        {8'hFF, {ADR_WIDTH-8{1'b0}}},
+        {8'hFF, {ADR_WIDTH-8{1'b0}}},
+        {8'hFF, {ADR_WIDTH-8{1'b0}}},
+        {8'hFF, {ADR_WIDTH-8{1'b0}}}
+    };
+    parameter [NUM_SLAVES*ADR_WIDTH-1: 0] SLAVE_ADR = {
+        {XBAR_BASE_ADR},
+        {SYS_BASE_ADR},
+        {SPI_BASE_ADR},
+        {FLASH_CTRL_CFG},
+        {LA_BASE_ADR},
+        {GPIO_BASE_ADR},
+        {UART_BASE_ADR},
+        {FLASH_BASE_ADR},
+        {RAM_BASE_ADR}
+    };
+
+    // memory-mapped I/O control registers
+    wire [15:0] gpio_pullup;    	// Intermediate GPIO pullup
+    wire [15:0] gpio_pulldown;  	// Intermediate GPIO pulldown
+    wire [15:0] gpio_outenb;    	// Intermediate GPIO out enable (bar)
+    wire [15:0] gpio_out;      	 	// Intermediate GPIO output
+
+    wire [15:0] gpio;				// GPIO output data
+    wire [15:0] gpio_pu;			// GPIO pull-up enable
+    wire [15:0] gpio_pd;			// GPIO pull-down enable
+    wire [15:0] gpio_oeb;			// GPIO output enable (sense negative)
+
+    wire [1:0] rcosc_output_dest;	// RC oscillator output destination
+    wire [1:0] overtemp_dest;		// Over-temperature alarm destination
+    wire [1:0] pll_output_dest;		// PLL clock output destination
+    wire [1:0] xtal_output_dest; 	// Crystal oscillator output destination
+    wire [1:0] trap_output_dest; 	// Trap signal output destination
+    wire [1:0] irq_7_inputsrc;		// IRQ 5 source
+    wire [1:0] irq_8_inputsrc;		// IRQ 6 source
+
+    // Analgo registers (not-used)
+    reg	adc0_ena;					// ADC0 enable
+    reg	adc0_convert;				// ADC0 convert
+    reg [1:0] adc0_clksrc;			// ADC0 clock source
+    reg [1:0] adc0_inputsrc;		// ADC0 input source
+    reg adc1_ena;					// ADC1 enable
+    reg adc1_convert;				// ADC1 convert
+    reg [1:0] adc1_clksrc;			// ADC1 clock source
+    reg [1:0] adc1_inputsrc;		// ADC1 input source
+    reg	dac_ena;					// DAC enable
+    reg [9:0] dac_value;			// DAC output value
+    reg	comp_ena;					// Comparator enable
+    reg [1:0] comp_ninputsrc;		// Comparator negative input source
+    reg [1:0] comp_pinputsrc;		// Comparator positive input source
+    reg [1:0] comp_output_dest; 	// Comparator output destination
+    
+    reg analog_out_sel;				// Analog output select
+     reg	opamp_ena;					// Analog output op-amp enable
+     reg	opamp_bias_ena;				// Analog output op-amp bias enable
+     reg	bg_ena;						// Bandgap enable
+    wire adc0_clk;					// ADC0 clock (multiplexed)
+    wire adc1_clk;					// ADC1 clock (multiplexed)
+
+    // ADC clock assignments
+    assign adc0_clk = (adc0_clksrc == 2'b00) ? rcosc_in :
+              (adc0_clksrc == 2'b01) ? spi_sck :
+              (adc0_clksrc == 2'b10) ? xtal_in :
+              ext_clk;
+
+    assign adc1_clk = (adc1_clksrc == 2'b00) ? rcosc_in :
+              (adc1_clksrc == 2'b01) ? spi_sck :
+              (adc1_clksrc == 2'b10) ? xtal_in :
+              ext_clk;
+
+    // GPIO assignments
+    assign gpio_out[0] = (comp_output_dest == 2'b01) ? comp_in : gpio[0];
+    assign gpio_out[1] = (comp_output_dest == 2'b10) ? comp_in : gpio[1];
+    assign gpio_out[2] = (rcosc_output_dest == 2'b01) ? rcosc_in : gpio[2];
+    assign gpio_out[3] = (rcosc_output_dest == 2'b10) ? rcosc_in : gpio[3];
+    assign gpio_out[4] = (rcosc_output_dest == 2'b11) ? rcosc_in : gpio[4];
+    assign gpio_out[5] = (xtal_output_dest == 2'b01) ? xtal_in : gpio[5]; 
+    assign gpio_out[6] = (xtal_output_dest == 2'b10) ? xtal_in : gpio[6]; 
+    assign gpio_out[7] = (xtal_output_dest == 2'b11) ? xtal_in : gpio[7]; 
+    assign gpio_out[8] = (pll_output_dest == 2'b01) ? pll_clk : gpio[8];
+    assign gpio_out[9] = (pll_output_dest == 2'b10) ? pll_clk : gpio[9];
+    assign gpio_out[10] = (pll_output_dest == 2'b11) ? clk : gpio[10];
+    assign gpio_out[11] = (trap_output_dest == 2'b01) ? trap : gpio[11];
+    assign gpio_out[12] = (trap_output_dest == 2'b10) ? trap : gpio[12];
+    assign gpio_out[13] = (trap_output_dest == 2'b11) ? trap : gpio[13];
+    assign gpio_out[14] = (overtemp_dest == 2'b01) ? overtemp : gpio[14];
+    assign gpio_out[15] = (overtemp_dest == 2'b10) ? overtemp : gpio[15];
+
+    assign gpio_outenb[0] = (comp_output_dest == 2'b00)  ? gpio_oeb[0] : 1'b0;
+    assign gpio_outenb[1] = (comp_output_dest == 2'b00)  ? gpio_oeb[1] : 1'b0;
+    assign gpio_outenb[2] = (rcosc_output_dest == 2'b00) ? gpio_oeb[2] : 1'b0; 
+    assign gpio_outenb[3] = (rcosc_output_dest == 2'b00) ? gpio_oeb[3] : 1'b0;
+    assign gpio_outenb[4] = (rcosc_output_dest == 2'b00) ? gpio_oeb[4] : 1'b0;
+    assign gpio_outenb[5] = (xtal_output_dest == 2'b00)  ? gpio_oeb[5] : 1'b0;
+    assign gpio_outenb[6] = (xtal_output_dest == 2'b00)  ? gpio_oeb[6] : 1'b0;
+    assign gpio_outenb[7] = (xtal_output_dest == 2'b00)  ? gpio_oeb[7] : 1'b0;
+    assign gpio_outenb[8] = (pll_output_dest == 2'b00)   ? gpio_oeb[8] : 1'b0;
+    assign gpio_outenb[9] = (pll_output_dest == 2'b00)   ? gpio_oeb[9] : 1'b0;
+    assign gpio_outenb[10] = (pll_output_dest == 2'b00)  ? gpio_oeb[10] : 1'b0;
+    assign gpio_outenb[11] = (trap_output_dest == 2'b00) ? gpio_oeb[11] : 1'b0;
+    assign gpio_outenb[12] = (trap_output_dest == 2'b00) ? gpio_oeb[12] : 1'b0;
+    assign gpio_outenb[13] = (trap_output_dest == 2'b00) ? gpio_oeb[13] : 1'b0;
+    assign gpio_outenb[14] = (overtemp_dest == 2'b00)    ? gpio_oeb[14] : 1'b0;
+    assign gpio_outenb[15] = (overtemp_dest == 2'b00)    ? gpio_oeb[15] : 1'b0;
+
+    assign gpio_pullup[0] = (comp_output_dest == 2'b00)  ? gpio_pu[0] : 1'b0;
+    assign gpio_pullup[1] = (comp_output_dest == 2'b00)  ? gpio_pu[1] : 1'b0;
+    assign gpio_pullup[2] = (rcosc_output_dest == 2'b00) ? gpio_pu[2] : 1'b0; 
+    assign gpio_pullup[3] = (rcosc_output_dest == 2'b00) ? gpio_pu[3] : 1'b0;
+    assign gpio_pullup[4] = (rcosc_output_dest == 2'b00) ? gpio_pu[4] : 1'b0;
+    assign gpio_pullup[5] = (xtal_output_dest == 2'b00)  ? gpio_pu[5] : 1'b0;
+    assign gpio_pullup[6] = (xtal_output_dest == 2'b00)  ? gpio_pu[6] : 1'b0;
+    assign gpio_pullup[7] = (xtal_output_dest == 2'b00)  ? gpio_pu[7] : 1'b0;
+    assign gpio_pullup[8] = (pll_output_dest == 2'b00)   ? gpio_pu[8] : 1'b0;
+    assign gpio_pullup[9] = (pll_output_dest == 2'b00)   ? gpio_pu[9] : 1'b0;
+    assign gpio_pullup[10] = (pll_output_dest == 2'b00)  ? gpio_pu[10] : 1'b0;
+    assign gpio_pullup[11] = (trap_output_dest == 2'b00) ? gpio_pu[11] : 1'b0;
+    assign gpio_pullup[12] = (trap_output_dest == 2'b00) ? gpio_pu[12] : 1'b0;
+    assign gpio_pullup[13] = (trap_output_dest == 2'b00) ? gpio_pu[13] : 1'b0;
+    assign gpio_pullup[14] = (overtemp_dest == 2'b00)    ? gpio_pu[14] : 1'b0;
+    assign gpio_pullup[15] = (overtemp_dest == 2'b00)    ? gpio_pu[15] : 1'b0;
+
+    assign gpio_pulldown[0] = (comp_output_dest == 2'b00)  ? gpio_pd[0] : 1'b0;
+    assign gpio_pulldown[1] = (comp_output_dest == 2'b00)  ? gpio_pd[1] : 1'b0;
+    assign gpio_pulldown[2] = (rcosc_output_dest == 2'b00) ? gpio_pd[2] : 1'b0; 
+    assign gpio_pulldown[3] = (rcosc_output_dest == 2'b00) ? gpio_pd[3] : 1'b0;
+    assign gpio_pulldown[4] = (rcosc_output_dest == 2'b00) ? gpio_pd[4] : 1'b0;
+    assign gpio_pulldown[5] = (xtal_output_dest == 2'b00)  ? gpio_pd[5] : 1'b0;
+    assign gpio_pulldown[6] = (xtal_output_dest == 2'b00)  ? gpio_pd[6] : 1'b0;
+    assign gpio_pulldown[7] = (xtal_output_dest == 2'b00)  ? gpio_pd[7] : 1'b0;
+    assign gpio_pulldown[8] = (pll_output_dest == 2'b00)   ? gpio_pd[8] : 1'b0;
+    assign gpio_pulldown[9] = (pll_output_dest == 2'b00)   ? gpio_pd[9] : 1'b0;
+    assign gpio_pulldown[10] = (pll_output_dest == 2'b00)  ? gpio_pd[10] : 1'b0;
+    assign gpio_pulldown[11] = (trap_output_dest == 2'b00) ? gpio_pd[11] : 1'b0;
+    assign gpio_pulldown[12] = (trap_output_dest == 2'b00) ? gpio_pd[12] : 1'b0;
+    assign gpio_pulldown[13] = (trap_output_dest == 2'b00) ? gpio_pd[13] : 1'b0;
+    assign gpio_pulldown[14] = (overtemp_dest == 2'b00)    ? gpio_pd[14] : 1'b0;
+    assign gpio_pulldown[15] = (overtemp_dest == 2'b00)    ? gpio_pd[15] : 1'b0;
+
+    // Convert GPIO signals to s8 pad signals
+    convert_gpio_sigs convert_gpio_bit [15:0] (
+        .gpio_out(gpio_out),
+        .gpio_outenb(gpio_outenb),
+        .gpio_pu(gpio_pullup),
+        .gpio_pd(gpio_pulldown),
+        .gpio_out_pad(gpio_out_pad),
+        .gpio_outenb_pad(gpio_outenb_pad),
+        .gpio_inenb_pad(gpio_inenb_pad),
+        .gpio_mode1_pad(gpio_mode1_pad),
+        .gpio_mode0_pad(gpio_mode0_pad)
+    );
+
+    reg [31:0] irq;
+    wire irq_7;
+    wire irq_8;
+    wire irq_stall;
+    wire irq_uart;
+
+    assign irq_7 = (irq_7_inputsrc == 2'b01) ? gpio_in_pad[0] :
+            (irq_7_inputsrc == 2'b10) ? gpio_in_pad[1] :
+            (irq_7_inputsrc == 2'b11) ? gpio_in_pad[2] : 1'b0;
+    assign irq_8 = (irq_8_inputsrc == 2'b01) ? gpio_in_pad[3] :
+            (irq_8_inputsrc == 2'b10) ? gpio_in_pad[4] :
+            (irq_8_inputsrc == 2'b11) ? gpio_in_pad[5] : 1'b0;
+
+    assign irq_uart = 0;
+    assign irq_stall = 0;
+
+    always @* begin
+        irq = 0;
+        irq[3] = irq_stall;
+        irq[4] = irq_uart;
+        irq[5] = irq_pin;
+        irq[6] = irq_spi;
+        irq[7] = irq_7;
+        irq[8] = irq_8;
+        irq[9] = comp_output_dest[0] & comp_output_dest[1] & comp_in;
+        irq[10] = overtemp_dest[0] & overtemp_dest[1] & overtemp;
+    end
+
+    // wire mem_valid;
+    // wire mem_instr;
+    // wire mem_ready;
+    // wire [31:0] mem_addr;
+    // wire [31:0] mem_wdata;
+    // wire [3:0] mem_wstrb;
+    // wire [31:0] mem_rdata;
+
+    // wire spimem_ready;
+    // wire [31:0] spimem_rdata;
+
+    // reg ram_ready;
+    // wire [31:0] ram_rdata;
+
+    // assign iomem_valid = mem_valid && (mem_addr[31:24] > 8'h 01);
+    // assign iomem_wstrb = mem_wstrb;
+    // assign iomem_addr = mem_addr;
+    // assign iomem_wdata = mem_wdata;
+
+    // wire spimemio_cfgreg_sel = mem_valid && (mem_addr == 32'h 0200_0000);
+    // wire [31:0] spimemio_cfgreg_do;
+
+    // wire        simpleuart_reg_div_sel = mem_valid && (mem_addr == 32'h 0200_0004);
+    // wire [31:0] simpleuart_reg_div_do;
+
+    // wire        simpleuart_reg_dat_sel = mem_valid && (mem_addr == 32'h 0200_0008);
+    // wire [31:0] simpleuart_reg_dat_do;
+    // wire        simpleuart_reg_dat_wait;
+
+    // Akin to the slave ack ? 
+    // assign mem_ready = (iomem_valid && iomem_ready) || spimem_ready || ram_ready || spimemio_cfgreg_sel ||
+    // 		simpleuart_reg_div_sel || (simpleuart_reg_dat_sel && !simpleuart_reg_dat_wait);
+
+    // Akin to wb_intercon -- mem_rdata like cpu_dat_i
+    // assign mem_rdata = (iomem_valid && iomem_ready) ? iomem_rdata : spimem_ready ? spimem_rdata : ram_ready ? ram_rdata :
+    // 		spimemio_cfgreg_sel ? spimemio_cfgreg_do : simpleuart_reg_div_sel ? simpleuart_reg_div_do :
+    // 		simpleuart_reg_dat_sel ? simpleuart_reg_dat_do : 32'h 0000_0000;
+
+    wire wb_clk_i;
+    wire wb_rst_i;
+
+    // Assumption : no syscon module and wb_clk is the clock coming from the chip pin ? 
+    assign wb_clk_i = clk;
+    assign wb_rst_i = ~resetn;      // Redundant
+
+    // Wishbone Master
+    wire [31:0] cpu_adr_o;
+    wire [31:0] cpu_dat_i;
+    wire [3:0] cpu_sel_o;
+    wire cpu_we_o;
+    wire cpu_cyc_o;
+    wire cpu_stb_o;
+    wire [31:0] cpu_dat_o;
+    wire cpu_ack_i;
+
+    assign xbar_cyc_o = cpu_cyc_o;
+    assign xbar_we_o  = cpu_we_o;
+    assign xbar_sel_o = cpu_sel_o;
+    assign xbar_adr_o = cpu_adr_o;
+    assign xbar_dat_o = cpu_dat_o;
+    
+    picorv32_wb #(
+        .STACKADDR(STACKADDR),
+        .PROGADDR_RESET(PROGADDR_RESET),
+        .PROGADDR_IRQ(PROGADDR_IRQ),
+        .BARREL_SHIFTER(1),
+        .COMPRESSED_ISA(1),
+        .ENABLE_MUL(1),
+        .ENABLE_DIV(1),
+        .ENABLE_IRQ(1),
+        .ENABLE_IRQ_QREGS(0)
+    ) cpu (
+        .wb_clk_i (wb_clk_i),
+        .wb_rst_i (wb_rst_i),
+        .trap     (trap),
+        .irq      (irq),
+        .mem_instr(mem_instr),
+        .wbm_adr_o(cpu_adr_o),     
+        .wbm_dat_i(cpu_dat_i),    
+        .wbm_stb_o(cpu_stb_o),    
+        .wbm_ack_i(cpu_ack_i),    
+        .wbm_cyc_o(cpu_cyc_o),    
+        .wbm_dat_o(cpu_dat_o),    
+        .wbm_we_o(cpu_we_o),      
+        .wbm_sel_o(cpu_sel_o)     
+    );
+
+    // Wishbone Slave SPIMEMIO
+    wire spimemio_flash_stb_i;
+    wire spimemio_flash_ack_o;
+    wire [31:0] spimemio_flash_dat_o;
+
+    wire spimemio_cfg_stb_i;
+    wire spimemio_cfg_ack_o;
+    wire [31:0] spimemio_cfg_dat_o;
+
+    spimemio_wb spimemio (
+        .wb_clk_i(wb_clk_i),
+        .wb_rst_i(wb_rst_i),
+
+        .wb_adr_i(cpu_adr_o), 
+        .wb_dat_i(cpu_dat_o),
+        .wb_sel_i(cpu_sel_o),
+        .wb_we_i(cpu_we_o),
+        .wb_cyc_i(cpu_cyc_o),
+
+        // FLash Slave
+        .wb_flash_stb_i(spimemio_flash_stb_i),
+        .wb_flash_ack_o(spimemio_flash_ack_o),
+        .wb_flash_dat_o(spimemio_flash_dat_o),
+        
+        // Config Register Slave 
+        .wb_cfg_stb_i(spimemio_cfg_stb_i),
+        .wb_cfg_ack_o(spimemio_cfg_ack_o),
+        .wb_cfg_dat_o(spimemio_cfg_dat_o),
+
+        .flash_csb (flash_csb),
+        .flash_clk (flash_clk),
+
+        .flash_csb_oeb (flash_csb_oeb),
+        .flash_clk_oeb (flash_clk_oeb),
+
+        .flash_io0_oeb (flash_io0_oeb),
+        .flash_io1_oeb (flash_io1_oeb),
+        .flash_io2_oeb (flash_io2_oeb),
+        .flash_io3_oeb (flash_io3_oeb),
+
+        .flash_csb_ieb (flash_csb_ieb),
+        .flash_clk_ieb (flash_clk_ieb),
+
+        .flash_io0_ieb (flash_io0_ieb),
+        .flash_io1_ieb (flash_io1_ieb),
+        .flash_io2_ieb (flash_io2_ieb),
+        .flash_io3_ieb (flash_io3_ieb),
+
+        .flash_io0_do (flash_io0_do),
+        .flash_io1_do (flash_io1_do),
+        .flash_io2_do (flash_io2_do),
+        .flash_io3_do (flash_io3_do),
+
+        .flash_io0_di (flash_io0_di),
+        .flash_io1_di (flash_io1_di),
+        .flash_io2_di (flash_io2_di),
+        .flash_io3_di (flash_io3_di)
+    );
+
+    // Wishbone Slave uart	
+    wire uart_stb_i;
+    wire uart_ack_o;
+    wire [31:0] uart_dat_o;
+
+    simpleuart_wb #(
+        .BASE_ADR(UART_BASE_ADR),
+        .CLK_DIV(UART_CLK_DIV),
+        .DATA(UART_DATA)
+    ) simpleuart (
+        // Wishbone Interface
+        .wb_clk_i(wb_clk_i),
+        .wb_rst_i(wb_rst_i),
+
+        .wb_adr_i(cpu_adr_o),      
+        .wb_dat_i(cpu_dat_o),
+        .wb_sel_i(cpu_sel_o),
+        .wb_we_i(cpu_we_o),
+        .wb_cyc_i(cpu_cyc_o),
+
+        .wb_stb_i(uart_stb_i),
+        .wb_ack_o(uart_ack_o),
+        .wb_dat_o(uart_dat_o),
+
+        .ser_tx(ser_tx),
+        .ser_rx(ser_rx)
+    );
+
+    // Wishbone Slave GPIO Registers
+    wire gpio_stb_i;
+    wire gpio_ack_o;
+    wire [31:0] gpio_dat_o;
+
+    gpio_wb #(
+        .BASE_ADR(GPIO_BASE_ADR),
+        .GPIO_DATA(GPIO_DATA),
+        .GPIO_ENA(GPIO_ENA),
+        .GPIO_PD(GPIO_PD),
+        .GPIO_PU(GPIO_PU)
+    ) gpio_wb (
+        .wb_clk_i(wb_clk_i),
+        .wb_rst_i(wb_rst_i),
+
+        .wb_adr_i(cpu_adr_o), 
+        .wb_dat_i(cpu_dat_o),
+        .wb_sel_i(cpu_sel_o),
+        .wb_we_i(cpu_we_o),
+        .wb_cyc_i(cpu_cyc_o),
+
+        .wb_stb_i(gpio_stb_i),
+        .wb_ack_o(gpio_ack_o),
+        .wb_dat_o(gpio_dat_o),
+        .gpio_in_pad(gpio_in_pad),
+
+        .gpio(gpio),
+        .gpio_oeb(gpio_oeb),
+        .gpio_pu(gpio_pu),
+        .gpio_pd(gpio_pd)
+    );
+
+    // Wishbone SPI System Control Registers (RO)
+    wire spi_sys_stb_i;
+    wire spi_sys_ack_o;
+    wire [31:0] spi_sys_dat_o;
+
+    spi_sysctrl_wb #(
+        .BASE_ADR(SPI_BASE_ADR),
+        .SPI_CFG(SPI_CFG),
+        .SPI_ENA(SPI_ENA),
+        .SPI_PLL_CFG(SPI_PLL_CFG),
+        .SPI_MFGR_ID(SPI_MFGR_ID),
+        .SPI_PROD_ID(SPI_PROD_ID),
+        .SPI_MASK_REV(SPI_MASK_REV),
+        .SPI_PLL_BYPASS(SPI_PLL_BYPASS)
+    ) spi_sysctrl (
+        .wb_clk_i(wb_clk_i),
+        .wb_rst_i(wb_rst_i),
+
+        .wb_adr_i(cpu_adr_o), 
+        .wb_dat_i(cpu_dat_o),
+        .wb_sel_i(cpu_sel_o),
+        .wb_we_i(cpu_we_o),
+        .wb_cyc_i(cpu_cyc_o),
+
+        .wb_stb_i(spi_sys_stb_i),
+        .wb_ack_o(spi_sys_ack_o),
+        .wb_dat_o(spi_sys_dat_o),
+        
+        .spi_ro_config(spi_ro_config), // (verify) wire input to the core not connected to HKSPI, what should it be connected to ? 
+        .spi_ro_pll_div(spi_ro_pll_div), 
+        .spi_ro_pll_sel(spi_ro_pll_sel),
+        .spi_ro_xtal_ena(spi_ro_xtal_ena),
+        .spi_ro_reg_ena(spi_ro_reg_ena), 
+    
+        .spi_ro_pll_trim(spi_ro_pll_trim),
+        .spi_ro_pll_dco_ena(spi_ro_pll_dco_ena),  
+
+        .spi_ro_mfgr_id(spi_ro_mfgr_id),
+        .spi_ro_prod_id(spi_ro_prod_id), 
+        .spi_ro_mask_rev(spi_ro_mask_rev), 
+        .pll_bypass(ext_clk_sel)
+    );
+    
+    // Wishbone Slave System Control Register
+    wire sys_stb_i;
+    wire sys_ack_o;
+    wire [31:0] sys_dat_o;
+    
+    sysctrl_wb #(
+        .BASE_ADR(SYS_BASE_ADR),
+        .OSC_ENA(OSC_ENA),
+        .OSC_OUT(OSC_OUT),
+        .XTAL_OUT(XTAL_OUT),
+        .PLL_OUT(PLL_OUT),
+        .TRAP_OUT(TRAP_OUT),
+        .IRQ7_SRC(IRQ7_SRC),
+        .IRQ8_SRC(IRQ8_SRC),
+        .OVERTEMP_ENA(OVERTEMP_ENA),
+        .OVERTEMP_DATA(OVERTEMP_DATA),
+        .OVERTEMP_OUT(OVERTEMP_OUT)
+    ) sysctrl (
+        .wb_clk_i(wb_clk_i),
+        .wb_rst_i(wb_rst_i),
+
+        .wb_adr_i(cpu_adr_o), 
+        .wb_dat_i(cpu_dat_o),
+        .wb_sel_i(cpu_sel_o),
+        .wb_we_i(cpu_we_o),
+        .wb_cyc_i(cpu_cyc_o),
+        
+        .wb_stb_i(sys_stb_i),
+        .wb_ack_o(sys_ack_o),
+        .wb_dat_o(sys_dat_o),
+
+        .overtemp(overtemp),
+        .rcosc_ena(rcosc_ena),
+        .rcosc_output_dest(rcosc_output_dest),
+        .xtal_output_dest(xtal_output_dest),
+        .pll_output_dest(pll_output_dest),
+        .trap_output_dest(trap_output_dest),
+        .irq_7_inputsrc(irq_7_inputsrc),
+        .irq_8_inputsrc(irq_8_inputsrc),
+        .overtemp_ena(overtemp_ena),
+        .overtemp_dest(overtemp_dest)
+    );
+
+    // Logic Analyzer 
+    wire la_stb_i;
+    wire la_ack_o;
+    wire [31:0] la_dat_o;
+
+    la_wb #(
+        .BASE_ADR(LA_BASE_ADR),
+        .LA_DATA_0(LA_DATA_0),
+        .LA_DATA_1(LA_DATA_1),
+        .LA_DATA_3(LA_DATA_3),
+        .LA_ENA_0(LA_ENA_0),
+        .LA_ENA_1(LA_ENA_1),
+        .LA_ENA_2(LA_ENA_2),
+        .LA_ENA_3(LA_ENA_3)
+    ) la (
+        .wb_clk_i(wb_clk_i),
+        .wb_rst_i(wb_rst_i),
+
+        .wb_adr_i(cpu_adr_o), 
+        .wb_dat_i(cpu_dat_o),
+        .wb_sel_i(cpu_sel_o),
+        .wb_we_i(cpu_we_o),
+        .wb_cyc_i(cpu_cyc_o),
+        
+        .wb_stb_i(la_stb_i),
+        .wb_ack_o(la_ack_o),
+        .wb_dat_o(la_dat_o),
+
+        .la_data(la_output),
+        .la_ena(la_oe)
+    );
+    
+    // Wishbone Slave RAM
+    wire mem_stb_i;
+    wire mem_ack_o;
+    wire [31:0] mem_dat_o;
+
+    mem_wb #(
+        .MEM_WORDS(MEM_WORDS)
+    ) soc_mem (
+        .wb_clk_i(wb_clk_i),
+        .wb_rst_i(wb_rst_i),
+
+        .wb_adr_i(cpu_adr_o), 
+        .wb_dat_i(cpu_dat_o),
+        .wb_sel_i(cpu_sel_o),
+        .wb_we_i(cpu_we_o),
+        .wb_cyc_i(cpu_cyc_o),
+
+        .wb_stb_i(mem_stb_i),
+        .wb_ack_o(mem_ack_o), 
+        .wb_dat_o(mem_dat_o)
+    );
+
+    // Wishbone intercon logic
+    wb_intercon #(
+        .AW(ADR_WIDTH),
+        .DW(DAT_WIDTH),
+        .NS(NUM_SLAVES),
+        .ADR_MASK(ADR_MASK),
+        .SLAVE_ADR(SLAVE_ADR)
+    ) intercon (
+        // Master Interface
+        .wbm_adr_i(cpu_adr_o),
+        .wbm_stb_i(cpu_stb_o),
+        .wbm_dat_o(cpu_dat_i),
+        .wbm_ack_o(cpu_ack_i),
+
+        // Slaves Interface
+        .wbs_stb_o({ xbar_stb_o, sys_stb_i, spi_sys_stb_i, spimemio_cfg_stb_i, la_stb_i, gpio_stb_i, uart_stb_i, spimemio_flash_stb_i, mem_stb_i }), 
+        .wbs_dat_i({ xbar_dat_i, sys_dat_o, spi_sys_dat_o, spimemio_cfg_dat_o, la_dat_o, gpio_dat_o, uart_dat_o, spimemio_flash_dat_o, mem_dat_o }),
+        .wbs_ack_i({ xbar_ack_i, sys_ack_o, spi_sys_ack_o, spimemio_cfg_ack_o, la_ack_o, gpio_ack_o, uart_ack_o, spimemio_flash_ack_o, mem_ack_o })
+    );
+
+    // Akin to ram ack
+    // always @(posedge clk)
+    // ram_ready <= mem_valid && !mem_ready && mem_addr < 4*MEM_WORDS;
+
+    always @(posedge clk) begin
+        if (!resetn) begin
+            adc0_ena <= 0;
+            adc0_convert <= 0;
+            adc0_clksrc <= 0;
+            adc0_inputsrc <= 0;
+            adc1_ena <= 0;
+            adc1_convert <= 0;
+            adc1_clksrc <= 0;
+            adc1_inputsrc <= 0;
+            dac_ena <= 0;
+            dac_value <= 0;
+            comp_ena <= 0;
+            comp_ninputsrc <= 0;
+            comp_pinputsrc <= 0;
+            comp_output_dest <= 0;	
+            analog_out_sel <= 0;
+            opamp_ena <= 0;
+            opamp_bias_ena <= 0;
+            bg_ena <= 0;
+        end else begin
+            // iomem_ready <= 0;
+            // if (iomem_valid && !iomem_ready && iomem_addr[31:8] == 24'h030000) begin
+                // 	iomem_ready <= 1;	
+                // end else if (iomem_addr[7:0] == 8'hc0) begin
+                // 	iomem_rdata <= {31'd0, analog_out_sel};
+                // 	if (iomem_wstrb[0]) analog_out_sel <= iomem_wdata[0];
+                // end else if (iomem_addr[7:0] == 8'hc4) begin
+                // 	iomem_rdata <= {31'd0, opamp_bias_ena};
+                // 	if (iomem_wstrb[0]) opamp_bias_ena <= iomem_wdata[0];
+                // end else if (iomem_addr[7:0] == 8'hc8) begin
+                // 	iomem_rdata <= {31'd0, opamp_ena};
+                // 	if (iomem_wstrb[0]) opamp_ena <= iomem_wdata[0];
+                // end else if (iomem_addr[7:0] == 8'hd0) begin
+                // 	iomem_rdata <= {31'd0, bg_ena};
+                // 	if (iomem_wstrb[0]) bg_ena <= iomem_wdata[0];
+            // end
+        end
+    end
+
+endmodule
+
+
+/* Convert the standard set of GPIO signals: input, output, output_enb,
+ * pullup, and pulldown into the set needed by the s8 GPIO pads:
+ * input, output, output_enb, input_enb, mode.  Note that dm[2] on
+ * thepads is always equal to dm[1] in this setup, so mode is shown as
+ * only a 2-bit signal.
+ *
+ * This module is bit-sliced.  Instantiate once for each GPIO pad.
+ */
+
+module convert_gpio_sigs (
+    input        gpio_out,
+    input        gpio_outenb,
+    input        gpio_pu,
+    input        gpio_pd,
+    output       gpio_out_pad,
+    output       gpio_outenb_pad,
+    output       gpio_inenb_pad,
+    output       gpio_mode1_pad,
+    output       gpio_mode0_pad
+);
+
+    assign gpio_out_pad = (gpio_pu == 1'b0 && gpio_pd == 1'b0) ? gpio_out :
+            (gpio_pu == 1'b1) ? 1 : 0;
+
+    assign gpio_outenb_pad = (gpio_outenb == 1'b0) ? 0 :
+            (gpio_pu == 1'b1 || gpio_pd == 1'b1) ? 0 : 1;
+
+    assign gpio_inenb_pad = ~gpio_outenb;
+
+    assign gpio_mode1_pad = ~gpio_outenb_pad;
+    assign gpio_mode0_pad = gpio_outenb;
+
+endmodule
+
+// Implementation note:
+// Replace the following two modules with wrappers for your SRAM cells.
+module openstriVe_soc_regs (
+    input clk, wen,
+    input [5:0] waddr,
+    input [5:0] raddr1,
+    input [5:0] raddr2,
+    input [31:0] wdata,
+    output [31:0] rdata1,
+    output [31:0] rdata2
+);
+    reg [31:0] regs [0:31];
+
+    always @(posedge clk)
+        if (wen) regs[waddr[4:0]] <= wdata;
+
+    assign rdata1 = regs[raddr1[4:0]];
+    assign rdata2 = regs[raddr2[4:0]];
+endmodule
diff --git a/verilog/rtl/picorv32.v b/verilog/rtl/picorv32.v
index af634b4..cbbbb60 100644
--- a/verilog/rtl/picorv32.v
+++ b/verilog/rtl/picorv32.v
@@ -17,6 +17,11 @@
  *
  */
 
+/* verilator lint_off WIDTH */
+/* verilator lint_off PINMISSING */
+/* verilator lint_off CASEOVERLAP */
+/* verilator lint_off CASEINCOMPLETE */
+
 `timescale 1 ns / 1 ps
 // `default_nettype none
 // `define DEBUGNETS
@@ -122,6 +127,8 @@
 	output reg        rvfi_trap,
 	output reg        rvfi_halt,
 	output reg        rvfi_intr,
+	output reg [ 1:0] rvfi_mode,
+	output reg [ 1:0] rvfi_ixl,
 	output reg [ 4:0] rvfi_rs1_addr,
 	output reg [ 4:0] rvfi_rs2_addr,
 	output reg [31:0] rvfi_rs1_rdata,
@@ -135,6 +142,16 @@
 	output reg [ 3:0] rvfi_mem_wmask,
 	output reg [31:0] rvfi_mem_rdata,
 	output reg [31:0] rvfi_mem_wdata,
+
+	output reg [63:0] rvfi_csr_mcycle_rmask,
+	output reg [63:0] rvfi_csr_mcycle_wmask,
+	output reg [63:0] rvfi_csr_mcycle_rdata,
+	output reg [63:0] rvfi_csr_mcycle_wdata,
+
+	output reg [63:0] rvfi_csr_minstret_rmask,
+	output reg [63:0] rvfi_csr_minstret_wmask,
+	output reg [63:0] rvfi_csr_minstret_rdata,
+	output reg [63:0] rvfi_csr_minstret_wdata,
 `endif
 
 	// Trace Interface
@@ -636,7 +653,7 @@
 	wire instr_trap;
 
 	reg [regindex_bits-1:0] decoded_rd, decoded_rs1, decoded_rs2;
-	reg [31:0] decoded_imm, decoded_imm_uj;
+	reg [31:0] decoded_imm, decoded_imm_j;
 	reg decoder_trigger;
 	reg decoder_trigger_q;
 	reg decoder_pseudo_trigger;
@@ -858,7 +875,7 @@
 			is_alu_reg_imm               <= mem_rdata_latched[6:0] == 7'b0010011;
 			is_alu_reg_reg               <= mem_rdata_latched[6:0] == 7'b0110011;
 
-			{ decoded_imm_uj[31:20], decoded_imm_uj[10:1], decoded_imm_uj[11], decoded_imm_uj[19:12], decoded_imm_uj[0] } <= $signed({mem_rdata_latched[31:12], 1'b0});
+			{ decoded_imm_j[31:20], decoded_imm_j[10:1], decoded_imm_j[11], decoded_imm_j[19:12], decoded_imm_j[0] } <= $signed({mem_rdata_latched[31:12], 1'b0});
 
 			decoded_rd <= mem_rdata_latched[11:7];
 			decoded_rs1 <= mem_rdata_latched[19:15];
@@ -877,8 +894,8 @@
 				decoded_rs1 <= 0;
 				decoded_rs2 <= 0;
 
-				{ decoded_imm_uj[31:11], decoded_imm_uj[4], decoded_imm_uj[9:8], decoded_imm_uj[10], decoded_imm_uj[6],
-				  decoded_imm_uj[7], decoded_imm_uj[3:1], decoded_imm_uj[5], decoded_imm_uj[0] } <= $signed({mem_rdata_latched[12:2], 1'b0});
+				{ decoded_imm_j[31:11], decoded_imm_j[4], decoded_imm_j[9:8], decoded_imm_j[10], decoded_imm_j[6],
+				  decoded_imm_j[7], decoded_imm_j[3:1], decoded_imm_j[5], decoded_imm_j[0] } <= $signed({mem_rdata_latched[12:2], 1'b0});
 
 				case (mem_rdata_latched[1:0])
 					2'b00: begin // Quadrant 0
@@ -1099,7 +1116,7 @@
 			(* parallel_case *)
 			case (1'b1)
 				instr_jal:
-					decoded_imm <= decoded_imm_uj;
+					decoded_imm <= decoded_imm_j;
 				|{instr_lui, instr_auipc}:
 					decoded_imm <= mem_rdata_q[31:12] << 12;
 				|{instr_jalr, is_lb_lh_lw_lbu_lhu, is_alu_reg_imm}:
@@ -1314,7 +1331,13 @@
 `ifndef PICORV32_REGS
 	always @(posedge clk) begin
 		if (resetn && cpuregs_write && latched_rd)
+`ifdef PICORV32_TESTBUG_001
+			cpuregs[latched_rd ^ 1] <= cpuregs_wrdata;
+`elsif PICORV32_TESTBUG_002
+			cpuregs[latched_rd] <= cpuregs_wrdata ^ 1;
+`else
 			cpuregs[latched_rd] <= cpuregs_wrdata;
+`endif
 	end
 
 	always @* begin
@@ -1412,15 +1435,9 @@
 		next_irq_pending = ENABLE_IRQ ? irq_pending & LATCHED_IRQ : 'bx;
 
 		if (ENABLE_IRQ && ENABLE_IRQ_TIMER && timer) begin
-			if (timer - 1 == 0)
-				next_irq_pending[irq_timer] = 1;
 			timer <= timer - 1;
 		end
 
-		if (ENABLE_IRQ) begin
-			next_irq_pending = next_irq_pending | irq;
-		end
-
 		decoder_trigger <= mem_do_rinst && mem_done;
 		decoder_trigger_q <= decoder_trigger;
 		decoder_pseudo_trigger <= 0;
@@ -1544,7 +1561,7 @@
 					end
 					if (instr_jal) begin
 						mem_do_rinst <= 1;
-						reg_next_pc <= current_pc + decoded_imm_uj;
+						reg_next_pc <= current_pc + decoded_imm_j;
 						latched_branch <= 1;
 					end else begin
 						mem_do_rinst <= 0;
@@ -1890,6 +1907,13 @@
 			end
 		endcase
 
+		if (ENABLE_IRQ) begin
+			next_irq_pending = next_irq_pending | irq;
+			if(ENABLE_IRQ_TIMER && timer)
+				if (timer - 1 == 0)
+					next_irq_pending[irq_timer] = 1;
+		end
+
 		if (CATCH_MISALIGN && resetn && (mem_do_rdata || mem_do_wdata)) begin
 			if (mem_wordsize == 0 && reg_op1[1:0] != 0) begin
 				`debug($display("MISALIGNED WORD: 0x%08x", reg_op1);)
@@ -1962,6 +1986,8 @@
 		rvfi_trap <= trap;
 		rvfi_halt <= trap;
 		rvfi_intr <= dbg_irq_enter;
+		rvfi_mode <= 3;
+		rvfi_ixl <= 1;
 
 		if (!resetn) begin
 			dbg_irq_call <= 0;
@@ -1981,8 +2007,16 @@
 			rvfi_rd_wdata <= 0;
 		end else
 		if (cpuregs_write && !irq_state) begin
+`ifdef PICORV32_TESTBUG_003
+			rvfi_rd_addr <= latched_rd ^ 1;
+`else
 			rvfi_rd_addr <= latched_rd;
+`endif
+`ifdef PICORV32_TESTBUG_004
+			rvfi_rd_wdata <= latched_rd ? cpuregs_wrdata ^ 1 : 0;
+`else
 			rvfi_rd_wdata <= latched_rd ? cpuregs_wrdata : 0;
+`endif
 		end else
 		if (rvfi_valid) begin
 			rvfi_rd_addr <= 0;
@@ -2023,7 +2057,40 @@
 	end
 
 	always @* begin
+`ifdef PICORV32_TESTBUG_005
+		rvfi_pc_wdata = (dbg_irq_call ? dbg_irq_ret : dbg_insn_addr) ^ 4;
+`else
 		rvfi_pc_wdata = dbg_irq_call ? dbg_irq_ret : dbg_insn_addr;
+`endif
+
+		rvfi_csr_mcycle_rmask = 0;
+		rvfi_csr_mcycle_wmask = 0;
+		rvfi_csr_mcycle_rdata = 0;
+		rvfi_csr_mcycle_wdata = 0;
+
+		rvfi_csr_minstret_rmask = 0;
+		rvfi_csr_minstret_wmask = 0;
+		rvfi_csr_minstret_rdata = 0;
+		rvfi_csr_minstret_wdata = 0;
+
+		if (rvfi_valid && rvfi_insn[6:0] == 7'b 1110011 && rvfi_insn[13:12] == 3'b010) begin
+			if (rvfi_insn[31:20] == 12'h C00) begin
+				rvfi_csr_mcycle_rmask = 64'h 0000_0000_FFFF_FFFF;
+				rvfi_csr_mcycle_rdata = {32'h 0000_0000, rvfi_rd_wdata};
+			end
+			if (rvfi_insn[31:20] == 12'h C80) begin
+				rvfi_csr_mcycle_rmask = 64'h FFFF_FFFF_0000_0000;
+				rvfi_csr_mcycle_rdata = {rvfi_rd_wdata, 32'h 0000_0000};
+			end
+			if (rvfi_insn[31:20] == 12'h C02) begin
+				rvfi_csr_minstret_rmask = 64'h 0000_0000_FFFF_FFFF;
+				rvfi_csr_minstret_rdata = {32'h 0000_0000, rvfi_rd_wdata};
+			end
+			if (rvfi_insn[31:20] == 12'h C82) begin
+				rvfi_csr_minstret_rmask = 64'h FFFF_FFFF_0000_0000;
+				rvfi_csr_minstret_rdata = {rvfi_rd_wdata, 32'h 0000_0000};
+			end
+		end
 	end
 `endif
 
@@ -2913,7 +2980,7 @@
 		.trace_valid(trace_valid),
 		.trace_data (trace_data)
 	);
-
+	// Wishbone Controller
 	localparam IDLE = 2'b00;
 	localparam WBSTART = 2'b01;
 	localparam WBEND = 2'b10;
diff --git a/verilog/rtl/ring_osc2x13.v b/verilog/rtl/ring_osc2x13.v
index 4363c00..58a01af 100644
--- a/verilog/rtl/ring_osc2x13.v
+++ b/verilog/rtl/ring_osc2x13.v
@@ -10,40 +10,40 @@
 
     wire d0, d1, d2;
 
-    sky130_fd_sc_hd__clkbuf_2 delaybuf0 (
+    scs8hd_clkbuf_2 delaybuf0 (
 	.A(in),
 	.X(ts)
     );
 
-    sky130_fd_sc_hd__clkbuf_1 delaybuf1 (
+    scs8hd_clkbuf_1 delaybuf1 (
 	.A(ts),
 	.X(d0)
     );
 
-    sky130_fd_sc_hd__einvp_2 delayen1 (
+    scs8hd_einvp_2 delayen1 (
 	.A(d0),
 	.TE(trim[1]),
 	.Z(d1)
     );
 
-    sky130_fd_sc_hd__einvn_4 delayenb1 (
+    scs8hd_einvn_4 delayenb1 (
 	.A(ts),
 	.TEB(trim[1]),
 	.Z(d1)
     );
 
-    sky130_fd_sc_hd__clkinv_1 delayint0 (
+    scs8hd_clkinv_1 delayint0 (
 	.A(d1),
 	.Y(d2)
     );
 
-    sky130_fd_sc_hd__einvp_2 delayen0 (
+    scs8hd_einvp_2 delayen0 (
 	.A(d2),
 	.TE(trim[0]),
 	.Z(out)
     );
 
-    sky130_fd_sc_hd__einvn_8 delayenb0 (
+    scs8hd_einvn_8 delayenb0 (
 	.A(ts),
 	.TEB(trim[0]),
 	.Z(out)
@@ -59,53 +59,53 @@
 
     wire d0, d1, d2, ctrl0, one;
 
-    sky130_fd_sc_hd__clkbuf_1 delaybuf0 (
+    scs8hd_clkbuf_1 delaybuf0 (
 	.A(in),
 	.X(d0)
     );
 
-    sky130_fd_sc_hd__einvp_2 delayen1 (
+    scs8hd_einvp_2 delayen1 (
 	.A(d0),
 	.TE(trim[1]),
 	.Z(d1)
     );
 
-    sky130_fd_sc_hd__einvn_4 delayenb1 (
+    scs8hd_einvn_4 delayenb1 (
 	.A(in),
 	.TEB(trim[1]),
 	.Z(d1)
     );
 
-    sky130_fd_sc_hd__clkinv_1 delayint0 (
+    scs8hd_clkinv_1 delayint0 (
 	.A(d1),
 	.Y(d2)
     );
 
-    sky130_fd_sc_hd__einvp_2 delayen0 (
+    scs8hd_einvp_2 delayen0 (
 	.A(d2),
 	.TE(trim[0]),
 	.Z(out)
     );
 
-    sky130_fd_sc_hd__einvn_8 delayenb0 (
+    scs8hd_einvn_8 delayenb0 (
 	.A(in),
 	.TEB(ctrl0),
 	.Z(out)
     );
 
-    sky130_fd_sc_hd__einvp_1 reseten0 (
+    scs8hd_einvp_1 reseten0 (
 	.A(one),
 	.TE(reset),
 	.Z(out)
     );
 
-    sky130_fd_sc_hd__or2_2 ctrlen0 (
+    scs8hd_or2_2 ctrlen0 (
 	.A(reset),
 	.B(trim[0]),
 	.X(ctrl0)
     );
 
-    sky130_fd_sc_hd__conb_1 const1 (
+    scs8hd_conb_1 const1 (
 	.HI(one),
 	.LO()
     );
@@ -159,19 +159,19 @@
 
     // Buffered outputs a 0 and 90 degrees phase (approximately)
 
-    sky130_fd_sc_hd__clkinv_2 ibufp00 (
+    scs8hd_clkinv_2 ibufp00 (
 	.A(d[0]),
 	.Y(c[0])
     );
-    sky130_fd_sc_hd__clkinv_8 ibufp01 (
+    scs8hd_clkinv_8 ibufp01 (
 	.A(c[0]),
 	.Y(clockp[0])
     );
-    sky130_fd_sc_hd__clkinv_2 ibufp10 (
+    scs8hd_clkinv_2 ibufp10 (
 	.A(d[6]),
 	.Y(c[1])
     );
-    sky130_fd_sc_hd__clkinv_8 ibufp11 (
+    scs8hd_clkinv_8 ibufp11 (
 	.A(c[1]),
 	.Y(clockp[1])
     );
diff --git a/verilog/rtl/simpleuart.v b/verilog/rtl/simpleuart.v
index 50808cb..51e95c7 100644
--- a/verilog/rtl/simpleuart.v
+++ b/verilog/rtl/simpleuart.v
@@ -17,121 +17,180 @@
  *
  */
 
-module simpleuart (
-	input clk,
-	input resetn,
+module simpleuart_wb # (
+    parameter BASE_ADR = 32'h 2000_0000,
+    parameter CLK_DIV = 8'h00,
+    parameter DATA = 8'h04
+) (
+    input wb_clk_i,
+    input wb_rst_i,
 
-	output ser_tx,
-	input  ser_rx,
+    input [31:0] wb_adr_i,      // (verify): input address was originaly 22 bits , why ? (max number of words ?)
+    input [31:0] wb_dat_i,
+    input [3:0]  wb_sel_i,
+    input wb_we_i,
+    input wb_cyc_i,
+    input wb_stb_i,
 
-	input   [3:0] reg_div_we,
-	input  [31:0] reg_div_di,
-	output [31:0] reg_div_do,
+    output wb_ack_o,
+    output [31:0] wb_dat_o,
 
-	input         reg_dat_we,
-	input         reg_dat_re,
-	input  [31:0] reg_dat_di,
-	output [31:0] reg_dat_do,
-	output        reg_dat_wait
+    output ser_tx,
+    input  ser_rx
+
 );
-	reg [31:0] cfg_divider;
+    wire [31:0] simpleuart_reg_div_do;
+    wire [31:0] simpleuart_reg_dat_do;
 
-	reg [3:0] recv_state;
-	reg [31:0] recv_divcnt;
-	reg [7:0] recv_pattern;
-	reg [7:0] recv_buf_data;
-	reg recv_buf_valid;
+    wire resetn = ~wb_rst_i;
+    wire valid = wb_stb_i && wb_cyc_i; 
+    wire simpleuart_reg_div_sel = valid && (wb_adr_i == (BASE_ADR | CLK_DIV));
+    wire simpleuart_reg_dat_sel = valid && (wb_adr_i == (BASE_ADR | DATA));
 
-	reg [9:0] send_pattern;
-	reg [3:0] send_bitcnt;
-	reg [31:0] send_divcnt;
-	reg send_dummy;
+    wire [3:0] reg_div_we = simpleuart_reg_div_sel ? (wb_sel_i & {4{wb_we_i}}): 4'b 0000; // simpleuart_reg_div_sel ? mem_wstrb : 4'b 0000), // sel: depends on address buss
+    wire reg_dat_we = simpleuart_reg_dat_sel ? (wb_sel_i[0] & wb_we_i): 1'b 0;      // simpleuart_reg_dat_sel ? mem_wstrb[0] : 1'b 0
 
-	assign reg_div_do = cfg_divider;
+    wire [31:0] mem_wdata = wb_dat_i;
+    wire reg_dat_re = simpleuart_reg_dat_sel && !wb_sel_i && ~wb_we_i; // read_enable
 
-	assign reg_dat_wait = reg_dat_we && (send_bitcnt || send_dummy);
-	assign reg_dat_do = recv_buf_valid ? recv_buf_data : ~0;
+    assign wb_dat_o = simpleuart_reg_div_sel ? simpleuart_reg_div_do: simpleuart_reg_dat_do;
+    assign wb_ack_o = (simpleuart_reg_div_sel || simpleuart_reg_dat_sel) && (!reg_dat_wait);
+    
+    simpleuart simpleuart (
+        .clk    (wb_clk_i),
+        .resetn (resetn),
 
-	always @(posedge clk) begin
-		if (!resetn) begin
-			cfg_divider <= 1;
-		end else begin
-			if (reg_div_we[0]) cfg_divider[ 7: 0] <= reg_div_di[ 7: 0];
-			if (reg_div_we[1]) cfg_divider[15: 8] <= reg_div_di[15: 8];
-			if (reg_div_we[2]) cfg_divider[23:16] <= reg_div_di[23:16];
-			if (reg_div_we[3]) cfg_divider[31:24] <= reg_div_di[31:24];
-		end
-	end
+        .ser_tx      (ser_tx),
+        .ser_rx      (ser_rx),
 
-	always @(posedge clk) begin
-		if (!resetn) begin
-			recv_state <= 0;
-			recv_divcnt <= 0;
-			recv_pattern <= 0;
-			recv_buf_data <= 0;
-			recv_buf_valid <= 0;
-		end else begin
-			recv_divcnt <= recv_divcnt + 1;
-			if (reg_dat_re)
-				recv_buf_valid <= 0;
-			case (recv_state)
-				0: begin
-					if (!ser_rx)
-						recv_state <= 1;
-					recv_divcnt <= 0;
-				end
-				1: begin
-					if (2*recv_divcnt > cfg_divider) begin
-						recv_state <= 2;
-						recv_divcnt <= 0;
-					end
-				end
-				10: begin
-					if (recv_divcnt > cfg_divider) begin
-						recv_buf_data <= recv_pattern;
-						recv_buf_valid <= 1;
-						recv_state <= 0;
-					end
-				end
-				default: begin
-					if (recv_divcnt > cfg_divider) begin
-						recv_pattern <= {ser_rx, recv_pattern[7:1]};
-						recv_state <= recv_state + 1;
-						recv_divcnt <= 0;
-					end
-				end
-			endcase
-		end
-	end
+        .reg_div_we  (reg_div_we), 
+        .reg_div_di  (mem_wdata),
+        .reg_div_do  (simpleuart_reg_div_do),
 
-	assign ser_tx = send_pattern[0];
+        .reg_dat_we  (reg_dat_we),
+        .reg_dat_re  (reg_dat_re),
+        .reg_dat_di  (mem_wdata),
+        .reg_dat_do  (simpleuart_reg_dat_do),
+        .reg_dat_wait(reg_dat_wait)
+    );
 
-	always @(posedge clk) begin
-		if (reg_div_we)
-			send_dummy <= 1;
-		send_divcnt <= send_divcnt + 1;
-		if (!resetn) begin
-			send_pattern <= ~0;
-			send_bitcnt <= 0;
-			send_divcnt <= 0;
-			send_dummy <= 1;
-		end else begin
-			if (send_dummy && !send_bitcnt) begin
-				send_pattern <= ~0;
-				send_bitcnt <= 15;
-				send_divcnt <= 0;
-				send_dummy <= 0;
-			end else
-			if (reg_dat_we && !send_bitcnt) begin
-				send_pattern <= {1'b1, reg_dat_di[7:0], 1'b0};
-				send_bitcnt <= 10;
-				send_divcnt <= 0;
-			end else
-			if (send_divcnt > cfg_divider && send_bitcnt) begin
-				send_pattern <= {1'b1, send_pattern[9:1]};
-				send_bitcnt <= send_bitcnt - 1;
-				send_divcnt <= 0;
-			end
-		end
-	end
+endmodule
+
+module simpleuart (
+    input clk,
+    input resetn,
+
+    output ser_tx,
+    input  ser_rx,
+
+    input   [3:0] reg_div_we,         
+    input  [31:0] reg_div_di,         
+    output [31:0] reg_div_do,         
+
+    input         reg_dat_we,         
+    input         reg_dat_re,         
+    input  [31:0] reg_dat_di,
+    output [31:0] reg_dat_do,
+    output        reg_dat_wait
+);
+    reg [31:0] cfg_divider;
+
+    reg [3:0] recv_state;
+    reg [31:0] recv_divcnt;
+    reg [7:0] recv_pattern;
+    reg [7:0] recv_buf_data;
+    reg recv_buf_valid;
+
+    reg [9:0] send_pattern;
+    reg [3:0] send_bitcnt;
+    reg [31:0] send_divcnt;
+    reg send_dummy;
+
+    assign reg_div_do = cfg_divider;
+
+    assign reg_dat_wait = reg_dat_we && (send_bitcnt || send_dummy);
+    assign reg_dat_do = recv_buf_valid ? recv_buf_data : ~0;
+
+    always @(posedge clk) begin
+        if (!resetn) begin
+            cfg_divider <= 1;
+        end else begin
+            if (reg_div_we[0]) cfg_divider[ 7: 0] <= reg_div_di[ 7: 0];
+            if (reg_div_we[1]) cfg_divider[15: 8] <= reg_div_di[15: 8];
+            if (reg_div_we[2]) cfg_divider[23:16] <= reg_div_di[23:16];
+            if (reg_div_we[3]) cfg_divider[31:24] <= reg_div_di[31:24];
+        end
+    end
+
+    always @(posedge clk) begin
+        if (!resetn) begin
+            recv_state <= 0;
+            recv_divcnt <= 0;
+            recv_pattern <= 0;
+            recv_buf_data <= 0;
+            recv_buf_valid <= 0;
+        end else begin
+            recv_divcnt <= recv_divcnt + 1;
+            if (reg_dat_re)
+                recv_buf_valid <= 0;
+            case (recv_state)
+                0: begin
+                    if (!ser_rx)
+                        recv_state <= 1;
+                    recv_divcnt <= 0;
+                end
+                1: begin
+                    if (2*recv_divcnt > cfg_divider) begin
+                        recv_state <= 2;
+                        recv_divcnt <= 0;
+                    end
+                end
+                10: begin
+                    if (recv_divcnt > cfg_divider) begin
+                        recv_buf_data <= recv_pattern;
+                        recv_buf_valid <= 1;
+                        recv_state <= 0;
+                    end
+                end
+                default: begin
+                    if (recv_divcnt > cfg_divider) begin
+                        recv_pattern <= {ser_rx, recv_pattern[7:1]};
+                        recv_state <= recv_state + 1;
+                        recv_divcnt <= 0;
+                    end
+                end
+            endcase
+        end
+    end
+
+    assign ser_tx = send_pattern[0];
+
+    always @(posedge clk) begin
+        if (reg_div_we)
+            send_dummy <= 1;
+        send_divcnt <= send_divcnt + 1;
+        if (!resetn) begin
+            send_pattern <= ~0;
+            send_bitcnt <= 0;
+            send_divcnt <= 0;
+            send_dummy <= 1;
+        end else begin
+            if (send_dummy && !send_bitcnt) begin
+                send_pattern <= ~0;
+                send_bitcnt <= 15;
+                send_divcnt <= 0;
+                send_dummy <= 0;
+            end else
+            if (reg_dat_we && !send_bitcnt) begin
+                send_pattern <= {1'b1, reg_dat_di[7:0], 1'b0};
+                send_bitcnt <= 10;
+                send_divcnt <= 0;
+            end else
+            if (send_divcnt > cfg_divider && send_bitcnt) begin
+                send_pattern <= {1'b1, send_pattern[9:1]};
+                send_bitcnt <= send_bitcnt - 1;
+                send_divcnt <= 0;
+            end
+        end
+    end
 endmodule
diff --git a/verilog/rtl/spi_slave.v b/verilog/rtl/spi_slave.v
index 50a6520..16a1923 100644
--- a/verilog/rtl/spi_slave.v
+++ b/verilog/rtl/spi_slave.v
@@ -83,97 +83,97 @@
     // Readback data is captured on the falling edge of SCK so that
     // it is guaranteed valid at the next rising edge.
     always @(negedge SCK or posedge CSB) begin
-	if (CSB == 1'b1) begin
-	    wrstb <= 1'b0;
-	    ldata  <= 8'b00000000;
-	    sdoenb <= 1'b1;
+    if (CSB == 1'b1) begin
+        wrstb <= 1'b0;
+        ldata  <= 8'b00000000;
+        sdoenb <= 1'b1;
         end else begin
 
-	    // After CSB low, 1st SCK starts command
+        // After CSB low, 1st SCK starts command
 
-	    if (state == `DATA) begin
-		if (readmode == 1'b1) begin
-		    sdoenb <= 1'b0;
-		    if (count == 3'b000) begin
-			ldata <= idata;
-		    end else begin
-			ldata <= {ldata[6:0], 1'b0};	// Shift out
-		    end
-		end else begin
-		    sdoenb <= 1'b1;
-		end
+        if (state == `DATA) begin
+        if (readmode == 1'b1) begin
+            sdoenb <= 1'b0;
+            if (count == 3'b000) begin
+            ldata <= idata;
+            end else begin
+            ldata <= {ldata[6:0], 1'b0};	// Shift out
+            end
+        end else begin
+            sdoenb <= 1'b1;
+        end
 
-		// Apply write strobe on SCK negative edge on the next-to-last
-		// data bit so that it updates data on the rising edge of SCK
-		// on the last data bit.
+        // Apply write strobe on SCK negative edge on the next-to-last
+        // data bit so that it updates data on the rising edge of SCK
+        // on the last data bit.
  
-		if (count == 3'b111) begin
-		    if (writemode == 1'b1) begin
-			wrstb <= 1'b1;
- 		    end
-		end else begin
-		    wrstb <= 1'b0;
-		end
-	    end else begin
-		wrstb <= 1'b0;
-		sdoenb <= 1'b1;
-	    end		// ! state `DATA
-	end		// ! CSB
+        if (count == 3'b111) begin
+            if (writemode == 1'b1) begin
+            wrstb <= 1'b1;
+             end
+        end else begin
+            wrstb <= 1'b0;
+        end
+        end else begin
+        wrstb <= 1'b0;
+        sdoenb <= 1'b1;
+        end		// ! state `DATA
+    end		// ! CSB
     end			// always @ ~SCK
 
     always @(posedge SCK or posedge CSB) begin
-	if (CSB == 1'b1) begin
-	    // Default state on reset
-	    addr <= 8'h00;
-	    rdstb <= 1'b0;
-	    predata <= 7'b0000000;
-	    state  <= `COMMAND;
-	    count  <= 3'b000;
-	    readmode <= 1'b0;
-	    writemode <= 1'b0;
-	    fixed <= 3'b000;
+    if (CSB == 1'b1) begin
+        // Default state on reset
+        addr <= 8'h00;
+        rdstb <= 1'b0;
+        predata <= 7'b0000000;
+        state  <= `COMMAND;
+        count  <= 3'b000;
+        readmode <= 1'b0;
+        writemode <= 1'b0;
+        fixed <= 3'b000;
         end else begin
-	    // After CSB low, 1st SCK starts command
-	    if (state == `COMMAND) begin
-		rdstb <= 1'b0;
-		count <= count + 1;
-		if (count == 3'b000) begin
-		    writemode <= SDI;
-		end else if (count == 3'b001) begin
-		    readmode <= SDI;
-		end else if (count < 3'b101) begin
-		    fixed <= {fixed[1:0], SDI}; 
-		end else if (count == 3'b111) begin
-		    state <= `ADDRESS;
-		end
-	    end else if (state == `ADDRESS) begin
-		count <= count + 1;
-		addr <= {addr[6:0], SDI};
-		if (count == 3'b111) begin
-		    if (readmode == 1'b1) begin
-			rdstb <= 1'b1;
-		    end
-		    state <= `DATA;
-		end else begin
-		    rdstb <= 1'b0;
-		end
-	    end else if (state == `DATA) begin
-		predata <= {predata[6:0], SDI};
-		count <= count + 1;
-		if (count == 3'b111) begin
-		    if (fixed == 3'b001) begin
-			state <= `COMMAND;
-		    end else if (fixed != 3'b000) begin
-			fixed <= fixed - 1;
-			addr <= addr + 1;	// Auto increment address (fixed)
-		    end else begin	
-			addr <= addr + 1;	// Auto increment address (streaming)
-		    end
-		end else begin
-		    rdstb <= 1'b0;
-		end
-	    end		// ! state `DATA
-	end		// ! CSB
+        // After CSB low, 1st SCK starts command
+        if (state == `COMMAND) begin
+        rdstb <= 1'b0;
+        count <= count + 1;
+        if (count == 3'b000) begin
+            writemode <= SDI;
+        end else if (count == 3'b001) begin
+            readmode <= SDI;
+        end else if (count < 3'b101) begin
+            fixed <= {fixed[1:0], SDI}; 
+        end else if (count == 3'b111) begin
+            state <= `ADDRESS;
+        end
+        end else if (state == `ADDRESS) begin
+        count <= count + 1;
+        addr <= {addr[6:0], SDI};
+        if (count == 3'b111) begin
+            if (readmode == 1'b1) begin
+            rdstb <= 1'b1;
+            end
+            state <= `DATA;
+        end else begin
+            rdstb <= 1'b0;
+        end
+        end else if (state == `DATA) begin
+        predata <= {predata[6:0], SDI};
+        count <= count + 1;
+        if (count == 3'b111) begin
+            if (fixed == 3'b001) begin
+            state <= `COMMAND;
+            end else if (fixed != 3'b000) begin
+            fixed <= fixed - 1;
+            addr <= addr + 1;	// Auto increment address (fixed)
+            end else begin	
+            addr <= addr + 1;	// Auto increment address (streaming)
+            end
+        end else begin
+            rdstb <= 1'b0;
+        end
+        end		// ! state `DATA
+    end		// ! CSB
     end			// always @ SCK
 
 endmodule // spi_slave
diff --git a/verilog/rtl/spi_sysctrl.v b/verilog/rtl/spi_sysctrl.v
new file mode 100644
index 0000000..7a34a7f
--- /dev/null
+++ b/verilog/rtl/spi_sysctrl.v
@@ -0,0 +1,182 @@
+module spi_sysctrl_wb #(
+    parameter BASE_ADR = 32'h2E00_0000,
+    parameter SPI_CFG = 8'h00,
+    parameter SPI_ENA = 8'h04,
+    parameter SPI_PLL_CFG = 8'h08,
+    parameter SPI_MFGR_ID = 8'h0c,
+    parameter SPI_PROD_ID = 8'h10,
+    parameter SPI_MASK_REV = 8'h14,
+    parameter SPI_PLL_BYPASS = 8'h18
+) (
+    input wb_clk_i,
+    input wb_rst_i,
+
+    input [31:0] wb_dat_i,
+    input [31:0] wb_adr_i,
+    input [3:0] wb_sel_i,
+    input wb_cyc_i,
+    input wb_stb_i,
+    input wb_we_i,
+
+    output [31:0] wb_dat_o,
+    output wb_ack_o,
+
+    // Read-Only HKSPI Registers
+    input [7:0] spi_ro_config, // (verify) wire input to the core not connected to HKSPI, what should it be connected to ? 
+    
+    input [4:0] spi_ro_pll_div, 
+    input [2:0] spi_ro_pll_sel,
+    input spi_ro_xtal_ena,
+    input spi_ro_reg_ena, 
+    
+    input [25:0] spi_ro_pll_trim,
+    input spi_ro_pll_dco_ena,  
+
+    input [11:0] spi_ro_mfgr_id,
+    input [7:0] spi_ro_prod_id, 
+    input [3:0] spi_ro_mask_rev, 
+    input pll_bypass
+);
+
+    wire resetn;
+    wire valid;
+    wire ready;
+    wire [3:0] iomem_we;
+
+    assign resetn = ~wb_rst_i;
+    assign valid = wb_stb_i && wb_cyc_i; 
+
+    assign iomem_we = wb_sel_i & {4{wb_we_i}};
+    assign wb_ack_o = ready;
+    
+    spi_sysctrl #(
+        .BASE_ADR(BASE_ADR),
+        .SPI_CFG(SPI_CFG),
+        .SPI_ENA(SPI_ENA),
+        .SPI_PLL_CFG(SPI_PLL_CFG),
+        .SPI_MFGR_ID(SPI_MFGR_ID),
+        .SPI_PROD_ID(SPI_PROD_ID),
+        .SPI_MASK_REV(SPI_MASK_REV),
+        .SPI_PLL_BYPASS(SPI_PLL_BYPASS)
+    ) spi_sysctrl (
+        .clk(wb_clk_i),
+        .resetn(resetn),
+
+        .iomem_addr(wb_adr_i),
+        .iomem_valid(valid),
+        .iomem_wstrb(iomem_we),
+        .iomem_wdata(wb_dat_i),
+        .iomem_rdata(wb_dat_o),
+        .iomem_ready(ready),
+        
+        .spi_ro_config(spi_ro_config), // (verify) wire input to the core not connected to HKSPI, what should it be connected to ? 
+        .spi_ro_pll_div(spi_ro_pll_div), 
+        .spi_ro_pll_sel(spi_ro_pll_sel),
+        .spi_ro_xtal_ena(spi_ro_xtal_ena),
+        .spi_ro_reg_ena(spi_ro_reg_ena), 
+    
+        .spi_ro_pll_trim(spi_ro_pll_trim),
+        .spi_ro_pll_dco_ena(spi_ro_pll_dco_ena),  
+
+        .spi_ro_mfgr_id(spi_ro_mfgr_id),
+        .spi_ro_prod_id(spi_ro_prod_id), 
+        .spi_ro_mask_rev(spi_ro_mask_rev), 
+        .pll_bypass(pll_bypass)
+    );
+
+endmodule
+
+module spi_sysctrl #(
+    parameter BASE_ADR = 32'h2300_0000,
+    parameter SPI_CFG = 8'h00,
+    parameter SPI_ENA = 8'h04,
+    parameter SPI_PLL_CFG = 8'h08,
+    parameter SPI_MFGR_ID = 8'h0c,
+    parameter SPI_PROD_ID = 8'h10,
+    parameter SPI_MASK_REV = 8'h14,
+    parameter SPI_PLL_BYPASS = 8'h18
+) (
+    input clk,
+    input resetn,
+
+    input [31:0] iomem_addr,
+    input iomem_valid,
+    input [3:0] iomem_wstrb,
+    input [31:0] iomem_wdata,
+    output reg [31:0] iomem_rdata,
+    output reg iomem_ready,
+
+    input [7:0] spi_ro_config, // (verify) wire input to the core not connected to HKSPI, what should it be connected to ? 
+    
+    input [4:0] spi_ro_pll_div, 
+    input [2:0] spi_ro_pll_sel,
+    input spi_ro_xtal_ena,
+    input spi_ro_reg_ena, 
+    
+    input [25:0] spi_ro_pll_trim,
+    input spi_ro_pll_dco_ena,  
+
+    input [11:0] spi_ro_mfgr_id,
+    input [7:0] spi_ro_prod_id, 
+    input [3:0] spi_ro_mask_rev, 
+    input pll_bypass
+); 
+    // Read-only Registers
+   
+    wire spi_cfg_sel;
+    wire spi_ena_sel;
+    wire pll_cfg_sel;
+    wire spi_mfgr_sel;
+    wire spi_prod_sel;
+    wire spi_maskrev_sel;
+    wire pll_bypass_sel;
+
+
+    assign spi_cfg_sel  = (iomem_addr[7:0] == SPI_CFG);
+    assign spi_ena_sel  = (iomem_addr[7:0] == SPI_ENA);
+    assign pll_cfg_sel  = (iomem_addr[7:0] == SPI_PLL_CFG);
+    assign spi_mfgr_sel = (iomem_addr[7:0] == SPI_MFGR_ID);
+    assign spi_prod_sel = (iomem_addr[7:0] == SPI_PROD_ID);
+    
+    assign spi_maskrev_sel = (iomem_addr[7:0] == SPI_MASK_REV);
+    assign pll_bypass_sel  = (iomem_addr[7:0] == SPI_PLL_BYPASS);
+
+    always @(posedge clk) begin
+        iomem_ready <= 0;
+        if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin
+            iomem_ready <= 1;
+            if (spi_cfg_sel) begin
+                iomem_rdata <= {24'd0, spi_ro_config};
+
+            end else if (spi_ena_sel) begin
+                iomem_rdata <= {
+                    22'd0,
+                    spi_ro_pll_div,
+                    spi_ro_pll_sel,
+                    spi_ro_xtal_ena,
+                    spi_ro_reg_ena
+                };
+
+            end else if (pll_cfg_sel) begin
+                iomem_rdata <= {
+                    5'd0,
+                    spi_ro_pll_trim,
+                    spi_ro_pll_dco_ena
+                };
+
+            end else if (spi_mfgr_sel) begin
+                iomem_rdata <= {20'd0, spi_ro_mfgr_id};
+
+            end else if (spi_prod_sel) begin
+                iomem_rdata <= {24'd0, spi_ro_prod_id};
+
+            end else if (spi_maskrev_sel) begin
+                iomem_rdata <= {28'd0, spi_ro_mask_rev};
+
+            end else if (pll_bypass_sel) begin
+                iomem_rdata <= {31'd0, pll_bypass};
+            end
+        end
+    end
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/spimemio.v b/verilog/rtl/spimemio.v
index f5cc5c0..053aa61 100644
--- a/verilog/rtl/spimemio.v
+++ b/verilog/rtl/spimemio.v
@@ -17,585 +17,700 @@
  *
  */
 
-module spimemio (
-	input clk, resetn,
+module spimemio_wb (
+    input wb_clk_i,
+    input wb_rst_i,
 
-	input valid,
-	output ready,
-	input [23:0] addr,
-	output reg [31:0] rdata,
+    input [31:0] wb_adr_i, 
+     input [31:0] wb_dat_i,
+    input [3:0] wb_sel_i,
+    input wb_we_i,
+    input wb_cyc_i,
 
-	output flash_csb,
-	output flash_clk,
+    input wb_flash_stb_i,
+    input wb_cfg_stb_i,
 
-	output flash_csb_oeb,
-	output flash_clk_oeb,
+    output wb_flash_ack_o,
+    output wb_cfg_ack_o,
 
-	output flash_io0_oeb,
-	output flash_io1_oeb,
-	output flash_io2_oeb,
-	output flash_io3_oeb,
+    output [31:0] wb_flash_dat_o,
+    output [31:0] wb_cfg_dat_o,
 
-	output flash_csb_ieb,
-	output flash_clk_ieb,
+    output flash_csb,
+    output flash_clk,
 
-	output flash_io0_ieb,
-	output flash_io1_ieb,
-	output flash_io2_ieb,
-	output flash_io3_ieb,
+    output flash_csb_oeb,
+    output flash_clk_oeb,
 
-	output flash_io0_do,
-	output flash_io1_do,
-	output flash_io2_do,
-	output flash_io3_do,
+    output flash_io0_oeb,
+    output flash_io1_oeb,
+    output flash_io2_oeb,
+    output flash_io3_oeb,
 
-	input  flash_io0_di,
-	input  flash_io1_di,
-	input  flash_io2_di,
-	input  flash_io3_di,
+    output flash_csb_ieb,
+    output flash_clk_ieb,
 
-	input   [3:0] cfgreg_we,
-	input  [31:0] cfgreg_di,
-	output [31:0] cfgreg_do
+    output flash_io0_ieb,
+    output flash_io1_ieb,
+    output flash_io2_ieb,
+    output flash_io3_ieb,
+
+    output flash_io0_do,
+    output flash_io1_do,
+    output flash_io2_do,
+    output flash_io3_do,
+
+    input  flash_io0_di,
+    input  flash_io1_di,
+    input  flash_io2_di,
+    input  flash_io3_di
+
 );
-	reg        xfer_resetn;
-	reg        din_valid;
-	wire       din_ready;
-	reg  [7:0] din_data;
-	reg  [3:0] din_tag;
-	reg        din_cont;
-	reg        din_qspi;
-	reg        din_ddr;
-	reg        din_rd;
+    wire spimem_ready;
+    wire [23:0] mem_addr;
+    wire [31:0] spimem_rdata;
+    wire [31:0] spimemio_cfgreg_do;
+    wire [3:0] cfgreg_we;
+    wire spimemio_cfgreg_sel;
+    wire valid;
+    wire resetn;
 
-	wire       dout_valid;
-	wire [7:0] dout_data;
-	wire [3:0] dout_tag;
+    assign resetn = ~wb_rst_i;
+    assign valid = wb_cyc_i && wb_flash_stb_i;    
+    assign wb_flash_ack_o = spimem_ready;
+    assign wb_cfg_ack_o = spimemio_cfgreg_sel;
 
-	reg [23:0] buffer;
+    assign mem_addr = wb_adr_i[23:0];
+    assign spimemio_cfgreg_sel = wb_cyc_i && wb_cfg_stb_i;
 
-	reg [23:0] rd_addr;
-	reg rd_valid;
-	reg rd_wait;
-	reg rd_inc;
+    assign cfgreg_we = spimemio_cfgreg_sel ? wb_sel_i & {4{wb_we_i}} : 4'b 0000;
+    assign wb_flash_dat_o = spimem_rdata;
+    assign wb_cfg_dat_o = spimemio_cfgreg_do;
 
-	assign ready = valid && (addr == rd_addr) && rd_valid;
-	wire jump = valid && !ready && (addr != rd_addr+4) && rd_valid;
+    spimemio spimemio (
+        .clk    (wb_clk_i),
+        .resetn (resetn),
+        .valid  (valid),
+        .ready  (spimem_ready),
+        .addr   (mem_addr),
+        .rdata  (spimem_rdata),
 
-	reg softreset;
+        .flash_csb    (flash_csb),
+        .flash_clk    (flash_clk),
 
-	reg       config_en;      // cfgreg[31]
-	reg       config_ddr;     // cfgreg[22]
-	reg       config_qspi;    // cfgreg[21]
-	reg       config_cont;    // cfgreg[20]
-	reg [3:0] config_dummy;   // cfgreg[19:16]
-	reg [3:0] config_oe;      // cfgreg[11:8]
-	reg       config_csb;     // cfgreg[5]
-	reg       config_clk;     // cfgref[4]
-	reg [3:0] config_do;      // cfgreg[3:0]
+        .flash_csb_oeb (flash_csb_oeb),
+        .flash_clk_oeb (flash_clk_oeb),
 
-	assign cfgreg_do[31] = config_en;
-	assign cfgreg_do[30:23] = 0;
-	assign cfgreg_do[22] = config_ddr;
-	assign cfgreg_do[21] = config_qspi;
-	assign cfgreg_do[20] = config_cont;
-	assign cfgreg_do[19:16] = config_dummy;
-	assign cfgreg_do[15:12] = 0;
-	assign cfgreg_do[11:8] = {~flash_io3_oeb, ~flash_io2_oeb, ~flash_io1_oeb, ~flash_io0_oeb};
-	assign cfgreg_do[7:6] = 0;
-	assign cfgreg_do[5] = flash_csb;
-	assign cfgreg_do[4] = flash_clk;
-	assign cfgreg_do[3:0] = {flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
+        .flash_io0_oeb (flash_io0_oeb),
+        .flash_io1_oeb (flash_io1_oeb),
+        .flash_io2_oeb (flash_io2_oeb),
+        .flash_io3_oeb (flash_io3_oeb),
 
-	always @(posedge clk) begin
-		softreset <= !config_en || cfgreg_we;
-		if (!resetn) begin
-			softreset <= 1;
-			config_en <= 1;
-			config_csb <= 0;
-			config_clk <= 0;
-			config_oe <= 0;
-			config_do <= 0;
-			config_ddr <= 0;
-			config_qspi <= 0;
-			config_cont <= 0;
-			config_dummy <= 8;
-		end else begin
-			if (cfgreg_we[0]) begin
-				config_csb <= cfgreg_di[5];
-				config_clk <= cfgreg_di[4];
-				config_do <= cfgreg_di[3:0];
-			end
-			if (cfgreg_we[1]) begin
-				config_oe <= cfgreg_di[11:8];
-			end
-			if (cfgreg_we[2]) begin
-				config_ddr <= cfgreg_di[22];
-				config_qspi <= cfgreg_di[21];
-				config_cont <= cfgreg_di[20];
-				config_dummy <= cfgreg_di[19:16];
-			end
-			if (cfgreg_we[3]) begin
-				config_en <= cfgreg_di[31];
-			end
-		end
-	end
+        .flash_csb_ieb (flash_csb_ieb),
+        .flash_clk_ieb (flash_clk_ieb),
 
-	wire xfer_csb;
-	wire xfer_clk;
+        .flash_io0_ieb (flash_io0_ieb),
+        .flash_io1_ieb (flash_io1_ieb),
+        .flash_io2_ieb (flash_io2_ieb),
+        .flash_io3_ieb (flash_io3_ieb),
 
-	wire xfer_io0_oe;
-	wire xfer_io1_oe;
-	wire xfer_io2_oe;
-	wire xfer_io3_oe;
+        .flash_io0_do (flash_io0_do),
+        .flash_io1_do (flash_io1_do),
+        .flash_io2_do (flash_io2_do),
+        .flash_io3_do (flash_io3_do),
 
-	wire xfer_io0_do;
-	wire xfer_io1_do;
-	wire xfer_io2_do;
-	wire xfer_io3_do;
+        .flash_io0_di (flash_io0_di),
+        .flash_io1_di (flash_io1_di),
+        .flash_io2_di (flash_io2_di),
+        .flash_io3_di (flash_io3_di),
 
-	reg xfer_io0_90;
-	reg xfer_io1_90;
-	reg xfer_io2_90;
-	reg xfer_io3_90;
+        .cfgreg_we(cfgreg_we),
+        .cfgreg_di(wb_dat_i),
+        .cfgreg_do(spimemio_cfgreg_do)
+    );
 
-	always @(negedge clk) begin
-		xfer_io0_90 <= xfer_io0_do;
-		xfer_io1_90 <= xfer_io1_do;
-		xfer_io2_90 <= xfer_io2_do;
-		xfer_io3_90 <= xfer_io3_do;
-	end
+endmodule
 
-	assign flash_csb = config_en ? xfer_csb : config_csb;
-	assign flash_clk = config_en ? xfer_clk : config_clk;
+module spimemio (
+    input clk, resetn,
 
-	assign flash_csb_oeb = ~resetn;
-	assign flash_clk_oeb = ~resetn;
+    input valid,
+    output ready,
+    input [23:0] addr,
+    output reg [31:0] rdata,
 
-	assign flash_io0_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io0_oe : ~config_oe[0]);
-	assign flash_io1_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io1_oe : ~config_oe[1]);
-	assign flash_io2_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io2_oe : ~config_oe[2]);
-	assign flash_io3_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io3_oe : ~config_oe[3]);
-	assign flash_csb_ieb = 1'b1;	/* Always disabled */
-	assign flash_clk_ieb = 1'b1;	/* Always disabled */
+    output flash_csb,
+    output flash_clk,
 
-	assign flash_io0_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io0_oe : config_oe[0]);
-	assign flash_io1_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io1_oe : config_oe[1]);
-	assign flash_io2_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io2_oe : config_oe[2]);
-	assign flash_io3_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io3_oe : config_oe[3]);
+    output flash_csb_oeb,
+    output flash_clk_oeb,
 
-	assign flash_io0_do = config_en ? (config_ddr ? xfer_io0_90 : xfer_io0_do) : config_do[0];
-	assign flash_io1_do = config_en ? (config_ddr ? xfer_io1_90 : xfer_io1_do) : config_do[1];
-	assign flash_io2_do = config_en ? (config_ddr ? xfer_io2_90 : xfer_io2_do) : config_do[2];
-	assign flash_io3_do = config_en ? (config_ddr ? xfer_io3_90 : xfer_io3_do) : config_do[3];
+    output flash_io0_oeb,
+    output flash_io1_oeb,
+    output flash_io2_oeb,
+    output flash_io3_oeb,
 
-	wire xfer_dspi = din_ddr && !din_qspi;
-	wire xfer_ddr = din_ddr && din_qspi;
+    output flash_csb_ieb,
+    output flash_clk_ieb,
 
-	spimemio_xfer xfer (
-		.clk          (clk         ),
-		.resetn       (resetn 	   ),
-		.xfer_resetn  (xfer_resetn ),
-		.din_valid    (din_valid   ),
-		.din_ready    (din_ready   ),
-		.din_data     (din_data    ),
-		.din_tag      (din_tag     ),
-		.din_cont     (din_cont    ),
-		.din_dspi     (xfer_dspi   ),
-		.din_qspi     (din_qspi    ),
-		.din_ddr      (xfer_ddr    ),
-		.din_rd       (din_rd      ),
-		.dout_valid   (dout_valid  ),
-		.dout_data    (dout_data   ),
-		.dout_tag     (dout_tag    ),
-		.flash_csb    (xfer_csb    ),
-		.flash_clk    (xfer_clk    ),
-		.flash_io0_oe (xfer_io0_oe ),
-		.flash_io1_oe (xfer_io1_oe ),
-		.flash_io2_oe (xfer_io2_oe ),
-		.flash_io3_oe (xfer_io3_oe ),
-		.flash_io0_do (xfer_io0_do ),
-		.flash_io1_do (xfer_io1_do ),
-		.flash_io2_do (xfer_io2_do ),
-		.flash_io3_do (xfer_io3_do ),
-		.flash_io0_di (flash_io0_di),
-		.flash_io1_di (flash_io1_di),
-		.flash_io2_di (flash_io2_di),
-		.flash_io3_di (flash_io3_di)
-	);
+    output flash_io0_ieb,
+    output flash_io1_ieb,
+    output flash_io2_ieb,
+    output flash_io3_ieb,
 
-	reg [3:0] state;
+    output flash_io0_do,
+    output flash_io1_do,
+    output flash_io2_do,
+    output flash_io3_do,
 
-	always @(posedge clk) begin
-		xfer_resetn <= 1;
-		din_valid <= 0;
+    input  flash_io0_di,
+    input  flash_io1_di,
+    input  flash_io2_di,
+    input  flash_io3_di,
 
-		if (!resetn || softreset) begin
-			state <= 0;
-			xfer_resetn <= 0;
-			rd_valid <= 0;
-			din_tag <= 0;
-			din_cont <= 0;
-			din_qspi <= 0;
-			din_ddr <= 0;
-			din_rd <= 0;
-		end else begin
-			if (dout_valid && dout_tag == 1) buffer[ 7: 0] <= dout_data;
-			if (dout_valid && dout_tag == 2) buffer[15: 8] <= dout_data;
-			if (dout_valid && dout_tag == 3) buffer[23:16] <= dout_data;
-			if (dout_valid && dout_tag == 4) begin
-				rdata <= {dout_data, buffer};
-				rd_addr <= rd_inc ? rd_addr + 4 : addr;
-				rd_valid <= 1;
-				rd_wait <= rd_inc;
-				rd_inc <= 1;
-			end
+    input   [3:0] cfgreg_we,
+    input  [31:0] cfgreg_di,
+    output [31:0] cfgreg_do
+);
+    reg        xfer_resetn;
+    reg        din_valid;
+    wire       din_ready;
+    reg  [7:0] din_data;
+    reg  [3:0] din_tag;
+    reg        din_cont;
+    reg        din_qspi;
+    reg        din_ddr;
+    reg        din_rd;
 
-			if (valid)
-				rd_wait <= 0;
+    wire       dout_valid;
+    wire [7:0] dout_data;
+    wire [3:0] dout_tag;
 
-			case (state)
-				0: begin
-					din_valid <= 1;
-					din_data <= 8'h ff;
-					din_tag <= 0;
-					if (din_ready) begin
-						din_valid <= 0;
-						state <= 1;
-					end
-				end
-				1: begin
-					if (dout_valid) begin
-						xfer_resetn <= 0;
-						state <= 2;
-					end
-				end
-				2: begin
-					din_valid <= 1;
-					din_data <= 8'h ab;
-					din_tag <= 0;
-					if (din_ready) begin
-						din_valid <= 0;
-						state <= 3;
-					end
-				end
-				3: begin
-					if (dout_valid) begin
-						xfer_resetn <= 0;
-						state <= 4;
-					end
-				end
-				4: begin
-					rd_inc <= 0;
-					din_valid <= 1;
-					din_tag <= 0;
-					case ({config_ddr, config_qspi})
-						2'b11: din_data <= 8'h ED;
-						2'b01: din_data <= 8'h EB;
-						2'b10: din_data <= 8'h BB;
-						2'b00: din_data <= 8'h 03;
-					endcase
-					if (din_ready) begin
-						din_valid <= 0;
-						state <= 5;
-					end
-				end
-				5: begin
-					if (valid && !ready) begin
-						din_valid <= 1;
-						din_tag <= 0;
-						din_data <= addr[23:16];
-						din_qspi <= config_qspi;
-						din_ddr <= config_ddr;
-						if (din_ready) begin
-							din_valid <= 0;
-							state <= 6;
-						end
-					end
-				end
-				6: begin
-					din_valid <= 1;
-					din_tag <= 0;
-					din_data <= addr[15:8];
-					if (din_ready) begin
-						din_valid <= 0;
-						state <= 7;
-					end
-				end
-				7: begin
-					din_valid <= 1;
-					din_tag <= 0;
-					din_data <= addr[7:0];
-					if (din_ready) begin
-						din_valid <= 0;
-						din_data <= 0;
-						state <= config_qspi || config_ddr ? 8 : 9;
-					end
-				end
-				8: begin
-					din_valid <= 1;
-					din_tag <= 0;
-					din_data <= config_cont ? 8'h A5 : 8'h FF;
-					if (din_ready) begin
-						din_rd <= 1;
-						din_data <= config_dummy;
-						din_valid <= 0;
-						state <= 9;
-					end
-				end
-				9: begin
-					din_valid <= 1;
-					din_tag <= 1;
-					if (din_ready) begin
-						din_valid <= 0;
-						state <= 10;
-					end
-				end
-				10: begin
-					din_valid <= 1;
-					din_data <= 8'h 00;
-					din_tag <= 2;
-					if (din_ready) begin
-						din_valid <= 0;
-						state <= 11;
-					end
-				end
-				11: begin
-					din_valid <= 1;
-					din_tag <= 3;
-					if (din_ready) begin
-						din_valid <= 0;
-						state <= 12;
-					end
-				end
-				12: begin
-					if (!rd_wait || valid) begin
-						din_valid <= 1;
-						din_tag <= 4;
-						if (din_ready) begin
-							din_valid <= 0;
-							state <= 9;
-						end
-					end
-				end
-			endcase
+    reg [23:0] buffer;
 
-			if (jump) begin
-				rd_inc <= 0;
-				rd_valid <= 0;
-				xfer_resetn <= 0;
-				if (config_cont) begin
-					state <= 5;
-				end else begin
-					state <= 4;
-					din_qspi <= 0;
-					din_ddr <= 0;
-				end
-				din_rd <= 0;
-			end
-		end
-	end
+    reg [23:0] rd_addr;
+    reg rd_valid;
+    reg rd_wait;
+    reg rd_inc;
+
+    assign ready = valid && (addr == rd_addr) && rd_valid;
+    wire jump = valid && !ready && (addr != rd_addr+4) && rd_valid;
+
+    reg softreset;
+
+    reg       config_en;      // cfgreg[31]
+    reg       config_ddr;     // cfgreg[22]
+    reg       config_qspi;    // cfgreg[21]
+    reg       config_cont;    // cfgreg[20]
+    reg [3:0] config_dummy;   // cfgreg[19:16]
+    reg [3:0] config_oe;      // cfgreg[11:8]
+    reg       config_csb;     // cfgreg[5]
+    reg       config_clk;     // cfgref[4]
+    reg [3:0] config_do;      // cfgreg[3:0]
+
+    assign cfgreg_do[31] = config_en;
+    assign cfgreg_do[30:23] = 0;
+    assign cfgreg_do[22] = config_ddr;
+    assign cfgreg_do[21] = config_qspi;
+    assign cfgreg_do[20] = config_cont;
+    assign cfgreg_do[19:16] = config_dummy;
+    assign cfgreg_do[15:12] = 0;
+    assign cfgreg_do[11:8] = {~flash_io3_oeb, ~flash_io2_oeb, ~flash_io1_oeb, ~flash_io0_oeb};
+    assign cfgreg_do[7:6] = 0;
+    assign cfgreg_do[5] = flash_csb;
+    assign cfgreg_do[4] = flash_clk;
+    assign cfgreg_do[3:0] = {flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
+
+    always @(posedge clk) begin
+        softreset <= !config_en || cfgreg_we;
+        if (!resetn) begin
+            softreset <= 1;
+            config_en <= 1;
+            config_csb <= 0;
+            config_clk <= 0;
+            config_oe <= 0;
+            config_do <= 0;
+            config_ddr <= 0;
+            config_qspi <= 0;
+            config_cont <= 0;
+            config_dummy <= 8;
+        end else begin
+            if (cfgreg_we[0]) begin
+                config_csb <= cfgreg_di[5];
+                config_clk <= cfgreg_di[4];
+                config_do <= cfgreg_di[3:0];
+            end
+            if (cfgreg_we[1]) begin
+                config_oe <= cfgreg_di[11:8];
+            end
+            if (cfgreg_we[2]) begin
+                config_ddr <= cfgreg_di[22];
+                config_qspi <= cfgreg_di[21];
+                config_cont <= cfgreg_di[20];
+                config_dummy <= cfgreg_di[19:16];
+            end
+            if (cfgreg_we[3]) begin
+                config_en <= cfgreg_di[31];
+            end
+        end
+    end
+
+    wire xfer_csb;
+    wire xfer_clk;
+
+    wire xfer_io0_oe;
+    wire xfer_io1_oe;
+    wire xfer_io2_oe;
+    wire xfer_io3_oe;
+
+    wire xfer_io0_do;
+    wire xfer_io1_do;
+    wire xfer_io2_do;
+    wire xfer_io3_do;
+
+    reg xfer_io0_90;
+    reg xfer_io1_90;
+    reg xfer_io2_90;
+    reg xfer_io3_90;
+
+    always @(negedge clk) begin
+        xfer_io0_90 <= xfer_io0_do;
+        xfer_io1_90 <= xfer_io1_do;
+        xfer_io2_90 <= xfer_io2_do;
+        xfer_io3_90 <= xfer_io3_do;
+    end
+
+    assign flash_csb = config_en ? xfer_csb : config_csb;
+    assign flash_clk = config_en ? xfer_clk : config_clk;
+
+    assign flash_csb_oeb = ~resetn;
+    assign flash_clk_oeb = ~resetn;
+
+    assign flash_io0_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io0_oe : ~config_oe[0]);
+    assign flash_io1_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io1_oe : ~config_oe[1]);
+    assign flash_io2_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io2_oe : ~config_oe[2]);
+    assign flash_io3_oeb = ~resetn ? 1'b1 : (config_en ? ~xfer_io3_oe : ~config_oe[3]);
+    assign flash_csb_ieb = 1'b1;	/* Always disabled */
+    assign flash_clk_ieb = 1'b1;	/* Always disabled */
+
+    assign flash_io0_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io0_oe : config_oe[0]);
+    assign flash_io1_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io1_oe : config_oe[1]);
+    assign flash_io2_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io2_oe : config_oe[2]);
+    assign flash_io3_ieb = ~resetn ? 1'b1 : (config_en ? xfer_io3_oe : config_oe[3]);
+
+    assign flash_io0_do = config_en ? (config_ddr ? xfer_io0_90 : xfer_io0_do) : config_do[0];
+    assign flash_io1_do = config_en ? (config_ddr ? xfer_io1_90 : xfer_io1_do) : config_do[1];
+    assign flash_io2_do = config_en ? (config_ddr ? xfer_io2_90 : xfer_io2_do) : config_do[2];
+    assign flash_io3_do = config_en ? (config_ddr ? xfer_io3_90 : xfer_io3_do) : config_do[3];
+
+    wire xfer_dspi = din_ddr && !din_qspi;
+    wire xfer_ddr = din_ddr && din_qspi;
+
+    spimemio_xfer xfer (
+        .clk          (clk         ),
+        .resetn       (resetn 	   ),
+        .xfer_resetn  (xfer_resetn ),
+        .din_valid    (din_valid   ),
+        .din_ready    (din_ready   ),
+        .din_data     (din_data    ),
+        .din_tag      (din_tag     ),
+        .din_cont     (din_cont    ),
+        .din_dspi     (xfer_dspi   ),
+        .din_qspi     (din_qspi    ),
+        .din_ddr      (xfer_ddr    ),
+        .din_rd       (din_rd      ),
+        .dout_valid   (dout_valid  ),
+        .dout_data    (dout_data   ),
+        .dout_tag     (dout_tag    ),
+        .flash_csb    (xfer_csb    ),
+        .flash_clk    (xfer_clk    ),
+        .flash_io0_oe (xfer_io0_oe ),
+        .flash_io1_oe (xfer_io1_oe ),
+        .flash_io2_oe (xfer_io2_oe ),
+        .flash_io3_oe (xfer_io3_oe ),
+        .flash_io0_do (xfer_io0_do ),
+        .flash_io1_do (xfer_io1_do ),
+        .flash_io2_do (xfer_io2_do ),
+        .flash_io3_do (xfer_io3_do ),
+        .flash_io0_di (flash_io0_di),
+        .flash_io1_di (flash_io1_di),
+        .flash_io2_di (flash_io2_di),
+        .flash_io3_di (flash_io3_di)
+    );
+
+    reg [3:0] state;
+
+    always @(posedge clk) begin
+        xfer_resetn <= 1;
+        din_valid <= 0;
+
+        if (!resetn || softreset) begin
+            state <= 0;
+            xfer_resetn <= 0;
+            rd_valid <= 0;
+            din_tag <= 0;
+            din_cont <= 0;
+            din_qspi <= 0;
+            din_ddr <= 0;
+            din_rd <= 0;
+        end else begin
+            if (dout_valid && dout_tag == 1) buffer[ 7: 0] <= dout_data;
+            if (dout_valid && dout_tag == 2) buffer[15: 8] <= dout_data;
+            if (dout_valid && dout_tag == 3) buffer[23:16] <= dout_data;
+            if (dout_valid && dout_tag == 4) begin
+                rdata <= {dout_data, buffer};
+                rd_addr <= rd_inc ? rd_addr + 4 : addr;
+                rd_valid <= 1;
+                rd_wait <= rd_inc;
+                rd_inc <= 1;
+            end
+
+            if (valid)
+                rd_wait <= 0;
+
+            case (state)
+                0: begin
+                    din_valid <= 1;
+                    din_data <= 8'h ff;
+                    din_tag <= 0;
+                    if (din_ready) begin
+                        din_valid <= 0;
+                        state <= 1;
+                    end
+                end
+                1: begin
+                    if (dout_valid) begin
+                        xfer_resetn <= 0;
+                        state <= 2;
+                    end
+                end
+                2: begin
+                    din_valid <= 1;
+                    din_data <= 8'h ab;
+                    din_tag <= 0;
+                    if (din_ready) begin
+                        din_valid <= 0;
+                        state <= 3;
+                    end
+                end
+                3: begin
+                    if (dout_valid) begin
+                        xfer_resetn <= 0;
+                        state <= 4;
+                    end
+                end
+                4: begin
+                    rd_inc <= 0;
+                    din_valid <= 1;
+                    din_tag <= 0;
+                    case ({config_ddr, config_qspi})
+                        2'b11: din_data <= 8'h ED;
+                        2'b01: din_data <= 8'h EB;
+                        2'b10: din_data <= 8'h BB;
+                        2'b00: din_data <= 8'h 03;
+                    endcase
+                    if (din_ready) begin
+                        din_valid <= 0;
+                        state <= 5;
+                    end
+                end
+                5: begin
+                    if (valid && !ready) begin
+                        din_valid <= 1;
+                        din_tag <= 0;
+                        din_data <= addr[23:16];
+                        din_qspi <= config_qspi;
+                        din_ddr <= config_ddr;
+                        if (din_ready) begin
+                            din_valid <= 0;
+                            state <= 6;
+                        end
+                    end
+                end
+                6: begin
+                    din_valid <= 1;
+                    din_tag <= 0;
+                    din_data <= addr[15:8];
+                    if (din_ready) begin
+                        din_valid <= 0;
+                        state <= 7;
+                    end
+                end
+                7: begin
+                    din_valid <= 1;
+                    din_tag <= 0;
+                    din_data <= addr[7:0];
+                    if (din_ready) begin
+                        din_valid <= 0;
+                        din_data <= 0;
+                        state <= config_qspi || config_ddr ? 8 : 9;
+                    end
+                end
+                8: begin
+                    din_valid <= 1;
+                    din_tag <= 0;
+                    din_data <= config_cont ? 8'h A5 : 8'h FF;
+                    if (din_ready) begin
+                        din_rd <= 1;
+                        din_data <= config_dummy;
+                        din_valid <= 0;
+                        state <= 9;
+                    end
+                end
+                9: begin
+                    din_valid <= 1;
+                    din_tag <= 1;
+                    if (din_ready) begin
+                        din_valid <= 0;
+                        state <= 10;
+                    end
+                end
+                10: begin
+                    din_valid <= 1;
+                    din_data <= 8'h 00;
+                    din_tag <= 2;
+                    if (din_ready) begin
+                        din_valid <= 0;
+                        state <= 11;
+                    end
+                end
+                11: begin
+                    din_valid <= 1;
+                    din_tag <= 3;
+                    if (din_ready) begin
+                        din_valid <= 0;
+                        state <= 12;
+                    end
+                end
+                12: begin
+                    if (!rd_wait || valid) begin
+                        din_valid <= 1;
+                        din_tag <= 4;
+                        if (din_ready) begin
+                            din_valid <= 0;
+                            state <= 9;
+                        end
+                    end
+                end
+            endcase
+
+            if (jump) begin
+                rd_inc <= 0;
+                rd_valid <= 0;
+                xfer_resetn <= 0;
+                if (config_cont) begin
+                    state <= 5;
+                end else begin
+                    state <= 4;
+                    din_qspi <= 0;
+                    din_ddr <= 0;
+                end
+                din_rd <= 0;
+            end
+        end
+    end
 endmodule
 
 module spimemio_xfer (
-	input clk, resetn, xfer_resetn,
+    input clk, resetn, xfer_resetn,
 
-	input            din_valid,
-	output           din_ready,
-	input      [7:0] din_data,
-	input      [3:0] din_tag,
-	input            din_cont,
-	input            din_dspi,
-	input            din_qspi,
-	input            din_ddr,
-	input            din_rd,
+    input            din_valid,
+    output           din_ready,
+    input      [7:0] din_data,
+    input      [3:0] din_tag,
+    input            din_cont,
+    input            din_dspi,
+    input            din_qspi,
+    input            din_ddr,
+    input            din_rd,
 
-	output           dout_valid,
-	output     [7:0] dout_data,
-	output     [3:0] dout_tag,
+    output           dout_valid,
+    output     [7:0] dout_data,
+    output     [3:0] dout_tag,
 
-	output reg flash_csb,
-	output reg flash_clk,
+    output reg flash_csb,
+    output reg flash_clk,
 
-	output reg flash_io0_oe,
-	output reg flash_io1_oe,
-	output reg flash_io2_oe,
-	output reg flash_io3_oe,
+    output reg flash_io0_oe,
+    output reg flash_io1_oe,
+    output reg flash_io2_oe,
+    output reg flash_io3_oe,
 
-	output reg flash_io0_do,
-	output reg flash_io1_do,
-	output reg flash_io2_do,
-	output reg flash_io3_do,
+    output reg flash_io0_do,
+    output reg flash_io1_do,
+    output reg flash_io2_do,
+    output reg flash_io3_do,
 
-	input      flash_io0_di,
-	input      flash_io1_di,
-	input      flash_io2_di,
-	input      flash_io3_di
+    input      flash_io0_di,
+    input      flash_io1_di,
+    input      flash_io2_di,
+    input      flash_io3_di
 );
-	reg [7:0] obuffer;
-	reg [7:0] ibuffer;
+    reg [7:0] obuffer;
+    reg [7:0] ibuffer;
 
-	reg [3:0] count;
-	reg [3:0] dummy_count;
+    reg [3:0] count;
+    reg [3:0] dummy_count;
 
-	reg xfer_cont;
-	reg xfer_dspi;
-	reg xfer_qspi;
-	reg xfer_ddr;
-	reg xfer_ddr_q;
-	reg xfer_rd;
-	reg [3:0] xfer_tag;
-	reg [3:0] xfer_tag_q;
+    reg xfer_cont;
+    reg xfer_dspi;
+    reg xfer_qspi;
+    reg xfer_ddr;
+    reg xfer_ddr_q;
+    reg xfer_rd;
+    reg [3:0] xfer_tag;
+    reg [3:0] xfer_tag_q;
 
-	reg [7:0] next_obuffer;
-	reg [7:0] next_ibuffer;
-	reg [3:0] next_count;
+    reg [7:0] next_obuffer;
+    reg [7:0] next_ibuffer;
+    reg [3:0] next_count;
 
-	reg fetch;
-	reg next_fetch;
-	reg last_fetch;
+    reg fetch;
+    reg next_fetch;
+    reg last_fetch;
 
-	always @(posedge clk) begin
-		xfer_ddr_q <= xfer_ddr;
-		xfer_tag_q <= xfer_tag;
-	end
+    always @(posedge clk) begin
+        xfer_ddr_q <= xfer_ddr;
+        xfer_tag_q <= xfer_tag;
+    end
 
-	assign din_ready = din_valid && xfer_resetn && next_fetch;
+    assign din_ready = din_valid && xfer_resetn && next_fetch;
 
-	assign dout_valid = (xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch) && xfer_resetn;
-	assign dout_data = ibuffer;
-	assign dout_tag = xfer_tag_q;
+    assign dout_valid = (xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch) && xfer_resetn;
+    assign dout_data = ibuffer;
+    assign dout_tag = xfer_tag_q;
 
-	always @* begin
-		flash_io0_oe = 0;
-		flash_io1_oe = 0;
-		flash_io2_oe = 0;
-		flash_io3_oe = 0;
+    always @* begin
+        flash_io0_oe = 0;
+        flash_io1_oe = 0;
+        flash_io2_oe = 0;
+        flash_io3_oe = 0;
 
-		flash_io0_do = 0;
-		flash_io1_do = 0;
-		flash_io2_do = 0;
-		flash_io3_do = 0;
+        flash_io0_do = 0;
+        flash_io1_do = 0;
+        flash_io2_do = 0;
+        flash_io3_do = 0;
 
-		next_obuffer = obuffer;
-		next_ibuffer = ibuffer;
-		next_count = count;
-		next_fetch = 0;
+        next_obuffer = obuffer;
+        next_ibuffer = ibuffer;
+        next_count = count;
+        next_fetch = 0;
 
-		if (dummy_count == 0) begin
-			casez ({xfer_ddr, xfer_qspi, xfer_dspi})
-				3'b 000: begin
-					flash_io0_oe = 1;
-					flash_io0_do = obuffer[7];
+        if (dummy_count == 0) begin
+            casez ({xfer_ddr, xfer_qspi, xfer_dspi})
+                3'b 000: begin
+                    flash_io0_oe = 1;
+                    flash_io0_do = obuffer[7];
 
-					if (flash_clk) begin
-						next_obuffer = {obuffer[6:0], 1'b 0};
-						next_count = count - |count;
-					end else begin
-						next_ibuffer = {ibuffer[6:0], flash_io1_di};
-					end
+                    if (flash_clk) begin
+                        next_obuffer = {obuffer[6:0], 1'b 0};
+                        next_count = count - |count;
+                    end else begin
+                        next_ibuffer = {ibuffer[6:0], flash_io1_di};
+                    end
 
-					next_fetch = (next_count == 0);
-				end
-				3'b 01?: begin
-					flash_io0_oe = !xfer_rd;
-					flash_io1_oe = !xfer_rd;
-					flash_io2_oe = !xfer_rd;
-					flash_io3_oe = !xfer_rd;
+                    next_fetch = (next_count == 0);
+                end
+                3'b 01?: begin
+                    flash_io0_oe = !xfer_rd;
+                    flash_io1_oe = !xfer_rd;
+                    flash_io2_oe = !xfer_rd;
+                    flash_io3_oe = !xfer_rd;
 
-					flash_io0_do = obuffer[4];
-					flash_io1_do = obuffer[5];
-					flash_io2_do = obuffer[6];
-					flash_io3_do = obuffer[7];
+                    flash_io0_do = obuffer[4];
+                    flash_io1_do = obuffer[5];
+                    flash_io2_do = obuffer[6];
+                    flash_io3_do = obuffer[7];
 
-					if (flash_clk) begin
-						next_obuffer = {obuffer[3:0], 4'b 0000};
-						next_count = count - {|count, 2'b00};
-					end else begin
-						next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
-					end
+                    if (flash_clk) begin
+                        next_obuffer = {obuffer[3:0], 4'b 0000};
+                        next_count = count - {|count, 2'b00};
+                    end else begin
+                        next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
+                    end
 
-					next_fetch = (next_count == 0);
-				end
-				3'b 11?: begin
-					flash_io0_oe = !xfer_rd;
-					flash_io1_oe = !xfer_rd;
-					flash_io2_oe = !xfer_rd;
-					flash_io3_oe = !xfer_rd;
+                    next_fetch = (next_count == 0);
+                end
+                3'b 11?: begin
+                    flash_io0_oe = !xfer_rd;
+                    flash_io1_oe = !xfer_rd;
+                    flash_io2_oe = !xfer_rd;
+                    flash_io3_oe = !xfer_rd;
 
-					flash_io0_do = obuffer[4];
-					flash_io1_do = obuffer[5];
-					flash_io2_do = obuffer[6];
-					flash_io3_do = obuffer[7];
+                    flash_io0_do = obuffer[4];
+                    flash_io1_do = obuffer[5];
+                    flash_io2_do = obuffer[6];
+                    flash_io3_do = obuffer[7];
 
-					next_obuffer = {obuffer[3:0], 4'b 0000};
-					next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
-					next_count = count - {|count, 2'b00};
+                    next_obuffer = {obuffer[3:0], 4'b 0000};
+                    next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
+                    next_count = count - {|count, 2'b00};
 
-					next_fetch = (next_count == 0);
-				end
-				3'b ??1: begin
-					flash_io0_oe = !xfer_rd;
-					flash_io1_oe = !xfer_rd;
+                    next_fetch = (next_count == 0);
+                end
+                3'b ??1: begin
+                    flash_io0_oe = !xfer_rd;
+                    flash_io1_oe = !xfer_rd;
 
-					flash_io0_do = obuffer[6];
-					flash_io1_do = obuffer[7];
+                    flash_io0_do = obuffer[6];
+                    flash_io1_do = obuffer[7];
 
-					if (flash_clk) begin
-						next_obuffer = {obuffer[5:0], 2'b 00};
-						next_count = count - {|count, 1'b0};
-					end else begin
-						next_ibuffer = {ibuffer[5:0], flash_io1_di, flash_io0_di};
-					end
+                    if (flash_clk) begin
+                        next_obuffer = {obuffer[5:0], 2'b 00};
+                        next_count = count - {|count, 1'b0};
+                    end else begin
+                        next_ibuffer = {ibuffer[5:0], flash_io1_di, flash_io0_di};
+                    end
 
-					next_fetch = (next_count == 0);
-				end
-			endcase
-		end
-	end
+                    next_fetch = (next_count == 0);
+                end
+            endcase
+        end
+    end
 
-	always @(posedge clk) begin
-		if (!resetn || !xfer_resetn) begin
-			fetch <= 1;
-			last_fetch <= 1;
-			flash_csb <= 1;
-			flash_clk <= 0;
-			count <= 0;
-			dummy_count <= 0;
-			xfer_tag <= 0;
-			xfer_cont <= 0;
-			xfer_dspi <= 0;
-			xfer_qspi <= 0;
-			xfer_ddr <= 0;
-			xfer_rd <= 0;
-		end else begin
-			fetch <= next_fetch;
-			last_fetch <= xfer_ddr ? fetch : 1;
-			if (dummy_count) begin
-				flash_clk <= !flash_clk && !flash_csb;
-				dummy_count <= dummy_count - flash_clk;
-			end else
-			if (count) begin
-				flash_clk <= !flash_clk && !flash_csb;
-				obuffer <= next_obuffer;
-				ibuffer <= next_ibuffer;
-				count <= next_count;
-			end
-			if (din_valid && din_ready) begin
-				flash_csb <= 0;
-				flash_clk <= 0;
+    always @(posedge clk) begin
+        if (!resetn || !xfer_resetn) begin
+            fetch <= 1;
+            last_fetch <= 1;
+            flash_csb <= 1;
+            flash_clk <= 0;
+            count <= 0;
+            dummy_count <= 0;
+            xfer_tag <= 0;
+            xfer_cont <= 0;
+            xfer_dspi <= 0;
+            xfer_qspi <= 0;
+            xfer_ddr <= 0;
+            xfer_rd <= 0;
+        end else begin
+            fetch <= next_fetch;
+            last_fetch <= xfer_ddr ? fetch : 1;
+            if (dummy_count) begin
+                flash_clk <= !flash_clk && !flash_csb;
+                dummy_count <= dummy_count - flash_clk;
+            end else
+            if (count) begin
+                flash_clk <= !flash_clk && !flash_csb;
+                obuffer <= next_obuffer;
+                ibuffer <= next_ibuffer;
+                count <= next_count;
+            end
+            if (din_valid && din_ready) begin
+                flash_csb <= 0;
+                flash_clk <= 0;
 
-				count <= 8;
-				dummy_count <= din_rd ? din_data : 0;
-				obuffer <= din_data;
+                count <= 8;
+                dummy_count <= din_rd ? din_data : 0;
+                obuffer <= din_data;
 
-				xfer_tag <= din_tag;
-				xfer_cont <= din_cont;
-				xfer_dspi <= din_dspi;
-				xfer_qspi <= din_qspi;
-				xfer_ddr <= din_ddr;
-				xfer_rd <= din_rd;
-			end
-		end
-	end
+                xfer_tag <= din_tag;
+                xfer_cont <= din_cont;
+                xfer_dspi <= din_dspi;
+                xfer_qspi <= din_qspi;
+                xfer_ddr <= din_ddr;
+                xfer_rd <= din_rd;
+            end
+        end
+    end
 endmodule
+
diff --git a/verilog/rtl/sram_1rw1r_32_256_8_sky130.v b/verilog/rtl/sram_1rw1r_32_256_8_sky130.v
new file mode 100644
index 0000000..2dd1c62
--- /dev/null
+++ b/verilog/rtl/sram_1rw1r_32_256_8_sky130.v
@@ -0,0 +1,108 @@
+// OpenRAM SRAM model
+// Words: 256
+// Word size: 32
+// Write size: 8
+
+module sram_1rw1r_32_256_8_sky130(
+// Port 0: RW
+    clk0,csb0,web0,wmask0,addr0,din0,dout0,
+// Port 1: R
+    clk1,csb1,addr1,dout1
+  );
+
+  parameter NUM_WMASKS = 4 ;
+  parameter DATA_WIDTH = 32 ;
+  parameter ADDR_WIDTH = 8 ;
+  parameter RAM_DEPTH = 1 << ADDR_WIDTH;
+  // FIXME: This delay is arbitrary.
+  parameter DELAY = 1 ;
+
+  input  clk0; // clock
+  input   csb0; // active low chip select
+  input  web0; // active low write control
+  input [NUM_WMASKS-1:0]   wmask0; // write mask
+  input [ADDR_WIDTH-1:0]  addr0;
+  input [DATA_WIDTH-1:0]  din0;
+  output [DATA_WIDTH-1:0] dout0;
+  input  clk1; // clock
+  input   csb1; // active low chip select
+  input [ADDR_WIDTH-1:0]  addr1;
+  output [DATA_WIDTH-1:0] dout1;
+
+  reg  csb0_reg;
+  reg  web0_reg;
+  reg [NUM_WMASKS-1:0]   wmask0_reg;
+  reg [ADDR_WIDTH-1:0]  addr0_reg;
+  reg [DATA_WIDTH-1:0]  din0_reg;
+  reg [DATA_WIDTH-1:0]  dout0;
+
+  // All inputs are registers
+  always @(posedge clk0)
+  begin
+    csb0_reg = csb0;
+    web0_reg = web0;
+    wmask0_reg = wmask0;
+    addr0_reg = addr0;
+    din0_reg = din0;
+    dout0 = 32'bx;
+`ifdef DBG
+    if ( !csb0_reg && web0_reg ) 
+      $display($time," Reading %m addr0=%b dout0=%b",addr0_reg,mem[addr0_reg]);
+    if ( !csb0_reg && !web0_reg )
+      $display($time," Writing %m addr0=%b din0=%b wmask0=%b",addr0_reg,din0_reg,wmask0_reg);
+`endif 
+   end
+
+  reg  csb1_reg;
+  reg [ADDR_WIDTH-1:0]  addr1_reg;
+  reg [DATA_WIDTH-1:0]  dout1;
+
+  // All inputs are registers
+  always @(posedge clk1)
+  begin
+    csb1_reg = csb1;
+    addr1_reg = addr1;
+`ifdef DBG
+    if (!csb0 && !web0 && !csb1 && (addr0 == addr1))
+         $display($time," WARNING: Writing and reading addr0=%b and addr1=%b simultaneously!",addr0,addr1);
+    dout1 = 32'bx;
+    if ( !csb1_reg ) 
+      $display($time," Reading %m addr1=%b dout1=%b",addr1_reg,mem[addr1_reg]);
+`endif  
+   end
+
+reg [DATA_WIDTH-1:0]    mem [0:RAM_DEPTH-1];
+
+  // Memory Write Block Port 0
+  // Write Operation : When web0 = 0, csb0 = 0
+  always @ (negedge clk0)
+  begin : MEM_WRITE0
+    if ( !csb0_reg && !web0_reg ) begin
+        if (wmask0_reg[0])
+                mem[addr0_reg][7:0] = din0_reg[7:0];
+        if (wmask0_reg[1])
+                mem[addr0_reg][15:8] = din0_reg[15:8];
+        if (wmask0_reg[2])
+                mem[addr0_reg][23:16] = din0_reg[23:16];
+        if (wmask0_reg[3])
+                mem[addr0_reg][31:24] = din0_reg[31:24];
+    end
+  end
+
+  // Memory Read Block Port 0
+  // Read Operation : When web0 = 1, csb0 = 0
+  always @ (negedge clk0)
+  begin : MEM_READ0
+    if (!csb0_reg && web0_reg)
+       dout0 <= #(DELAY) mem[addr0_reg];
+  end
+
+  // Memory Read Block Port 1
+  // Read Operation : When web1 = 1, csb1 = 0
+  always @ (negedge clk1)
+  begin : MEM_READ1
+    if (!csb1_reg)
+       dout1 <= #(DELAY) mem[addr1_reg];
+  end
+
+endmodule
diff --git a/verilog/rtl/striVe_clkrst.v b/verilog/rtl/striVe_clkrst.v
index 6310274..ff42831 100644
--- a/verilog/rtl/striVe_clkrst.v
+++ b/verilog/rtl/striVe_clkrst.v
@@ -1,31 +1,35 @@
 module striVe_clkrst(
-	input ext_clk_sel,
-	input ext_clk,
-	input pll_clk,
-	input reset, 
-	input ext_reset,
-	output clk,
-	output resetn
+`ifdef LVS
+    input vdd1v8,
+    input vss,
+`endif
+    input ext_clk_sel,
+    input ext_clk,
+    input pll_clk,
+    input reset, 
+    input ext_reset,
+    output clk,
+    output resetn
 );
 
-	// Clock assignment (to do:  make this glitch-free)
-	assign clk = (ext_clk_sel == 1'b1) ? ext_clk : pll_clk;
+    // Clock assignment (to do:  make this glitch-free)
+    assign clk = (ext_clk_sel == 1'b1) ? ext_clk : pll_clk;
 
-	// Reset assignment.  "reset" comes from POR, while "ext_reset"
-	// comes from standalone SPI (and is normally zero unless
-	// activated from the SPI).
+    // Reset assignment.  "reset" comes from POR, while "ext_reset"
+    // comes from standalone SPI (and is normally zero unless
+    // activated from the SPI).
 
-	// Staged-delay reset
-	reg [2:0] reset_delay;
+    // Staged-delay reset
+    reg [2:0] reset_delay;
 
-	always @(posedge clk or posedge reset) begin
-	    if (reset == 1'b1) begin
-		reset_delay <= 3'b111;
-	    end else begin
-		reset_delay <= {1'b0, reset_delay[2:1]};
-	    end
-	end
+    always @(posedge clk or posedge reset) begin
+        if (reset == 1'b1) begin
+        reset_delay <= 3'b111;
+        end else begin
+        reset_delay <= {1'b0, reset_delay[2:1]};
+        end
+    end
 
-	assign resetn = ~(reset_delay[0] | ext_reset);
+    assign resetn = ~(reset_delay[0] | ext_reset);
 
 endmodule
diff --git a/verilog/rtl/striVe_soc.v b/verilog/rtl/striVe_soc.v
deleted file mode 100644
index 1899a99..0000000
--- a/verilog/rtl/striVe_soc.v
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- *  PicoSoC - A simple example SoC using PicoRV32
- *
- *  Copyright (C) 2017  Clifford Wolf <clifford@clifford.at>
- *
- *  Permission to use, copy, modify, and/or distribute this software for any
- *  purpose with or without fee is hereby granted, provided that the above
- *  copyright notice and this permission notice appear in all copies.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- *  Revision 1,  July 2019:  Added signals to drive flash_clk and flash_csb
- *  output enable (inverted), tied to reset so that the flash is completely
- *  isolated from the processor when the processor is in reset.
- *
- *  Also: Made ram_wenb a 4-bit bus so that the memory access can be made
- *  byte-wide for byte-wide instructions.
- */
-
-`ifdef PICORV32_V
-`error "openstriVe_soc.v must be read before picorv32.v!"
-`endif
-
-/* Note:  Synthesize register memory from flops */
-/* Inefficient, but not terribly so */
-
-/* Also note:  To avoid having a hard macro in the place & route	 */
-/* (method not finished yet in qflow), SRAM pins are brought out to	 */
-/* the openstriVe_soc I/O so that openstriVe_soc.v itself is fully synthesizable */
-/* and routable with qflow as-is.					*/
-
-`define PICORV32_REGS openstriVe_soc_regs
-
-module striVe_soc (
-`ifdef LVS
-	inout vdd1v8,	    /* 1.8V domain */
-	inout vss,
-`endif
-	input pll_clk,
-	input ext_clk,
-	input ext_clk_sel,
-	/*
-	input ext_reset,
-	input reset,
-	*/
-
-	input clk,
-	input resetn,
-	// Main SRAM, including clk and resetn above
-	// (Not used:  RAM is synthesized in this version)
-	/*
-	output [3:0] ram_wenb,
-	output [9:0] ram_addr,
-	output [31:0] ram_wdata,
-	input  [31:0] ram_rdata,
-	*/
-
-	// Memory mapped I/O signals
-	output [15:0] gpio_out_pad,		// Connect to out on gpio pad
-	input  [15:0] gpio_in_pad,		// Connect to in on gpio pad
-	output [15:0] gpio_mode0_pad,		// Connect to dm[0] on gpio pad
-	output [15:0] gpio_mode1_pad,		// Connect to dm[2] on gpio pad
-	output [15:0] gpio_outenb_pad,		// Connect to oe_n on gpio pad
-	output [15:0] gpio_inenb_pad,		// Connect to inp_dis on gpio pad
-
-	output 	      adc0_ena,
-	output 	      adc0_convert,
-	input  [9:0]  adc0_data,
-	input  	      adc0_done,
-	output	      adc0_clk,
-	output [1:0]  adc0_inputsrc,
-	output 	      adc1_ena,
-	output 	      adc1_convert,
-	output	      adc1_clk,
-	output [1:0]  adc1_inputsrc,
-	input  [9:0]  adc1_data,
-	input  	      adc1_done,
-
-	output	      dac_ena,
-	output [9:0]  dac_value,
-
-	output	      analog_out_sel,	// Analog output select (DAC or bandgap)
-	output	      opamp_ena,	// Op-amp enable for analog output
-	output	      opamp_bias_ena,	// Op-amp bias enable for analog output
-	output	      bg_ena,		// Bandgap enable
-
-	output	      comp_ena,
-	output [1:0]  comp_ninputsrc,
-	output [1:0]  comp_pinputsrc,
-	output	      rcosc_ena,
-
-	output	      overtemp_ena,
-	input	      overtemp,
-	input	      rcosc_in,		// RC oscillator output
-	input	      xtal_in,		// crystal oscillator output
-	input	      comp_in,		// comparator output
-	input	      spi_sck,
-
-	input [7:0]   spi_ro_config,
-	input 	      spi_ro_xtal_ena,
-	input 	      spi_ro_reg_ena,
-	input 	      spi_ro_pll_dco_ena,
-	input [4:0]   spi_ro_pll_div,
-	input [2:0]   spi_ro_pll_sel,
-	input [25:0]  spi_ro_pll_trim,
-
-	input [11:0]  spi_ro_mfgr_id,
-	input [7:0]   spi_ro_prod_id,
-	input [3:0]   spi_ro_mask_rev,
-
-	output ser_tx,
-	input  ser_rx,
-
-	// IRQ
-	input  irq_pin,		// dedicated IRQ pin
-	input  irq_spi,		// IRQ from standalone SPI
-
-	// trap
-	output trap,
-
-	// Flash memory control (SPI master)
-	output flash_csb,
-	output flash_clk,
-
-	output flash_csb_oeb,
-	output flash_clk_oeb,
-
-	output flash_io0_oeb,
-	output flash_io1_oeb,
-	output flash_io2_oeb,
-	output flash_io3_oeb,
-
-	output flash_csb_ieb,
-	output flash_clk_ieb,
-
-	output flash_io0_ieb,
-	output flash_io1_ieb,
-	output flash_io2_ieb,
-	output flash_io3_ieb,
-
-	output flash_io0_do,
-	output flash_io1_do,
-	output flash_io2_do,
-	output flash_io3_do,
-
-	input  flash_io0_di,
-	input  flash_io1_di,
-	input  flash_io2_di,
-	input  flash_io3_di
-);
-	/* Increase scratchpad memory to 1K words */
-	/* parameter integer MEM_WORDS = 1024; */
-	/* Memory reverted back to 256 words while memory has to be synthesized */
-	parameter integer MEM_WORDS = 256;
-	parameter [31:0] STACKADDR = (4*MEM_WORDS);       // end of memory
-	parameter [31:0] PROGADDR_RESET = 32'h 0010_0000; // 1 MB into flash
-
-//	wire	      resetn;
-//	wire	      clk;
-
-	wire          iomem_valid;
-	reg           iomem_ready;
-	wire   [ 3:0] iomem_wstrb;
-	wire   [31:0] iomem_addr;
-	wire   [31:0] iomem_wdata;
-	reg    [31:0] iomem_rdata;
-
-	// memory-mapped I/O control registers
-
-        wire   [15:0] gpio_pullup;      // Intermediate GPIO pullup
-        wire   [15:0] gpio_pulldown;    // Intermediate GPIO pulldown
-        wire   [15:0] gpio_outenb;      // Intermediate GPIO out enable (bar)
-        wire   [15:0] gpio_out;         // Intermediate GPIO output
-
-	reg    [15:0] gpio;		// GPIO output data
-	reg    [15:0] gpio_pu;		// GPIO pull-up enable
-	reg    [15:0] gpio_pd;		// GPIO pull-down enable
-	reg    [15:0] gpio_oeb;		// GPIO output enable (sense negative)
-	reg 	      adc0_ena;		// ADC0 enable
-	reg 	      adc0_convert;	// ADC0 convert
-	reg    [1:0]  adc0_clksrc;	// ADC0 clock source
-	reg    [1:0]  adc0_inputsrc;	// ADC0 input source
-	reg 	      adc1_ena;		// ADC1 enable
-	reg 	      adc1_convert;	// ADC1 convert
-	reg    [1:0]  adc1_clksrc;	// ADC1 clock source
-	reg    [1:0]  adc1_inputsrc;	// ADC1 input source
-	reg	      dac_ena;		// DAC enable
-	reg    [9:0]  dac_value;	// DAC output value
-	reg	      comp_ena;		// Comparator enable
-	reg    [1:0]  comp_ninputsrc;	// Comparator negative input source
-	reg    [1:0]  comp_pinputsrc;	// Comparator positive input source
-	reg	      rcosc_ena;	// RC oscillator enable
-	reg	      overtemp_ena;	// Over-temperature alarm enable
-	reg    [1:0]  comp_output_dest; // Comparator output destination
-	reg    [1:0]  rcosc_output_dest; // RC oscillator output destination
-	reg    [1:0]  overtemp_dest;	// Over-temperature alarm destination
-	reg    [1:0]  pll_output_dest;	// PLL clock output destination
-	reg    [1:0]  xtal_output_dest; // Crystal oscillator output destination
-	reg    [1:0]  trap_output_dest; // Trap signal output destination
-	reg    [1:0]  irq_7_inputsrc;	// IRQ 5 source
-	reg    [1:0]  irq_8_inputsrc;	// IRQ 6 source
-	reg	      analog_out_sel;	// Analog output select
- 	reg	      opamp_ena;	// Analog output op-amp enable
- 	reg	      opamp_bias_ena;	// Analog output op-amp bias enable
- 	reg	      bg_ena;		// Bandgap enable
-	wire	      adc0_clk;		// ADC0 clock (multiplexed)
-	wire	      adc1_clk;		// ADC1 clock (multiplexed)
-
-	wire [3:0] ram_wenb;
-	wire [9:0] ram_addr;
-	wire [31:0] ram_wdata;
-	
-//	// Clock assignment (to do:  make this glitch-free)
-//	assign clk = (ext_clk_sel == 1'b1) ? ext_clk : pll_clk;
-//
-//	// Reset assignment.  "reset" comes from POR, while "ext_reset"
-//	// comes from standalone SPI (and is normally zero unless
-//	// activated from the SPI).
-//
-//	// Staged-delay reset
-//	reg [2:0] reset_delay;
-//
-//	always @(posedge clk or posedge reset) begin
-//	    if (reset == 1'b1) begin
-//		reset_delay <= 3'b111;
-//	    end else begin
-//		reset_delay <= {1'b0, reset_delay[2:1]};
-//	    end
-//	end
-//
-//	assign resetn = ~(reset_delay[0] | ext_reset);
-
-	// ADC clock assignments
-	
-	assign adc0_clk = (adc0_clksrc == 2'b00) ? rcosc_in :
-			  (adc0_clksrc == 2'b01) ? spi_sck :
-			  (adc0_clksrc == 2'b10) ? xtal_in :
-			  ext_clk;
-
-	assign adc1_clk = (adc1_clksrc == 2'b00) ? rcosc_in :
-			  (adc1_clksrc == 2'b01) ? spi_sck :
-			  (adc1_clksrc == 2'b10) ? xtal_in :
-			  ext_clk;
-
-	// GPIO assignments
-
-	assign gpio_out[0] = (comp_output_dest == 2'b01) ? comp_in : gpio[0];
-	assign gpio_out[1] = (comp_output_dest == 2'b10) ? comp_in : gpio[1];
-	assign gpio_out[2] = (rcosc_output_dest == 2'b01) ? rcosc_in : gpio[2];
-	assign gpio_out[3] = (rcosc_output_dest == 2'b10) ? rcosc_in : gpio[3];
-	assign gpio_out[4] = (rcosc_output_dest == 2'b11) ? rcosc_in : gpio[4];
-	assign gpio_out[5] = (xtal_output_dest == 2'b01) ? xtal_in : gpio[5]; 
-	assign gpio_out[6] = (xtal_output_dest == 2'b10) ? xtal_in : gpio[6]; 
-	assign gpio_out[7] = (xtal_output_dest == 2'b11) ? xtal_in : gpio[7]; 
-	assign gpio_out[8] = (pll_output_dest == 2'b01) ? pll_clk : gpio[8];
-	assign gpio_out[9] = (pll_output_dest == 2'b10) ? pll_clk : gpio[9];
-	assign gpio_out[10] = (pll_output_dest == 2'b11) ? clk : gpio[10];
-	assign gpio_out[11] = (trap_output_dest == 2'b01) ? trap : gpio[11];
-	assign gpio_out[12] = (trap_output_dest == 2'b10) ? trap : gpio[12];
-	assign gpio_out[13] = (trap_output_dest == 2'b11) ? trap : gpio[13];
-	assign gpio_out[14] = (overtemp_dest == 2'b01) ? overtemp : gpio[14];
-	assign gpio_out[15] = (overtemp_dest == 2'b10) ? overtemp : gpio[15];
-
-	assign gpio_outenb[0] = (comp_output_dest == 2'b00)  ? gpio_oeb[0] : 1'b0;
-	assign gpio_outenb[1] = (comp_output_dest == 2'b00)  ? gpio_oeb[1] : 1'b0;
-	assign gpio_outenb[2] = (rcosc_output_dest == 2'b00) ? gpio_oeb[2] : 1'b0; 
-	assign gpio_outenb[3] = (rcosc_output_dest == 2'b00) ? gpio_oeb[3] : 1'b0;
-	assign gpio_outenb[4] = (rcosc_output_dest == 2'b00) ? gpio_oeb[4] : 1'b0;
-	assign gpio_outenb[5] = (xtal_output_dest == 2'b00)  ? gpio_oeb[5] : 1'b0;
-	assign gpio_outenb[6] = (xtal_output_dest == 2'b00)  ? gpio_oeb[6] : 1'b0;
-	assign gpio_outenb[7] = (xtal_output_dest == 2'b00)  ? gpio_oeb[7] : 1'b0;
-	assign gpio_outenb[8] = (pll_output_dest == 2'b00)   ? gpio_oeb[8] : 1'b0;
-	assign gpio_outenb[9] = (pll_output_dest == 2'b00)   ? gpio_oeb[9] : 1'b0;
-	assign gpio_outenb[10] = (pll_output_dest == 2'b00)  ? gpio_oeb[10] : 1'b0;
-	assign gpio_outenb[11] = (trap_output_dest == 2'b00) ? gpio_oeb[11] : 1'b0;
-	assign gpio_outenb[12] = (trap_output_dest == 2'b00) ? gpio_oeb[12] : 1'b0;
-	assign gpio_outenb[13] = (trap_output_dest == 2'b00) ? gpio_oeb[13] : 1'b0;
-	assign gpio_outenb[14] = (overtemp_dest == 2'b00)    ? gpio_oeb[14] : 1'b0;
-	assign gpio_outenb[15] = (overtemp_dest == 2'b00)    ? gpio_oeb[15] : 1'b0;
-
-	assign gpio_pullup[0] = (comp_output_dest == 2'b00)  ? gpio_pu[0] : 1'b0;
-	assign gpio_pullup[1] = (comp_output_dest == 2'b00)  ? gpio_pu[1] : 1'b0;
-	assign gpio_pullup[2] = (rcosc_output_dest == 2'b00) ? gpio_pu[2] : 1'b0; 
-	assign gpio_pullup[3] = (rcosc_output_dest == 2'b00) ? gpio_pu[3] : 1'b0;
-	assign gpio_pullup[4] = (rcosc_output_dest == 2'b00) ? gpio_pu[4] : 1'b0;
-	assign gpio_pullup[5] = (xtal_output_dest == 2'b00)  ? gpio_pu[5] : 1'b0;
-	assign gpio_pullup[6] = (xtal_output_dest == 2'b00)  ? gpio_pu[6] : 1'b0;
-	assign gpio_pullup[7] = (xtal_output_dest == 2'b00)  ? gpio_pu[7] : 1'b0;
-	assign gpio_pullup[8] = (pll_output_dest == 2'b00)   ? gpio_pu[8] : 1'b0;
-	assign gpio_pullup[9] = (pll_output_dest == 2'b00)   ? gpio_pu[9] : 1'b0;
-	assign gpio_pullup[10] = (pll_output_dest == 2'b00)  ? gpio_pu[10] : 1'b0;
-	assign gpio_pullup[11] = (trap_output_dest == 2'b00) ? gpio_pu[11] : 1'b0;
-	assign gpio_pullup[12] = (trap_output_dest == 2'b00) ? gpio_pu[12] : 1'b0;
-	assign gpio_pullup[13] = (trap_output_dest == 2'b00) ? gpio_pu[13] : 1'b0;
-	assign gpio_pullup[14] = (overtemp_dest == 2'b00)    ? gpio_pu[14] : 1'b0;
-	assign gpio_pullup[15] = (overtemp_dest == 2'b00)    ? gpio_pu[15] : 1'b0;
-
-	assign gpio_pulldown[0] = (comp_output_dest == 2'b00)  ? gpio_pd[0] : 1'b0;
-	assign gpio_pulldown[1] = (comp_output_dest == 2'b00)  ? gpio_pd[1] : 1'b0;
-	assign gpio_pulldown[2] = (rcosc_output_dest == 2'b00) ? gpio_pd[2] : 1'b0; 
-	assign gpio_pulldown[3] = (rcosc_output_dest == 2'b00) ? gpio_pd[3] : 1'b0;
-	assign gpio_pulldown[4] = (rcosc_output_dest == 2'b00) ? gpio_pd[4] : 1'b0;
-	assign gpio_pulldown[5] = (xtal_output_dest == 2'b00)  ? gpio_pd[5] : 1'b0;
-	assign gpio_pulldown[6] = (xtal_output_dest == 2'b00)  ? gpio_pd[6] : 1'b0;
-	assign gpio_pulldown[7] = (xtal_output_dest == 2'b00)  ? gpio_pd[7] : 1'b0;
-	assign gpio_pulldown[8] = (pll_output_dest == 2'b00)   ? gpio_pd[8] : 1'b0;
-	assign gpio_pulldown[9] = (pll_output_dest == 2'b00)   ? gpio_pd[9] : 1'b0;
-	assign gpio_pulldown[10] = (pll_output_dest == 2'b00)  ? gpio_pd[10] : 1'b0;
-	assign gpio_pulldown[11] = (trap_output_dest == 2'b00) ? gpio_pd[11] : 1'b0;
-	assign gpio_pulldown[12] = (trap_output_dest == 2'b00) ? gpio_pd[12] : 1'b0;
-	assign gpio_pulldown[13] = (trap_output_dest == 2'b00) ? gpio_pd[13] : 1'b0;
-	assign gpio_pulldown[14] = (overtemp_dest == 2'b00)    ? gpio_pd[14] : 1'b0;
-	assign gpio_pulldown[15] = (overtemp_dest == 2'b00)    ? gpio_pd[15] : 1'b0;
-
-        // Convert GPIO signals to s8 pad signals
-        convert_gpio_sigs convert_gpio_bit [15:0] (
-            .gpio_out(gpio_out),
-            .gpio_outenb(gpio_outenb),
-            .gpio_pu(gpio_pullup),
-            .gpio_pd(gpio_pulldown),
-            .gpio_out_pad(gpio_out_pad),
-            .gpio_outenb_pad(gpio_outenb_pad),
-            .gpio_inenb_pad(gpio_inenb_pad),
-            .gpio_mode1_pad(gpio_mode1_pad),
-            .gpio_mode0_pad(gpio_mode0_pad)
-        );
-
-	wire irq_7, irq_8;
-
-	assign irq_7 = (irq_7_inputsrc == 2'b01) ? gpio_in_pad[0] :
-		       (irq_7_inputsrc == 2'b10) ? gpio_in_pad[1] :
-		       (irq_7_inputsrc == 2'b11) ? gpio_in_pad[2] : 1'b0;
-	assign irq_8 = (irq_8_inputsrc == 2'b01) ? gpio_in_pad[3] :
-		       (irq_8_inputsrc == 2'b10) ? gpio_in_pad[4] :
-		       (irq_8_inputsrc == 2'b11) ? gpio_in_pad[5] : 1'b0;
-
-	assign ram_wenb = (mem_valid && !mem_ready && mem_addr < 4*MEM_WORDS) ?
-		{~mem_wstrb[3], ~mem_wstrb[2], ~mem_wstrb[1], ~mem_wstrb[0]} : 4'b1111;
-        assign ram_addr = mem_addr[11:2];
-	assign ram_wdata = mem_wdata;		// Just for naming conventions.
-
-	reg [31:0] irq;
-	wire irq_stall = 0;
-	wire irq_uart = 0;
-
-	always @* begin
-		irq = 0;
-		irq[3] = irq_stall;
-		irq[4] = irq_uart;
-		irq[5] = irq_pin;
-		irq[6] = irq_spi;
-		irq[7] = irq_7;
-		irq[8] = irq_8;
-		irq[9] = comp_output_dest[0] & comp_output_dest[1] & comp_in;
-		irq[10] = overtemp_dest[0] & overtemp_dest[1] & overtemp;
-	end
-
-	wire mem_valid;
-	wire mem_instr;
-	wire mem_ready;
-	wire [31:0] mem_addr;
-	wire [31:0] mem_wdata;
-	wire [3:0] mem_wstrb;
-	wire [31:0] mem_rdata;
-
-	wire spimem_ready;
-	wire [31:0] spimem_rdata;
-
-	reg ram_ready;
-	wire [31:0] ram_rdata;
-
-	assign iomem_valid = mem_valid && (mem_addr[31:24] > 8'h 01);
-	assign iomem_wstrb = mem_wstrb;
-	assign iomem_addr = mem_addr;
-	assign iomem_wdata = mem_wdata;
-
-	wire spimemio_cfgreg_sel = mem_valid && (mem_addr == 32'h 0200_0000);
-	wire [31:0] spimemio_cfgreg_do;
-
-	wire        simpleuart_reg_div_sel = mem_valid && (mem_addr == 32'h 0200_0004);
-	wire [31:0] simpleuart_reg_div_do;
-
-	wire        simpleuart_reg_dat_sel = mem_valid && (mem_addr == 32'h 0200_0008);
-	wire [31:0] simpleuart_reg_dat_do;
-	wire        simpleuart_reg_dat_wait;
-
-	assign mem_ready = (iomem_valid && iomem_ready) || spimem_ready || ram_ready || spimemio_cfgreg_sel ||
-			simpleuart_reg_div_sel || (simpleuart_reg_dat_sel && !simpleuart_reg_dat_wait);
-
-	assign mem_rdata = (iomem_valid && iomem_ready) ? iomem_rdata : spimem_ready ? spimem_rdata : ram_ready ? ram_rdata :
-			spimemio_cfgreg_sel ? spimemio_cfgreg_do : simpleuart_reg_div_sel ? simpleuart_reg_div_do :
-			simpleuart_reg_dat_sel ? simpleuart_reg_dat_do : 32'h 0000_0000;
-
-	picorv32 #(
-		.STACKADDR(STACKADDR),
-		.PROGADDR_RESET(PROGADDR_RESET),
-		.PROGADDR_IRQ(32'h 0000_0000),
-		.BARREL_SHIFTER(1),
-		.COMPRESSED_ISA(1),
-		.ENABLE_MUL(1),
-		.ENABLE_DIV(1),
-		.ENABLE_IRQ(1),
-		.ENABLE_IRQ_QREGS(0)
-	) cpu (
-		.clk         (clk        ),
-		.resetn      (resetn     ),
-		.mem_valid   (mem_valid  ),
-		.mem_instr   (mem_instr  ),
-		.mem_ready   (mem_ready  ),
-		.mem_addr    (mem_addr   ),
-		.mem_wdata   (mem_wdata  ),
-		.mem_wstrb   (mem_wstrb  ),
-		.mem_rdata   (mem_rdata  ),
-		.irq         (irq        ),
-		.trap        (trap       )
-	);
-
-	spimemio spimemio (
-		.clk    (clk),
-		.resetn (resetn),
-		.valid  (mem_valid && mem_addr >= 4*MEM_WORDS && mem_addr < 32'h 0200_0000),
-		.ready  (spimem_ready),
-		.addr   (mem_addr[23:0]),
-		.rdata  (spimem_rdata),
-
-		.flash_csb    (flash_csb   ),
-		.flash_clk    (flash_clk   ),
-
-		.flash_csb_oeb (flash_csb_oeb),
-		.flash_clk_oeb (flash_clk_oeb),
-
-		.flash_io0_oeb (flash_io0_oeb),
-		.flash_io1_oeb (flash_io1_oeb),
-		.flash_io2_oeb (flash_io2_oeb),
-		.flash_io3_oeb (flash_io3_oeb),
-
-		.flash_csb_ieb (flash_csb_ieb),
-		.flash_clk_ieb (flash_clk_ieb),
-
-		.flash_io0_ieb (flash_io0_ieb),
-		.flash_io1_ieb (flash_io1_ieb),
-		.flash_io2_ieb (flash_io2_ieb),
-		.flash_io3_ieb (flash_io3_ieb),
-
-		.flash_io0_do (flash_io0_do),
-		.flash_io1_do (flash_io1_do),
-		.flash_io2_do (flash_io2_do),
-		.flash_io3_do (flash_io3_do),
-
-		.flash_io0_di (flash_io0_di),
-		.flash_io1_di (flash_io1_di),
-		.flash_io2_di (flash_io2_di),
-		.flash_io3_di (flash_io3_di),
-
-		.cfgreg_we(spimemio_cfgreg_sel ? mem_wstrb : 4'b 0000),
-		.cfgreg_di(mem_wdata),
-		.cfgreg_do(spimemio_cfgreg_do)
-	);
-
-	simpleuart simpleuart (
-		.clk         (clk         ),
-		.resetn      (resetn      ),
-
-		.ser_tx      (ser_tx      ),
-		.ser_rx      (ser_rx      ),
-
-		.reg_div_we  (simpleuart_reg_div_sel ? mem_wstrb : 4'b 0000),
-		.reg_div_di  (mem_wdata),
-		.reg_div_do  (simpleuart_reg_div_do),
-
-		.reg_dat_we  (simpleuart_reg_dat_sel ? mem_wstrb[0] : 1'b 0),
-		.reg_dat_re  (simpleuart_reg_dat_sel && !mem_wstrb),
-		.reg_dat_di  (mem_wdata),
-		.reg_dat_do  (simpleuart_reg_dat_do),
-		.reg_dat_wait(simpleuart_reg_dat_wait)
-	);
-
-	always @(posedge clk)
-		ram_ready <= mem_valid && !mem_ready && mem_addr < 4*MEM_WORDS;
-
-	// PicoSoC memory mapped IP
-	// 2 ADCs (1 multiplexed from internal signals, including core 1.8V VDD,
-	//	DAC output, comparator input, external input)
-	// 1 DAC
-	// 1 comparator (1 end tied to DAC, other could be shared w/ADC input)
-	// 1 RC oscillator (output can be tied to one or both ADC clocks)
-	// 1 crystal oscillator (output to level-shift-down = 3V buffer powered at 1.8V)
-	// 1 1.8V regulator (sets VDD on padframe)
-	// 1 bandgap
-	// 1 power-on-reset (POR)
-	// 1 temperature alarm
-	
-	// NOTE: Signals affecting critical core functions are controlled through
-	// an independent SPI having read-only access through the picorv32 core.
-	// SPI pins are independent of picorv32 SPI master.  Signals controlled by
-	// the SPI are:
-	// 1) crystal oscillator enable (default on)
-	// 2) 1.8V regulator enable (default on)
-	// 3) bandgap enable (default on)
-	// 4) picorv32 internal debug signals (TBD)
-	// 5) additional picorv32 IRQ (TBD)
-	// 6) PLL enables (default on)
-	// 7) PLL trim (default TBD)
-	// NOTE:  SPI should have a pass-through mode that configures SDO as a
-	// copy of a chosen signal for as long as CSB is held low.  This can be
-	// an SPI command, allows other internal signals to be passed to the
-	// output and viewed, including the RC oscillator output, comparator output,
-	// and other edge-based signals.
-
-	// Memory map:
-	// NOTE:
-
-	// SPI master:	0x02000000	(control)
-	// UART:	0x02000004-8	(clock, data)
-	// GPIO:	0x03000000	(in/out, pu/pd, data)
-	// ADC0:	0x03000020
-	// ADC1:	0x03000040
-	// DAC:		0x03000060
-	// comparator:	0x03000080
-	// RC osc:	0x030000a0
-	// SPI slave:	0x030000c0	(read-only)
-
-	// Memory map details:
-	// GPIO:	32 channels total.  
-	//		addr 0x03000000		data (16 bits)
-	//		addr 0x03000001		out (=1) or in (=0) (default 0)
-	//		addr 0x03000002		pu (=1) or none (=0) (default 0)
-	//		addr 0x03000003		pd (=1) or none (=0) (default 0)
-	//		addr 0x03000004-f 	reserved (may be used for other pad I/O)
-	//
-	// ADC0:	addr 0x03000020		enable
-	// 		addr 0x03000021		data (read-only)
-	//      	addr 0x03000022		done (read-only)
-	//		addr 0x03000023		start conversion
-	//		addr 0x03000024		clock source (RC osc, SPI clk, xtal, core)
-	//		addr 0x03000025		input source (core VDD, ext, DAC, comp in)
-	//
-	// ADC1:	addr 0x03000040		enable
-	// 		addr 0x03000041		data (read-only)
-	//      	addr 0x03000042		done (read-only)
-	//		addr 0x03000043		start conversion
-	//		addr 0x03000044		clock source (RC osc, SPI clk, xtal, core)
-	//		addr 0x03000045		input source (bg, ext, I/O vdd, gnd)
-	//
-	// DAC:		addr 0x03000060		enable
-	//     		addr 0x03000061		value
-	//
-	// comparator:  addr 0x03000080		enable
-	//		addr 0x03000081		value
-	//		addr 0x03000082		input source (DAC, bg, core VDD, ext)
-	//		addr 0x03000083		output dest (ext gpio pin 0-1, IRQ, none)
-	//
-	// bandgap:	addr 0x03000090		enable
-	//
-	// RC osc:	addr 0x030000a0		enable
-	//		addr 0x030000a1		output dest (ext gpio pin 2-4)
-	//
-	// SPI slave:	addr 0x030000c0		SPI configuration
-	//		addr 0x030000c1		xtal osc, reg, bg enables
-	// 		addr 0x030000c2		PLL enables, trim
-	// 		addr 0x030000c3		manufacturer ID
-	// 		addr 0x030000c4		product ID
-	// 		addr 0x030000c5		product mask revision
-	// Xtal mon:	addr 0x030000c6		xtal osc output dest (ext gpio pin 5-7)
-	// PLL mon:	addr 0x030000c7		PLL output dest (ext gpio pin 8-10)
-	// trap mon:	addr 0x030000c8		trap output dest (ext gpio pin 11-13)
-	// IRQ7 src:	addr 0x030000c9		IRQ 7 source (ext gpio pin 0-3)
-	// IRQ8 src:	addr 0x030000ca		IRQ 8 source (ext gpio pin 4-7)
-	// Analog:	addr 0x030000cb		analog output select (DAC, bg)
-	//
-	// Overtemp:	addr 0x030000e0		over-temperature alarm enable
-	//		addr 0x030000e1		over-temperature alarm data
-	//		addr 0x030000e2		output dest (ext gpio pin 14-15, IRQ)
-
-	always @(posedge clk) begin
-		if (!resetn) begin
-			gpio <= 0;
-			gpio_oeb <= 16'hffff;
-			gpio_pu <= 0;
-			gpio_pd <= 0;
-			adc0_ena <= 0;
-			adc0_convert <= 0;
-			adc0_clksrc <= 0;
-			adc0_inputsrc <= 0;
-			adc1_ena <= 0;
-			adc1_convert <= 0;
-			adc1_clksrc <= 0;
-			adc1_inputsrc <= 0;
-			dac_ena <= 0;
-			dac_value <= 0;
-			comp_ena <= 0;
-			comp_ninputsrc <= 0;
-			comp_pinputsrc <= 0;
-			rcosc_ena <= 0;
-			comp_output_dest <= 0;
-			rcosc_output_dest <= 0;
-			overtemp_dest <= 0;
-			overtemp_ena <= 0;
-			pll_output_dest <= 0;
-			xtal_output_dest <= 0;
-			trap_output_dest <= 0;
-			irq_7_inputsrc <= 0;
-			irq_8_inputsrc <= 0;
-			analog_out_sel <= 0;
-			opamp_ena <= 0;
-			opamp_bias_ena <= 0;
-			bg_ena <= 0;
-
-		end else begin
-			iomem_ready <= 0;
-			if (iomem_valid && !iomem_ready && iomem_addr[31:8] == 24'h030000) begin
-				iomem_ready <= 1;
-				if (iomem_addr[7:0] == 8'h00) begin
-					iomem_rdata <= {gpio_out, gpio_in_pad};
-					if (iomem_wstrb[0]) gpio[ 7: 0] <= iomem_wdata[ 7: 0];
-					if (iomem_wstrb[1]) gpio[15: 8] <= iomem_wdata[15: 8];
-				end else if (iomem_addr[7:0] == 8'h04) begin
-					iomem_rdata <= {16'd0, gpio_oeb};
-					if (iomem_wstrb[0]) gpio_oeb[ 7: 0] <= iomem_wdata[ 7: 0];
-					if (iomem_wstrb[1]) gpio_oeb[15: 8] <= iomem_wdata[15: 8];
-				end else if (iomem_addr[7:0] == 8'h08) begin
-					iomem_rdata <= {16'd0, gpio_pu};
-					if (iomem_wstrb[0]) gpio_pu[ 7: 0] <= iomem_wdata[ 7: 0];
-					if (iomem_wstrb[1]) gpio_pu[15: 8] <= iomem_wdata[15: 8];
-				end else if (iomem_addr[7:0] == 8'h0c) begin
-					iomem_rdata <= {16'd0, gpio_pu};
-					if (iomem_wstrb[0]) gpio_pd[ 7: 0] <= iomem_wdata[ 7: 0];
-					if (iomem_wstrb[1]) gpio_pd[15: 8] <= iomem_wdata[15: 8];
-				end else if (iomem_addr[7:0] == 8'h10) begin
-					iomem_rdata <= {31'd0, adc0_ena};
-					if (iomem_wstrb[0]) adc0_ena <= iomem_wdata[0];
-				end else if (iomem_addr[7:0] == 8'h14) begin
-					iomem_rdata <= {22'd0, adc0_data};
-				end else if (iomem_addr[7:0] == 8'h18) begin
-					iomem_rdata <= {31'd0, adc0_done};
-				end else if (iomem_addr[7:0] == 8'h1c) begin
-					iomem_rdata <= {31'd0, adc0_convert};
-					if (iomem_wstrb[0]) adc0_convert <= iomem_wdata[0];
-				end else if (iomem_addr[7:0] == 8'h20) begin
-					iomem_rdata <= {30'd0, adc0_clksrc};
-					if (iomem_wstrb[0]) adc0_clksrc <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'h24) begin
-					iomem_rdata <= {30'd0, adc0_inputsrc};
-					if (iomem_wstrb[0]) adc0_inputsrc <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'h30) begin
-					iomem_rdata <= {31'd0, adc1_ena};
-					if (iomem_wstrb[0]) adc1_ena <= iomem_wdata[0];
-				end else if (iomem_addr[7:0] == 8'h34) begin
-					iomem_rdata <= {22'd0, adc1_data};
-				end else if (iomem_addr[7:0] == 8'h38) begin
-					iomem_rdata <= {31'd0, adc1_done};
-				end else if (iomem_addr[7:0] == 8'h3c) begin
-					iomem_rdata <= {31'd0, adc1_convert};
-					if (iomem_wstrb[0]) adc1_convert <= iomem_wdata[0];
-				end else if (iomem_addr[7:0] == 8'h40) begin
-					iomem_rdata <= {30'd0, adc1_clksrc};
-					if (iomem_wstrb[0]) adc1_clksrc <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'h44) begin
-					iomem_rdata <= {30'd0, adc1_inputsrc};
-					if (iomem_wstrb[0]) adc1_inputsrc <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'h50) begin
-					iomem_rdata <= {31'd0, dac_ena};
-					if (iomem_wstrb[0]) dac_ena <= iomem_wdata[0];
-				end else if (iomem_addr[7:0] == 8'h54) begin
-					iomem_rdata <= {22'd0, dac_value};
-					if (iomem_wstrb[0]) dac_value[7:0] <= iomem_wdata[7:0];
-					if (iomem_wstrb[1]) dac_value[9:8] <= iomem_wdata[9:8];
-				end else if (iomem_addr[7:0] == 8'h60) begin
-					iomem_rdata <= {31'd0, comp_ena};
-					if (iomem_wstrb[0]) comp_ena <= iomem_wdata[0];
-				end else if (iomem_addr[7:0] == 8'h64) begin
-					iomem_rdata <= {30'd0, comp_ninputsrc};
-					if (iomem_wstrb[0]) comp_ninputsrc <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'h68) begin
-					iomem_rdata <= {30'd0, comp_pinputsrc};
-					if (iomem_wstrb[0]) comp_pinputsrc <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'h6c) begin
-					iomem_rdata <= {30'd0, comp_output_dest};
-					if (iomem_wstrb[0]) comp_output_dest <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'h70) begin
-					iomem_rdata <= {31'd0, rcosc_ena};
-					if (iomem_wstrb[0]) rcosc_ena <= iomem_wdata[0];
-				end else if (iomem_addr[7:0] == 8'h74) begin
-					iomem_rdata <= {30'd0, rcosc_output_dest};
-					if (iomem_wstrb[0]) rcosc_output_dest <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'h80) begin
-					iomem_rdata <= {24'd0, spi_ro_config};
-				end else if (iomem_addr[7:0] == 8'h84) begin
-					iomem_rdata <= {22'd0, spi_ro_pll_div, spi_ro_pll_sel, spi_ro_xtal_ena, spi_ro_reg_ena};
-				end else if (iomem_addr[7:0] == 8'h88) begin
-					iomem_rdata <= {5'd0, spi_ro_pll_trim, spi_ro_pll_dco_ena};
-				end else if (iomem_addr[7:0] == 8'h8c) begin
-					iomem_rdata <= {20'd0, spi_ro_mfgr_id};
-				end else if (iomem_addr[7:0] == 8'h90) begin
-					iomem_rdata <= {24'd0, spi_ro_prod_id};
-				end else if (iomem_addr[7:0] == 8'h94) begin
-					iomem_rdata <= {28'd0, spi_ro_mask_rev};
-				end else if (iomem_addr[7:0] == 8'h98) begin
-					iomem_rdata <= {31'd0, ext_clk_sel};
-				end else if (iomem_addr[7:0] == 8'ha0) begin
-					iomem_rdata <= {30'd0, xtal_output_dest};
-					if (iomem_wstrb[0]) xtal_output_dest <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'ha4) begin
-					iomem_rdata <= {30'd0, pll_output_dest};
-					if (iomem_wstrb[0]) pll_output_dest <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'ha8) begin
-					iomem_rdata <= {30'd0, trap_output_dest};
-					if (iomem_wstrb[0]) trap_output_dest <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'hb0) begin
-					iomem_rdata <= {30'd0, irq_7_inputsrc};
-					if (iomem_wstrb[0]) irq_7_inputsrc <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'hb4) begin
-					iomem_rdata <= {30'd0, irq_8_inputsrc};
-					if (iomem_wstrb[0]) irq_8_inputsrc <= iomem_wdata[1:0];
-				end else if (iomem_addr[7:0] == 8'hc0) begin
-					iomem_rdata <= {31'd0, analog_out_sel};
-					if (iomem_wstrb[0]) analog_out_sel <= iomem_wdata[0];
-				end else if (iomem_addr[7:0] == 8'hc4) begin
-					iomem_rdata <= {31'd0, opamp_bias_ena};
-					if (iomem_wstrb[0]) opamp_bias_ena <= iomem_wdata[0];
-				end else if (iomem_addr[7:0] == 8'hc8) begin
-					iomem_rdata <= {31'd0, opamp_ena};
-					if (iomem_wstrb[0]) opamp_ena <= iomem_wdata[0];
-				end else if (iomem_addr[7:0] == 8'hd0) begin
-					iomem_rdata <= {31'd0, bg_ena};
-					if (iomem_wstrb[0]) bg_ena <= iomem_wdata[0];
-				end else if (iomem_addr[7:0] == 8'he0) begin
-					iomem_rdata <= {31'd0, overtemp_ena};
-					if (iomem_wstrb[0]) overtemp_ena <= iomem_wdata[0];
-				end else if (iomem_addr[7:0] == 8'he4) begin
-					iomem_rdata <= {31'd0, overtemp};
-				end else if (iomem_addr[7:0] == 8'he8) begin
-					iomem_rdata <= {30'd0, overtemp_dest};
-					if (iomem_wstrb[0]) overtemp_dest <= iomem_wdata[1:0];
-				end
-			end
-		end
-	end
-
-	openstriVe_soc_mem #(.WORDS(MEM_WORDS)) picomem (
-		.clk(clk),
-		.ena(resetn),
-		.wen((mem_valid && !mem_ready && mem_addr < 4*MEM_WORDS) ? mem_wstrb : 4'b0),
-		.addr(mem_addr[23:2]),
-		.wdata(mem_wdata),
-		.rdata(ram_rdata)
-	);
-endmodule
-
-`include "picorv32.v"
-`include "spimemio.v"
-`include "simpleuart.v"
-
-// Implementation note:
-// Replace the following two modules with wrappers for your SRAM cells.
-
-module openstriVe_soc_regs (
-	input clk, wen,
-	input [5:0] waddr,
-	input [5:0] raddr1,
-	input [5:0] raddr2,
-	input [31:0] wdata,
-	output [31:0] rdata1,
-	output [31:0] rdata2
-);
-	reg [31:0] regs [0:31];
-
-	always @(posedge clk)
-		if (wen) regs[waddr[4:0]] <= wdata;
-
-	assign rdata1 = regs[raddr1[4:0]];
-	assign rdata2 = regs[raddr2[4:0]];
-endmodule
-
-module openstriVe_soc_mem #(
-	parameter integer WORDS = 256
-) (
-	input clk,
-	input ena,
-	input [3:0] wen,
-	input [21:0] addr,
-	input [31:0] wdata,
-	output reg [31:0] rdata
-);
-	reg [31:0] mem [0:WORDS-1];
-
-	always @(posedge clk) begin
-		if (ena == 1'b1) begin
-			rdata <= mem[addr];
-			if (wen[0]) mem[addr][ 7: 0] <= wdata[ 7: 0];
-			if (wen[1]) mem[addr][15: 8] <= wdata[15: 8];
-			if (wen[2]) mem[addr][23:16] <= wdata[23:16];
-			if (wen[3]) mem[addr][31:24] <= wdata[31:24];
-		end
-	end
-endmodule
-
-/* Convert the standard set of GPIO signals: input, output, output_enb,
- * pullup, and pulldown into the set needed by the s8 GPIO pads:
- * input, output, output_enb, input_enb, mode.  Note that dm[2] on
- * thepads is always equal to dm[1] in this setup, so mode is shown as
- * only a 2-bit signal.
- *
- * This module is bit-sliced.  Instantiate once for each GPIO pad.
- */
-
-module convert_gpio_sigs (
-    input        gpio_out,
-    input        gpio_outenb,
-    input        gpio_pu,
-    input        gpio_pd,
-    output       gpio_out_pad,
-    output       gpio_outenb_pad,
-    output       gpio_inenb_pad,
-    output       gpio_mode1_pad,
-    output       gpio_mode0_pad
-);
-
-    assign gpio_out_pad = (gpio_pu == 1'b0 && gpio_pd == 1'b0) ? gpio_out :
-            (gpio_pu == 1'b1) ? 1 : 0;
-
-    assign gpio_outenb_pad = (gpio_outenb == 1'b0) ? 0 :
-            (gpio_pu == 1'b1 || gpio_pd == 1'b1) ? 0 : 1;
-
-    assign gpio_inenb_pad = ~gpio_outenb;
-
-    assign gpio_mode1_pad = ~gpio_outenb_pad;
-    assign gpio_mode0_pad = gpio_outenb;
-
-endmodule
-
diff --git a/verilog/rtl/striVe_spi.v b/verilog/rtl/striVe_spi.v
index 323ecf6..54643c3 100644
--- a/verilog/rtl/striVe_spi.v
+++ b/verilog/rtl/striVe_spi.v
@@ -40,12 +40,12 @@
 
 module striVe_spi(
 `ifdef LVS
-	vdd, vss, 
+    vdd, vss, 
 `endif
-	RSTB, SCK, SDI, CSB, SDO, sdo_enb,
-	xtal_ena, reg_ena, pll_dco_ena, pll_div, pll_sel,
-	pll_trim, pll_bypass, irq, reset, RST, trap,
-	mfgr_id, prod_id, mask_rev_in, mask_rev);
+    RSTB, SCK, SDI, CSB, SDO, sdo_enb,
+    xtal_ena, reg_ena, pll_dco_ena, pll_div, pll_sel,
+    pll_trim, pll_bypass, irq, reset, RST, trap,
+    mfgr_id, prod_id, mask_rev_in, mask_rev);
 
 `ifdef LVS
     inout vdd;	    // 3.3V supply
@@ -97,16 +97,16 @@
     // Instantiate the SPI slave module
 
     spi_slave U1 (
-	.SCK(SCK),
-	.SDI(SDI),
-	.CSB(CSB),
-	.SDO(SDO),
-	.sdoenb(sdo_enb),
-	.idata(odata),
-	.odata(idata),
-	.oaddr(iaddr),
-	.rdstb(rdstb),
-	.wrstb(wrstb)
+    .SCK(SCK),
+    .SDI(SDI),
+    .CSB(CSB),
+    .SDO(SDO),
+    .sdoenb(sdo_enb),
+    .idata(odata),
+    .odata(idata),
+    .oaddr(iaddr),
+    .rdstb(rdstb),
+    .wrstb(wrstb)
     );
 
     wire [11:0] mfgr_id;
@@ -121,74 +121,74 @@
     // All values are 1-4 bits and no shadow registers are required.
 
     assign odata = 
-	(iaddr == 8'h00) ? 8'h00 :	// SPI status (fixed)
-	(iaddr == 8'h01) ? {mask_rev, mfgr_id[11:8]} : 	// Mask rev (metal programmed)
-	(iaddr == 8'h02) ? mfgr_id[7:0] :	// Manufacturer ID (fixed)
-	(iaddr == 8'h03) ? prod_id :	// Product ID (fixed)
-	(iaddr == 8'h04) ? {5'b00000, xtal_ena, reg_ena, pll_dco_ena} :
-	(iaddr == 8'h05) ? {7'b0000000, pll_bypass} :
-	(iaddr == 8'h06) ? {7'b0000000, irq} :
-	(iaddr == 8'h07) ? {7'b0000000, reset} :
-	(iaddr == 8'h08) ? {7'b0000000, trap} :
-	(iaddr == 8'h09) ? pll_trim[7:0] :
-	(iaddr == 8'h0a) ? pll_trim[15:8] :
-	(iaddr == 8'h0b) ? pll_trim[23:16] :
-	(iaddr == 8'h0c) ? {6'b000000, pll_trim[25:24]} :
-	(iaddr == 8'h0d) ? {5'b00000, pll_sel} :
-	(iaddr == 8'h0e) ? {3'b000, pll_div} :
-			   8'h00;	// Default
+    (iaddr == 8'h00) ? 8'h00 :	// SPI status (fixed)
+    (iaddr == 8'h01) ? {mask_rev, mfgr_id[11:8]} : 	// Mask rev (metal programmed)
+    (iaddr == 8'h02) ? mfgr_id[7:0] :	// Manufacturer ID (fixed)
+    (iaddr == 8'h03) ? prod_id :	// Product ID (fixed)
+    (iaddr == 8'h04) ? {5'b00000, xtal_ena, reg_ena, pll_dco_ena} :
+    (iaddr == 8'h05) ? {7'b0000000, pll_bypass} :
+    (iaddr == 8'h06) ? {7'b0000000, irq} :
+    (iaddr == 8'h07) ? {7'b0000000, reset} :
+    (iaddr == 8'h08) ? {7'b0000000, trap} :
+    (iaddr == 8'h09) ? pll_trim[7:0] :
+    (iaddr == 8'h0a) ? pll_trim[15:8] :
+    (iaddr == 8'h0b) ? pll_trim[23:16] :
+    (iaddr == 8'h0c) ? {6'b000000, pll_trim[25:24]} :
+    (iaddr == 8'h0d) ? {5'b00000, pll_sel} :
+    (iaddr == 8'h0e) ? {3'b000, pll_div} :
+               8'h00;	// Default
 
     // Register mapping and I/O to slave module
 
     always @(posedge SCK or negedge RSTB) begin
-	if (RSTB == 1'b0) begin
-	    // Set trim for PLL at (almost) slowest rate (~90MHz).  However,
-	    // pll_trim[12] must be set to zero for proper startup.
-	    pll_trim <= 26'b11111111111110111111111111;
-	    pll_sel <= 3'b000;
-	    pll_div <= 5'b00100;	// Default divide-by-8
-	    xtal_ena <= 1'b1;
-	    reg_ena <= 1'b1;
-	    pll_dco_ena <= 1'b1;	// Default free-running PLL
-	    pll_bypass <= 1'b1;		// NOTE: Default bypass mode (don't use PLL)
-	    irq <= 1'b0;
-	    reset <= 1'b0;
-	end else if (wrstb == 1'b1) begin
-	    case (iaddr)
-		8'h04: begin
-			 pll_dco_ena <= idata[2];
-			 reg_ena    <= idata[1];
-			 xtal_ena  <= idata[0];
-		       end
-		8'h05: begin
-			 pll_bypass <= idata[0];
-		       end
-		8'h06: begin
-			 irq <= idata[0];
-		       end
-		8'h07: begin
-			 reset <= idata[0];
-		       end
-		// Register 8 is read-only
-		8'h09: begin
- 			 pll_trim[7:0] <= idata;
-		       end
-		8'h0a: begin
- 			 pll_trim[15:8] <= idata;
-		       end
-		8'h0b: begin
- 			 pll_trim[23:16] <= idata;
-		       end
-		8'h0c: begin
- 			 pll_trim[25:24] <= idata[1:0];
-		       end
-		8'h0d: begin
-			 pll_sel <= idata[2:0];
-		       end
-		8'h0e: begin
-			 pll_div <= idata[4:0];
-		       end
-	    endcase	// (iaddr)
-	end
+    if (RSTB == 1'b0) begin
+        // Set trim for PLL at (almost) slowest rate (~90MHz).  However,
+        // pll_trim[12] must be set to zero for proper startup.
+        pll_trim <= 26'b11111111111110111111111111;
+        pll_sel <= 3'b000;
+        pll_div <= 5'b00100;	// Default divide-by-8
+        xtal_ena <= 1'b1;
+        reg_ena <= 1'b1;
+        pll_dco_ena <= 1'b1;	// Default free-running PLL
+        pll_bypass <= 1'b1;		// NOTE: Default bypass mode (don't use PLL)
+        irq <= 1'b0;
+        reset <= 1'b0;
+    end else if (wrstb == 1'b1) begin
+        case (iaddr)
+        8'h04: begin
+             pll_dco_ena <= idata[2];
+             reg_ena    <= idata[1];
+             xtal_ena  <= idata[0];
+               end
+        8'h05: begin
+             pll_bypass <= idata[0];
+               end
+        8'h06: begin
+             irq <= idata[0];
+               end
+        8'h07: begin
+             reset <= idata[0];
+               end
+        // Register 8 is read-only
+        8'h09: begin
+              pll_trim[7:0] <= idata;
+               end
+        8'h0a: begin
+              pll_trim[15:8] <= idata;
+               end
+        8'h0b: begin
+              pll_trim[23:16] <= idata;
+               end
+        8'h0c: begin
+              pll_trim[25:24] <= idata[1:0];
+               end
+        8'h0d: begin
+             pll_sel <= idata[2:0];
+               end
+        8'h0e: begin
+             pll_div <= idata[4:0];
+               end
+        endcase	// (iaddr)
+    end
     end
 endmodule	// striVe_spi_orig
diff --git a/verilog/rtl/sysctrl.v b/verilog/rtl/sysctrl.v
new file mode 100644
index 0000000..5daf5b3
--- /dev/null
+++ b/verilog/rtl/sysctrl.v
@@ -0,0 +1,219 @@
+module sysctrl_wb #(
+    parameter BASE_ADR      = 32'h2F00_0000,
+    parameter OSC_ENA       = 8'h00,
+    parameter OSC_OUT       = 8'h04,
+    parameter XTAL_OUT      = 8'h08,
+    parameter PLL_OUT       = 8'h0c,
+    parameter TRAP_OUT      = 8'h10,
+    parameter IRQ7_SRC      = 8'h14,
+    parameter IRQ8_SRC      = 8'h18,
+    parameter OVERTEMP_ENA  = 8'h1c,
+    parameter OVERTEMP_DATA = 8'h20,
+    parameter OVERTEMP_OUT  = 8'h24
+) (
+    input wb_clk_i,
+    input wb_rst_i,
+
+    input [31:0] wb_dat_i,
+    input [31:0] wb_adr_i,
+    input [3:0] wb_sel_i,
+    input wb_cyc_i,
+    input wb_stb_i,
+    input wb_we_i,
+
+    output [31:0] wb_dat_o,
+    output wb_ack_o,
+    
+    input overtemp,
+
+    output rcosc_ena,
+    output [1:0] rcosc_output_dest,
+    output [1:0] xtal_output_dest,
+    output [1:0] pll_output_dest,
+    output [1:0] trap_output_dest,
+    output [1:0] irq_7_inputsrc,
+    output [1:0] irq_8_inputsrc,
+    output overtemp_ena,
+    output [1:0] overtemp_dest
+
+);
+
+    wire resetn;
+    wire valid;
+    wire ready;
+    wire [3:0] iomem_we;
+
+    assign resetn = ~wb_rst_i;
+    assign valid = wb_stb_i && wb_cyc_i; 
+
+    assign iomem_we = wb_sel_i & {4{wb_we_i}};
+    assign wb_ack_o = ready;
+    
+    sysctrl #(
+        .BASE_ADR(BASE_ADR),
+        .OSC_ENA(OSC_ENA),
+        .OSC_OUT(OSC_OUT),
+        .XTAL_OUT(XTAL_OUT),
+        .PLL_OUT(PLL_OUT),
+        .TRAP_OUT(TRAP_OUT),
+        .IRQ7_SRC(IRQ7_SRC),
+        .IRQ8_SRC(IRQ8_SRC),
+        .OVERTEMP_ENA(OVERTEMP_ENA),
+        .OVERTEMP_DATA(OVERTEMP_DATA),
+        .OVERTEMP_OUT(OVERTEMP_OUT)
+    ) sysctrl (
+        .clk(wb_clk_i),
+        .resetn(resetn),
+        
+        .overtemp(overtemp), 
+
+        .iomem_addr(wb_adr_i),
+        .iomem_valid(valid),
+        .iomem_wstrb(iomem_we),
+        .iomem_wdata(wb_dat_i),
+        .iomem_rdata(wb_dat_o),
+        .iomem_ready(ready),
+        
+        .rcosc_ena(rcosc_ena), // (verify) wire input to the core not connected to HKSPI, what should it be connected to ? 
+        .rcosc_output_dest(rcosc_output_dest), 
+        .xtal_output_dest(xtal_output_dest),
+        .pll_output_dest(pll_output_dest),
+        .trap_output_dest(trap_output_dest), 
+    
+        .irq_7_inputsrc(irq_7_inputsrc),
+        .irq_8_inputsrc(irq_8_inputsrc),  
+
+        .overtemp_ena(overtemp_ena),
+        .overtemp_dest(overtemp_dest) 
+    );
+
+endmodule
+
+module sysctrl #(
+    parameter BASE_ADR = 32'h2300_0000,
+    parameter OSC_ENA       = 8'h00,
+    parameter OSC_OUT       = 8'h04,
+    parameter XTAL_OUT      = 8'h08,
+    parameter PLL_OUT       = 8'h0c,
+    parameter TRAP_OUT      = 8'h10,
+    parameter IRQ7_SRC      = 8'h14,
+    parameter IRQ8_SRC      = 8'h18,
+    parameter OVERTEMP_ENA  = 8'h1c,
+    parameter OVERTEMP_DATA = 8'h20,
+    parameter OVERTEMP_OUT  = 8'h24
+) (
+    input clk,
+    input resetn,
+    
+    input overtemp,
+
+    input [31:0] iomem_addr,
+    input iomem_valid,
+    input [3:0] iomem_wstrb,
+    input [31:0] iomem_wdata,
+    output reg [31:0] iomem_rdata,
+    output reg iomem_ready,
+
+    output rcosc_ena,
+    output [1:0] rcosc_output_dest,
+    output [1:0] xtal_output_dest,
+    output [1:0] pll_output_dest,
+    output [1:0] trap_output_dest,
+    output [1:0] irq_7_inputsrc,
+    output [1:0] irq_8_inputsrc,
+    output overtemp_ena,
+    output [1:0] overtemp_dest
+); 
+    reg rcosc_ena;
+    reg [1:0] rcosc_output_dest;
+    reg [1:0] xtal_output_dest;
+    reg [1:0] pll_output_dest;
+    reg [1:0] trap_output_dest;
+    reg [1:0] irq_7_inputsrc;
+    reg [1:0] irq_8_inputsrc;
+    reg overtemp_ena;
+    reg [1:0] overtemp_dest;
+
+    assign osc_ena_sel  = (iomem_addr[7:0] == OSC_ENA);
+    assign osc_out_sel  = (iomem_addr[7:0] == OSC_OUT);
+    assign pll_out_sel  = (iomem_addr[7:0] == PLL_OUT);
+    assign trap_out_sel = (iomem_addr[7:0] == TRAP_OUT);
+    assign xtal_out_sel = (iomem_addr[7:0] == XTAL_OUT);
+
+    assign irq7_sel  = (iomem_addr[7:0] == IRQ7_SRC);
+    assign irq8_sel  = (iomem_addr[7:0] == IRQ8_SRC);
+
+    assign overtemp_sel       = (iomem_addr[7:0] == OVERTEMP_DATA);
+    assign overtemp_ena_sel   = (iomem_addr[7:0] == OVERTEMP_ENA);
+    assign overtemp_dest_sel  = (iomem_addr[7:0] == OVERTEMP_OUT);
+
+    always @(posedge clk) begin
+        if (!resetn) begin
+            rcosc_ena <= 0;
+            rcosc_output_dest <= 0;
+            pll_output_dest <= 0;
+            xtal_output_dest <= 0;
+            trap_output_dest <= 0;
+            irq_7_inputsrc <= 0;
+            irq_8_inputsrc <= 0;
+            overtemp_dest <= 0;
+            overtemp_ena <= 0;
+        end else begin
+            iomem_ready <= 0;
+            if (iomem_valid && !iomem_ready && iomem_addr[31:8] == BASE_ADR[31:8]) begin
+                iomem_ready <= 1'b 1;
+                
+                if (osc_ena_sel) begin
+                    iomem_rdata <= {31'd0, rcosc_ena};					
+                    if (iomem_wstrb[0])
+                        rcosc_ena <= iomem_wdata[0];
+
+                end else if (osc_out_sel) begin
+                    iomem_rdata <= {30'd0, rcosc_output_dest};
+                    if (iomem_wstrb[0])
+                        rcosc_output_dest <= iomem_wdata[1:0];
+
+                end else if (xtal_out_sel) begin
+                    iomem_rdata <= {30'd0, xtal_output_dest};
+                    if (iomem_wstrb[0])
+                        xtal_output_dest <= iomem_wdata[1:0];
+
+                end else if (pll_out_sel) begin
+                    iomem_rdata <= {30'd0, pll_output_dest};
+                    if (iomem_wstrb[0])
+                        pll_output_dest <= iomem_wdata[1:0];
+
+                end else if (trap_out_sel) begin
+                    iomem_rdata <= {30'd0, trap_output_dest};
+                    if (iomem_wstrb[0]) 
+                        trap_output_dest <= iomem_wdata[1:0];
+
+                end else if (irq7_sel) begin
+                    iomem_rdata <= {30'd0, irq_7_inputsrc};
+                    if (iomem_wstrb[0])
+                        irq_7_inputsrc <= iomem_wdata[1:0];
+
+                end else if (irq8_sel) begin
+                    iomem_rdata <= {30'd0, irq_8_inputsrc};
+                    if (iomem_wstrb[0])
+                        irq_8_inputsrc <= iomem_wdata[1:0];
+
+                end else if (overtemp_ena_sel) begin
+                    iomem_rdata <= {31'd0, overtemp_ena};
+                    if (iomem_wstrb[0])
+                        overtemp_ena <= iomem_wdata[0];
+
+                end else if (overtemp_sel) begin
+                    iomem_rdata <= {31'd0, overtemp};
+
+                end else if (overtemp_dest_sel) begin
+                    iomem_rdata <= {30'd0, overtemp_dest};
+                    if (iomem_wstrb[0])
+                        overtemp_dest <= iomem_wdata[1:0];
+
+                end
+            end
+        end
+    end
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/wb_intercon.v b/verilog/rtl/wb_intercon.v
new file mode 100644
index 0000000..3a2c58f
--- /dev/null
+++ b/verilog/rtl/wb_intercon.v
@@ -0,0 +1,57 @@
+module wb_intercon #(
+    parameter DW = 32,          // Data Width
+    parameter AW = 32,          // Address Width
+    parameter NS = 6           // Number of Slaves
+) (
+    // Master Interface
+    input [AW-1:0] wbm_adr_i,
+    input wbm_stb_i,
+
+    output reg [DW-1:0] wbm_dat_o,
+    output wbm_ack_o,
+
+    // Slave Interface
+    input [NS*DW-1:0] wbs_dat_i,
+    input [NS-1:0] wbs_ack_i,
+    output [NS-1:0] wbs_stb_o
+);
+    parameter [NS*AW-1:0] ADR_MASK = {      // Page & Sub-page bits
+        {8'hFF, {24{1'b0}} },
+        {8'hFF, {24{1'b0}} },
+        {8'hFF, {24{1'b0}} },
+        {8'hFF, {24{1'b0}} },
+        {8'hFF, {24{1'b0}} },
+        {8'hFF, {24{1'b0}} }
+    };
+    parameter [NS*AW-1:0] SLAVE_ADR = {
+        {8'h28, {24{1'b0}} },    // Flash Configuration Register
+        {8'h23, {24{1'b0}} },    // System Control
+        {8'h21, {24{1'b0}} },    // GPIOs
+        {8'h20, {24{1'b0}} },    // UART 
+        {8'h10, {24{1'b0}} },    // Flash 
+        {8'h00, {24{1'b0}} }     // RAM
+    };
+    
+    wire [NS-1: 0] slave_sel;
+
+    // Address decoder
+    genvar iS;
+    generate
+        for (iS = 0; iS < NS; iS = iS + 1) begin
+            assign slave_sel[iS] = 
+                ((wbm_adr_i & ADR_MASK[(iS+1)*AW-1:iS*AW]) == SLAVE_ADR[(iS+1)*AW-1:iS*AW]);
+        end
+    endgenerate
+
+    // Data-out Assignment
+    assign wbm_ack_o = |(wbs_ack_i & slave_sel);
+    assign wbs_stb_o =  {NS{wbm_stb_i}} & slave_sel;
+
+    integer i;
+    always @(*) begin
+        wbm_dat_o = {DW{1'b0}};
+        for (i=0; i<(NS*DW); i=i+1)
+            wbm_dat_o[i%DW] = wbm_dat_o[i%DW] | (slave_sel[i/DW] & wbs_dat_i[i]);
+    end
+ 
+endmodule
\ No newline at end of file