[Testbench] Add ccff_test for caravel

This commit is contained in:
tangxifan 2020-12-16 20:25:21 -07:00
parent 9a23f0b15e
commit 2d8b4b59db
4 changed files with 436 additions and 0 deletions

View File

@ -0,0 +1,30 @@
FIRMWARE_PATH = ../common
GCC_PATH?=/var/tmp/xtang/riscv32i/bin
GCC_PREFIX?=riscv32-unknown-elf
.SUFFIXES:
PATTERN = ccff_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,98 @@
#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
reg_mprj_io_0 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_1 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_2 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_3 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_4 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_5 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_6 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_7 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_8 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_9 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_10 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_12 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_13 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_14 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_15 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_16 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_17 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_18 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_19 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_20 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_21 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_22 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_23 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_24 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_25 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_26 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_27 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_28 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_29 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_30 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_31 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_32 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_33 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_34 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_36 = GPIO_MODE_USER_STD_INPUT_NOPULL;
reg_mprj_io_37 = GPIO_MODE_USER_STD_INPUT_NOPULL;
// 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,58 @@
@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 05 31
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 07 02 13 07 20 40 98 C3 B7 07
00 26 93 87 47 02 13 07 20 40 98 C3 B7 07 00 26
93 87 87 02 13 07 20 40 98 C3 B7 07 00 26 93 87
C7 02 13 07 20 40 98 C3 B7 07 00 26 93 87 07 03
13 07 20 40 98 C3 B7 07 00 26 93 87 47 03 13 07
20 40 98 C3 B7 07 00 26 93 87 87 03 13 07 20 40
98 C3 B7 07 00 26 93 87 C7 03 13 07 20 40 98 C3
B7 07 00 26 93 87 07 04 13 07 20 40 98 C3 B7 07
00 26 93 87 47 04 13 07 20 40 98 C3 B7 07 00 26
93 87 87 04 13 07 20 40 98 C3 B7 07 00 26 93 87
07 05 13 07 20 40 98 C3 B7 07 00 26 93 87 47 05
13 07 20 40 98 C3 B7 07 00 26 93 87 87 05 13 07
20 40 98 C3 B7 07 00 26 93 87 C7 05 13 07 20 40
98 C3 B7 07 00 26 93 87 07 06 13 07 20 40 98 C3
B7 07 00 26 93 87 47 06 13 07 20 40 98 C3 B7 07
00 26 93 87 87 06 13 07 20 40 98 C3 B7 07 00 26
93 87 C7 06 13 07 20 40 98 C3 B7 07 00 26 93 87
07 07 13 07 20 40 98 C3 B7 07 00 26 93 87 47 07
13 07 20 40 98 C3 B7 07 00 26 93 87 87 07 13 07
20 40 98 C3 B7 07 00 26 93 87 C7 07 13 07 20 40
98 C3 B7 07 00 26 93 87 07 08 13 07 20 40 98 C3
B7 07 00 26 93 87 47 08 13 07 20 40 98 C3 B7 07
00 26 93 87 87 08 13 07 20 40 98 C3 B7 07 00 26
93 87 C7 08 13 07 20 40 98 C3 B7 07 00 26 93 87
07 09 13 07 20 40 98 C3 B7 07 00 26 93 87 47 09
13 07 20 40 98 C3 B7 07 00 26 93 87 87 09 13 07
20 40 98 C3 B7 07 00 26 93 87 C7 09 13 07 20 40
98 C3 B7 07 00 26 93 87 07 0A 13 07 20 40 98 C3
B7 07 00 26 93 87 47 0A 13 07 20 40 98 C3 B7 07
00 26 93 87 87 0A 13 07 20 40 98 C3 B7 07 00 26
93 87 07 0B 13 07 20 40 98 C3 B7 07 00 26 93 87
47 0B 13 07 20 40 98 C3 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,250 @@
`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_PROG_CLOCK_PERIOD 12.5
`define FPGA_CLOCK_PERIOD 12.5
module ccff_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] prog_clock;
wire [0:0] Test_en;
wire [0:0] Reset;
reg [0:0] op_clock_reg;
wire [0:0] op_clk;
wire [0:0] op_clock;
reg [0:0] prog_reset;
reg [0:0] greset;
// ---- Configuration-chain head -----
reg [0:0] ccff_head;
// ---- Configuration-chain tail -----
wire [0:0] ccff_tail;
// ---- Scan-chain head -----
wire [0:0] sc_head;
// ---- Scan-chain tail -----
wire [0:0] sc_tail;
wire [0:0] IO_ISOL_N;
// ----- Counters for error checking -----
integer num_prog_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 config_done = 0;
initial
begin
config_done = 1'b0;
soc_setup_done = 1'b0;
end
// ----- Begin raw programming clock signal generation -----
initial
begin
prog_clock_reg[0] = 1'b0;
end
always
begin
#(`FPGA_PROG_CLOCK_PERIOD) prog_clock_reg[0] = ~prog_clock_reg[0];
end
// ----- End raw programming clock signal generation -----
// ----- Begin raw operating clock signal generation -----
initial
begin
op_clock_reg[0] = 1'b0;
end
// ----- End raw operating clock signal generation -----
// ----- Actual operating clock is triggered only when config_done is enabled -----
assign prog_clock[0] = prog_clock_reg[0] & (~prog_reset[0]);
assign op_clock[0] = op_clock_reg[0];
// ----- Begin programming reset signal generation -----
initial
begin
prog_reset[0] = 1'b1;
#(`SOC_SETUP_TIME_PERIOD + 2 * `FPGA_PROG_CLOCK_PERIOD) 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;
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] = 1'b0;
assign sc_head[0] = 1'b0;
assign IO_ISOL_N[0] = ~greset;
// ----- 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 programming reset is disabled (in the 2nd clock
// cycle). Then the head of configuration chain should be always zero
always @(negedge prog_clock[0]) begin
ccff_head = 1'b1;
if (0 != num_prog_cycles) begin
ccff_head = 1'b0;
end
end
// ----- Count the number of programming cycles -------
always @(posedge prog_clock[0]) begin
num_prog_cycles = num_prog_cycles + 1;
// Indicate when configuration is suppose to end
if (`FPGA_BITSTREAM_SIZE + 1 == num_prog_cycles) begin
config_done = 1'b1;
end
// Check the ccff_tail when configuration is done
if (1'b1 == config_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 (ccff_tail !== 1'b1) begin
$display("Error: ccff_tail = %b", sc_tail);
num_errors = num_errors + 1;
end
end
if (1 <= num_checked_points) begin
if (ccff_tail !== 1'b0) begin
$display("Error: ccff_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