fibonacci: Import from RELEASE-1.1 caravel_test framework

.. into the fibonacci_test subdirectory.

Signed-off-by: Konrad Rzeszutek Wilk <konrad@kernel.org>
diff --git a/verilog/dv/fibonacci_test/Makefile b/verilog/dv/fibonacci_test/Makefile
new file mode 100644
index 0000000..072d695
--- /dev/null
+++ b/verilog/dv/fibonacci_test/Makefile
@@ -0,0 +1,94 @@
+# 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
+
+## Caravel Pointers
+CARAVEL_ROOT ?= ../../../caravel
+CARAVEL_PATH ?= $(CARAVEL_ROOT)
+CARAVEL_FIRMWARE_PATH = $(CARAVEL_PATH)/verilog/dv/caravel
+CARAVEL_VERILOG_PATH  = $(CARAVEL_PATH)/verilog
+CARAVEL_RTL_PATH = $(CARAVEL_VERILOG_PATH)/rtl
+CARAVEL_BEHAVIOURAL_MODELS = $(CARAVEL_VERILOG_PATH)/dv/caravel
+
+## User Project Pointers
+UPRJ_VERILOG_PATH ?= ../../../verilog
+UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl
+UPRJ_BEHAVIOURAL_MODELS = ../
+
+## RISCV GCC
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+
+# include the modules that cocotb needs for test
+#export PYTHONPATH := $(UPRJ_RTL_PATH)/wrapped_wrapper/wrapper/test
+
+.SUFFIXES:
+
+PATTERN = wrapper
+
+all:  coco_test
+
+hex:  ${PATTERN:=.hex}
+
+coco_test: ${PATTERN}.hex
+	rm -rf sim_build/
+	mkdir sim_build/
+	iverilog -o sim_build/sim.vvp -s wrapper_tb wrapper_tb.v -DSIM -DFUNCTIONAL \
+	-I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH)
+	MODULE=test_caravel vvp -M $$(cocotb-config --prefix)/cocotb/libs -m libcocotbvpi_icarus sim_build/sim.vvp
+	! grep failure results.xml
+
+%.vvp: %_tb.v %.hex
+ifeq ($(SIM),RTL)
+	iverilog -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) \
+	$< -o $@
+else
+	iverilog -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS) -I$(UPRJ_RTL_PATH)   -I $(UPRJ_VERILOG_PATH) \
+	$< -o $@
+endif
+
+%.vcd: %.vvp
+	vvp $<
+
+test:
+	echo ${GCC_PATH}/${GCC_PREFIX}-gcc -I $(CARAVEL_PATH) -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(CARAVEL_FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(CARAVEL_FIRMWARE_PATH)/start.s $<
+
+%.elf: %.c sections.lds start.S
+	${GCC_PATH}/${GCC_PREFIX}-gcc -I $(CARAVEL_PATH) -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ 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
+
+.PHONY: clean hex all
diff --git a/verilog/dv/fibonacci_test/__init__.py b/verilog/dv/fibonacci_test/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/verilog/dv/fibonacci_test/__init__.py
diff --git a/verilog/dv/fibonacci_test/custom_ops.S b/verilog/dv/fibonacci_test/custom_ops.S
new file mode 100644
index 0000000..e3d1e2d
--- /dev/null
+++ b/verilog/dv/fibonacci_test/custom_ops.S
@@ -0,0 +1,116 @@
+/*
+ *  SPDX-FileCopyrightText: 2015 Clifford Wolf
+ *  PicoRV32 -- A Small RISC-V (RV32I) Processor Core
+ *
+ *  Copyright (C) 2015  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.
+ *
+ *  SPDX-License-Identifier: ISC
+ */
+
+#define regnum_q0   0
+#define regnum_q1   1
+#define regnum_q2   2
+#define regnum_q3   3
+
+#define regnum_x0   0
+#define regnum_x1   1
+#define regnum_x2   2
+#define regnum_x3   3
+#define regnum_x4   4
+#define regnum_x5   5
+#define regnum_x6   6
+#define regnum_x7   7
+#define regnum_x8   8
+#define regnum_x9   9
+#define regnum_x10 10
+#define regnum_x11 11
+#define regnum_x12 12
+#define regnum_x13 13
+#define regnum_x14 14
+#define regnum_x15 15
+#define regnum_x16 16
+#define regnum_x17 17
+#define regnum_x18 18
+#define regnum_x19 19
+#define regnum_x20 20
+#define regnum_x21 21
+#define regnum_x22 22
+#define regnum_x23 23
+#define regnum_x24 24
+#define regnum_x25 25
+#define regnum_x26 26
+#define regnum_x27 27
+#define regnum_x28 28
+#define regnum_x29 29
+#define regnum_x30 30
+#define regnum_x31 31
+
+#define regnum_zero 0
+#define regnum_ra   1
+#define regnum_sp   2
+#define regnum_gp   3
+#define regnum_tp   4
+#define regnum_t0   5
+#define regnum_t1   6
+#define regnum_t2   7
+#define regnum_s0   8
+#define regnum_s1   9
+#define regnum_a0  10
+#define regnum_a1  11
+#define regnum_a2  12
+#define regnum_a3  13
+#define regnum_a4  14
+#define regnum_a5  15
+#define regnum_a6  16
+#define regnum_a7  17
+#define regnum_s2  18
+#define regnum_s3  19
+#define regnum_s4  20
+#define regnum_s5  21
+#define regnum_s6  22
+#define regnum_s7  23
+#define regnum_s8  24
+#define regnum_s9  25
+#define regnum_s10 26
+#define regnum_s11 27
+#define regnum_t3  28
+#define regnum_t4  29
+#define regnum_t5  30
+#define regnum_t6  31
+
+// x8 is s0 and also fp
+#define regnum_fp   8
+
+#define r_type_insn(_f7, _rs2, _rs1, _f3, _rd, _opc) \
+.word (((_f7) << 25) | ((_rs2) << 20) | ((_rs1) << 15) | ((_f3) << 12) | ((_rd) << 7) | ((_opc) << 0))
+
+#define picorv32_getq_insn(_rd, _qs) \
+r_type_insn(0b0000000, 0, regnum_ ## _qs, 0b100, regnum_ ## _rd, 0b0001011)
+
+#define picorv32_setq_insn(_qd, _rs) \
+r_type_insn(0b0000001, 0, regnum_ ## _rs, 0b010, regnum_ ## _qd, 0b0001011)
+
+#define picorv32_retirq_insn() \
+r_type_insn(0b0000010, 0, 0, 0b000, 0, 0b0001011)
+
+#define picorv32_maskirq_insn(_rd, _rs) \
+r_type_insn(0b0000011, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011)
+
+#define picorv32_waitirq_insn(_rd) \
+r_type_insn(0b0000100, 0, 0, 0b100, regnum_ ## _rd, 0b0001011)
+
+#define picorv32_timer_insn(_rd, _rs) \
+r_type_insn(0b0000101, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011)
+
diff --git a/verilog/dv/fibonacci_test/sections.lds b/verilog/dv/fibonacci_test/sections.lds
new file mode 100644
index 0000000..c328222
--- /dev/null
+++ b/verilog/dv/fibonacci_test/sections.lds
@@ -0,0 +1,83 @@
+/*
+# 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
+*/
+
+/*
+ *-------------------------------------------------------------------------
+ * Note:  This is like the default sections.lds file for Caravel, but moves
+ * the start of SRAM used by the compiler to address 0x80 to make room for
+ * memory used by the firmware routines defined in the local start.S file.
+ *-------------------------------------------------------------------------
+ */
+
+MEMORY {
+	FLASH (rx)	: ORIGIN = 0x10000000, LENGTH = 0x400000 	/* 4MB */
+	RAM(xrw)	: ORIGIN = 0x00000080, LENGTH = 0x0380		/* 256 words (1 KB) */ 
+}
+
+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/dv/fibonacci_test/start.S b/verilog/dv/fibonacci_test/start.S
new file mode 100644
index 0000000..ed66ceb
--- /dev/null
+++ b/verilog/dv/fibonacci_test/start.S
@@ -0,0 +1,217 @@
+/*
+ * 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
+ */
+
+/*-----------------------------------------------*/
+/* Start code that enables and handles IRQs 	 */
+/*-----------------------------------------------*/
+/* Code modified specifically for this testbench */
+/*-----------------------------------------------*/
+
+#undef ENABLE_FASTIRQ
+
+#include "custom_ops.S"
+
+.section .text
+.global irq
+
+reset_vec:
+	j start
+
+.balign 16
+# this interrupt handler adapted from Claire's here: 
+# https://raw.githubusercontent.com/cliffordwolf/picorv32/master/firmware/start.S
+irq_vec:
+    /* save registers */
+
+    sw gp,   0*4+0x200(zero)
+    sw x1,   1*4+0x200(zero)
+    sw x2,   2*4+0x200(zero)
+    sw x3,   3*4+0x200(zero)
+    sw x4,   4*4+0x200(zero)
+    sw x5,   5*4+0x200(zero)
+    sw x6,   6*4+0x200(zero)
+    sw x7,   7*4+0x200(zero)
+    sw x8,   8*4+0x200(zero)
+    sw x9,   9*4+0x200(zero)
+    sw x10, 10*4+0x200(zero)
+    sw x11, 11*4+0x200(zero)
+    sw x12, 12*4+0x200(zero)
+    sw x13, 13*4+0x200(zero)
+    sw x14, 14*4+0x200(zero)
+    sw x15, 15*4+0x200(zero)
+    sw x16, 16*4+0x200(zero)
+    sw x17, 17*4+0x200(zero)
+    sw x18, 18*4+0x200(zero)
+    sw x19, 19*4+0x200(zero)
+    sw x20, 20*4+0x200(zero)
+    sw x21, 21*4+0x200(zero)
+    sw x22, 22*4+0x200(zero)
+    sw x23, 23*4+0x200(zero)
+    sw x24, 24*4+0x200(zero)
+    sw x25, 25*4+0x200(zero)
+    sw x26, 26*4+0x200(zero)
+    sw x27, 27*4+0x200(zero)
+    sw x28, 28*4+0x200(zero)
+    sw x29, 29*4+0x200(zero)
+    sw x30, 30*4+0x200(zero)
+    sw x31, 31*4+0x200(zero)
+
+    // call to C function
+    jal ra, irq
+
+    // retire interrupt
+    picorv32_retirq_insn()
+
+.balign 0x200
+irq_regs:
+    // registers are saved to this memory region during interrupt handling
+    // the program counter is saved as register 0
+    .fill 32,4
+
+
+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
+
+# This part copied from Tim's demo. 
+# Write these instructions to memory location zero and following:
+# lui t4, 0x10000	= 10000eb7
+# addi t4, t4, 4	= 0e91
+# jalr t4, 0		= 000e80e7
+#
+# These three instructions jump to 0x10000004, which is the location
+# of the interrupt handler.  For a fast interrupt handler, the whole
+# handler should be moved into SRAM.
+li  t4, 0x10000eb7
+sw  t4, 0(zero)
+li  t4, 0x80e70e91
+sw  t4, 4(zero)
+li  t4, 0x000e
+sw  t4, 8(zero)
+
+# Enable the user interrupts only on irq[14:12]
+# needs to be 0 to allow the interrupt
+# https://github.com/efabless/caravel-lite/blob/13f2590e4b3a74b910dac56a6b757f5a66fd5212/verilog/rtl/mgmt_soc.v#L360
+li   t4, 0x8FFF 
+picorv32_maskirq_insn(t4, t4)
+
+# call main
+call main
+loop:
+j loop
+
+.global flashio_worker_begin
+.global flashio_worker_end
+
+flashio_worker_begin:
+# a0 ... data pointer
+# a1 ... data length
+# a2 ... optional WREN cmd (0 = disable)
+
+# address of SPI ctrl reg
+li   t0, 0x02000000
+
+# 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:
+beqz a1, flashio_worker_L3
+li   t5, 8
+lbu  t2, 0(a0)
+flashio_worker_L2:
+srli t4, t2, 7
+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
+andi t2, t2, 0xff
+addi t5, t5, -1
+bnez t5, flashio_worker_L2
+sb   t2, 0(a0)
+addi a0, a0, 1
+addi a1, a1, -1
+j    flashio_worker_L1
+flashio_worker_L3:
+
+# Back to MEMIO mode
+li   t1, 0x80
+sb   t1, 3(t0)
+
+ret
+flashio_worker_end:
+
diff --git a/verilog/dv/fibonacci_test/test_caravel.py b/verilog/dv/fibonacci_test/test_caravel.py
new file mode 100644
index 0000000..caefaf7
--- /dev/null
+++ b/verilog/dv/fibonacci_test/test_caravel.py
@@ -0,0 +1,122 @@
+import cocotb
+from cocotb.clock import Clock
+from cocotb.binary import BinaryValue
+from cocotb.triggers import ClockCycles, RisingEdge, FallingEdge;
+from cocotb.result import TestSuccess;
+
+@cocotb.test()
+async def test_start(dut):
+    clock = Clock(dut.clock, 10, units="ns")
+    cocotb.fork(clock.start())
+
+    dut.RSTB <= 0
+    dut.power1 <= 0;
+    dut.power2 <= 0;
+    dut.power3 <= 0;
+    dut.power4 <= 0;
+    dut.uut.mprj.wrapper_fibonacci.wbs_dat_i.value <= 0;
+
+    dut._log.info("Cycling power");
+    await ClockCycles(dut.clock, 8)
+    dut.power1 <= 1;
+    await ClockCycles(dut.clock, 8)
+    dut.power2 <= 1;
+    await ClockCycles(dut.clock, 8)
+    dut.power3 <= 1;
+    await ClockCycles(dut.clock, 8)
+    dut.power4 <= 1;
+
+    await ClockCycles(dut.clock, 80)
+    dut.RSTB <= 1
+
+    dut._log.info("Waiting for active (This can take a while)");
+    # wait for the project to become active
+    # wrapper.v has  .active     (la_data_in[32+0])
+    # wrapper.c: reg_la1_ena = 0;
+    #            reg_la1_data = 1; /* 0x2500,0004 */
+    await RisingEdge(dut.uut.mprj.wrapper_fibonacci.active)
+    dut._log.info("Active ON");
+
+async def test_wb(dut, i):
+
+    ack_str = "";
+    addr = int(dut.uut.mprj.wrapper_fibonacci.wbs_adr_i.value);
+    data = int(dut.uut.mprj.wrapper_fibonacci.wbs_dat_o.value);
+    ack = int(dut.uut.mprj.wrapper_fibonacci.wbs_ack_o.value);
+    try:
+        data_i = int(dut.uut.mprj.wrapper_fibonacci.wbs_dat_i.value);
+    except:
+        dut._log.info("%4d %s %s DATA_IN=RAW[%s] DATA_OUT=%s" % (i, hex(addr), ack_str,  dut.uut.mprj.wrapper_fibonacci.wbs_dat_i.value, hex(data)));
+        pass
+
+    if (addr >= 0x30000000):
+        if (ack == 1):
+            ack_str = "ACK";
+
+        dut._log.info("%4d %s %s DATA_IN=%s DATA_OUT=%s" % (i, hex(addr), ack_str,  hex(data_i), hex(data)));
+
+        if (ack == 0):
+            return;
+
+        if (addr == 0x30000000): # CTRL_GET_NR
+            assert(data == 9);
+
+        if (addr == 0x30000004): # CTRL_GET_ID
+            assert(data == 0x4669626f);
+
+        if (addr == 0x30000020): # CTRL_PANIC
+            assert (data_i == 0x0badf00d); # It is a write..
+
+            raise TestSuccess
+
+@cocotb.test()
+async def test_values(dut):
+    clock = Clock(dut.clock, 10, units="ns")
+    cocotb.fork(clock.start())
+
+    # wait for the reset (
+    dut._log.info("Waiting for reset");
+
+    #         /* .reset(la_data_in[0]) */
+    # reg_la0_ena = 0; /* 0x2500,0010 */
+    # reg_la0_data = 1; /* RST on 0x2500,0000*/
+
+    await RisingEdge(dut.uut.mprj.wrapper_fibonacci.Fibonacci.reset)
+    await FallingEdge(dut.uut.mprj.wrapper_fibonacci.Fibonacci.reset)
+    dut._log.info("Reset done");
+
+    await ClockCycles(dut.clock,1)
+
+    value = str(dut.mprj_io.value)[:-8].replace('z','');
+
+    dut._log.info("dut.mprj_io=%d" % (int(value)));
+    assert (int(value) == 0);
+
+    prio_value = 0;
+    p_prio_value = 0;
+
+    for i in range(50):
+        # We get these annoying 'ZZ' in there, so we do this dance to get rid of it.
+        value = BinaryValue(str(dut.mprj_io.value)[:-8].replace('z',''));
+
+        current_value  = int(value);
+
+        if (i == 0) or ((i > 0) and ((i % 44) == 0)):
+            prio_value = 0;
+            p_prio_value = 0;
+        if (i == 1) or ((i > 1) and ((i % 45) == 0)):
+            p_prio_value = 0;
+            prio_value = 1;
+
+        #print("i = %d p_prio_value=%d,prio_value=%d,current_value=%d" % (i, p_prio_value, prio_value, current_value));
+        assert (current_value == (prio_value + p_prio_value));
+        if (i >= 2) and ((i % 44) and (i % 45)):
+            p_prio_value = prio_value;
+            prio_value = current_value;
+
+        await ClockCycles(dut.clock,1)
+
+    for i in range(300000):
+
+        await ClockCycles(dut.clock,1)
+        await test_wb(dut, i);
diff --git a/verilog/dv/fibonacci_test/wrapper.c b/verilog/dv/fibonacci_test/wrapper.c
new file mode 100644
index 0000000..40dc5aa
--- /dev/null
+++ b/verilog/dv/fibonacci_test/wrapper.c
@@ -0,0 +1,191 @@
+/*
+ * 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
+ */
+
+#include "verilog/dv/caravel/defs.h"
+#include "verilog/dv/caravel/stub.c"
+
+#define BASE_ADDRESS 		0x30000000
+#define CTRL_GET_NR		(BASE_ADDRESS + 0x00)
+#define CTRL_GET_ID		(BASE_ADDRESS + 0x04)
+#define CTRL_SET_IRQ		(BASE_ADDRESS + 0x08)
+#define CTRL_FIBONACCI_CTRL	(BASE_ADDRESS + 0x0c)
+#define CTRL_FIBONACCI_CLOCK	(BASE_ADDRESS + 0x10)
+#define CTRL_FIBONACCI_VAL	(BASE_ADDRESS + 0x14)
+#define CTRL_WRITE		(BASE_ADDRESS + 0x18)
+#define CTRL_READ		(BASE_ADDRESS + 0x1C)
+#define CTRL_PANIC		(BASE_ADDRESS + 0x20)
+
+#define CTRL_ID			0x4669626f
+#define CTRL_NR			9
+
+static uint32_t read(unsigned long addr)
+{
+	return *(volatile uint32_t *)addr;
+}
+
+static void write(unsigned long addr, uint32_t val)
+{
+	*(volatile uint32_t *)addr = val;
+}
+
+
+void configure_gpio(void)
+{
+        reg_mprj_io_37 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_36 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_35 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_34 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_33 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_32 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_31 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_30 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_29 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_28 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_27 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_26 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_25 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_24 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_23 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_22 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_21 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_20 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_19 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_18 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_17 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_16 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_15 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_14 = GPIO_MODE_USER_STD_OUTPUT;
+
+        reg_mprj_io_13 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_12 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_11 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_10 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_9 = GPIO_MODE_USER_STD_OUTPUT;
+        reg_mprj_io_8 = GPIO_MODE_USER_STD_OUTPUT;
+
+	/* Enable user IRQs */
+	reg_mprj_irq = 3;
+}
+
+void activate(void)
+{
+	/* [31:0] is	reg_la0_oenb, 0x2500,0010
+	 * [63:32] is	reg_la1_oenb, 0x2500,0014
+	 * [95:64] is	reg_la2_oenb  0x2500,0018
+	 * [127:96] is	reg_la3_oenb  0x2500,001C
+	 *
+	 * All data go on la_data_in[127:0] , which starts
+	 * at 0x2500,0000
+	 */
+	reg_la1_iena = 0 << 3; /* 0x25000024: Input enable off */
+	reg_la1_oenb = 0 << 3; /* 0x25000014: 32th, corresponds to active */
+	/* .active() HIGH */
+	reg_la1_data = 1 << 3; /* 0x25000004 */
+}
+
+void reset(void)
+{
+	/* .reset(la_data_in[0]) */
+	reg_la0_iena = 0;
+	reg_la0_oenb = 0; /* 0x2500,0010 */
+
+	reg_la0_data = 1; /* RST on 0x2500,0000*/
+	reg_la0_data = 0; /* RST off */
+}
+
+void panic(uint32_t line)
+{
+	/* TODO: Strobe LEDs or UART. 6/7*/
+	do {
+		write(CTRL_PANIC, line);
+	} while (1);
+
+}
+#define BUG_ON(x) { if ((x)) panic(__LINE__); }
+
+#define MAGIC_VAL 0xdeadbeef
+#define MAGIC_END 0x0badf00d
+
+volatile bool flag;
+
+// gets jumped to from the interrupt handler defined in start.S
+uint32_t *irq()
+{
+	flag = 0;
+
+	write(CTRL_SET_IRQ, 0); /* Ack the IRQ */
+
+	write(CTRL_PANIC, MAGIC_END);
+}
+
+void wishbone_test(void)
+{
+	uint32_t val;
+
+	val = read(CTRL_GET_ID);
+	BUG_ON(val != CTRL_ID);
+
+	val = read(CTRL_GET_NR);
+	BUG_ON(val != CTRL_NR);
+
+	write(CTRL_FIBONACCI_CTRL, 0);
+	val = read(CTRL_FIBONACCI_CTRL);
+        BUG_ON(val != 0);
+
+	write(CTRL_FIBONACCI_CTRL, 1);
+	val = read(CTRL_FIBONACCI_CTRL);
+        BUG_ON(val != 1);
+
+	val = read(CTRL_FIBONACCI_VAL);
+
+	write(CTRL_WRITE, MAGIC_VAL);
+	val = read(CTRL_READ);
+	BUG_ON(val != MAGIC_VAL);
+
+	val = 1 << 1;
+	write(CTRL_FIBONACCI_CLOCK, val);
+
+	val = 1 << 0;
+	write(CTRL_SET_IRQ, val);
+
+	do {
+		// Spin until IRQ comes
+	} while (flag);
+
+	write(CTRL_PANIC, MAGIC_END);
+}
+
+void main()
+{
+	flag = 1;
+
+	// All GPIO pins are configured to be output
+	configure_gpio();
+
+        /* Apply configuration */
+        reg_mprj_xfer = 1;
+        while (reg_mprj_xfer == 1);
+
+	activate();
+
+	reset();
+
+	wishbone_test();
+	/* There it goes .. */
+
+}
+
diff --git a/verilog/dv/fibonacci_test/wrapper.gtkw b/verilog/dv/fibonacci_test/wrapper.gtkw
new file mode 100644
index 0000000..c1295d7
--- /dev/null
+++ b/verilog/dv/fibonacci_test/wrapper.gtkw
@@ -0,0 +1,65 @@
+[*]
+[*] GTKWave Analyzer v3.3.103 (w)1999-2019 BSI
+[*] Fri Jun  4 22:54:35 2021
+[*]
+[dumpfile] "/home/zerotoasic/caravel_user_project/verilog/dv/caravel_test/wrapper_tb.vcd"
+[dumpfile_mtime] "Fri Jun  4 22:54:01 2021"
+[dumpfile_size] 380876468
+[savefile] "/home/zerotoasic/caravel_user_project/verilog/dv/caravel_test/wrapper.gtkw"
+[timestart] 309998
+[size] 1433 953
+[pos] -1 -1
+*0.000000 310000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[treeopen] wrapper_tb.
+[treeopen] wrapper_tb.uut.
+[treeopen] wrapper_tb.uut.mprj.
+[sst_width] 214
+[signals_width] 274
+[sst_expanded] 1
+[sst_vpaned_height] 276
+@28
+wrapper_tb.uut.mprj.wrapper_fibonacci.active
+@22
+wrapper_tb.uut.mprj.wrapper_fibonacci.buf_io_oeb[37:0]
+wrapper_tb.uut.mprj.wrapper_fibonacci.buf_io_out[37:0]
+@28
+wrapper_tb.uut.mprj.wrapper_fibonacci.buf_irq[2:0]
+@22
+wrapper_tb.uut.mprj.wrapper_fibonacci.buf_la_data_out[31:0]
+@28
+wrapper_tb.uut.mprj.wrapper_fibonacci.buf_wbs_ack_o
+@22
+wrapper_tb.uut.mprj.wrapper_fibonacci.buf_wbs_dat_o[31:0]
+wrapper_tb.uut.mprj.wrapper_fibonacci.clock_op[5:0]
+wrapper_tb.uut.mprj.wrapper_fibonacci.clocks[5:0]
+@28
+wrapper_tb.uut.mprj.wrapper_fibonacci.fibonacci_clock
+wrapper_tb.uut.mprj.wrapper_fibonacci.fibonacci_switch
+@22
+wrapper_tb.uut.mprj.wrapper_fibonacci.io_in[37:0]
+wrapper_tb.uut.mprj.wrapper_fibonacci.io_oeb[37:0]
+wrapper_tb.uut.mprj.wrapper_fibonacci.io_out[37:0]
+@29
+wrapper_tb.uut.mprj.wrapper_fibonacci.irq[2:0]
+@22
+wrapper_tb.uut.mprj.wrapper_fibonacci.la_data_in[31:0]
+wrapper_tb.uut.mprj.wrapper_fibonacci.la_data_out[31:0]
+wrapper_tb.uut.mprj.wrapper_fibonacci.la_oenb[31:0]
+@28
+wrapper_tb.uut.mprj.wrapper_fibonacci.reset
+wrapper_tb.uut.mprj.wrapper_fibonacci.wb_clk_i
+wrapper_tb.uut.mprj.wrapper_fibonacci.wb_rst_i
+wrapper_tb.uut.mprj.wrapper_fibonacci.wbs_ack_o
+@22
+wrapper_tb.uut.mprj.wrapper_fibonacci.wbs_adr_i[31:0]
+@28
+wrapper_tb.uut.mprj.wrapper_fibonacci.wbs_cyc_i
+@22
+wrapper_tb.uut.mprj.wrapper_fibonacci.wbs_dat_i[31:0]
+wrapper_tb.uut.mprj.wrapper_fibonacci.wbs_dat_o[31:0]
+wrapper_tb.uut.mprj.wrapper_fibonacci.wbs_sel_i[3:0]
+@28
+wrapper_tb.uut.mprj.wrapper_fibonacci.wbs_stb_i
+wrapper_tb.uut.mprj.wrapper_fibonacci.wbs_we_i
+[pattern_trace] 1
+[pattern_trace] 0
diff --git a/verilog/dv/fibonacci_test/wrapper_tb.v b/verilog/dv/fibonacci_test/wrapper_tb.v
new file mode 100644
index 0000000..acf68ae
--- /dev/null
+++ b/verilog/dv/fibonacci_test/wrapper_tb.v
@@ -0,0 +1,87 @@
+// 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 "uprj_netlists.v" // this file gets created automatically by multi_project_tools from the source section of info.yaml
+`include "caravel_netlists.v"
+`include "spiflash.v"
+
+module wrapper_tb;
+    initial begin
+        $dumpfile ("wrapper_tb.vcd");
+        $dumpvars (0, wrapper_tb);
+        #1;
+    end
+
+	reg clock;
+    reg RSTB;
+	reg power1, power2;
+	reg power3, power4;
+
+    wire gpio;
+    wire [37:0] mprj_io;
+
+	wire flash_csb;
+	wire flash_clk;
+	wire flash_io0;
+	wire flash_io1;
+
+	wire VDD3V3 = power1;
+	wire VDD1V8 = power2;
+	wire USER_VDD3V3 = power3;
+	wire USER_VDD1V8 = power4;
+	wire VSS = 1'b0;
+
+	caravel uut (
+		.vddio	  (VDD3V3),
+		.vssio	  (VSS),
+		.vdda	  (VDD3V3),
+		.vssa	  (VSS),
+		.vccd	  (VDD1V8),
+		.vssd	  (VSS),
+		.vdda1    (USER_VDD3V3),
+		.vdda2    (USER_VDD3V3),
+		.vssa1	  (VSS),
+		.vssa2	  (VSS),
+		.vccd1	  (USER_VDD1V8),
+		.vccd2	  (USER_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("wrapper.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(),			// not used
+		.io3()			// not used
+	);
+
+endmodule
+`default_nettype wire