From a360b77618e38aaedc1b3f74f1a6dff91fd2cd7b Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 31 Oct 2021 16:58:44 -0400 Subject: [PATCH] Added a testbench that demonstrates copying a portion of a program in flash into SRAM and executing it. --- verilog/dv/caravel/mgmt_soc/Makefile | 2 +- .../dv/caravel/mgmt_soc/sram_exec/Makefile | 86 +++++++++ verilog/dv/caravel/mgmt_soc/sram_exec/README | 24 +++ .../dv/caravel/mgmt_soc/sram_exec/sram_exec.c | 76 ++++++++ .../caravel/mgmt_soc/sram_exec/sram_exec_tb.v | 177 ++++++++++++++++++ 5 files changed, 364 insertions(+), 1 deletion(-) create mode 100644 verilog/dv/caravel/mgmt_soc/sram_exec/Makefile create mode 100644 verilog/dv/caravel/mgmt_soc/sram_exec/README create mode 100755 verilog/dv/caravel/mgmt_soc/sram_exec/sram_exec.c create mode 100755 verilog/dv/caravel/mgmt_soc/sram_exec/sram_exec_tb.v diff --git a/verilog/dv/caravel/mgmt_soc/Makefile b/verilog/dv/caravel/mgmt_soc/Makefile index 176e3dc7..d9fd2db3 100644 --- a/verilog/dv/caravel/mgmt_soc/Makefile +++ b/verilog/dv/caravel/mgmt_soc/Makefile @@ -19,7 +19,7 @@ .SUFFIXES: .SILENT: clean all -PATTERNS = gpio_mgmt gpio mem uart perf hkspi sysctrl mprj_ctrl mprj_bitbang pass_thru timer timer2 pll storage qspi caravan irq user_pass_thru spi_master +PATTERNS = gpio_mgmt gpio mem uart perf hkspi sysctrl mprj_ctrl mprj_bitbang pass_thru timer timer2 pll storage qspi caravan irq user_pass_thru spi_master sram_exec all: ${PATTERNS} for i in ${PATTERNS}; do \ diff --git a/verilog/dv/caravel/mgmt_soc/sram_exec/Makefile b/verilog/dv/caravel/mgmt_soc/sram_exec/Makefile new file mode 100644 index 00000000..61f819fd --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/sram_exec/Makefile @@ -0,0 +1,86 @@ +# SPDX-FileCopyrightText: 2020 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +PDK_PATH = $(PDK_ROOT)/sky130A +VERILOG_PATH = ../../../.. +RTL_PATH = $(VERILOG_PATH)/rtl +BEHAVIOURAL_MODELS = ../../ + +# Temporary: Path to management SoC wrapper repository +MGMT_WRAPPER_PATH = ~/gits/caravel_pico/verilog/rtl + +FIRMWARE_PATH = ../.. +GCC_PATH?=/ef/apps/bin +GCC_PREFIX?=riscv32-unknown-elf + +SIM_DEFINES = -DFUNCTIONAL -DSIM + +SIM?=RTL + +.SUFFIXES: + +PATTERN = sram_exec + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex +ifeq ($(SIM),RTL) + iverilog -Ttyp $(SIM_DEFINES) -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(RTL_PATH) -I $(MGMT_WRAPPER_PATH) \ + $< -o $@ +else + iverilog -Ttyp $(SIM_DEFINES) -DGL -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(VERILOG_PATH) -I $(RTL_PATH) \ + $< -o $@ +endif + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s check-env + ${GCC_PATH}/${GCC_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + ${GCC_PATH}/${GCC_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +check-env: +ifndef PDK_ROOT + $(error PDK_ROOT is undefined, please export it before running make) +endif +ifeq (,$(wildcard $(PDK_ROOT)/sky130A)) + $(error $(PDK_ROOT)/sky130A not found, please install pdk before running make) +endif +ifeq (,$(wildcard $(GCC_PATH)/$(GCC_PREFIX)-gcc )) + $(error $(GCC_PATH)/$(GCC_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make) +endif +# check for efabless style installation +ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog)) +SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE +endif +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all + diff --git a/verilog/dv/caravel/mgmt_soc/sram_exec/README b/verilog/dv/caravel/mgmt_soc/sram_exec/README new file mode 100644 index 00000000..ad92671c --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/sram_exec/README @@ -0,0 +1,24 @@ + +------------------------------------------------ +Caravel +sram_exec testbench +------------------------------------------------ + +This testbench demonstrates how to copy a portion of a program from +flash memory into SRAM and to run it from there. diff --git a/verilog/dv/caravel/mgmt_soc/sram_exec/sram_exec.c b/verilog/dv/caravel/mgmt_soc/sram_exec/sram_exec.c new file mode 100755 index 00000000..37582e21 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/sram_exec/sram_exec.c @@ -0,0 +1,76 @@ +/* + * 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 copying code into SRAM and running it from there. +// ------------------------------------------------------------------------- + +void test_function() +{ + int i; + reg_mprj_datah = 0xa; // Signal middle of test + for (i = 0; i < 10; i++) { + reg_mprj_datal = i << 16; + } + return; +} + +void main() +{ + // uint32_t func[&test_routine_end - &test_routine_begin]; + // uint32_t *src_ptr; + uint16_t func[&main - &test_function]; + uint16_t *src_ptr; + uint16_t *dst_ptr; + + // Copy test routine from flash into SRAM + // 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; + + // src_ptr = &test_routine_begin; + src_ptr = &test_function; + dst_ptr = func; + + // while (src_ptr != &test_routine_end) + while (src_ptr != &main) + *(dst_ptr++) = *(src_ptr++); + + // Call the routine in SRAM + + ((void(*)())func)(); + + reg_mprj_datal = 0x40000; + reg_mprj_datah = 0xc; // Signal end of test +} + diff --git a/verilog/dv/caravel/mgmt_soc/sram_exec/sram_exec_tb.v b/verilog/dv/caravel/mgmt_soc/sram_exec/sram_exec_tb.v new file mode 100755 index 00000000..dc9eff47 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/sram_exec/sram_exec_tb.v @@ -0,0 +1,177 @@ +`default_nettype none +/* + * SPDX-FileCopyrightText: 2017 Clifford Wolf, 2018 Tim Edwards + * + * Caravel - A full example SoC using PicoRV32 in SkyWater sky130 + * + * Copyright (C) 2017 Clifford Wolf + * Copyright (C) 2021 Tim Edwards + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * SPDX-License-Identifier: ISC + */ + +`timescale 1 ns / 1 ps + +`include "__uprj_netlists.v" +`include "caravel_netlists.v" +`include "spiflash.v" + +module sram_exec_tb; + + reg clock; + reg power1; + reg power2; + + always #10 clock <= (clock === 1'b0); + + initial begin + clock <= 0; + end + + initial begin + $dumpfile("sram_exec.vcd"); + $dumpvars(0, sram_exec_tb); + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (60) begin + repeat (1000) @(posedge clock); + $display("+1000 cycles"); + end + $display("%c[1;31m",27); + `ifdef GL + $display ("Monitor: Timeout, Test SRAM exec (GL) Failed"); + `else + $display ("Monitor: Timeout, Test SRAM exec (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 SRAM exec (GL) Started"); + `else + $display("Monitor: Test SRAM exec (RTL) Started"); + `endif + wait(status == 4'ha); + `ifdef GL + $display("Monitor: Test SRAM exec (GL) called SRAM routine"); + `else + $display("Monitor: Test SRAM exec (RTL) called SRAM routine"); + `endif + wait(status == 4'hc); + `ifdef GL + $display("Monitor: Test SRAM exec (GL) Passed"); + `else + $display("Monitor: Test SRAM exec (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("sram_exec.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule