Add miner testbench
diff --git a/build b/build
new file mode 100755
index 0000000..d3b2ee9
--- /dev/null
+++ b/build
@@ -0,0 +1,6 @@
+#!/bin/bash
+cd openlane
+make user_proj_example | tee ../user_proj_example.log
+make user_project_wrapper | tee ../user_project_wrapper.log
+cd ..
+make ship | tee ../ship.log
diff --git a/verilog/dv/caravel/user_proj_example/miner_test/Makefile b/verilog/dv/caravel/user_proj_example/miner_test/Makefile
new file mode 100644
index 0000000..f6bf3f8
--- /dev/null
+++ b/verilog/dv/caravel/user_proj_example/miner_test/Makefile
@@ -0,0 +1,54 @@
+FIRMWARE_PATH = ../..
+RTL_PATH = ../../../../rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../ 
+
+GCC_PATH?=/opt/riscv32imc/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=~/openlane/pdks/sky130A
+GCC_OPTS=-fverbose-asm -Wa,-adhlns="$@.lst" -Wl,-Map=$@.map
+GCC_OPTS+=-march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug
+GCC_OPTS+=-ffreestanding -nostdlib
+GCC_OPTS+=-O3
+
+SIM?=RTL
+
+.SUFFIXES:
+
+PATTERN = miner_test
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ifeq ($(SIM),RTL)
+	iverilog -DFUNCTIONAL -DSIM -I $(BEHAVIOURAL_MODELS) \
+	-I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \
+	$< -o $@
+else
+	iverilog -DFUNCTIONAL -DSIM -DGL -I $(BEHAVIOURAL_MODELS) \
+	-I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \
+	$< -o $@
+endif
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s
+	${GCC_PATH}/${GCC_PREFIX}-gcc ${GCC_OPTS} -o $@ $(FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+	${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@ 
+	# to fix flash base address
+	sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+	${GCC_PATH}/${GCC_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.lst *.map
+
+.PHONY: clean hex all
diff --git a/verilog/dv/caravel/user_proj_example/miner_test/miner_test.c b/verilog/dv/caravel/user_proj_example/miner_test/miner_test.c
new file mode 100644
index 0000000..b1b8a5c
--- /dev/null
+++ b/verilog/dv/caravel/user_proj_example/miner_test/miner_test.c
@@ -0,0 +1,86 @@
+#include "../../defs.h"
+#include "../../stub.c"
+
+static volatile unsigned *regs = (unsigned*)0x30000000U;
+
+static const unsigned soln_b = 0;
+static const unsigned stat_b = 2;
+static const unsigned hdr_b = 4;
+static const unsigned diff_b = 12;
+static const unsigned start_b = 20;
+static const unsigned ctl_b = 22;
+
+// header: 644a7f32 cc155134 2997512a df12ab67 b94e7a63 2a26a07e d4615959 dd8d5b09
+// nonce:  1883832e 85da0f7a
+// hash:   a4b44b86 80040878 f767b763 c46bbca6 19c1e1af 1c5c37da 42e11e05 8cb09ca0
+
+static inline void write_reg(unsigned r, unsigned v) {
+    regs[r] = v;
+}
+
+static inline unsigned read_reg(unsigned r) {
+    return regs[r];
+}
+
+
+void main()
+{
+    unsigned long long start, s, solution;
+    unsigned status;
+
+	// Set UART clock to 64 kbaud (enable before I/O configuration)
+	reg_uart_clkdiv = 625;
+	reg_uart_enable = 1;
+
+        /* Apply configuration */
+        reg_mprj_xfer = 1;
+        while (reg_mprj_xfer == 1);
+
+    for (int i = 0; i < 32; i++) {
+        write_reg(ctl_b, 0);
+        // header 
+        write_reg(hdr_b + 0, (0x644a7f32));
+        write_reg(hdr_b + 1, (0xcc155134));
+        write_reg(hdr_b + 2, (0x2997512a));
+        write_reg(hdr_b + 3, (0xdf12ab67));
+        write_reg(hdr_b + 4, (0xb94e7a63));
+        write_reg(hdr_b + 5, (0x2a26a07e));
+        write_reg(hdr_b + 6, (0xd4615959));
+        write_reg(hdr_b + 7, (0xdd8d5b09));
+        // start nonce
+        start = 0x1883832e85da0f7aULL;
+        s = start - i;
+        write_reg(start_b + 1, (unsigned)s);
+        write_reg(start_b + 0, s >> 32);
+        // diff
+        write_reg(diff_b + 0, (0xa4b44b86));
+        write_reg(diff_b + 1, (0x80040878));
+        write_reg(diff_b + 2, (0xf767b763));
+        write_reg(diff_b + 3, (0xc46bbca6));
+        write_reg(diff_b + 4, (0x19c1e1af));
+        write_reg(diff_b + 5, (0x1c5c37da));
+        write_reg(diff_b + 6, (0x42e11e05));
+        write_reg(diff_b + 7, (0x8cb09ca0));
+
+        // control
+        write_reg(ctl_b, 0x01800003);
+           
+        for (int j = 0; j < 5000000; j = j + 1) {
+            status = read_reg(stat_b);
+            if ((status & 7) == 7)
+                break;
+        }
+        status = read_reg(ctl_b);
+        solution = read_reg(soln_b + 0) +
+            ((unsigned long long)read_reg(soln_b + 1) << 32);
+        write_reg(ctl_b, 0);
+        if ((solution != start) || ((status & 7) != 7)) {
+	    print("\nFailed\n");	// Makes simulation very long!
+	    reg_mprj_datal = 0xAB510000;
+            return;
+        }
+    }
+    print("\nPassed\n");	// Makes simulation very long!
+    reg_mprj_datal = 0xAB510000;
+}
+
diff --git a/verilog/dv/caravel/user_proj_example/miner_test/miner_test_tb.v b/verilog/dv/caravel/user_proj_example/miner_test/miner_test_tb.v
new file mode 100644
index 0000000..31f6d34
--- /dev/null
+++ b/verilog/dv/caravel/user_proj_example/miner_test/miner_test_tb.v
@@ -0,0 +1,138 @@
+// SPDX-FileCopyrightText: 2020 Efabless Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+
+`default_nettype none
+
+`timescale 1 ns / 1 ps
+
+`include "caravel.v"
+`include "spiflash.v"
+`include "tbuart.v"
+
+module miner_test_tb;
+	reg clock;
+    	reg RSTB;
+	reg power1, power2;
+
+    	wire gpio;
+	wire uart_tx;
+    	wire [37:0] mprj_io;
+	wire [15:0] checkbits;
+
+	assign checkbits  = mprj_io[31:16];
+	assign uart_tx = mprj_io[6];
+
+	always #12.5 clock <= (clock === 1'b0);
+
+	initial begin
+		clock = 0;
+	end
+
+	initial begin
+		$dumpfile("miner_test.vcd");
+		$dumpvars(0, miner_test_tb);
+
+		// Repeat cycles of 1000 clock edges as needed to complete testbench
+		repeat (200) begin
+			repeat (1000) @(posedge clock);
+			$display("+1000 cycles");
+		end
+		$display("%c[1;31m",27);
+		$display ("Monitor: Timeout, Test Mega-Project IO (RTL) Failed");
+		$display("%c[0m",27);
+		$finish;
+	end
+
+	initial begin
+		wait(checkbits == 16'hAB40);
+		$display("Miner test started");
+		wait(checkbits == 16'hAB41);
+		wait(checkbits == 16'hAB51);
+		#10000;
+		$finish;
+	end
+
+	initial begin
+		RSTB <= 1'b0;
+		#1000;
+		RSTB <= 1'b1;	    // Release reset
+		#2000;
+	end
+
+	initial begin		// Power-up sequence
+		power1 <= 1'b0;
+		power2 <= 1'b0;
+		#200;
+		power1 <= 1'b1;
+		#200;
+		power2 <= 1'b1;
+	end
+
+    	wire flash_csb;
+	wire flash_clk;
+	wire flash_io0;
+	wire flash_io1;
+
+	wire VDD1V8;
+    	wire VDD3V3;
+	wire VSS;
+    
+	assign VDD3V3 = power1;
+	assign VDD1V8 = power2;
+	assign VSS = 1'b0;
+
+	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("miner_test.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(),			// not used
+		.io3()			// not used
+	);
+
+	// Testbench UART
+	tbuart tbuart (
+		.ser_rx(uart_tx)
+	);
+
+endmodule
+`default_nettype wire