caravel_test: Import from git@github.com:konradwilk/sha1.git

046ef581e5191a01ea3d8b2537ddfc44783dd941

Signed-off-by: Konrad Rzeszutek Wilk <konrad@kernel.org>
diff --git a/verilog/dv/caravel_test/Makefile b/verilog/dv/caravel_test/Makefile
new file mode 100644
index 0000000..072d695
--- /dev/null
+++ b/verilog/dv/caravel_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/caravel_test/__init__.py b/verilog/dv/caravel_test/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/verilog/dv/caravel_test/__init__.py
diff --git a/verilog/dv/caravel_test/custom_ops.S b/verilog/dv/caravel_test/custom_ops.S
new file mode 100644
index 0000000..e3d1e2d
--- /dev/null
+++ b/verilog/dv/caravel_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/caravel_test/sections.lds b/verilog/dv/caravel_test/sections.lds
new file mode 100644
index 0000000..c328222
--- /dev/null
+++ b/verilog/dv/caravel_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/caravel_test/start.S b/verilog/dv/caravel_test/start.S
new file mode 100644
index 0000000..ed66ceb
--- /dev/null
+++ b/verilog/dv/caravel_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/caravel_test/test_caravel.py b/verilog/dv/caravel_test/test_caravel.py
new file mode 100644
index 0000000..6a3f870
--- /dev/null
+++ b/verilog/dv/caravel_test/test_caravel.py
@@ -0,0 +1,96 @@
+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_sha1.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_sha1.active)
+    dut._log.info("Active ON");
+
+async def test_wb(dut, i):
+
+    ack_str = "";
+    addr = int(dut.uut.mprj.wrapper_sha1.wbs_adr_i.value);
+    ack = int(dut.uut.mprj.wrapper_sha1.wbs_ack_o.value);
+    try:
+        data = int(dut.uut.mprj.wrapper_sha1.wbs_dat_o.value);
+        data_i = int(dut.uut.mprj.wrapper_sha1.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_sha1.wbs_dat_i.value,
+                      dut.uut.mprj.wrapper_sha1.wbs_dat_o.value));
+        pass
+
+    if (addr >= 0x30000024):
+        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 == 0x30000024): # CTRL_GET_NR
+            assert(data == 4);
+
+        if (addr == 0x30000028): # CTRL_GET_ID
+            assert(data == 0x53484131);
+
+        if (addr == 0x30000038): # 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_sha1.reset)
+    await FallingEdge(dut.uut.mprj.wrapper_sha1.reset)
+
+    dut._log.info("Reset done");
+
+    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/caravel_test/wrapper.c b/verilog/dv/caravel_test/wrapper.c
new file mode 100644
index 0000000..edb30cd
--- /dev/null
+++ b/verilog/dv/caravel_test/wrapper.c
@@ -0,0 +1,205 @@
+/*
+ * 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 		0x30000024
+#define CTRL_GET_NR		(BASE_ADDRESS + 0x00)
+#define CTRL_GET_ID		(BASE_ADDRESS + 0x04)
+#define CTRL_SHA1_OPS		(BASE_ADDRESS + 0x08)
+#define CTRL_MSG_IN		(BASE_ADDRESS + 0x0C)
+#define CTRL_SHA1_DIGEST	(BASE_ADDRESS + 0x10)
+#define CTRL_PANIC		(BASE_ADDRESS + 0x14)
+
+#define CTRL_ID			0x53484131
+#define CTRL_NR			4
+
+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 = 1;
+}
+
+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_SHA1_OPS, 0); /* Ack the IRQ */
+
+	write(CTRL_PANIC, MAGIC_END);
+}
+
+void wishbone_test(void)
+{
+	uint32_t val, i;
+
+	val = read(CTRL_GET_ID);
+	BUG_ON(val != CTRL_ID);
+
+	val = read(CTRL_GET_NR);
+	BUG_ON(val != CTRL_NR);
+
+        /* The sha1_done should _NOT_ be set */
+	val = read(CTRL_SHA1_OPS);
+        BUG_ON(val & 0x1 == 0x1)
+
+	write(CTRL_MSG_IN, 0x61626380); /* [0]= */
+        for (i = 1; i < 15; i++)
+		write(CTRL_MSG_IN, 0x0);
+
+        write(CTRL_MSG_IN, 0x18); /* [15]= */
+
+        /* The sha1_done should be set */
+	val = read(CTRL_SHA1_OPS);
+        BUG_ON(val & 0x1 != 0x1)
+
+        do {
+	   val = read(CTRL_SHA1_OPS);
+           /* [3] will be set when it is done. */
+           if (val & 1 << 3)
+              break;
+        } while (val & 1); /* Spin as long as sha1_on is set */
+
+
+        val = read(CTRL_SHA1_DIGEST);
+        BUG_ON(val != 0xa9993e36);
+
+        val = read(CTRL_SHA1_DIGEST);
+        BUG_ON(val != 0x4706816a);
+
+        val = read(CTRL_SHA1_DIGEST);
+        BUG_ON(val != 0xba3e2571);
+
+        val = read(CTRL_SHA1_DIGEST);
+        BUG_ON(val != 0x7850c26c);
+
+        val = read(CTRL_SHA1_DIGEST);
+        BUG_ON(val != 0x9cd0d89d);
+
+	do {
+		// Spin until IRQ come in (it may already..)
+	} 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/caravel_test/wrapper_tb.v b/verilog/dv/caravel_test/wrapper_tb.v
new file mode 100644
index 0000000..acf68ae
--- /dev/null
+++ b/verilog/dv/caravel_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
diff --git a/verilog/rtl/sha1/src/sha1_wb.v b/verilog/rtl/sha1/src/sha1_wb.v
new file mode 100644
index 0000000..a52e033
--- /dev/null
+++ b/verilog/rtl/sha1/src/sha1_wb.v
@@ -0,0 +1,423 @@
+`default_nettype none
+`timescale 1ns/1ns
+`ifdef FORMAL
+`define MPRJ_IO_PADS 38
+`endif
+`ifdef VERILATOR
+`define MPRJ_IO_PADS 38
+`endif
+
+module sha1_wb #(
+    parameter    [31:0] BASE_ADDRESS   = 32'h30000024,
+    parameter  IDX_WIDTH = 6,
+    parameter  DATA_WIDTH = 32
+    ) (
+    input wire reset,
+    input wire [7:0] chicken_bits_in,
+    output wire [15:0] chicken_bits_out,
+    output wire done,
+    output wire irq,
+
+    /* WishBone logic */
+
+    input wire wb_clk_i,
+    input wire wb_rst_i,
+    input wire wbs_stb_i, /* strobe */
+    input wire wbs_cyc_i,
+    input wire wbs_we_i,
+    input wire [3:0] wbs_sel_i,
+    input wire [31:0] wbs_dat_i,
+    input wire [31:0] wbs_adr_i,
+    output wire wbs_ack_o,
+    output wire [31:0] wbs_dat_o
+
+);
+    wire wb_active = wbs_stb_i & wbs_cyc_i;
+
+    reg [31:0] buffer;
+    reg [31:0] buffer_o;
+
+    reg sha1_on;
+    reg sha1_reset;
+    reg sha1_panic;
+    reg sha1_done;
+    wire finish;
+    reg [2:0] sha1_digest_idx;
+    reg [6:0] sha1_msg_idx;
+    reg transmit;
+
+    wire [159:0] digest;
+    reg [DATA_WIDTH-1:0] message[79:0];
+    reg [IDX_WIDTH:0] index;
+
+    localparam STATE_INIT   = 0;
+    localparam STATE_START  = 1;
+    localparam LOOP_ONE     = 2; /* Really  0 <= i <= 19 */
+    localparam LOOP_TWO     = 3; /*         20        39 */
+    localparam LOOP_THREE   = 4; /*         40        59 */
+    localparam LOOP_FOUR    = 5; /*         60        79 */
+    localparam STATE_DONE   = 6;
+    localparam STATE_FINAL  = 7;
+    localparam STATE_PANIC  = 8;
+    reg [3:0] state;
+
+    wire [DATA_WIDTH-1:0] w;
+    wire [DATA_WIDTH-1:0] a_left_5;
+    wire [DATA_WIDTH-1:0] w_left_1;
+    wire [DATA_WIDTH-1:0] b_old_left_30;
+
+    reg [DATA_WIDTH-1:0] a;
+    reg [DATA_WIDTH-1:0] a_old;
+    reg [DATA_WIDTH-1:0] b;
+    reg [DATA_WIDTH-1:0] b_old;
+    reg [DATA_WIDTH-1:0] c;
+    reg [DATA_WIDTH-1:0] c_old;
+    reg [DATA_WIDTH-1:0] d;
+    reg [DATA_WIDTH-1:0] d_old;
+    reg [DATA_WIDTH-1:0] e;
+    reg [DATA_WIDTH-1:0] e_old;
+
+    reg [DATA_WIDTH-1:0] k;
+    reg [DATA_WIDTH-1:0] f;
+    reg [DATA_WIDTH-1:0] temp;
+    reg [DATA_WIDTH-1:0] temp_old;
+
+    reg [DATA_WIDTH-1:0] h0;
+    reg [DATA_WIDTH-1:0] h1;
+    reg [DATA_WIDTH-1:0] h2;
+    reg [DATA_WIDTH-1:0] h3;
+    reg [DATA_WIDTH-1:0] h4;
+
+    reg panic;
+    reg inc_counter;
+    reg copy_values;
+    reg compute;
+
+    /* CTRL_GET parameters. */
+    localparam CTRL_GET_NR		= BASE_ADDRESS;
+    localparam CTRL_NR 			= 4;
+
+    localparam CTRL_GET_ID		= BASE_ADDRESS + 'h4;
+    localparam CTRL_ID			= 32'h53484131; /* SHA1 */
+    localparam DEFAULT			= 32'hf00df00d;
+    /*
+     * When writing: The [2:0] are operations.
+     * When reading: [10:4] in what loop we are [0->79]. [1:0] are operations.
+     */
+    localparam CTRL_SHA1_OPS    = BASE_ADDRESS + 'h8;
+    localparam ON			    = 4'b0001;
+    localparam OFF			    = 4'b0000;
+    localparam RESET			= 4'b0010;
+    localparam PANIC			= 4'b0100; /* Can only be read. */
+    localparam DONE			    = 4'b1000; /* Can only be read. */
+
+    /* This requires 16 CTRL_MSG_IN and after that we start processing. */
+    localparam CTRL_MSG_IN		= BASE_ADDRESS + 'hC;
+    localparam ACK			    = 32'h0000001;
+    localparam EINVAL			= 32'hfffffea; /* -14 */
+
+    /* Five reads for the digest. */
+    localparam CTRL_SHA1_DIGEST 		= BASE_ADDRESS + 'h10;
+    localparam EBUSY            = 32'hfffffff0; /* -10 */
+    localparam CTRL_PANIC 			= BASE_ADDRESS + 'h14;
+
+    always @(posedge wb_clk_i) begin
+        if (reset) begin
+            buffer_o <= DEFAULT;
+            buffer <= DEFAULT;
+            sha1_panic <= 1'b0;
+            transmit <= 1'b0;
+            sha1_msg_idx <= 0;
+            sha1_digest_idx <= 0;
+            sha1_done <= 0;
+            sha1_reset <= 1'b1; /* Reset the SHA1 compute engine */
+            sha1_on <= 1'b0;
+        end else begin
+            if (transmit)
+                transmit <= 1'b0;
+
+            if (sha1_reset) begin
+                sha1_digest_idx <= 0;
+                sha1_reset <= 1'b0;
+            end
+            if (finish)
+                sha1_done <= 1'b1;
+            if (chicken_bits_in) begin
+		case (chicken_bits_in[7:0])
+		   8'b0000_0001: sha1_on <= 1'b1;
+		   8'b0000_0010: sha1_on <= 1'b0;
+		   8'b0000_0100: sha1_reset <= 1'b1;
+		   8'b0000_1000: sha1_reset <= 1'b0;
+		   8'b0001_0000: sha1_panic <= 1'b1;
+		   8'b0010_0000: sha1_panic <= 1'b0;
+		   8'b0100_0000: sha1_done <= 1'b1;
+		   8'b1000_0000: sha1_done <= 1'b0;
+		   default: ;
+                endcase
+            end
+            if (wb_active && !wbs_we_i) begin
+                case (wbs_adr_i)
+                    CTRL_GET_NR:
+                    begin
+                        buffer_o <= CTRL_NR;
+                    end
+                    CTRL_GET_ID:
+                        buffer_o <= CTRL_ID;
+                    CTRL_MSG_IN:
+                        buffer_o <= EINVAL;
+                    CTRL_SHA1_OPS:
+                        buffer_o <= {21'b0, index, sha1_done, sha1_panic, sha1_reset, sha1_on};
+                    CTRL_SHA1_DIGEST:
+                    begin
+                        if (sha1_done) begin
+                            case (sha1_digest_idx)
+                                'h4: buffer_o <= h4;
+                                'h3: buffer_o <= h3;
+                                'h2: buffer_o <= h2;
+                                'h1: buffer_o <= h1;
+                                'h0: buffer_o <= h0;
+                                default: sha1_panic <= 1'b1;
+                            endcase
+                            if (!transmit) begin
+                                if (sha1_digest_idx == 4)
+                                    sha1_digest_idx <= 0;
+                                else
+                                    sha1_digest_idx <= sha1_digest_idx + 1'b1;
+                            end
+                        end else
+                            buffer_o <= EBUSY;
+                    end
+                    CTRL_PANIC:
+                        buffer_o <= {31'b0, sha1_panic};
+                endcase
+                if ((wbs_adr_i[31:0] >= BASE_ADDRESS) && (wbs_adr_i <= CTRL_PANIC))
+                    transmit <= 1'b1;
+            end
+		    /* Write case */
+            if (wb_active && wbs_we_i && &wbs_sel_i) begin
+                case (wbs_adr_i)
+                    CTRL_SHA1_OPS:
+                    begin
+                        sha1_on <= wbs_dat_i[0];
+                        sha1_reset <= wbs_dat_i[1];
+                        if (wbs_dat_i[0]) begin
+                            sha1_msg_idx <= 0;
+                            sha1_done <= 0;
+                            sha1_digest_idx <= 0;
+                        end
+                        buffer_o <= {21'b0, index, sha1_done, sha1_panic, wbs_dat_i[1], wbs_dat_i[0]};
+                    end
+                    CTRL_MSG_IN:
+                    begin
+                        if (sha1_on)
+                            buffer_o <= EINVAL;
+                        else begin
+                            buffer_o <= ACK;
+                            if (sha1_msg_idx > 15)
+                                    sha1_panic <= 1'b1;
+                            else
+                                message[sha1_msg_idx] <= wbs_dat_i;
+                            if (!transmit) begin
+                                if (sha1_msg_idx == 'hf) begin
+                                    sha1_on <= 1'b1;
+                                    sha1_msg_idx <= 0;
+                                end else
+                                    sha1_msg_idx <= sha1_msg_idx + 1'b1;
+                            end
+                        end
+                    end
+                    CTRL_PANIC:
+                    begin
+                        sha1_panic <= 1'b1;
+                        buffer <= wbs_dat_i;
+                        buffer_o <= ACK;
+                    end
+                endcase
+                if ((wbs_adr_i[31:0] >= BASE_ADDRESS) && (wbs_adr_i <= CTRL_PANIC))
+                    transmit <= 1'b1;
+            end
+        end
+    end
+
+    always @(posedge wb_clk_i) begin
+        if (reset || sha1_reset) begin
+            state <= STATE_INIT;
+            temp <= DEFAULT;
+            index <= 0;
+            panic <= 0;
+            inc_counter <= 1'b0;
+            copy_values <= 1'b0;
+            compute <= 1'b0;
+        end else begin
+            /* We are running and someone turned it off. */
+            if ((index > 1) && !sha1_on)
+                state <= STATE_INIT;
+
+            /* Never should happen. TODO: Remove*/
+            if (index > 80) begin
+                panic <= 1'b1;
+                state <= STATE_PANIC;
+            end
+            /* Increment if allowed to increment counter. */
+            if (inc_counter) begin
+                index <= index + 1'b1;
+                inc_counter <= 1'b0;
+            end
+            /*
+             * Every LOOP_ call ends up with copying the data, so
+             * make it generic
+             */
+            if (compute) begin
+                a_old <= a;
+                b_old <= b;
+                c_old <= c;
+                d_old <= d;
+            end
+            if (copy_values) begin
+                e <= d_old;
+                d <= c_old;
+                c <= b_old_left_30;
+                b <= a_old;
+                a <= temp;
+                copy_values <= 1'b0;
+                compute <= 1'b1;
+                inc_counter <= 1'b1;
+            end
+            /*
+             * For t = 16 to 79
+             * w[i] = (w[i-3] xor w[i-8] xor w[i-14] xor w[i-16]) leftrotate 1
+             *
+             * This means we need this ready before we get to index=16 hence
+             * the +1 adjustment for every offset.
+             */
+            if (index >= 15) begin
+                message[index+1] <= {(message[index-3+1][30:0] ^ message[index-8+1][30:0] ^
+                                     message[index-14+1][30:0] ^ message[index-16+1][30:0]),
+                                     (message[index-3+1][31] ^ message[index-8+1][31] ^
+                                      message[index-14+1][31] ^ message[index-16+1][31])};
+            end
+            case (state)
+                STATE_INIT: begin
+                    if (sha1_on)
+                        state <= STATE_START;
+                    else
+                        state <= STATE_INIT;
+                end
+                STATE_START: begin
+                    a <= 32'h67452301;
+                    h0 <= 32'h67452301;
+                    b <= 32'hEFCDAB89;
+                    h1 <= 32'hEFCDAB89;
+                    c <= 32'h98BADCFE;
+                    h2 <= 32'h98BADCFE;
+                    d <= 32'h10325476;
+                    h3 <=  32'h10325476;
+                    e <= 32'hC3D2E1F0;
+                    h4 <= 32'hC3D2E1F0;
+
+                    state <= LOOP_ONE;
+                    k <= 32'h5A827999;
+                    index <= 0;
+                    inc_counter <= 1'b1;
+                    compute <= 1'b1;
+                    copy_values <= 1'b0;
+                end
+
+                LOOP_ONE: begin
+                    if ((index == 19) && (inc_counter)) begin
+                        state <= LOOP_TWO;
+                        k <= 32'h6ED9EBA1;
+                    end
+
+                    if (compute) begin
+                    /* f = (b and c) or ((not b) and d) */
+                    /* temp = (a leftrotate 5) + f + e + k + w[i] */
+                        temp <= (a_left_5) + ((b & c) | (~b) & d) + e + k + w;
+                        copy_values <= 1'b1;
+                        compute <= 1'b0;
+                    end
+                end
+                LOOP_TWO: begin
+                    if ((index == 39) && (inc_counter)) begin
+                        state <= LOOP_THREE;
+                        k <= 32'h8F1BBCDC;
+                    end
+                    if (compute) begin
+                    /* f = b xor c xor d */
+                    /* temp = (a leftrotate 5) + f + e + k + w[i] */
+                        temp <= (a_left_5) + (b ^ c ^ d) + e + k + w;
+                        copy_values <= 1'b1;
+                        compute <= 1'b0;
+                    end
+                end
+                LOOP_THREE: begin
+                    if ((index == 59) && (inc_counter)) begin
+                        state <= LOOP_FOUR;
+                        k <= 32'hCA62C1D6;
+                    end
+                    if (compute) begin
+                    /* f = (b and c) or (b and d) or (c and d) */
+                    /* temp = (a leftrotate 5) + f + e + k + w[i] */
+                        temp <= (a_left_5) + ((b & c) | (b & d) | (c & d)) + e + k + w;
+                        copy_values <= 1'b1;
+                        compute <= 1'b0;
+                    end
+                end
+                LOOP_FOUR: begin
+                    if ((index == 79)  && (inc_counter)) begin
+                        state <= STATE_DONE;
+                        k <= DEFAULT;
+                    end
+                    if (compute) begin
+                    /* f = b xor c xor d
+                    /* temp = (a leftrotate 5) + f + e + k + w[i] */
+                        temp <= (a_left_5) + (b ^ c ^ d) + e + k + w;
+                        copy_values <= 1'b1;
+                        compute <= 1'b0;
+                    end
+                end
+                STATE_DONE: begin
+                    index <= 0;
+                    inc_counter <= 1'b0;
+                    if (compute) begin
+                        h0 <= h0 + a;
+                        h1 <= h1 + b;
+                        h2 <= h2 + c;
+                        h3 <= h3 + d;
+                        h4 <= h4 + e;
+                        state <= STATE_FINAL;
+                        copy_values <= 1'b0;
+                        compute <= 1'b0;
+                    end
+                end
+                STATE_FINAL: begin
+                    if (!sha1_on)
+                        state <= STATE_INIT;
+                end
+                STATE_PANIC: begin
+                end
+            endcase
+        end
+    end
+
+    assign a_left_5 = {a[26:0], a[31:27]};
+    assign b_old_left_30 = {b_old[1:0], b_old[31:2]};
+
+    /* Provides the w[index] funcionality */
+    assign w =  message[index];
+
+    assign digest = {h0, h1, h2, h3, h4};
+
+    assign finish = (state == STATE_FINAL) ? 1'b1 : 1'b0;
+
+    assign wbs_ack_o = reset ? 1'b0 : transmit;
+
+    assign wbs_dat_o = reset ? 32'b0 : buffer_o;
+
+    assign done = reset ? 1'b0 : sha1_done;
+
+    assign irq = reset ? 1'b0: sha1_done;
+
+    assign chicken_bits_out = {buffer_o[14:0], sha1_panic};
+endmodule
+`default_nettype wire
diff --git a/verilog/rtl/sha1/src/wrapper_sha1.v b/verilog/rtl/sha1/src/wrapper_sha1.v
new file mode 100644
index 0000000..4459881
--- /dev/null
+++ b/verilog/rtl/sha1/src/wrapper_sha1.v
@@ -0,0 +1,101 @@
+`default_nettype none
+`timescale 1ns/1ns
+`ifdef FORMAL
+`define MPRJ_IO_PADS 38
+`endif
+`ifdef VERILATOR
+`define MPRJ_IO_PADS 38
+`endif
+module wrapper_sha1  (
+`ifdef USE_POWER_PINS
+    inout vdda1,	// User area 1 3.3V supply
+    inout vdda2,	// User area 2 3.3V supply
+    inout vssa1,	// User area 1 analog ground
+    inout vssa2,	// User area 2 analog ground
+    inout vccd1,	// User area 1 1.8V supply
+    inout vccd2,	// User area 2 1.8v supply
+    inout vssd1,	// User area 1 digital ground
+    inout vssd2,	// User area 2 digital ground
+`endif
+    // interface as user_proj_example.v
+    input wire wb_clk_i,
+    input wire wb_rst_i,
+    input wire wbs_stb_i, /* strobe */
+    input wire wbs_cyc_i,
+    input wire wbs_we_i,
+    input wire [3:0] wbs_sel_i,
+    input wire [31:0] wbs_dat_i,
+    input wire [31:0] wbs_adr_i,
+    output wire wbs_ack_o,
+    output wire [31:0] wbs_dat_o,
+
+    // Logic Analyzer Signals
+    // only provide first 32 bits to reduce wiring congestion
+    input  wire [31:0] la_data_in,
+    output wire [31:0] la_data_out,
+    input  wire [31:0] la_oenb,
+
+    // IOs
+    input  wire [`MPRJ_IO_PADS-1:0] io_in,
+    output wire [`MPRJ_IO_PADS-1:0] io_out,
+    output wire [`MPRJ_IO_PADS-1:0] io_oeb,
+
+    // IRQ
+    output wire [2:0] irq,
+
+    // active input, only connect tristated outputs if this is high
+    input wire active
+);
+
+    // all outputs must be tristated before being passed onto the project
+    wire buf_wbs_ack_o;
+    wire [31:0] buf_wbs_dat_o;
+    wire [31:0] buf_la_data_out;
+    wire [`MPRJ_IO_PADS-1:0] buf_io_out;
+    wire [`MPRJ_IO_PADS-1:0] buf_io_oeb;
+    wire [2:0] buf_irq;
+
+`ifdef FORMAL
+    // formal can't deal with z, so set all outputs to 0 if not active
+    assign wbs_ack_o    = active ? buf_wbs_ack_o    : 1'b0;
+    assign wbs_dat_o    = active ? buf_wbs_dat_o    : 32'b0;
+    assign la_data_out  = active ? buf_la_data_out  : 32'b0;
+    assign io_out       = active ? buf_io_out       : {`MPRJ_IO_PADS{1'b0}};
+    assign io_oeb       = active ? buf_io_oeb       : {`MPRJ_IO_PADS{1'b0}};
+    assign irq		= active ? buf_irq          : 3'b0;
+`include "properties.v"
+`else
+    // tristate buffers
+    assign wbs_ack_o    = active ? buf_wbs_ack_o    : 1'bz;
+    assign wbs_dat_o    = active ? buf_wbs_dat_o    : 32'bz;
+    assign la_data_out  = active ? buf_la_data_out  : 32'bz;
+    assign io_out       = active ? buf_io_out       : {`MPRJ_IO_PADS{1'bz}};
+    assign io_oeb       = active ? buf_io_oeb       : {`MPRJ_IO_PADS{1'bz}};
+    assign irq		= active ? buf_irq          : 3'bz;
+`endif
+
+    // permanently set oeb so that outputs are always enabled: 0 is output, 1 is high-impedance
+    assign buf_io_oeb = {`MPRJ_IO_PADS{1'b0}};
+
+    wire reset = la_data_in[0];
+
+
+    sha1_wb sha1_wishbone (
+        .reset(reset),
+        .chicken_bits_in(la_data_in[12:5]),
+        .chicken_bits_out(buf_la_data_out[20:5]),
+        .done(buf_io_out[8]),
+        .irq(buf_irq[0]),
+        .wb_clk_i(wb_clk_i),
+        .wb_rst_i(wb_rst_i),
+        .wbs_stb_i(wbs_stb_i),
+        .wbs_cyc_i(wbs_cyc_i),
+        .wbs_we_i(wbs_we_i),
+        .wbs_sel_i(wbs_sel_i),
+        .wbs_dat_i(wbs_dat_i),
+        .wbs_adr_i(wbs_adr_i),
+        .wbs_ack_o(buf_wbs_ack_o),
+        .wbs_dat_o(buf_wbs_dat_o));
+
+endmodule
+`default_nettype wire
diff --git a/verilog/rtl/uprj_netlists.v b/verilog/rtl/uprj_netlists.v
index 3537de8..a74edc1 100644
--- a/verilog/rtl/uprj_netlists.v
+++ b/verilog/rtl/uprj_netlists.v
@@ -1,4 +1,6 @@
-// SPDX-FileCopyrightText: 2020 Efabless Corporation
+// SPDX-FileCopyrightText: 
+// 2020 Efabless Corporation
+// 2021 Konrad Rzeszutek Wilk
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -21,8 +23,10 @@
     // Assume default net type to be wire because GL netlists don't have the wire definitions
     `default_nettype wire
     `include "gl/user_project_wrapper.v"
-    `include "gl/user_proj_example.v"
 `else
     `include "user_project_wrapper.v"
-    `include "user_proj_example.v"
-`endif
\ No newline at end of file
+    //  3 ('SHA1',)                      : /home/konrad/sha1
+	`include "sha1/src/wrapper_sha1.v"
+	`include "sha1/src/sha1_wb.v"
+
+`endif
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 2a3462b..12d1dec 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -78,52 +78,50 @@
     output [2:0] user_irq
 );
 
-/*--------------------------------------*/
-/* User project is instantiated  here   */
-/*--------------------------------------*/
+    // instantiate user project here
+        wrapper_sha1 wrapper_sha1(
+        `ifdef USE_POWER_PINS
+        .vdda1(vdda1),  // User area 1 3.3V power
+        .vdda2(vdda2),  // User area 2 3.3V power
+        .vssa1(vssa1),  // User area 1 analog ground
+        .vssa2(vssa2),  // User area 2 analog ground
+        .vccd1(vccd1),  // User area 1 1.8V power
+        .vccd2(vccd2),  // User area 2 1.8V power
+        .vssd1(vssd1),  // User area 1 digital ground
+        .vssd2(vssd2),  // User area 2 digital ground
+        `endif
 
-user_proj_example mprj (
-    `ifdef USE_POWER_PINS
-	.vdda1(vdda1),	// User area 1 3.3V power
-	.vdda2(vdda2),	// User area 2 3.3V power
-	.vssa1(vssa1),	// User area 1 analog ground
-	.vssa2(vssa2),	// User area 2 analog ground
-	.vccd1(vccd1),	// User area 1 1.8V power
-	.vccd2(vccd2),	// User area 2 1.8V power
-	.vssd1(vssd1),	// User area 1 digital ground
-	.vssd2(vssd2),	// User area 2 digital ground
-    `endif
+        // interface as user_proj_example.v
+        .wb_clk_i   (wb_clk_i),
+        .wb_rst_i   (wb_rst_i),
+        .wbs_stb_i  (wbs_stb_i),
+        .wbs_cyc_i  (wbs_cyc_i),
+        .wbs_we_i   (wbs_we_i),
+        .wbs_sel_i  (wbs_sel_i),
+        .wbs_dat_i  (wbs_dat_i),
+        .wbs_adr_i  (wbs_adr_i),
+        .wbs_ack_o  (wbs_ack_o),
+        .wbs_dat_o  (wbs_dat_o),
 
-    .wb_clk_i(wb_clk_i),
-    .wb_rst_i(wb_rst_i),
+        // only provide first 32 bits to reduce wiring congestion
+        .la_data_in (la_data_in [31:0]),
+        .la_data_out(la_data_out[31:0]),
+        .la_oenb    (la_oenb[31:0]),
 
-    // MGMT SoC Wishbone Slave
+        // IOs
+        .io_in      (io_in),
+        .io_out     (io_out),
+        .io_oeb     (io_oeb),
 
-    .wbs_cyc_i(wbs_cyc_i),
-    .wbs_stb_i(wbs_stb_i),
-    .wbs_we_i(wbs_we_i),
-    .wbs_sel_i(wbs_sel_i),
-    .wbs_adr_i(wbs_adr_i),
-    .wbs_dat_i(wbs_dat_i),
-    .wbs_ack_o(wbs_ack_o),
-    .wbs_dat_o(wbs_dat_o),
+        // IRQs
+        .irq        (user_irq),
 
-    // Logic Analyzer
+        // active input, only connect tristated outputs if this is high
+        .active     (la_data_in[32+3])
+        );
 
-    .la_data_in(la_data_in),
-    .la_data_out(la_data_out),
-    .la_oenb (la_oenb),
 
-    // IO Pads
-
-    .io_in (io_in),
-    .io_out(io_out),
-    .io_oeb(io_oeb),
-
-    // IRQ
-    .irq(user_irq)
-);
+    // end of module instantiation
 
 endmodule	// user_project_wrapper
-
 `default_nettype wire