diff --git a/verilog/dv/caravel/mgmt_soc/irq/Makefile b/verilog/dv/caravel/mgmt_soc/irq/Makefile new file mode 100644 index 00000000..d2072180 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/irq/Makefile @@ -0,0 +1,86 @@ +# 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 + +PDK_PATH = $(PDK_ROOT)/sky130A +VERILOG_PATH = ../../../.. +RTL_PATH = $(VERILOG_PATH)/rtl +BEHAVIOURAL_MODELS = ../../ + +# Temporary: Path to management SoC wrapper repository +MGMT_WRAPPER_PATH = ~/gits/caravel_pico/verilog/rtl + +FIRMWARE_PATH = ../.. +GCC_PATH?=/ef/apps/bin +GCC_PREFIX?=riscv32-unknown-elf + +SIM_DEFINES = -DFUNCTIONAL -DSIM + +SIM?=RTL + +.SUFFIXES: + +PATTERN = irq + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex +ifeq ($(SIM),RTL) + iverilog -Ttyp $(SIM_DEFINES) -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(RTL_PATH) -I $(MGMT_WRAPPER_PATH) \ + $< -o $@ +else + iverilog -Ttyp $(SIM_DEFINES) -DGL -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \ + $< -o $@ +endif + +%.vcd: %.vvp check-env + vvp $< + +%.elf: %.c sections.lds start.S check-env + ${GCC_PATH}/${GCC_PREFIX}-gcc -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 > $@ + +check-env: +ifndef PDK_ROOT + $(error PDK_ROOT is undefined, please export it before running make) +endif +ifeq (,$(wildcard $(PDK_ROOT)/sky130A)) + $(error $(PDK_ROOT)/sky130A not found, please install pdk before running make) +endif +ifeq (,$(wildcard $(GCC_PATH)/$(GCC_PREFIX)-gcc )) + $(error $(GCC_PATH)/$(GCC_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make) +endif +# check for efabless style installation +ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog)) +SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE +endif + +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all diff --git a/verilog/dv/caravel/mgmt_soc/irq/README b/verilog/dv/caravel/mgmt_soc/irq/README new file mode 100644 index 00000000..99d3cf9d --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/irq/README @@ -0,0 +1,32 @@ + +------------------------------------------------ +Caravel +irq testbench +------------------------------------------------ + +This testbench demonstrates how to use the interrupts on the +picoRV32. It uses the internal picoRV32 counter to set up an +interval timer. At each timer expiration, an interrupt is +generated, and the assembler code in start.S runs and captures +data from a routine emulating a Digilent PMOD MIC-3 microphone +module. Data are accumulated in a ring buffer reserved in the +top of memory. The main loop of the program queries the +current ring buffer position, reads the data there, and +displays the value on the GPIO (upper 16 of the lower 32 GPIO +channels). diff --git a/verilog/dv/caravel/mgmt_soc/irq/custom_ops.S b/verilog/dv/caravel/mgmt_soc/irq/custom_ops.S new file mode 100644 index 00000000..e3d1e2de --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/irq/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 + * + * 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/mgmt_soc/irq/irq.c b/verilog/dv/caravel/mgmt_soc/irq/irq.c new file mode 100755 index 00000000..61dfcdd9 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/irq/irq.c @@ -0,0 +1,67 @@ +/* + * 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 "../../defs.h" + +// ------------------------------------------------------------------------- +// Test IRQ callback +// ------------------------------------------------------------------------- + +uint16_t flag; + +void irq_callback() +{ + /* If this routine is called, then the test passes the 1st stage */ + reg_mprj_datah = 0xa; // Signal end of test 1st stage + reg_mprj_datal = 0x20000; + flag = 1; + return; +} + +void main() +{ + uint16_t data; + int i; + + // Configure GPIO upper bits to assert the test code + reg_mprj_io_35 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_34 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_33 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_32 = GPIO_MODE_MGMT_STD_OUTPUT; + + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT; + + /* Apply the GPIO configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + reg_mprj_datah = 0x5; // Signal start of test + reg_mprj_datal = 0; + flag = 0; + + // Loop, waiting for the interrupt to change reg_mprj_datah + + while (flag == 0) { + reg_mprj_datal = 0x10000; + } + reg_mprj_datal = 0x40000; + reg_mprj_datah = 0xc; // Signal end of test +} + diff --git a/verilog/dv/caravel/mgmt_soc/irq/irq_tb.v b/verilog/dv/caravel/mgmt_soc/irq/irq_tb.v new file mode 100755 index 00000000..0e03d6d0 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/irq/irq_tb.v @@ -0,0 +1,172 @@ +`default_nettype none +/* + * SPDX-FileCopyrightText: 2017 Clifford Wolf, 2018 Tim Edwards + * + * Caravel - A full example SoC using PicoRV32 in SkyWater sky130 + * + * Copyright (C) 2017 Clifford Wolf + * Copyright (C) 2021 Tim Edwards + * + * 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 + */ + +`timescale 1 ns / 1 ps + +`include "__uprj_netlists.v" +`include "caravel_netlists.v" +`include "spiflash.v" + +module irq_tb; + + reg clock; + reg power1; + reg power2; + + always #10 clock <= (clock === 1'b0); + + initial begin + clock <= 0; + end + + initial begin + $dumpfile("irq.vcd"); + $dumpvars(0, irq_tb); + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (12) begin + repeat (1000) @(posedge clock); + $display("+1000 cycles"); + end + $display("%c[1;31m",27); + `ifdef GL + $display ("Monitor: Timeout, Test IRQ (GL) Failed"); + `else + $display ("Monitor: Timeout, Test IRQ (RTL) Failed"); + `endif + $display("%c[0m",27); + $finish; + end + + wire [37:0] mprj_io; // Most of these are no-connects + wire [3:0] status; + wire [3:0] checkbits; + + assign checkbits = mprj_io[19:16]; + assign status = mprj_io[35:32]; + assign mprj_io[3] = 1'b1; // Force CSB high. + + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + wire gpio; + + reg RSTB; + + // Monitor + initial begin + wait(status == 4'h5); + `ifdef GL + $display("Monitor: Test IRQ (GL) Started"); + `else + $display("Monitor: Test IRQ (RTL) Started"); + `endif + wait(status == 4'ha); + wait(status == 4'hc); + `ifdef GL + $display("Monitor: Test IRQ (GL) Passed"); + `else + $display("Monitor: Test IRQ (RTL) Passed"); + `endif + $finish; + end + + initial begin + RSTB <= 1'b0; + #1000; + RSTB <= 1'b1; // Release reset + #2000; + end + + initial begin // Power-up + power1 <= 1'b0; + power2 <= 1'b0; + #200; + power1 <= 1'b1; + #200; + power2 <= 1'b1; + end + + always @(checkbits, status) begin + #1 $display("GPIO state = %b (%b)", checkbits, status); + end + + wire VDD3V3; + wire VDD1V8; + wire VSS; + + assign VDD3V3 = power1; + assign VDD1V8 = power2; + assign VSS = 1'b0; + + // These are the mappings of mprj_io GPIO pads that are set to + // specific functions on startup: + // + // JTAG = mgmt_gpio_io[0] (inout) + // SDO = mgmt_gpio_io[1] (output) + // SDI = mgmt_gpio_io[2] (input) + // CSB = mgmt_gpio_io[3] (input) + // SCK = mgmt_gpio_io[4] (input) + // ser_rx = mgmt_gpio_io[5] (input) + // ser_tx = mgmt_gpio_io[6] (output) + // irq = mgmt_gpio_io[7] (input) + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (VDD3V3), + .vdda2 (VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (VDD1V8), + .vccd2 (VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clock), + .gpio (gpio), + .mprj_io (mprj_io), + .flash_csb(flash_csb), + .flash_clk(flash_clk), + .flash_io0(flash_io0), + .flash_io1(flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("irq.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule diff --git a/verilog/dv/caravel/mgmt_soc/irq/sections.lds b/verilog/dv/caravel/mgmt_soc/irq/sections.lds new file mode 100755 index 00000000..c328222a --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/irq/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/mgmt_soc/irq/start.S b/verilog/dv/caravel/mgmt_soc/irq/start.S new file mode 100755 index 00000000..7c1c8a59 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/irq/start.S @@ -0,0 +1,195 @@ +/* + * 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 an IRQ */ +/*-----------------------------------------------*/ + +#undef ENABLE_FASTIRQ + +#include "custom_ops.S" + +.section .text +.global irq + +reset_vec: + j start + +/* Interrupt handler @ 0x10000004 */ +/* Requires defining a routine called irq_callback in the C code */ + +.balign 4 +irq_vec: + sw gp, 0*4+0x10(zero) + sw t0, 1*4+0x10(zero) + sw t1, 2*4+0x10(zero) + sw t2, 3*4+0x10(zero) + sw t4, 4*4+0x10(zero) + sw t5, 5*4+0x10(zero) + + call irq_callback + + lw gp, 0*4+0x10(zero) + lw t0, 1*4+0x10(zero) + lw t1, 2*4+0x10(zero) + lw t2, 3*4+0x10(zero) + lw t4, 4*4+0x10(zero) + lw t5, 5*4+0x10(zero) + + picorv32_retirq_insn() + +irq_regs: + .fill 32,8 + + +/* Main program */ + +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 + +# 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 timer IRQ only +li t4, 0xfff0 +picorv32_maskirq_insn(t4, t4) + +# Set the picorv32 32-bit counter/timer to trigger one interrupt. + +li t4, 0x1200 +picorv32_timer_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/mgmt_soc/mem/Makefile b/verilog/dv/caravel/mgmt_soc/mem/Makefile new file mode 100644 index 00000000..365e35f6 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/mem/Makefile @@ -0,0 +1,86 @@ +# 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 + +PDK_PATH = $(PDK_ROOT)/sky130A +VERILOG_PATH = ../../../.. +RTL_PATH = $(VERILOG_PATH)/rtl +BEHAVIOURAL_MODELS = ../../ + +# Temporary: Path to management SoC wrapper repository +MGMT_WRAPPER_PATH = ~/gits/caravel_pico/verilog/rtl + +FIRMWARE_PATH = ../.. +GCC_PATH?=/ef/apps/bin +GCC_PREFIX?=riscv32-unknown-elf + +SIM_DEFINES = -DFUNCTIONAL -DSIM + +SIM?=RTL + +.SUFFIXES: + +PATTERN = mem + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex +ifeq ($(SIM),RTL) + iverilog -Ttyp $(SIM_DEFINES) -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(RTL_PATH) -I $(MGMT_WRAPPER_PATH) \ + $< -o $@ +else + iverilog -Ttyp $(SIM_DEFINES) -DGL -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \ + $< -o $@ +endif + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s check-env + ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + ${GCC_PATH}/${GCC_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +check-env: +ifndef PDK_ROOT + $(error PDK_ROOT is undefined, please export it before running make) +endif +ifeq (,$(wildcard $(PDK_ROOT)/sky130A)) + $(error $(PDK_ROOT)/sky130A not found, please install pdk before running make) +endif +ifeq (,$(wildcard $(GCC_PATH)/$(GCC_PREFIX)-gcc )) + $(error $(GCC_PATH)/$(GCC_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make) +endif +# check for efabless style installation +ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog)) +SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE +endif +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all + diff --git a/verilog/dv/caravel/mgmt_soc/mem/mem.c b/verilog/dv/caravel/mgmt_soc/mem/mem.c new file mode 100644 index 00000000..a3b6fcc4 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/mem/mem.c @@ -0,0 +1,92 @@ +/* + * 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 "../../defs.h" + +// -------------------------------------------------------- + +/* + Memory Test + It uses GPIO to flag the success or failure of the test +*/ +unsigned int ints[10]; +unsigned short shorts[10]; +unsigned char bytes[10]; + +void main() +{ + int i; + + /* Upper 16 user area pins are configured to be GPIO output */ + + reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT; + + reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT; + + // Apply configuration + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + // start test + reg_mprj_datal = 0xA0400000; + + // Test Word R/W + for (i=0; i<10; i++) + ints[i] = i*5000 + 10000; + + for (i=0; i<10; i++) + if ((i*5000+10000) != ints[i]) + reg_mprj_datal = 0xAB400000; + + reg_mprj_datal = 0xAB410000; + + // Test Half Word R/W + reg_mprj_datal = 0xA0200000; + for (i=0; i<10; i++) + shorts[i] = i*500 + 100; + + for(i=0; i<10; i++) + if((i*500+100) != shorts[i]) + reg_mprj_datal = 0xAB200000; + + reg_mprj_datal = 0xAB210000; + + // Test byte R/W + reg_mprj_datal = 0xA0100000; + for(i=0; i<10; i++) + bytes[i] = i*5 + 10; + + for(i=0; i<10; i++) + if((i*5+10) != bytes[i]) + reg_mprj_datal = 0xAB100000; + + reg_mprj_datal = 0xAB110000; +} \ No newline at end of file diff --git a/verilog/dv/caravel/mgmt_soc/mem/mem_tb.v b/verilog/dv/caravel/mgmt_soc/mem/mem_tb.v new file mode 100644 index 00000000..4aa244a3 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/mem/mem_tb.v @@ -0,0 +1,203 @@ +`default_nettype none +/* + * SPDX-FileCopyrightText: 2017 Clifford Wolf, 2018 Tim Edwards + * + * StriVe - A full example SoC using PicoRV32 in SkyWater s8 + * + * Copyright (C) 2017 Clifford Wolf + * Copyright (C) 2018 Tim Edwards + * + * 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 + */ + +`timescale 1 ns / 1 ps + +`include "__uprj_netlists.v" +`include "caravel_netlists.v" +`include "spiflash.v" + +module mem_tb; + reg clock; + reg RSTB; + reg power1, power2; + + wire gpio; + wire [15:0] checkbits; + wire [37:0] mprj_io; + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + + assign checkbits = mprj_io[31:16]; + + // External clock is used by default. Make this artificially fast for the + // simulation. Normally this would be a slow clock and the digital PLL + // would be the fast clock. + + always #10 clock <= (clock === 1'b0); + + initial begin + clock = 0; + end + + initial begin + $dumpfile("mem.vcd"); + $dumpvars(0, mem_tb); + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (100) begin + repeat (1000) @(posedge clock); + //$display("+1000 cycles"); + end + $display("%c[1;31m",27); + `ifdef GL + $display ("Monitor: Timeout, Test MEM (GL) Failed"); + `else + $display ("Monitor: Timeout, Test MEM (RTL) Failed"); + `endif + $display("%c[0m",27); + $finish; + end + + initial begin + RSTB <= 1'b0; + #1000; + RSTB <= 1'b1; // Release reset + #2000; + end + + initial begin // Power-up sequence + power1 <= 1'b0; + power2 <= 1'b0; + #200; + power1 <= 1'b1; + #200; + power2 <= 1'b1; + end + + always @(checkbits) begin + if(checkbits == 16'hA040) begin + $display("Mem Test (word rw) started"); + end + else if(checkbits == 16'hAB40) begin + $display("%c[1;31m",27); + `ifdef GL + $display("Monitor: Test MEM (GL) [word rw] failed"); + `else + $display("Monitor: Test MEM (RTL) [word rw] failed"); + `endif + $display("%c[0m",27); + $finish; + end + else if(checkbits == 16'hAB41) begin + `ifdef GL + $display("Monitor: Test MEM (GL) [word rw] passed"); + `else + $display("Monitor: Test MEM (RTL) [word rw] passed"); + `endif + end + else if(checkbits == 16'hA020) begin + $display("Mem Test (short rw) started"); + end + else if(checkbits == 16'hAB20) begin + $display("%c[1;31m",27); + `ifdef GL + $display("Monitor: Test MEM (GL) [short rw] failed"); + `else + $display("Monitor: Test MEM (RTL) [short rw] failed"); + `endif + $display("%c[0m",27); + $finish; + end + else if(checkbits == 16'hAB21) begin + `ifdef GL + $display("Monitor: Test MEM (GL) [short rw] passed"); + `else + $display("Monitor: Test MEM (RTL) [short rw] passed"); + `endif + end + else if(checkbits == 16'hA010) begin + $display("Mem Test (byte rw) started"); + end + else if(checkbits == 16'hAB10) begin + $display("%c[1;31m",27); + `ifdef GL + $display("Monitor: Test MEM (GL) [byte rw] failed"); + `else + $display("Monitor: Test MEM (RTL) [byte rw] failed"); + `endif + $display("%c[0m",27); + $finish; + end + else if(checkbits == 16'hAB11) begin + `ifdef GL + $display("Monitor: Test MEM (GL) [byte rw] passed"); + `else + $display("Monitor: Test MEM (RTL) [byte rw] passed"); + `endif + $finish; + end + + end + + wire VDD3V3; + wire VDD1V8; + wire VSS; + + assign VSS = 1'b0; + assign VDD3V3 = power1; + assign VDD1V8 = power2; + + assign mprj_io[3] = 1'b1; // Force CSB high. + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (VDD3V3), + .vdda2 (VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (VDD1V8), + .vccd2 (VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clock), + .gpio (gpio), + .mprj_io (mprj_io), + .flash_csb(flash_csb), + .flash_clk(flash_clk), + .flash_io0(flash_io0), + .flash_io1(flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("mem.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/dv/caravel/mgmt_soc/mprj_ctrl/Makefile b/verilog/dv/caravel/mgmt_soc/mprj_ctrl/Makefile new file mode 100644 index 00000000..d1d9dd32 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/mprj_ctrl/Makefile @@ -0,0 +1,86 @@ +# 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 + +PDK_PATH = $(PDK_ROOT)/sky130A +VERILOG_PATH = ../../../.. +RTL_PATH = $(VERILOG_PATH)/rtl +BEHAVIOURAL_MODELS = ../../ + +# Temporary: Path to management SoC wrapper repository +MGMT_WRAPPER_PATH = ~/gits/caravel_pico/verilog/rtl + +FIRMWARE_PATH = ../.. +GCC_PATH?=/ef/apps/bin +GCC_PREFIX?=riscv32-unknown-elf + +SIM_DEFINES = -DFUNCTIONAL -DSIM + +SIM?=RTL + +.SUFFIXES: + +PATTERN = mprj_ctrl + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex +ifeq ($(SIM),RTL) + iverilog -Ttyp $(SIM_DEFINES) -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(RTL_PATH) -I $(MGMT_WRAPPER_PATH) \ + $< -o $@ +else + iverilog -Ttyp $(SIM_DEFINES) -DGL -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \ + $< -o $@ +endif + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s check-env + ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + ${GCC_PATH}/${GCC_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +check-env: +ifndef PDK_ROOT + $(error PDK_ROOT is undefined, please export it before running make) +endif +ifeq (,$(wildcard $(PDK_ROOT)/sky130A)) + $(error $(PDK_ROOT)/sky130A not found, please install pdk before running make) +endif +ifeq (,$(wildcard $(GCC_PATH)/$(GCC_PREFIX)-gcc )) + $(error $(GCC_PATH)/$(GCC_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make) +endif +# check for efabless style installation +ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog)) +SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE +endif +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all + diff --git a/verilog/dv/caravel/mgmt_soc/mprj_ctrl/mprj_ctrl.c b/verilog/dv/caravel/mgmt_soc/mprj_ctrl/mprj_ctrl.c new file mode 100644 index 00000000..1d7a140e --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/mprj_ctrl/mprj_ctrl.c @@ -0,0 +1,108 @@ +/* + * 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 "../../defs.h" + +// -------------------------------------------------------- + +/* + * User Project IO Control Test + */ + +void main() +{ + /* All GPIO pins are configured to be output */ + /* The lower 28 bits are connected to the user */ + /* project to output the counter result, and the */ + /* upper 4 bits are connected to the management */ + /* SoC to apply values that can be flagged by the */ + /* testbench for specific benchmark tests. */ + + /* GPIOs 31 to 16 are connected to the management SoC */ + reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT; + + /* GPIOs 27 to 0 are connected to the user area */ + 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; + reg_mprj_io_7 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_6 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_5 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_4 = GPIO_MODE_USER_STD_OUTPUT; + // reg_mprj_io_3 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_2 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_1 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_0 = GPIO_MODE_USER_STD_OUTPUT; + + // Apply configuration + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + reg_mprj_datal = 0; + + // start test + reg_mprj_datal = 0x50000000; + + // Write to IO Control + reg_mprj_io_0 = 0x004F; + if (reg_mprj_io_0 != 0x004F) + reg_mprj_datal = 0x60000000; + else + reg_mprj_datal = 0x70000000; + + // Write to IO Control + reg_mprj_io_1 = 0x005F; + if (reg_mprj_io_1 != 0x005F) + reg_mprj_datal = 0x80000000; + else + reg_mprj_datal = 0x90000000; + + // Write to IO Control + reg_mprj_io_2 = 0x006F; + if (reg_mprj_io_2 != 0x006F) + reg_mprj_datal = 0xA0000000; + else + reg_mprj_datal = 0xb0000000; + + // Write to IO Control (NOTE: Only 13 bits are valid) + reg_mprj_io_3 = 0xF0F5; + if (reg_mprj_io_3 != 0x10F5) + reg_mprj_datal = 0xc0000000; + else + reg_mprj_datal = 0xd0000000; +} + diff --git a/verilog/dv/caravel/mgmt_soc/mprj_ctrl/mprj_ctrl_tb.v b/verilog/dv/caravel/mgmt_soc/mprj_ctrl/mprj_ctrl_tb.v new file mode 100644 index 00000000..6ddfca37 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/mprj_ctrl/mprj_ctrl_tb.v @@ -0,0 +1,176 @@ +// 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" +`include "caravel_netlists.v" +`include "spiflash.v" + +module mprj_ctrl_tb; + reg clock; + reg RSTB; + reg power1, power2; + + wire gpio; + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + wire [37:0] user_io; + wire SDO; + + wire [3:0] checkbits; + + assign checkbits = user_io[31:28]; + + // External clock is used by default. Make this artificially fast for the + // simulation. Normally this would be a slow clock and the digital PLL + // would be the fast clock. + + always #10 clock <= (clock === 1'b0); + + initial begin + clock = 0; + end + + initial begin + $dumpfile("mprj_ctrl.vcd"); + $dumpvars(0, mprj_ctrl_tb); + repeat (25) begin + repeat (1000) @(posedge clock); + $display("+1000 cycles"); + end + $display("%c[1;31m",27); + `ifdef GL + $display ("Monitor: Timeout, Test User Project (GL) Failed"); + `else + $display ("Monitor: Timeout, Test User Project (RTL) Failed"); + `endif + $display("%c[0m",27); + $finish; + end + + always @(checkbits) begin + if(checkbits == 4'h5) begin + $display("User Project control Test started"); + end else if(checkbits == 4'h6) begin + $display("%c[1;31m",27); + $display("Monitor: IO control R/W failed (check 6)"); + $display("%c[0m",27); + $finish; + end else if(checkbits == 4'h7) begin + $display("Monitor: IO control R/W passed (check 7)"); + end else if(checkbits == 4'h8) begin + $display("%c[1;31m",27); + $display("Monitor: power control R/W failed (check 8)"); + $display("%c[0m",27); + $finish; + end else if(checkbits == 4'h9) begin + $display("Monitor: power control R/W passed (check 9)"); + end else if(checkbits == 4'ha) begin + $display("%c[1;31m",27); + $display("Monitor: power control R/W failed (check 10)"); + $display("%c[0m",27); + $finish; + end else if(checkbits == 4'hb) begin + $display("Monitor: power control R/W passed (check 11)"); + end else if(checkbits == 4'hc) begin + $display("%c[1;31m",27); + $display("Monitor: power control R/W failed (check 12)"); + $display("%c[0m",27); + $finish; + end else if(checkbits == 4'hd) begin + + $display("Monitor: power control R/W passed (check 13)"); + `ifdef GL + $display("Monitor: User Project control (GL) test passed."); + `else + $display("Monitor: User Project control (RTL) test passed."); + `endif + $finish; + end + end + + initial begin + RSTB <= 1'b0; + #1000; + RSTB <= 1'b1; // Release reset + #2000; + end + + initial begin + power1 <= 1'b0; + power2 <= 1'b0; + #200; + power1 <= 1'b1; + #200; + power2 <= 1'b1; + end + + always @(gpio) begin + #1 $display("GPIO state = %b ", gpio); + end + + wire VDD3V3; + wire VDD1V8; + wire VSS; + + assign VDD3V3 = power1; + assign VDD1V8 = power2; + assign VSS = 1'b0; + + assign user_io[3] = 1'b1; + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (VDD3V3), + .vdda2 (VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (VDD1V8), + .vccd2 (VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clock), + .gpio (gpio), + .mprj_io (user_io), + .flash_csb (flash_csb), + .flash_clk (flash_clk), + .flash_io0 (flash_io0), + .flash_io1 (flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("mprj_ctrl.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/dv/caravel/mgmt_soc/pass_thru/Makefile b/verilog/dv/caravel/mgmt_soc/pass_thru/Makefile new file mode 100644 index 00000000..b42527df --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/pass_thru/Makefile @@ -0,0 +1,86 @@ +# 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 + +PDK_PATH = $(PDK_ROOT)/sky130A +VERILOG_PATH = ../../../.. +RTL_PATH = $(VERILOG_PATH)/rtl +BEHAVIOURAL_MODELS = ../../ + +# Temporary: Path to management SoC wrapper repository +MGMT_WRAPPER_PATH = ~/gits/caravel_pico/verilog/rtl + +FIRMWARE_PATH = ../.. +GCC_PATH?=/ef/apps/bin +GCC_PREFIX?=riscv32-unknown-elf + +SIM_DEFINES = -DFUNCTIONAL -DSIM + +SIM?=RTL + +.SUFFIXES: + +PATTERN = pass_thru + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex +ifeq ($(SIM),RTL) + iverilog -Ttyp $(SIM_DEFINES) -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(RTL_PATH) -I $(MGMT_WRAPPER_PATH) \ + $< -o $@ +else + iverilog -Ttyp $(SIM_DEFINES) -DGL -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \ + $< -o $@ +endif + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s check-env + ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + ${GCC_PATH}/${GCC_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +check-env: +ifndef PDK_ROOT + $(error PDK_ROOT is undefined, please export it before running make) +endif +ifeq (,$(wildcard $(PDK_ROOT)/sky130A)) + $(error $(PDK_ROOT)/sky130A not found, please install pdk before running make) +endif +ifeq (,$(wildcard $(GCC_PATH)/$(GCC_PREFIX)-gcc )) + $(error $(GCC_PATH)/$(GCC_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make) +endif +# check for efabless style installation +ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog)) +SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE +endif +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all + diff --git a/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru.c b/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru.c new file mode 100644 index 00000000..33a981d5 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru.c @@ -0,0 +1,91 @@ +/* + * 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 "../../defs.h" + +// -------------------------------------------------------- + +void putchar(char c) +{ + if (c == '\n') + putchar('\r'); + reg_uart_data = c; +} + +void print(const char *p) +{ + while (*p) + putchar(*(p++)); +} + +// -------------------------------------------------------- + +void main() +{ + // This program is just to keep the processor busy while the + // housekeeping SPI is being accessed. to show that the + // processor is halted while the SPI is accessing the + // flash SPI in pass-through mode. + + // Configure I/O: High 16 bits of user area used for a 16-bit + // word to write and be detected by the testbench verilog. + // Only serial Tx line is used in this testbench. It connects + // to mprj_io[6]. Since all lines of the chip are input or + // high impedence on startup, the I/O has to be configured + // for output + + reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT; + + reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT; + + reg_mprj_io_6 = GPIO_MODE_MGMT_STD_OUTPUT; + + // Apply configuration + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + // Start test + reg_mprj_datal = 0xa0000000; + + // Set clock to 64 kbaud and enable the UART + reg_uart_clkdiv = 625; + reg_uart_enable = 1; + + // Test in progress + reg_mprj_datal = 0xa5000000; + + // Test message + print("Test message\n"); + + // End test + reg_mprj_datal = 0xab000000; +} + diff --git a/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru_tb.v b/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru_tb.v new file mode 100644 index 00000000..00c9e6ae --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/pass_thru/pass_thru_tb.v @@ -0,0 +1,351 @@ +// 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 +/* + * StriVe housekeeping pass-thru mode SPI testbench. + */ + +`timescale 1 ns / 1 ps + +`include "__uprj_netlists.v" +`include "caravel_netlists.v" +`include "spiflash.v" +`include "tbuart.v" + +module pass_thru_tb; + reg clock; + reg SDI, CSB, SCK, RSTB; + reg power1, power2; + + wire gpio; + wire [15:0] checkbits; + wire [37:0] mprj_io; + wire uart_tx; + wire uart_rx; + + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + wire flash_io2; + wire flash_io3; + + wire SDO; + + always #10 clock <= (clock === 1'b0); + + initial begin + clock = 0; + end + + initial begin // Power-up sequence + power1 <= 1'b0; + power2 <= 1'b0; + #200; + power1 <= 1'b1; + #200; + power2 <= 1'b1; + end + + // The main testbench is here. Put the housekeeping SPI into + // pass-thru mode and read several bytes from the flash SPI. + + // First define tasks for SPI functions + + task start_csb; + begin + SCK <= 1'b0; + SDI <= 1'b0; + CSB <= 1'b0; + #50; + end + endtask + + task end_csb; + begin + SCK <= 1'b0; + SDI <= 1'b0; + CSB <= 1'b1; + #50; + end + endtask + + task write_byte; + input [7:0] odata; + begin + SCK <= 1'b0; + for (i=7; i >= 0; i--) begin + #50; + SDI <= odata[i]; + #50; + SCK <= 1'b1; + #100; + SCK <= 1'b0; + end + end + endtask + + task read_byte; + output [7:0] idata; + begin + SCK <= 1'b0; + SDI <= 1'b0; + for (i=7; i >= 0; i--) begin + #50; + idata[i] = SDO; + #50; + SCK <= 1'b1; + #100; + SCK <= 1'b0; + end + end + endtask + + task read_write_byte + (input [7:0] odata, + output [7:0] idata); + begin + SCK <= 1'b0; + for (i=7; i >= 0; i--) begin + #50; + SDI <= odata[i]; + idata[i] = SDO; + #50; + SCK <= 1'b1; + #100; + SCK <= 1'b0; + end + end + endtask + + integer i; + + // Now drive the digital signals on the housekeeping SPI + reg [7:0] tbdata; + + initial begin + $dumpfile("pass_thru.vcd"); + $dumpvars(0, pass_thru_tb); + + CSB <= 1'b1; + SCK <= 1'b0; + SDI <= 1'b0; + RSTB <= 1'b0; + + #2000; + + RSTB <= 1'b1; + + // Wait on start of program execution + wait(checkbits == 16'hA000); + + // First do a normal read from the housekeeping SPI to + // make sure the housekeeping SPI works. + + start_csb(); + write_byte(8'h40); // Read stream command + write_byte(8'h03); // Address (register 3 = product ID) + read_byte(tbdata); + end_csb(); + #10; + $display("Read data = 0x%02x (should be 0x11)", tbdata); + if(tbdata !== 8'h11) begin + `ifdef GL + $display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish; + `else + $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; + `endif + end + + // Now write a command directly to the SPI flash. + start_csb(); + write_byte(8'hc4); // Pass-thru mode + write_byte(8'h03); // Command 03 (read values w/3-byte address + write_byte(8'h00); // Address is next three bytes (0x000000) + write_byte(8'h00); + write_byte(8'h00); + + read_byte(tbdata); + $display("Read flash data = 0x%02x (should be 0x93)", tbdata); + if(tbdata !== 8'h93) begin + `ifdef GL + $display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish; + `else + $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; + `endif + end + read_byte(tbdata); + $display("Read flash data = 0x%02x (should be 0x00)", tbdata); + if(tbdata !== 8'h00) begin + `ifdef GL + $display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish; + `else + $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; + `endif + end + read_byte(tbdata); + $display("Read flash data = 0x%02x (should be 0x00)", tbdata); + if(tbdata !== 8'h00) begin + `ifdef GL + $display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish; + `else + $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; + `endif + end + read_byte(tbdata); + $display("Read flash data = 0x%02x (should be 0x00)", tbdata); + if(tbdata !== 8'h00) begin + `ifdef GL + $display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish; + `else + $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; + `endif + end + read_byte(tbdata); + $display("Read flash data = 0x%02x (should be 0x93)", tbdata); + if(tbdata !== 8'h93) begin + `ifdef GL + $display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish; + `else + $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; + `endif + end + read_byte(tbdata); + $display("Read flash data = 0x%02x (should be 0x01)", tbdata); + if(tbdata !== 8'h01) begin + `ifdef GL + $display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish; + `else + $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; + `endif + end + read_byte(tbdata); + $display("Read flash data = 0x%02x (should be 0x00)", tbdata); + if(tbdata !== 8'h00) begin + `ifdef GL + $display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish; + `else + $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; + `endif + end + read_byte(tbdata); + $display("Read flash data = 0x%02x (should be 0x00)", tbdata); + if(tbdata !== 8'h00) begin + `ifdef GL + $display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish; + `else + $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; + `endif + end + + end_csb(); + + // Wait for processor to restart + wait(checkbits == 16'hA000); + + // Read product ID register again + + start_csb(); + write_byte(8'h40); // Read stream command + write_byte(8'h03); // Address (register 3 = product ID) + read_byte(tbdata); + end_csb(); + #10; + $display("Read data = 0x%02x (should be 0x11)", tbdata); + if(tbdata !== 8'h11) begin + `ifdef GL + $display("Monitor: Test HK SPI Pass-thru (GL) Failed"); $finish; + `else + $display("Monitor: Test HK SPI Pass-thru (RTL) Failed"); $finish; + `endif + end + + `ifdef GL + $display("Monitor: Test HK SPI Pass-thru (GL) Passed"); + `else + $display("Monitor: Test HK SPI Pass-thru (RTL) Passed"); + `endif + + #10000; + $finish; + end + + wire VDD3V3; + wire VDD1V8; + wire VSS; + + assign VDD3V3 = power1; + assign VDD1V8 = power2; + assign VSS = 1'b0; + + wire hk_sck; + wire hk_csb; + wire hk_sdi; + + assign hk_sck = SCK; + assign hk_csb = CSB; + assign hk_sdi = SDI; + + assign checkbits = mprj_io[31:16]; + assign uart_tx = mprj_io[6]; + assign mprj_io[5] = uart_rx; + assign mprj_io[4] = hk_sck; + assign mprj_io[3] = hk_csb; + assign mprj_io[2] = hk_sdi; + assign SDO = mprj_io[1]; + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (VDD3V3), + .vdda2 (VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (VDD1V8), + .vccd2 (VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clock), + .gpio (gpio), + .mprj_io (mprj_io), + .flash_csb(flash_csb), + .flash_clk(flash_clk), + .flash_io0(flash_io0), + .flash_io1(flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("pass_thru.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + + tbuart tbuart ( + .ser_rx(uart_tx) + ); + +endmodule +`default_nettype wire diff --git a/verilog/rtl/housekeeping.v b/verilog/rtl/housekeeping.v index a21fbec2..d681c5e2 100644 --- a/verilog/rtl/housekeeping.v +++ b/verilog/rtl/housekeeping.v @@ -263,17 +263,17 @@ module housekeeping #( // Pass-through mode. Housekeeping SPI signals get inserted // between the management SoC and the flash SPI I/O. - assign pad_flash_csb = (pass_thru_mgmt) ? mgmt_gpio_in[3] : spimemio_flash_csb; - assign pad_flash_csb_oeb = (pass_thru_mgmt) ? 1'b0 : (~porb ? 1'b1 : 1'b0); + assign pad_flash_csb = (pass_thru_mgmt_delay) ? mgmt_gpio_in[3] : spimemio_flash_csb; + assign pad_flash_csb_oeb = (pass_thru_mgmt_delay) ? 1'b0 : (~porb ? 1'b1 : 1'b0); assign pad_flash_clk = (pass_thru_mgmt) ? mgmt_gpio_in[4] : spimemio_flash_clk; assign pad_flash_clk_oeb = (pass_thru_mgmt) ? 1'b0 : (~porb ? 1'b1 : 1'b0); - assign pad_flash_io0_oeb = (pass_thru_mgmt) ? 1'b0 : spimemio_flash_io0_oeb; + assign pad_flash_io0_oeb = (pass_thru_mgmt_delay) ? 1'b0 : spimemio_flash_io0_oeb; assign pad_flash_io1_oeb = (pass_thru_mgmt) ? 1'b1 : spimemio_flash_io1_oeb; - assign pad_flash_io0_ieb = (pass_thru_mgmt) ? 1'b1 : ~spimemio_flash_io0_oeb; - assign pad_flash_io1_ieb = (pass_thru_mgmt) ? 1'b1 : ~spimemio_flash_io1_oeb; - assign pad_flash_io0_do = (pass_thru_mgmt) ? mgmt_gpio_in[2] : spimemio_flash_io0_do; + assign pad_flash_io0_ieb = (pass_thru_mgmt_delay) ? 1'b1 : ~spimemio_flash_io0_oeb; + assign pad_flash_io1_ieb = (pass_thru_mgmt) ? 1'b0 : ~spimemio_flash_io1_oeb; + assign pad_flash_io0_do = (pass_thru_mgmt_delay) ? mgmt_gpio_in[2] : spimemio_flash_io0_do; assign pad_flash_io1_do = spimemio_flash_io1_do; - assign spimemio_flash_io0_di = (pass_thru_mgmt) ? 1'b0 : pad_flash_io0_di; + assign spimemio_flash_io0_di = (pass_thru_mgmt_delay) ? 1'b0 : pad_flash_io0_di; assign spimemio_flash_io1_di = (pass_thru_mgmt) ? 1'b0 : pad_flash_io1_di; // Wishbone bus "back door" to SPI registers. This section of code @@ -715,7 +715,7 @@ module housekeeping #( : mgmt_gpio_data[10]; assign mgmt_gpio_out_pre[9] = (pass_thru_user) ? mgmt_gpio_in[4] : mgmt_gpio_data[9]; - assign mgmt_gpio_out_pre[8] = (pass_thru_user) ? mgmt_gpio_in[3] + assign mgmt_gpio_out_pre[8] = (pass_thru_user_delay) ? mgmt_gpio_in[3] : mgmt_gpio_data[8]; assign mgmt_gpio_out_pre[7] = mgmt_gpio_data[7];