Added management flash SPI pass-through mode testbench and debugged it.
diff --git a/verilog/dv/caravel/mgmt_soc/Makefile b/verilog/dv/caravel/mgmt_soc/Makefile
index 9f185c0..b2e847d 100644
--- a/verilog/dv/caravel/mgmt_soc/Makefile
+++ b/verilog/dv/caravel/mgmt_soc/Makefile
@@ -3,7 +3,7 @@
 .SUFFIXES:
 .SILENT: clean all
 
-PATTERNS = gpio mem uart perf hkspi sysctrl mprj_ctrl
+PATTERNS = gpio mem uart perf hkspi sysctrl mprj_ctrl pass_thru timer
 
 all:  ${PATTERNS}
 	for i in ${PATTERNS}; do \
diff --git a/verilog/dv/caravel/mgmt_soc/pass_thru/Makefile b/verilog/dv/caravel/mgmt_soc/pass_thru/Makefile
new file mode 100644
index 0000000..32d51ce
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/pass_thru/Makefile
@@ -0,0 +1,41 @@
+# ---- Test patterns for project striVe ----
+FIRMWARE_PATH = ../..
+RTL_PATH = ../../../../rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../ 
+
+GCC_PATH=/ef/apps/bin
+
+.SUFFIXES:
+
+PATTERN = pass_thru
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+	iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS)-I $(IP_PATH) -I $(RTL_PATH) \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+	${GCC_PATH}/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+	${GCC_PATH}/riscv32-unknown-elf-objcopy -O verilog $< $@
+	# to fix flash base address
+	sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+	${GCC_PATH}/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/caravel/mgmt_soc/pass_thru/pass_thru.c b/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru.c
new file mode 100644
index 0000000..d31b31f
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru.c
@@ -0,0 +1,74 @@
+#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()
+{
+    // This program is just to keep the processor busy while the
+    // housekeeping SPI is being accessed. to show that the
+    // processor is halted while the SPI is accessing the
+    // flash SPI in pass-through mode.
+
+    // Configure I/O:  High 16 bits of user area used for a 16-bit
+    // word to write and be detected by the testbench verilog.
+    // Only serial Tx line is used in this testbench.  It connects
+    // to mprj_io[6].  Since all lines of the chip are input or
+    // high impedence on startup, the I/O has to be configured
+    // for output
+
+    reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+    reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT;
+    reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+    reg_mprj_io_6 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+    // Apply configuration
+    reg_mprj_xfer = 1;
+    while (reg_mprj_xfer == 1);
+
+    // Start test
+    reg_mprj_datal = 0xa0000000;
+
+    // Set clock to 64 kbaud and enable the UART
+    reg_uart_clkdiv = 625;
+    reg_uart_enable = 1;
+
+    // Test in progress
+    reg_mprj_datal = 0xa5000000;
+
+    // Test message
+    print("Test message\n");
+
+    // End test
+    reg_mprj_datal = 0xab000000;
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru_tb.v b/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru_tb.v
new file mode 100644
index 0000000..e00c85f
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru_tb.v
@@ -0,0 +1,258 @@
+/*	
+ *	StriVe housekeeping pass-thru mode SPI testbench.
+ */
+
+`timescale 1 ns / 1 ps
+
+`include "caravel.v"
+`include "spiflash.v"
+`include "tbuart.v"
+
+module pass_thru_tb;
+	reg clock;
+	reg SDI, CSB, SCK, RSTB;
+
+	wire gpio;
+	wire [15:0] checkbits;
+	wire [36:0] mprj_io;
+	wire uart_tx;
+	wire uart_rx;
+
+	wire flash_csb;
+	wire flash_clk;
+	wire flash_io0;
+	wire flash_io1;
+	wire flash_io2;
+	wire flash_io3;
+
+	wire SDO;
+
+	always #10 clock <= (clock === 1'b0);
+
+	initial begin
+		clock = 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("pass_thru.vcd");
+	    $dumpvars(0, pass_thru_tb);
+
+	    CSB <= 1'b1;
+	    SCK <= 1'b0;
+	    SDI <= 1'b0;
+	    RSTB <= 1'b0;
+
+	    #2000;
+
+	    RSTB <= 1'b1;
+
+	    // Wait on start of program execution
+	    wait(checkbits == 16'hA000);
+
+            // 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 0x10)", tbdata);
+	    if(tbdata !== 8'h10) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+
+	    start_csb();
+	    write_byte(8'hc4);	// Pass-thru mode
+	    write_byte(8'h03);	// Command 03 (read values w/3-byte address
+	    write_byte(8'h00);	// Address is next three bytes (0x000000)
+	    write_byte(8'h00);
+	    write_byte(8'h00);
+
+	    read_byte(tbdata);
+	    $display("Read flash data = 0x%02x (should be 0x93)", tbdata);
+	    if(tbdata !== 8'h93) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read flash data = 0x%02x (should be 0x00)", tbdata);
+	    if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read flash data = 0x%02x (should be 0x00)", tbdata);
+	    if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read flash data = 0x%02x (should be 0x00)", tbdata);
+	    if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read flash data = 0x%02x (should be 0x93)", tbdata);
+	    if(tbdata !== 8'h93) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read flash data = 0x%02x (should be 0x01)", tbdata);
+	    if(tbdata !== 8'h01) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read flash data = 0x%02x (should be 0x00)", tbdata);
+	    if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+	    read_byte(tbdata);
+	    $display("Read flash data = 0x%02x (should be 0x00)", tbdata);
+	    if(tbdata !== 8'h00) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+
+	    end_csb();
+
+	    // Wait for processor to restart
+	    wait(checkbits == 16'hA000);
+
+	    // Read product ID register again
+
+	    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 0x10)", tbdata);
+	    if(tbdata !== 8'h10) begin $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; end
+
+	    $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;
+
+	wire hk_sck;
+	wire hk_csb;
+	wire hk_sdi;
+
+	assign hk_sck = SCK;
+	assign hk_csb = CSB;
+	assign hk_sdi = SDI;
+
+	assign checkbits = mprj_io[31:16];
+	assign uart_tx = mprj_io[6];
+	assign mprj_io[5] = uart_rx;
+	assign mprj_io[4] = hk_sck;
+	assign mprj_io[3] = hk_csb;
+	assign mprj_io[2] = hk_sdi;
+	assign SDO = mprj_io[1];
+	
+	caravel uut (
+		.vddio	  (VDD3V3),
+		.vssio	  (VSS),
+		.vdda	  (VDD3V3),
+		.vssa	  (VSS),
+		.vccd	  (VDD1V8),
+		.vssd	  (VSS),
+		.vdda1    (VDD3V3),
+		.vdda2    (VDD3V3),
+		.vssa1	  (VSS),
+		.vssa2	  (VSS),
+		.vccd1	  (VDD1V8),
+		.vccd2	  (VDD1V8),
+		.vssd1	  (VSS),
+		.vssd2	  (VSS),
+		.clock	  (clock),
+		.gpio     (gpio),
+		.mprj_io  (mprj_io),
+		.flash_csb(flash_csb),
+		.flash_clk(flash_clk),
+		.flash_io0(flash_io0),
+		.flash_io1(flash_io1),
+		.resetb	  (RSTB)
+	);
+
+	spiflash #(
+		.FILENAME("pass_thru.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(),			// not used
+		.io3()			// not used
+	);
+
+	tbuart tbuart (
+		.ser_rx(uart_tx)
+	);
+		
+endmodule
diff --git a/verilog/dv/caravel/mgmt_soc/timer/Makefile b/verilog/dv/caravel/mgmt_soc/timer/Makefile
new file mode 100644
index 0000000..a7a81eb
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/timer/Makefile
@@ -0,0 +1,40 @@
+FIRMWARE_PATH = ../..
+RTL_PATH = ../../../../rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../ 
+
+GCC_PATH=/ef/apps/bin
+
+.SUFFIXES:
+
+PATTERN = timer
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+	iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS)-I $(IP_PATH) -I $(RTL_PATH) \
+	$< -o $@
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+	${GCC_PATH}/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+	${GCC_PATH}/riscv32-unknown-elf-objcopy -O verilog $< $@ 
+	# to fix flash base address
+	sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+	${GCC_PATH}/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/caravel/mgmt_soc/timer/timer.c b/verilog/dv/caravel/mgmt_soc/timer/timer.c
new file mode 100644
index 0000000..ed74567
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/timer/timer.c
@@ -0,0 +1,95 @@
+#include "../../defs.h"
+
+// --------------------------------------------------------
+
+/*
+ *	Timer Test
+ */
+
+void main()
+{
+	int i;
+
+	/* Set data out to zero */
+	reg_mprj_datal = 0;
+
+	/* Lower 8 pins are input and upper 8 pins are output */
+	reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT;
+	reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT;
+	reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT;
+	reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT;
+	reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT;
+	reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT;
+	reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT;
+	reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+	reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+	reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+	reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+	reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+	reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+	reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+	reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+	reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_NOPULL;
+
+	/* Apply configuration */
+	reg_mprj_xfer = 1;
+	while (reg_mprj_xfer == 1);
+
+	// change the pull up and pull down (checked by the TB)
+	reg_mprj_datal = 0xa0000000;
+
+	reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+	reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+	reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+	reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+
+	reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+	reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+	reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+	reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+
+	/* Apply configuration */
+	reg_mprj_xfer = 1;
+	while (reg_mprj_xfer == 1);
+
+	reg_mprj_datal = 0x0b000000;
+
+	reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+	reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+	reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+	reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+
+	reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+	reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+	reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+	reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+
+	/* Apply configuration */
+	reg_mprj_xfer = 1;
+	while (reg_mprj_xfer == 1);
+
+	reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+	reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+	reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+	reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN;
+
+	reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+	reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+	reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+	reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLUP;
+
+	/* Apply configuration */
+	reg_mprj_xfer = 1;
+	while (reg_mprj_xfer == 1);
+
+	// read the lower 8 pins, add 1 then output the result
+	// checked by the TB
+	reg_mprj_datal = 0xab000000;
+
+	while (1){
+		int x = (reg_mprj_datal & 0xff0000) >> 16;
+		reg_mprj_datal = (x+1) << 24;
+	}
+}
+
diff --git a/verilog/dv/caravel/mgmt_soc/timer/timer_tb.v b/verilog/dv/caravel/mgmt_soc/timer/timer_tb.v
new file mode 100644
index 0000000..0cc67fd
--- /dev/null
+++ b/verilog/dv/caravel/mgmt_soc/timer/timer_tb.v
@@ -0,0 +1,168 @@
+/*
+ *  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 "caravel.v"
+`include "spiflash.v"
+
+module timer_tb;
+	wire VDD3V3;
+	assign VDD3V3 = 1'b1;
+
+	reg clock;
+
+	always #10 clock <= (clock === 1'b0);
+
+	initial begin
+		clock <= 0;
+	end
+
+	initial begin
+		$dumpfile("timer.vcd");
+		$dumpvars(0, timer_tb);
+
+		// Repeat cycles of 1000 clock edges as needed to complete testbench
+		repeat (25) begin
+			repeat (1000) @(posedge clock);
+			$display("+1000 cycles");
+		end
+		$display("%c[1;31m",27);
+		$display ("Monitor: Timeout, Test GPIO (RTL) Failed");
+		 $display("%c[0m",27);
+		$finish;
+	end
+
+	wire [36:0] mprj_io;	// Most of these are no-connects
+	wire [15:0] checkbits;
+	reg  [7:0] checkbits_lo;
+	wire [7:0] checkbits_hi;
+
+	assign mprj_io[23:16] = checkbits_lo;
+	assign checkbits = mprj_io[31:16];
+	assign checkbits_hi = checkbits[15:8];
+
+	wire flash_csb;
+	wire flash_clk;
+	wire flash_io0;
+	wire flash_io1;
+
+	reg RSTB;
+
+	// Transactor
+	initial begin
+		checkbits_lo <= {8{1'bz}};
+		wait(checkbits_hi == 8'hA0);
+		checkbits_lo <= 8'hF0;
+		wait(checkbits_hi == 8'h0B);
+		checkbits_lo <= 8'h0F;
+		wait(checkbits_hi == 8'hAB);
+		checkbits_lo <= 8'h0;
+		repeat (1000) @(posedge clock);
+		checkbits_lo <= 8'h1;
+		repeat (1000) @(posedge clock);
+		checkbits_lo <= 8'h3;
+	end
+
+	// Monitor
+	initial begin
+		wait(checkbits_hi == 8'hA0);
+		wait(checkbits[7:0]  == 8'hF0);
+		wait(checkbits_hi == 8'h0B);
+		wait(checkbits[7:0]  == 8'h0F);
+		wait(checkbits_hi == 8'hAB);
+		wait(checkbits[7:0]  == 8'h00);
+		wait(checkbits_hi == 8'h01);
+		wait(checkbits[7:0]  == 8'h01);
+		wait(checkbits_hi == 8'h02);
+		wait(checkbits[7:0]  == 8'h03);
+		wait(checkbits_hi == 8'h04);
+		$display("Monitor: Test GPIO (RTL) Passed");
+		$finish;
+	end
+
+	initial begin
+		RSTB <= 1'b0;
+		
+		#1000;
+		RSTB <= 1'b1;	    // Release reset
+		#2000;
+	end
+
+	always @(checkbits) begin
+		#1 $display("GPIO state = %b (%d - %d)", checkbits,
+				checkbits_hi, checkbits_lo);
+	end
+
+	wire VDD1V8;
+	wire VSS;
+
+	assign VSS = 1'b0;
+	assign VDD1V8 = 1'b1;
+
+	// These are the mappings of mprj_io GPIO pads that are set to
+	// specific functions on startup:
+	//
+	// JTAG      = mgmt_gpio_io[0]              (inout)
+	// SDO       = mgmt_gpio_io[1]              (output)
+	// SDI       = mgmt_gpio_io[2]              (input)
+	// CSB       = mgmt_gpio_io[3]              (input)
+	// SCK       = mgmt_gpio_io[4]              (input)
+	// ser_rx    = mgmt_gpio_io[5]              (input)
+	// ser_tx    = mgmt_gpio_io[6]              (output)
+	// irq       = mgmt_gpio_io[7]              (input)
+
+	caravel uut (
+		.vddio	  (VDD3V3),
+		.vssio	  (VSS),
+		.vdda	  (VDD3V3),
+		.vssa	  (VSS),
+		.vccd	  (VDD1V8),
+		.vssd	  (VSS),
+		.vdda1    (VDD3V3),
+		.vdda2    (VDD3V3),
+		.vssa1	  (VSS),
+		.vssa2	  (VSS),
+		.vccd1	  (VDD1V8),
+		.vccd2	  (VDD1V8),
+		.vssd1	  (VSS),
+		.vssd2	  (VSS),
+		.clock	  (clock),
+		.gpio     (gpio),
+		.mprj_io  (mprj_io),
+		.flash_csb(flash_csb),
+		.flash_clk(flash_clk),
+		.flash_io0(flash_io0),
+		.flash_io1(flash_io1),
+		.resetb	  (RSTB)
+	);
+
+	spiflash #(
+		.FILENAME("timer.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(),			// not used
+		.io3()			// not used
+	);
+
+endmodule
diff --git a/verilog/rtl/housekeeping_spi.v b/verilog/rtl/housekeeping_spi.v
index 0a1cce6..c6a4860 100644
--- a/verilog/rtl/housekeeping_spi.v
+++ b/verilog/rtl/housekeeping_spi.v
@@ -271,7 +271,7 @@
 // 01000000  Read  until CSB raised
 // 11000000  Simultaneous read/write until CSB raised
 // 11000100  Pass-through read/write to management area flash SPI until CSB raised
-// 11000101  Pass-through read/write to user area flash SPI until CSB raised
+// 11000010  Pass-through read/write to user area flash SPI until CSB raised
 // wrnnn000  Read/write as above, for nnn = 1 to 7 bytes, then terminate
 
 // Lower three bits are reserved for future use.
@@ -414,10 +414,13 @@
 	            readmode <= SDI;
 	        end else if (count < 3'b101) begin
 	            fixed <= {fixed[1:0], SDI}; 
-	        end else if (count < 3'b110) begin
+	        end else if (count == 3'b101) begin
+		    pre_pass_thru_mgmt <= SDI;
+	        end else if (count == 3'b110) begin
+		    pre_pass_thru_user <= SDI;
 		    pass_thru_mgmt_delay <= pre_pass_thru_mgmt;
-		    pass_thru_user_delay <= pre_pass_thru_user;
 	        end else if (count == 3'b111) begin
+		    pass_thru_user_delay <= pre_pass_thru_user;
 		    if (pre_pass_thru_mgmt == 1'b1) begin
 			state <= `MGMTPASS;
 			pre_pass_thru_mgmt <= 1'b0;
@@ -454,7 +457,11 @@
 	        end else begin
 	            rdstb <= 1'b0;
 	        end
-            end		// ! state `DATA
+	    end else if (state == `MGMTPASS) begin
+		pass_thru_mgmt <= 1'b1;
+	    end else if (state == `USERPASS) begin
+		pass_thru_user <= 1'b1;
+            end		// ! state `DATA | `MGMTPASS | `USERPASS
         end		// ! csb_reset 
     end			// always @ SCK
 
diff --git a/verilog/rtl/spimemio.v b/verilog/rtl/spimemio.v
index 2d0b6fe..074fff7 100644
--- a/verilog/rtl/spimemio.v
+++ b/verilog/rtl/spimemio.v
@@ -318,7 +318,7 @@
     assign flash_clk_ieb = 1'b1;	/* Always disabled */
 
     assign flash_io0_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io0_oe : config_oe[0]);
-    assign flash_io1_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io1_oe : config_oe[1]);
+    assign flash_io1_ieb = pass_thru ? 1'b0 : ~resetn ? 1'b1 : (config_en ? xfer_io1_oe : config_oe[1]);
     assign flash_io2_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io2_oe : config_oe[2]);
     assign flash_io3_ieb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? xfer_io3_oe : config_oe[3]);