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