diff --git a/TESTBENCH/caravel_dv/common/defs.h b/TESTBENCH/caravel_dv/common/defs.h new file mode 100644 index 0000000..2402f47 --- /dev/null +++ b/TESTBENCH/caravel_dv/common/defs.h @@ -0,0 +1,186 @@ +#ifndef _STRIVE_H_ +#define _STRIVE_H_ + +#include +#include + +// a pointer to this is a null pointer, but the compiler does not +// know that because "sram" is a linker symbol from sections.lds. +extern uint32_t sram; + +// Pointer to firmware flash routines +extern uint32_t flashio_worker_begin; +extern uint32_t flashio_worker_end; + +// Storage area (MGMT: 0x0100_0000, User: 0x0200_0000) +#define reg_rw_block0 (*(volatile uint32_t*)0x01000000) +#define reg_rw_block1 (*(volatile uint32_t*)0x01100000) +#define reg_ro_block0 (*(volatile uint32_t*)0x02000000) + +// UART (0x2000_0000) +#define reg_uart_clkdiv (*(volatile uint32_t*)0x20000000) +#define reg_uart_data (*(volatile uint32_t*)0x20000004) +#define reg_uart_enable (*(volatile uint32_t*)0x20000008) + +// GPIO (0x2100_0000) +#define reg_gpio_data (*(volatile uint32_t*)0x21000000) +#define reg_gpio_ena (*(volatile uint32_t*)0x21000004) +#define reg_gpio_pu (*(volatile uint32_t*)0x21000008) +#define reg_gpio_pd (*(volatile uint32_t*)0x2100000c) + +// Logic Analyzer (0x2200_0000) +#define reg_la0_data (*(volatile uint32_t*)0x25000000) +#define reg_la1_data (*(volatile uint32_t*)0x25000004) +#define reg_la2_data (*(volatile uint32_t*)0x25000008) +#define reg_la3_data (*(volatile uint32_t*)0x2500000c) + +#define reg_la0_ena (*(volatile uint32_t*)0x25000010) +#define reg_la1_ena (*(volatile uint32_t*)0x25000014) +#define reg_la2_ena (*(volatile uint32_t*)0x25000018) +#define reg_la3_ena (*(volatile uint32_t*)0x2500001c) + +// User Project Control (0x2300_0000) +#define reg_mprj_xfer (*(volatile uint32_t*)0x26000000) +#define reg_mprj_pwr (*(volatile uint32_t*)0x26000004) +#define reg_mprj_datal (*(volatile uint32_t*)0x26000008) +#define reg_mprj_datah (*(volatile uint32_t*)0x2600000c) + +#define reg_mprj_io_0 (*(volatile uint32_t*)0x26000020) +#define reg_mprj_io_1 (*(volatile uint32_t*)0x26000024) +#define reg_mprj_io_2 (*(volatile uint32_t*)0x26000028) +#define reg_mprj_io_3 (*(volatile uint32_t*)0x2600002c) +#define reg_mprj_io_4 (*(volatile uint32_t*)0x26000030) +#define reg_mprj_io_5 (*(volatile uint32_t*)0x26000034) +#define reg_mprj_io_6 (*(volatile uint32_t*)0x26000038) + +#define reg_mprj_io_7 (*(volatile uint32_t*)0x2600003c) +#define reg_mprj_io_8 (*(volatile uint32_t*)0x26000040) +#define reg_mprj_io_9 (*(volatile uint32_t*)0x26000044) +#define reg_mprj_io_10 (*(volatile uint32_t*)0x26000048) + +#define reg_mprj_io_11 (*(volatile uint32_t*)0x2600004c) +#define reg_mprj_io_12 (*(volatile uint32_t*)0x26000050) +#define reg_mprj_io_13 (*(volatile uint32_t*)0x26000054) +#define reg_mprj_io_14 (*(volatile uint32_t*)0x26000058) + +#define reg_mprj_io_15 (*(volatile uint32_t*)0x2600005c) +#define reg_mprj_io_16 (*(volatile uint32_t*)0x26000060) +#define reg_mprj_io_17 (*(volatile uint32_t*)0x26000064) +#define reg_mprj_io_18 (*(volatile uint32_t*)0x26000068) + +#define reg_mprj_io_19 (*(volatile uint32_t*)0x2600006c) +#define reg_mprj_io_20 (*(volatile uint32_t*)0x26000070) +#define reg_mprj_io_21 (*(volatile uint32_t*)0x26000074) +#define reg_mprj_io_22 (*(volatile uint32_t*)0x26000078) + +#define reg_mprj_io_23 (*(volatile uint32_t*)0x2600007c) +#define reg_mprj_io_24 (*(volatile uint32_t*)0x26000080) +#define reg_mprj_io_25 (*(volatile uint32_t*)0x26000084) +#define reg_mprj_io_26 (*(volatile uint32_t*)0x26000088) + +#define reg_mprj_io_27 (*(volatile uint32_t*)0x2600008c) +#define reg_mprj_io_28 (*(volatile uint32_t*)0x26000090) +#define reg_mprj_io_29 (*(volatile uint32_t*)0x26000094) +#define reg_mprj_io_30 (*(volatile uint32_t*)0x26000098) +#define reg_mprj_io_31 (*(volatile uint32_t*)0x2600009c) + +#define reg_mprj_io_32 (*(volatile uint32_t*)0x260000a0) +#define reg_mprj_io_33 (*(volatile uint32_t*)0x260000a4) +#define reg_mprj_io_34 (*(volatile uint32_t*)0x260000a8) +#define reg_mprj_io_35 (*(volatile uint32_t*)0x260000ac) +#define reg_mprj_io_36 (*(volatile uint32_t*)0x260000b0) +#define reg_mprj_io_37 (*(volatile uint32_t*)0x260000b4) + +// User Project Slaves (0x3000_0000) +#define reg_mprj_slave (*(volatile uint32_t*)0x30000000) + +// Flash Control SPI Configuration (2D00_0000) +#define reg_spictrl (*(volatile uint32_t*)0x2d000000) + +// Bit fields for Flash SPI control +#define FLASH_BITBANG_IO0 0x00000001 +#define FLASH_BITBANG_IO1 0x00000002 +#define FLASH_BITBANG_CLK 0x00000010 +#define FLASH_BITBANG_CSB 0x00000020 +#define FLASH_BITBANG_OEB0 0x00000100 +#define FLASH_BITBANG_OEB1 0x00000200 +#define FLASH_ENABLE 0x80000000 + +// Counter-Timer 0 Configuration +#define reg_timer0_config (*(volatile uint32_t*)0x22000000) +#define reg_timer0_value (*(volatile uint32_t*)0x22000004) +#define reg_timer0_data (*(volatile uint32_t*)0x22000008) + +// Counter-Timer 1 Configuration +#define reg_timer1_config (*(volatile uint32_t*)0x23000000) +#define reg_timer1_value (*(volatile uint32_t*)0x23000004) +#define reg_timer1_data (*(volatile uint32_t*)0x23000008) + +// Bit fields for Counter-timer configuration +#define TIMER_ENABLE 0x01 +#define TIMER_ONESHOT 0x02 +#define TIMER_UPCOUNT 0x04 +#define TIMER_CHAIN 0x08 +#define TIMER_IRQ_ENABLE 0x10 + +// SPI Master Configuration +#define reg_spimaster_config (*(volatile uint32_t*)0x24000000) +#define reg_spimaster_data (*(volatile uint32_t*)0x24000004) + +// Bit fields for SPI master configuration +#define SPI_MASTER_DIV_MASK 0x00ff +#define SPI_MASTER_MLB 0x0100 +#define SPI_MASTER_INV_CSB 0x0200 +#define SPI_MASTER_INV_CLK 0x0400 +#define SPI_MASTER_MODE_1 0x0800 +#define SPI_MASTER_STREAM 0x1000 +#define SPI_MASTER_ENABLE 0x2000 +#define SPI_MASTER_IRQ_ENABLE 0x4000 +#define SPI_HOUSEKEEPING_CONN 0x8000 + +// System Area (0x2F00_0000) +#define reg_power_good (*(volatile uint32_t*)0x2F000000) +#define reg_clk_out_dest (*(volatile uint32_t*)0x2F000004) +#define reg_trap_out_dest (*(volatile uint32_t*)0x2F000008) +#define reg_irq_source (*(volatile uint32_t*)0x2F00000C) + +// Bit fields for reg_power_good +#define USER1_VCCD_POWER_GOOD 0x01 +#define USER2_VCCD_POWER_GOOD 0x02 +#define USER1_VDDA_POWER_GOOD 0x04 +#define USER2_VDDA_POWER_GOOD 0x08 + +// Bit fields for reg_clk_out_dest +#define CLOCK1_MONITOR 0x01 +#define CLOCK2_MONITOR 0x02 + +// Bit fields for reg_irq_source +#define IRQ7_SOURCE 0x01 +#define IRQ8_SOURCE 0x02 + +// Individual bit fields for the GPIO pad control +#define MGMT_ENABLE 0x0001 +#define OUTPUT_DISABLE 0x0002 +#define HOLD_OVERRIDE 0x0004 +#define INPUT_DISABLE 0x0008 +#define MODE_SELECT 0x0010 +#define ANALOG_ENABLE 0x0020 +#define ANALOG_SELECT 0x0040 +#define ANALOG_POLARITY 0x0080 +#define SLOW_SLEW_MODE 0x0100 +#define TRIPPOINT_SEL 0x0200 +#define DIGITAL_MODE_MASK 0x1c00 + +// Useful GPIO mode values +#define GPIO_MODE_MGMT_STD_INPUT_NOPULL 0x0403 +#define GPIO_MODE_MGMT_STD_INPUT_PULLDOWN 0x0803 +#define GPIO_MODE_MGMT_STD_INPUT_PULLUP 0x0c03 +#define GPIO_MODE_MGMT_STD_OUTPUT 0x1809 + +#define GPIO_MODE_USER_STD_INPUT_NOPULL 0x0402 +#define GPIO_MODE_USER_STD_INPUT_PULLDOWN 0x0802 +#define GPIO_MODE_USER_STD_INPUT_PULLUP 0x0c02 +#define GPIO_MODE_USER_STD_OUTPUT 0x1808 + +// -------------------------------------------------------- +#endif diff --git a/TESTBENCH/caravel_dv/common/sections.lds b/TESTBENCH/caravel_dv/common/sections.lds new file mode 100644 index 0000000..8da9aae --- /dev/null +++ b/TESTBENCH/caravel_dv/common/sections.lds @@ -0,0 +1,58 @@ +MEMORY { + FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x400000 /* 4MB */ + RAM(xrw) : ORIGIN = 0x00000000, LENGTH = 0x0400 /* 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/TESTBENCH/caravel_dv/common/start.s b/TESTBENCH/caravel_dv/common/start.s new file mode 100644 index 0000000..62a6f42 --- /dev/null +++ b/TESTBENCH/caravel_dv/common/start.s @@ -0,0 +1,159 @@ +.section .text + +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 + +# copy data section +la a0, _sidata +la a1, _sdata +la a2, _edata +bge a1, a2, end_init_data +loop_init_data: +lw a3, 0(a0) +sw a3, 0(a1) +addi a0, a0, 4 +addi a1, a1, 4 +blt a1, a2, loop_init_data +end_init_data: + +# zero-init bss section +la a0, _sbss +la a1, _ebss +bge a0, a1, end_init_bss +loop_init_bss: +sw zero, 0(a0) +addi a0, a0, 4 +blt a0, a1, loop_init_bss +end_init_bss: + +# call main +call main +loop: +j loop + +.global flashio_worker_begin +.global flashio_worker_end + +.balign 4 + +flashio_worker_begin: +# a0 ... data pointer +# a1 ... data length +# a2 ... optional WREN cmd (0 = disable) + +# address of SPI ctrl reg +li t0, 0x28000000 + +# 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: + +# If byte count is zero, we're done +beqz a1, flashio_worker_L3 + +# Set t5 to count down 32 bits +li t5, 32 +# Load t2 from address a0 (4 bytes) +lw t2, 0(a0) + +flashio_worker_LY: +# Set t6 to count down 8 bits +li t6, 8 + +flashio_worker_L2: +# Clock out the bit (msb first) on IO0 and read bit in from IO1 +srli t4, t2, 31 +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 + +# Decrement 32 bit count +addi t5, t5, -1 +bnez t5, flashio_worker_LX + +sw t2, 0(a0) +addi a0, a0, 4 +lw t2, 0(a0) + +flashio_worker_LX: +addi t6, t6, -1 +bnez t6, flashio_worker_L2 +addi a1, a1, -1 +bnez a1, flashio_worker_LY + +beqz t5, flashio_worker_L3 +sw t2, 0(a0) + +flashio_worker_L3: +# Back to MEMIO mode +li t1, 0x80 +sb t1, 3(t0) + +ret +.balign 4 +flashio_worker_end: + diff --git a/TESTBENCH/caravel_dv/scff_test/Makefile b/TESTBENCH/caravel_dv/scff_test/Makefile new file mode 100644 index 0000000..820caa7 --- /dev/null +++ b/TESTBENCH/caravel_dv/scff_test/Makefile @@ -0,0 +1,30 @@ +FIRMWARE_PATH = ../common + +GCC_PATH?=/var/tmp/xtang/riscv32i/bin +GCC_PREFIX?=riscv32-unknown-elf + +.SUFFIXES: + +PATTERN = scff_test_caravel + +all: ${PATTERN:=.hex} + +hex: ${PATTERN:=.hex} + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s + ${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 > $@ + +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all diff --git a/TESTBENCH/caravel_dv/scff_test/scff_test_caravel.c b/TESTBENCH/caravel_dv/scff_test/scff_test_caravel.c new file mode 100644 index 0000000..20a18b5 --- /dev/null +++ b/TESTBENCH/caravel_dv/scff_test/scff_test_caravel.c @@ -0,0 +1,62 @@ +#include "../common/defs.h" + +/* + * Scan-chain Test: + * - Configures directions for control ports + * +==========+===============+===========+ + * | GPIO | Functionality | Direction | + * +==========+===============+===========+ + * | GPIO[0] | TEST_EN | input | + * +----------+---------------+-----------+ + * | GPIO[1] | IO_ISOL_N | input | + * +----------+---------------+-----------+ + * | GPIO[2] | RESET | input | + * +----------+---------------+-----------+ + * | GPIO[3] | PROG_RESET | input | + * +----------+---------------+-----------+ + * | GPIO[11] | SC_TAIL | output | + * +----------+---------------+-----------+ + * | GPIO[12] | CCFF_HEAD | input | + * +----------+---------------+-----------+ + * | GPIO[25] | MODE_SWITCH) | input | + * +----------+---------------+-----------+ + * | GPIO[26] | SC_HEAD | input | + * +----------+---------------+-----------+ + * | GPIO[35] | CCFF_TAIL | output | + * +----------+---------------+-----------+ + * | GPIO[36] | CLK | input | + * +----------+---------------+-----------+ + * | GPIO[37] | PROG_CLK | input | + * +----------+---------------+-----------+ + * + * - Configure FPGA data I/Os to be input +*/ + +void main() { + /* + IO Control Registers + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 3-bits | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | + + Output: 0000_0110_0000_1110 (0x1808) = GPIO_MODE_USER_STD_OUTPUT + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | + + + Input: 0000_0001_0000_1111 (0x0402) = GPIO_MODE_USER_STD_INPUT_NOPULL + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | + + */ + + // By default all the I/Os are in input mode + // Only specify those should be in output mode + reg_mprj_io_11 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_35 = GPIO_MODE_USER_STD_OUTPUT; + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + +} + diff --git a/TESTBENCH/caravel_dv/scff_test/scff_test_caravel.hex b/TESTBENCH/caravel_dv/scff_test/scff_test_caravel.hex new file mode 100755 index 0000000..2c091e0 --- /dev/null +++ b/TESTBENCH/caravel_dv/scff_test/scff_test_caravel.hex @@ -0,0 +1,26 @@ +@00000000 +93 00 00 00 93 01 00 00 13 02 00 00 93 02 00 00 +13 03 00 00 93 03 00 00 13 04 00 00 93 04 00 00 +13 05 00 00 93 05 00 00 13 06 00 00 93 06 00 00 +13 07 00 00 93 07 00 00 13 08 00 00 93 08 00 00 +13 09 00 00 93 09 00 00 13 0A 00 00 93 0A 00 00 +13 0B 00 00 93 0B 00 00 13 0C 00 00 93 0C 00 00 +13 0D 00 00 93 0D 00 00 13 0E 00 00 93 0E 00 00 +13 0F 00 00 93 0F 00 00 17 05 00 00 13 05 85 11 +93 05 00 00 13 06 00 00 63 D8 C5 00 14 41 94 C1 +11 05 91 05 E3 CC C5 FE 13 05 00 00 93 05 00 00 +63 57 B5 00 23 20 05 00 11 05 E3 4D B5 FE 71 28 +01 A0 01 00 B7 02 00 28 13 03 00 12 23 90 62 00 +A3 81 02 00 05 C6 21 4F 93 73 F6 0F 93 DE 73 00 +23 80 D2 01 93 EE 0E 01 23 80 D2 01 86 03 93 F3 +F3 0F 7D 1F E3 14 0F FE 23 80 62 00 A1 C9 13 0F +00 02 83 23 05 00 A1 4F 93 DE F3 01 23 80 D2 01 +93 EE 0E 01 23 80 D2 01 83 CE 02 00 93 FE 2E 00 +93 DE 1E 00 86 03 B3 E3 D3 01 7D 1F 63 17 0F 00 +23 20 75 00 11 05 83 23 05 00 FD 1F E3 96 0F FC +FD 15 F1 F1 63 04 0F 00 23 20 75 00 13 03 00 08 +A3 81 62 00 82 80 01 00 00 00 41 11 22 C6 00 08 +B7 07 00 26 93 87 C7 04 09 67 13 07 87 80 98 C3 +B7 07 00 26 93 87 C7 0A 09 67 13 07 87 80 98 C3 +B7 07 00 26 05 47 98 C3 01 00 B7 07 00 26 98 43 +85 47 E3 0C F7 FE 01 00 32 44 41 01 82 80 00 00 diff --git a/TESTBENCH/caravel_dv/scff_test/scff_test_caravel.v b/TESTBENCH/caravel_dv/scff_test/scff_test_caravel.v new file mode 100644 index 0000000..501e5f0 --- /dev/null +++ b/TESTBENCH/caravel_dv/scff_test/scff_test_caravel.v @@ -0,0 +1,245 @@ +`timescale 1 ns / 1 ps + +`define POWER_UP_TIME_PERIOD 200 +`define SOC_SETUP_TIME_PERIOD 2000 +`define SOC_CLOCK_PERIOD 12.5 +`define FPGA_CLOCK_PERIOD 12.5 + +module scff_test_caravel; + reg clock; + reg RSTB; + reg power1, power2; + reg power3, power4; + + wire gpio; + wire [37:0] mprj_io; + + // ----- Local wires for control ports of FPGA fabric ----- + wire [0:0] pReset; + reg [0:0] prog_clock_reg; + wire [0:0] prog_clk; + wire [0:0] Test_en; + wire [0:0] Reset; + reg [0:0] op_clock_reg; + wire [0:0] op_clk; + reg [0:0] prog_reset; + reg [0:0] greset; + + // ---- Configuration-chain head ----- + wire [0:0] ccff_head; + // ---- Configuration-chain tail ----- + wire [0:0] ccff_tail; + + // ---- Scan-chain head ----- + reg [0:0] sc_head; + // ---- Scan-chain tail ----- + wire [0:0] sc_tail; + + wire [0:0] IO_ISOL_N; + + // ----- Counters for error checking ----- + integer num_clock_cycles = 0; + integer num_errors = 0; + integer num_checked_points = 0; + + // Indicate when SoC setup phase should be finished + reg soc_setup_done = 0; + // Indicate when configuration should be finished + reg scan_done = 0; + + initial + begin + scan_done = 1'b0; + soc_setup_done = 1'b0; + end + + // ----- Begin raw programming clock signal generation ----- + initial + begin + prog_clock_reg[0] = 1'b0; + end + // ----- End raw programming clock signal generation ----- + + // ----- Begin raw operating clock signal generation ----- + initial + begin + op_clock_reg[0] = 1'b0; + end + always + begin + #(`FPGA_CLOCK_PERIOD) op_clock_reg[0] = ~op_clock_reg[0]; + end +// ----- End raw operating clock signal generation ----- +// ----- Actual operating clock is triggered only when scan_done is enabled ----- + assign prog_clock[0] = prog_clock_reg[0] & ~greset; + assign op_clock[0] = op_clock_reg[0] & ~greset; + + // ----- Begin programming reset signal generation ----- + initial + begin + prog_reset[0] = 1'b0; + end + + // ----- End programming reset signal generation ----- + + // ----- Begin operating reset signal generation ----- + // ----- Reset signal is disabled always ----- + initial + begin + greset[0] = 1'b1; + #(`SOC_SETUP_TIME_PERIOD + 2 * `FPGA_CLOCK_PERIOD) greset[0] = 1'b0; + end + // ----- End operating reset signal generation ----- + + // ----- Begin connecting global ports of FPGA fabric to stimuli ----- + assign op_clk[0] = op_clock[0]; + assign prog_clk[0] = prog_clock[0]; + assign pReset[0] = ~prog_reset[0]; + assign Reset[0] = ~greset[0]; + assign Test_en[0] = ~greset; + assign ccff_head[0] = 1'b0; + assign IO_ISOL_N[0] = 1'b0; + // ----- End connecting global ports of FPGA fabric to stimuli ----- + + assign mprj_io[0] = Test_en; + assign mprj_io[1] = IO_ISOL_N; + assign mprj_io[2] = Reset; + assign mprj_io[3] = pReset; + assign mprj_io[12] = ccff_head; + assign mprj_io[25] = 1'b0; // Set FPGA to interface logic analyzer by default + assign mprj_io[26] = sc_head; + assign mprj_io[36] = op_clk; + assign mprj_io[37] = prog_clk; + + assign sc_tail = mprj_io[11]; + assign ccff_tail = mprj_io[35]; + + assign mprj_io[10:4] = {7{1'b0}}; + assign mprj_io[24:13] = {12{1'b0}}; + assign mprj_io[34:27] = {8{1'b0}}; + +// Generate a pulse after operating reset is disabled (in the 2nd clock +// cycle). Then the head of scan chain should be always zero + always @(negedge op_clock[0]) begin + sc_head = 1'b1; + if (0 != num_clock_cycles) begin + sc_head = 1'b0; + end + end + +// ----- Count the number of programming cycles ------- + always @(posedge op_clock[0]) begin + num_clock_cycles = num_clock_cycles + 1; + // Indicate when scan chain loading is suppose to end + if (`FPGA_SCANCHAIN_SIZE + 1 == num_clock_cycles) begin + scan_done = 1'b1; + end + + // Check the tail of scan-chain when configuration is done + if (1'b1 == scan_done) begin + // The tail should spit a pulse after configuration is done + // So it should be at logic '1' and then pulled down to logic '0' + if (0 == num_checked_points) begin + if (sc_tail !== 1'b1) begin + $display("Error: sc_tail = %b", sc_tail); + num_errors = num_errors + 1; + end + end + if (1 <= num_checked_points) begin + if (sc_tail !== 1'b0) begin + $display("Error: sc_tail = %b", sc_tail); + num_errors = num_errors + 1; + end + end + num_checked_points = num_checked_points + 1; + end + + if (2 < num_checked_points) begin + $display("Simulation finish with %d errors", num_errors); + + // End simulation + $finish; + end + end + + // 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 #(`SOC_CLOCK_PERIOD) clock <= (clock === 1'b0); + + initial begin + clock = 0; + end + + initial begin + RSTB <= 1'b0; + soc_setup_done <= 1'b1; + #(`SOC_SETUP_TIME_PERIOD); + RSTB <= 1'b1; // Release reset + soc_setup_done <= 1'b1; // We can start scff test + end + + initial begin // Power-up sequence + power1 <= 1'b0; + power2 <= 1'b0; + power3 <= 1'b0; + power4 <= 1'b0; + #(`POWER_UP_TIME_PERIOD); + power1 <= 1'b1; + #(`POWER_UP_TIME_PERIOD); + power2 <= 1'b1; + #(`POWER_UP_TIME_PERIOD); + power3 <= 1'b1; + #(`POWER_UP_TIME_PERIOD); + power4 <= 1'b1; + end + + 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("/research/ece/lnis/USERS/tang/github/skywater-openfpga/TESTBENCH/caravel_dv/scff_test/scff_test_caravel.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule