[Testbench] Start building caravel testbench

This commit is contained in:
tangxifan 2020-12-16 14:53:52 -07:00
parent e24d643cbd
commit f5d78fc0fa
7 changed files with 766 additions and 0 deletions

View File

@ -0,0 +1,186 @@
#ifndef _STRIVE_H_
#define _STRIVE_H_
#include <stdint.h>
#include <stdbool.h>
// 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

View File

@ -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
}

View File

@ -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:

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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