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