mirror of https://github.com/efabless/caravel.git
Added testbenches for irq, mem, mprj_ctrl, and pass_thru (note that "mem"
does not pass yet and still needs to be debugged).
This commit is contained in:
parent
2e57b5da08
commit
0fa2e3bb89
|
@ -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
|
|
@ -0,0 +1,32 @@
|
|||
<!---
|
||||
# SPDX-FileCopyrightText: 2020 Efabless Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
------------------------------------------------
|
||||
Caravel
|
||||
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).
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015 Clifford Wolf
|
||||
* PicoRV32 -- A Small RISC-V (RV32I) Processor Core
|
||||
*
|
||||
* Copyright (C) 2015 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*/
|
||||
|
||||
#define regnum_q0 0
|
||||
#define regnum_q1 1
|
||||
#define regnum_q2 2
|
||||
#define regnum_q3 3
|
||||
|
||||
#define regnum_x0 0
|
||||
#define regnum_x1 1
|
||||
#define regnum_x2 2
|
||||
#define regnum_x3 3
|
||||
#define regnum_x4 4
|
||||
#define regnum_x5 5
|
||||
#define regnum_x6 6
|
||||
#define regnum_x7 7
|
||||
#define regnum_x8 8
|
||||
#define regnum_x9 9
|
||||
#define regnum_x10 10
|
||||
#define regnum_x11 11
|
||||
#define regnum_x12 12
|
||||
#define regnum_x13 13
|
||||
#define regnum_x14 14
|
||||
#define regnum_x15 15
|
||||
#define regnum_x16 16
|
||||
#define regnum_x17 17
|
||||
#define regnum_x18 18
|
||||
#define regnum_x19 19
|
||||
#define regnum_x20 20
|
||||
#define regnum_x21 21
|
||||
#define regnum_x22 22
|
||||
#define regnum_x23 23
|
||||
#define regnum_x24 24
|
||||
#define regnum_x25 25
|
||||
#define regnum_x26 26
|
||||
#define regnum_x27 27
|
||||
#define regnum_x28 28
|
||||
#define regnum_x29 29
|
||||
#define regnum_x30 30
|
||||
#define regnum_x31 31
|
||||
|
||||
#define regnum_zero 0
|
||||
#define regnum_ra 1
|
||||
#define regnum_sp 2
|
||||
#define regnum_gp 3
|
||||
#define regnum_tp 4
|
||||
#define regnum_t0 5
|
||||
#define regnum_t1 6
|
||||
#define regnum_t2 7
|
||||
#define regnum_s0 8
|
||||
#define regnum_s1 9
|
||||
#define regnum_a0 10
|
||||
#define regnum_a1 11
|
||||
#define regnum_a2 12
|
||||
#define regnum_a3 13
|
||||
#define regnum_a4 14
|
||||
#define regnum_a5 15
|
||||
#define regnum_a6 16
|
||||
#define regnum_a7 17
|
||||
#define regnum_s2 18
|
||||
#define regnum_s3 19
|
||||
#define regnum_s4 20
|
||||
#define regnum_s5 21
|
||||
#define regnum_s6 22
|
||||
#define regnum_s7 23
|
||||
#define regnum_s8 24
|
||||
#define regnum_s9 25
|
||||
#define regnum_s10 26
|
||||
#define regnum_s11 27
|
||||
#define regnum_t3 28
|
||||
#define regnum_t4 29
|
||||
#define regnum_t5 30
|
||||
#define regnum_t6 31
|
||||
|
||||
// x8 is s0 and also fp
|
||||
#define regnum_fp 8
|
||||
|
||||
#define r_type_insn(_f7, _rs2, _rs1, _f3, _rd, _opc) \
|
||||
.word (((_f7) << 25) | ((_rs2) << 20) | ((_rs1) << 15) | ((_f3) << 12) | ((_rd) << 7) | ((_opc) << 0))
|
||||
|
||||
#define picorv32_getq_insn(_rd, _qs) \
|
||||
r_type_insn(0b0000000, 0, regnum_ ## _qs, 0b100, regnum_ ## _rd, 0b0001011)
|
||||
|
||||
#define picorv32_setq_insn(_qd, _rs) \
|
||||
r_type_insn(0b0000001, 0, regnum_ ## _rs, 0b010, regnum_ ## _qd, 0b0001011)
|
||||
|
||||
#define picorv32_retirq_insn() \
|
||||
r_type_insn(0b0000010, 0, 0, 0b000, 0, 0b0001011)
|
||||
|
||||
#define picorv32_maskirq_insn(_rd, _rs) \
|
||||
r_type_insn(0b0000011, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011)
|
||||
|
||||
#define picorv32_waitirq_insn(_rd) \
|
||||
r_type_insn(0b0000100, 0, 0, 0b100, regnum_ ## _rd, 0b0001011)
|
||||
|
||||
#define picorv32_timer_insn(_rd, _rs) \
|
||||
r_type_insn(0b0000101, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011)
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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 <clifford@clifford.at>
|
||||
* Copyright (C) 2021 Tim Edwards <tim@efabless.com>
|
||||
*
|
||||
* 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
|
|
@ -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
|
||||
}
|
|
@ -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:
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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 <clifford@clifford.at>
|
||||
* Copyright (C) 2018 Tim Edwards <tim@efabless.com>
|
||||
*
|
||||
* 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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue