diff --git a/doc/memory_map.txt b/doc/memory_map.txt index 971c5669..64e88b40 100644 --- a/doc/memory_map.txt +++ b/doc/memory_map.txt @@ -24,12 +24,12 @@ SPI register description signal memory map address 12 PLL divider pll_div[4:0] 2610_0024 13 GPIO control serial_resetn/clock/data 2600_0000 - 14 SRAM read-only control TBD TBD - 15 SRAM read-only address TBD TBD - 16 SRAM read-only data TBD TBD - 17 SRAM read-only data TBD TBD - 18 SRAM read-only data TBD TBD - 19 SRAM read-only data TBD TBD + 14 SRAM read-only control hkspi_sram_clk/csb 2610_0034 + 15 SRAM read-only address hkspi_sram_addr 2610_0030 + 16 SRAM read-only data hkspi_sram_data[31:24] 2610_002f + 17 SRAM read-only data hkspi_sram_data[23:16] 2610_002e + 18 SRAM read-only data hkspi_sram_data[15:8] 2610_002d + 19 SRAM read-only data hkspi_sram_data[7:0] 2610_002c 1a Power monitor usr1/2_vcc/vdd_pwrgood 2620_0000 1b Output redirect clk1/clk2/trap_output_dest 2620_0004 diff --git a/verilog/dv/caravel/mgmt_soc/mprj_bitbang/Makefile b/verilog/dv/caravel/mgmt_soc/mprj_bitbang/Makefile new file mode 100644 index 00000000..7dd1bf5d --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/mprj_bitbang/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 = mprj_bitbang + +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/mprj_bitbang/mprj_bitbang.c b/verilog/dv/caravel/mgmt_soc/mprj_bitbang/mprj_bitbang.c new file mode 100644 index 00000000..f7307ddd --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/mprj_bitbang/mprj_bitbang.c @@ -0,0 +1,42 @@ +/* + * 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 by Bit-bang Method Test + */ + +void main() +{ + /* This program does nothing but apply output bits to all */ + /* GPIOs. Configuring the GPIOs is done by the verilog */ + /* testbench through the housekeeping SPI. */ + + /* However, the internal config must match the controller */ + /* config for the management SoC to apply output. */ + + reg_mprj_io_35 = GPIO_MODE_MGMT_STD_OUTPUT; + + reg_mprj_datal = 0xffffffff; + reg_mprj_datah = 0x0000003f; + + return; +} + diff --git a/verilog/dv/caravel/mgmt_soc/mprj_bitbang/mprj_bitbang_tb.v b/verilog/dv/caravel/mgmt_soc/mprj_bitbang/mprj_bitbang_tb.v new file mode 100644 index 00000000..375bd597 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/mprj_bitbang/mprj_bitbang_tb.v @@ -0,0 +1,507 @@ +// 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 +/* + Testbench of GPIO configuration through bit-bang method + using the StriVe housekeeping SPI. +*/ + +`timescale 1 ns / 1 ps + +`include "__uprj_netlists.v" +`include "caravel_netlists.v" +`include "spiflash.v" +`include "tbuart.v" + +module mprj_bitbang_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. + + // 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 + + task bitbang_one_clock; + begin + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h07); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h03); + end_csb(); + end + endtask + + task bitbang_one_clock_and_reset; + begin + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h07); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h05); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h07); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h03); + end_csb(); + end + endtask + + task bitbang_thirteen_clocks; + begin + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + end + endtask + + task bitbang_thirteen_clocks_and_reset; + begin + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock(); + bitbang_one_clock_and_reset(); + end + endtask + + integer i; + + // Now drive the digital signals on the housekeeping SPI + reg [7:0] tbdata; + + initial begin + $dumpfile("mprj_bitbang.vcd"); + $dumpvars(0, mprj_bitbang_tb); + + CSB <= 1'b1; + SCK <= 1'b0; + SDI <= 1'b0; + RSTB <= 1'b0; + + // Delay, then bring chip out of reset + #1000; + RSTB <= 1'b1; + #2000; + + start_csb(); + write_byte(8'h80); // Write stream command + write_byte(8'h13); // Address (register 19 = GPIO bit-bang control) + write_byte(8'h1b << 1); // Data = 0x01 (enable bit-bang mode) + end_csb(); + + // Clock 12 times. Set data when clock is zero. + // (NOTE: Bits moved up by 1 compared to previous caravel version. + // the testbench was updated by bit shifting all the data up by 1.) + // Bits: (0 = serial xfer) + // 1 = bit-bang enable + // 2 = bit-bang resetn + // 3 = bit-bang clock + // 4 = bit-bang data user 1 + // 5 = bit-bang data user 2 + + // Apply data 0x1809 (management standard output) to + // first block of user 1 and user 2 (GPIO 0 and 37) + // bits 0, 1, 9, and 12 are "1" (data go in backwards) + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h1f << 1); // bit 0 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h1b << 1); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h1f << 1); // bit 1 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h03 << 1); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h07 << 1); // bit 2 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h03 << 1); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h07 << 1); // bit 3 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h03 << 1); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h07 << 1); // bit 4 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h03 << 1); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h07 << 1); // bit 5 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h03 << 1); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h07 << 1); // bit 6 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h03 << 1); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h07 << 1); // bit 7 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h03 << 1); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h07 << 1); // bit 8 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h1b << 1); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h1f << 1); // bit 9 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h03 << 1); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h07 << 1); // bit 10 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h03 << 1); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h07 << 1); // bit 11 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h1b << 1); + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h1f << 1); // bit 12 + end_csb(); + + start_csb(); + write_byte(8'h80); + write_byte(8'h13); + write_byte(8'h03 << 1); + end_csb(); + + + // Toggle GPIO external control enable and clock forward 2 registers + // This moves ahead of the bidirectional registers at the front. + bitbang_thirteen_clocks(); + bitbang_thirteen_clocks_and_reset(); + + // There is no point in resetting bit bang mode because at + // this point the SPI pins just got disabled by loading zeros. + + #10000; + + // Timeout condition + `ifdef GL + $display("Monitor: Test GPIO bit-bang (GL) Failed"); + `else + $display("Monitor: Test GPIO bit-bang (RTL) Failed"); + `endif + + $finish; + end + + initial begin + // Wait for channel 35 to go high + wait(mprj_io[35] == 1'b1); + + `ifdef GL + $display("Monitor: Test GPIO bit-bang (GL) Passed"); + `else + $display("Monitor: Test GPIO bit-bang (RTL) Passed"); + `endif + $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("mprj_bitbang.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 diff --git a/verilog/dv/caravel/mgmt_soc/perf/Makefile b/verilog/dv/caravel/mgmt_soc/perf/Makefile new file mode 100644 index 00000000..5414bfe9 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/perf/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 = perf + +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/perf/perf.c b/verilog/dv/caravel/mgmt_soc/perf/perf.c new file mode 100644 index 00000000..5a17ba2f --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/perf/perf.c @@ -0,0 +1,71 @@ +/* + * 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" + +// -------------------------------------------------------- + +/* + Performance Test + It uses GPIO to flag the success or failure of the test +*/ +unsigned int ints[50]; +unsigned short shorts[50]; +unsigned char bytes[50]; + +int main() +{ + int i; + int sum = 0; + + /* 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); + + reg_mprj_datal = 0; + + // start test + reg_mprj_datal = 0xA0000000; + + for (i=0; i<100; i++) + sum += (sum + i); + + reg_mprj_datal = 0xAB000000; + + return sum; +} + diff --git a/verilog/dv/caravel/mgmt_soc/perf/perf_tb.v b/verilog/dv/caravel/mgmt_soc/perf/perf_tb.v new file mode 100644 index 00000000..25798ec2 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/perf/perf_tb.v @@ -0,0 +1,159 @@ +`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 + * Copyright (C) 2018 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 perf_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 + + reg [31:0] kcycles; + + initial begin + $dumpfile("perf.vcd"); + $dumpvars(0, perf_tb); + + kcycles = 0; + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (150) begin + repeat (1000) @(posedge clock); + //$display("+1000 cycles"); + kcycles <= kcycles + 1; + end + $display("%c[1;31m",27); + `ifdef GL + $display ("Monitor: Timeout, Test Performance (GL) Failed"); + `else + $display ("Monitor: Timeout, Test Performance (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 + //#1 $display("GPIO state = %X ", gpio); + if(checkbits == 16'hA000) begin + kcycles = 0; + $display("Performance Test started"); + end + else if(checkbits == 16'hAB00) begin + //$display("Monitor: number of cycles/100 iterations: %d KCycles", kcycles); + `ifdef GL + $display("Monitor: Test Performance (GL) passed [%0d KCycles]", kcycles); + `else + $display("Monitor: Test Performance (RTL) passed [%0d KCycles]", kcycles); + `endif + $finish; + end + end + + wire VDD3V3; + wire VDD1V8; + wire VSS; + + assign VDD3V3 = power1; + assign VDD1V8 = power2; + assign VSS = 1'b0; + + 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("perf.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule +`default_nettype wire diff --git a/verilog/dv/caravel/mgmt_soc/pll/Makefile b/verilog/dv/caravel/mgmt_soc/pll/Makefile new file mode 100644 index 00000000..b56e6332 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/pll/Makefile @@ -0,0 +1,82 @@ +# 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 + +FIRMWARE_PATH = ../.. +VERILOG_PATH = ../../../.. +RTL_PATH = $(VERILOG_PATH)/rtl +IP_PATH = ../../../../ip +BEHAVIOURAL_MODELS = ../../ + +# Temporary: Path to management SoC wrapper repository +MGMT_WRAPPER_PATH = ~/gits/caravel_pico/verilog/rtl + +GCC_PATH?=/ef/apps/bin +GCC_PREFIX?=riscv32-unknown-elf +PDK_PATH?=$(PDK_ROOT)/sky130A + +SIM_DEFINES = -DFUNCTIONAL -DSIM + +SIM?=RTL + +.SUFFIXES: + +PATTERN = pll + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex + iverilog -Ttyp $(SIM_DEFINES) -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) -I $(MGMT_WRAPPER_PATH) \ + $< -o $@ + +%.vcd: %.vvp check-env + vvp $< + +%.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 > $@ + +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/pll/pll.c b/verilog/dv/caravel/mgmt_soc/pll/pll.c new file mode 100644 index 00000000..81a1fc66 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/pll/pll.c @@ -0,0 +1,122 @@ +/* + * 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" + +// -------------------------------------------------------- + +/* + * PLL Test (self-switching) + * - Enables SPI master + * - Uses SPI master to internally access the housekeeping SPI + * - Switches PLL bypass + * - Changes PLL divider + * + * Tesbench mostly copied from sysctrl + */ +void main() +{ + int i; + + reg_mprj_datal = 0; + + // Configure upper 16 bits of user GPIO for generating testbench + // checkpoints. + + 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; + + // Enable SPI master + // SPI master configuration bits: + // bits 7-0: Clock prescaler value (default 2) + // bit 8: MSB/LSB first (0 = MSB first, 1 = LSB first) + // bit 9: CSB sense (0 = inverted, 1 = noninverted) + // bit 10: SCK sense (0 = noninverted, 1 = inverted) + // bit 11: mode (0 = read/write opposite edges, 1 = same edges) + // bit 12: stream (1 = CSB ends transmission) + // bit 13: enable (1 = enabled) + // bit 14: IRQ enable (1 = enabled) + // bit 15: Connect to housekeeping SPI (1 = connected) + + reg_spimaster_config = 0xa002; // Enable, prescaler = 2, + // connect to housekeeping SPI + + // Apply stream read (0x40 + 0x03) and read back one byte + + reg_spimaster_config = 0xb002; // Apply stream mode + reg_spimaster_data = 0x80; // Write 0x80 (write mode) + reg_spimaster_data = 0x08; // Write 0x18 (start address) + reg_spimaster_data = 0x01; // Write 0x01 to PLL enable, no DCO mode + reg_spimaster_config = 0xa102; // Release CSB (ends stream mode) + + reg_spimaster_config = 0xb002; // Apply stream mode + reg_spimaster_data = 0x80; // Write 0x80 (write mode) + reg_spimaster_data = 0x11; // Write 0x11 (start address) + reg_spimaster_data = 0x03; // Write 0x03 to PLL output divider + reg_spimaster_config = 0xa102; // Release CSB (ends stream mode) + + reg_spimaster_config = 0xb002; // Apply stream mode + reg_spimaster_data = 0x80; // Write 0x80 (write mode) + reg_spimaster_data = 0x09; // Write 0x09 (start address) + reg_spimaster_data = 0x00; // Write 0x00 to clock from PLL (no bypass) + reg_spimaster_config = 0xa102; // Release CSB (ends stream mode) + + // Write checkpoint + reg_mprj_datal = 0xA0410000; + + reg_spimaster_config = 0xb002; // Apply stream mode + reg_spimaster_data = 0x80; // Write 0x80 (write mode) + reg_spimaster_data = 0x12; // Write 0x12 (start address) + reg_spimaster_data = 0x03; // Write 0x03 to feedback divider (was 0x04) + reg_spimaster_config = 0xa102; // Release CSB (ends stream mode) + + // Write checkpoint + reg_mprj_datal = 0xA0420000; + + reg_spimaster_config = 0xb002; // Apply stream mode + reg_spimaster_data = 0x80; // Write 0x80 (write mode) + reg_spimaster_data = 0x11; // Write 0x11 (start address) + reg_spimaster_data = 0x04; // Write 0x04 to PLL output divider + reg_spimaster_config = 0xa102; // Release CSB (ends stream mode) + + reg_spimaster_config = 0x2102; // Release housekeeping SPI + + // End test + reg_mprj_datal = 0xA0900000; +} + diff --git a/verilog/dv/caravel/mgmt_soc/pll/pll_tb.v b/verilog/dv/caravel/mgmt_soc/pll/pll_tb.v new file mode 100644 index 00000000..5c037b06 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/pll/pll_tb.v @@ -0,0 +1,158 @@ +// 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 pll_tb; + reg clock; + reg power1; + reg power2; + reg RSTB; + + wire gpio; + wire [15:0] checkbits; + wire [7:0] spivalue; + wire [37:0] mprj_io; + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + wire SDO; + + assign checkbits = mprj_io[31:16]; + assign spivalue = mprj_io[15:8]; + + // 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("pll.vcd"); + $dumpvars(0, pll_tb); + repeat (25) begin + repeat (1000) @(posedge clock); + $display("+1000 cycles"); + end + $display("%c[1;31m",27); + $display ("Monitor: Timeout, Test PLL (RTL) Failed"); + $display("%c[0m",27); + $finish; + end + + // Monitor + initial begin + wait(checkbits == 16'hA040); + + $display("Monitor: Test PLL (RTL) Started"); + + wait(checkbits == 16'hA041); + // $display(" SPI value = 0x%x (should be 0x04)", spivalue); + // if(spivalue !== 32'h04) begin + // $display("Monitor: Test PLL (RTL) Failed"); + // $finish; + // end + wait(checkbits == 16'hA042); + // $display(" SPI value = 0x%x (should be 0x56)", spivalue); + // if(spivalue !== 32'h56) begin + // $display("Monitor: Test PLL (RTL) Failed"); + // $finish; + // end + + wait(checkbits == 16'hA090); + + $display("Monitor: Test PLL (RTL) Passed"); + $finish; + 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 @(checkbits) begin + #1 $display("GPIO state = %b ", checkbits); + end + + wire VDD3V3; + wire VDD1V8; + wire VSS; + + assign VDD3V3 = power1; + assign VDD1V8 = power2; + assign VSS = 1'b0; + + 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("pll.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule +`default_nettype wire diff --git a/verilog/dv/caravel/mgmt_soc/qspi/Makefile b/verilog/dv/caravel/mgmt_soc/qspi/Makefile new file mode 100644 index 00000000..685715f8 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/qspi/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 = qspi + +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/qspi/README b/verilog/dv/caravel/mgmt_soc/qspi/README new file mode 100644 index 00000000..4b3644af --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/qspi/README @@ -0,0 +1,28 @@ + +------------------------------------------------ +Caravel +qspi testbench +------------------------------------------------ + +This testbench is mainly a copy of the gpio testbench and uses the +same checks for pass/fail status. The difference is that the startup +C code puts the SPI flash into QSPI/DDR/CRM modes for fastest access +and enables the GPIO channels 36 and 37 to work as the flash IO2 and +IO3 channels. If the channel and spimemio setup works correctly, +then the testbench simulation will pass. diff --git a/verilog/dv/caravel/mgmt_soc/qspi/qspi.c b/verilog/dv/caravel/mgmt_soc/qspi/qspi.c new file mode 100644 index 00000000..597e45fe --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/qspi/qspi.c @@ -0,0 +1,132 @@ +/* + * 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" + +// -------------------------------------------------------- + +/* + * GPIO Test + * Tests PU and PD on the lower 8 pins while being driven from outside + * Tests Writing to the upper 8 pins + * Tests reading from the lower 8 pins + */ + +void main() +{ + int i; + + /* Set SPI flash latency to 8 for use with the spiflash.v + * module (note that spiflash.v does not have configuration + * registers emulated, so the external flash cannot be + * changed from its default of 8). + */ + + /* Set data out to zero */ + reg_mprj_datal = 0; + + /* Lower 8 pins are input and upper 8 pins are 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_INPUT_NOPULL; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + /* Now the flash SPI controller can be put in qspi/ddr/crm mode */ + /* First run DSPI + CRM */ + reg_spictrl = 0x80580000; // DSPI + CRM + + + // change the pull up and pull down (checked by the TB) + reg_mprj_datal = 0xa0000000; + + reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + /* Now run QSPI + CRM */ + reg_spictrl = 0x80380000; // QSPI + CRM + + reg_mprj_datal = 0x0b000000; + + reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + /* Now run QSPI + DDR + CRM */ + reg_spictrl = 0x80780000; // QSPI + DDR + CRM + + reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + // read the lower 8 pins, add 1 then output the result + // checked by the TB + reg_mprj_datal = 0xab000000; + + while (1){ + int x = (reg_mprj_datal & 0xff0000) >> 16; + reg_mprj_datal = (x+1) << 24; + } +} + diff --git a/verilog/dv/caravel/mgmt_soc/qspi/qspi_tb.v b/verilog/dv/caravel/mgmt_soc/qspi/qspi_tb.v new file mode 100644 index 00000000..d8683b99 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/qspi/qspi_tb.v @@ -0,0 +1,205 @@ +`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 + * Copyright (C) 2018 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 qspi_tb; + + reg clock; + reg power1; + reg power2; + + always #10 clock <= (clock === 1'b0); + + initial begin + clock <= 0; + end + + initial begin + $dumpfile("qspi.vcd"); + $dumpvars(0, qspi_tb); + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (25) begin + repeat (1000) @(posedge clock); + $display("+1000 cycles"); + end + $display("%c[1;31m",27); + `ifdef GL + $display ("Monitor: Timeout, Test GPIO (GL) Failed"); + `else + $display ("Monitor: Timeout, Test GPIO (RTL) Failed"); + `endif + $display("%c[0m",27); + $finish; + end + + wire [35:0] mprj_io; // Most of these are no-connects + wire [15:0] checkbits; + reg [7:0] checkbits_lo; + wire [7:0] checkbits_hi; + + assign mprj_io[23:16] = checkbits_lo; + assign checkbits = mprj_io[31:16]; + assign checkbits_hi = checkbits[15:8]; + assign mprj_io[3] = 1'b1; // Force CSB high. + + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + wire flash_io2; + wire flash_io3; + wire gpio; + + reg RSTB; + + // Transactor + initial begin + checkbits_lo <= {8{1'bz}}; + wait(checkbits_hi == 8'hA0); + checkbits_lo <= 8'hF0; + wait(checkbits_hi == 8'h0B); + checkbits_lo <= 8'h0F; + wait(checkbits_hi == 8'hAB); + checkbits_lo <= 8'h0; + repeat (1000) @(posedge clock); + checkbits_lo <= 8'h1; + repeat (1000) @(posedge clock); + checkbits_lo <= 8'h3; + end + + // Monitor + initial begin + wait(checkbits_hi == 8'hA0); + `ifdef GL + $display("Monitor: Test QSPI (GL) Started"); + `else + $display("Monitor: Test QSPI (RTL) Started"); + `endif + wait(checkbits[7:0] == 8'hF0); + wait(checkbits_hi == 8'h0B); + wait(checkbits[7:0] == 8'h0F); + wait(checkbits_hi == 8'hAB); + wait(checkbits[7:0] == 8'h00); + wait(checkbits_hi == 8'h01); + wait(checkbits[7:0] == 8'h01); + wait(checkbits_hi == 8'h02); + wait(checkbits[7:0] == 8'h03); + wait(checkbits_hi == 8'h04); + `ifdef GL + $display("Monitor: Test QSPI (GL) Passed"); + `else + $display("Monitor: Test QSPI (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) begin + #1 $display("GPIO state = %b (%d - %d)", checkbits, + checkbits_hi, checkbits_lo); + 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) + // flash_io2 = mgmt_gpio_io[36] (inout) + // flash_io3 = mgmt_gpio_io[37] (inout) + + 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 ({flash_io3, flash_io2, mprj_io}), + .flash_csb(flash_csb), + .flash_clk(flash_clk), + .flash_io0(flash_io0), + .flash_io1(flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("qspi.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(flash_io2), + .io3(flash_io3) + ); + +endmodule +`default_nettype wire diff --git a/verilog/dv/caravel/mgmt_soc/storage/Makefile b/verilog/dv/caravel/mgmt_soc/storage/Makefile new file mode 100644 index 00000000..bb5d4a41 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/storage/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 = storage + +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/storage/storage.c b/verilog/dv/caravel/mgmt_soc/storage/storage.c new file mode 100644 index 00000000..55fdd980 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/storage/storage.c @@ -0,0 +1,87 @@ +/* + * 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" + +// -------------------------------------------------------- + +/* + Storage area Test + It uses GPIO to flag the success or failure of the test +*/ + +void main() +{ + int i; + volatile uint32_t* ram_addr; + /* 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 Management R/W block0 + for (i=0; i<10; i++){ + ram_addr = ®_rw_block0 + i; + *ram_addr = i*5000 + 10000; + } + + for (i=0; i<10; i++){ + ram_addr = ®_rw_block0 + i; + if ((i*5000+10000) != *ram_addr) + reg_mprj_datal = 0xAB400000; + } + + reg_mprj_datal = 0xAB410000; + + // Test Management R/W block1 + reg_mprj_datal = 0xA0200000; + for (i=0; i<10; i++){ + ram_addr = ®_rw_block1 + i; + *ram_addr = i*5000 + 10000; + } + + for (i=0; i<10; i++){ + ram_addr = ®_rw_block1 + i; + if ((i*5000+10000) != *ram_addr) + reg_mprj_datal = 0xAB200000; + } + + reg_mprj_datal = 0xAB210000; +} + diff --git a/verilog/dv/caravel/mgmt_soc/storage/storage_tb.v b/verilog/dv/caravel/mgmt_soc/storage/storage_tb.v new file mode 100644 index 00000000..0adee87b --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/storage/storage_tb.v @@ -0,0 +1,190 @@ +`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 + * Copyright (C) 2018 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 storage_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("storage.vcd"); + $dumpvars(0, storage_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 Storage (GL) Failed"); + `else + $display ("Monitor: Timeout, Test Storage (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 + `ifdef GL + $display("Mem Test storage MGMT block0 (GL) [word rw] started"); + `else + $display("Mem Test storage MGMT block0 (RTL) [word rw] started"); + `endif + end + else if(checkbits == 16'hAB40) begin + $display("%c[1;31m",27); + `ifdef GL + $display("Monitor: Test storage MGMT block0 (GL) [word rw] failed"); + `else + $display("Monitor: Test storage MGMT block0 (RTL) [word rw] failed"); + `endif + $display("%c[0m",27); + $finish; + end + else if(checkbits == 16'hAB41) begin + `ifdef GL + $display("Monitor: Test storage MGMT block0 (GL) [word rw] passed"); + `else + $display("Monitor: Test storage MGMT block0 (RTL) [word rw] passed"); + `endif + end + else if(checkbits == 16'hA020) begin + `ifdef GL + $display("Mem Test storage MGMT block1 (GL) [word rw] started"); + `else + $display("Mem Test storage MGMT block1 (RTL) [word rw] started"); + `endif + end + else if(checkbits == 16'hAB20) begin + $display("%c[1;31m",27); + `ifdef GL + $display("Monitor: Test storage MGMT block1 (GL) [word rw] failed"); + `else + $display("Monitor: Test storage MGMT block1 (RTL) [word rw] failed"); + `endif + $display("%c[0m",27); + $finish; + end + else if(checkbits == 16'hAB21) begin + `ifdef GL + $display("Monitor: Test storage MGMT block1 (GL) [word rw] passed"); + `else + $display("Monitor: Test storage MGMT block1 (RTL) [word 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("storage.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule +`default_nettype wire diff --git a/verilog/rtl/caravel.v b/verilog/rtl/caravel.v index a6f4e35b..e1dcb695 100644 --- a/verilog/rtl/caravel.v +++ b/verilog/rtl/caravel.v @@ -347,6 +347,12 @@ module caravel ( wire mprj_vdd_pwrgood; wire mprj2_vdd_pwrgood; + // SRAM read-only access from houskeeping + wire hkspi_sram_clk; + wire hkspi_sram_csb; + wire [7:0] hkspi_sram_addr; + wire [31:0] hkspi_sram_rdata; + // Management processor (wrapper). Any management core // implementation must match this pinout. @@ -426,6 +432,12 @@ module caravel ( .la_oenb(la_oenb_mprj), .la_iena(la_iena_mprj), + // SRAM Read-only access from housekeeping + .hkspi_sram_clk(hkspi_sram_clk), + .hkspi_sram_csb(hkspi_sram_csb), + .hkspi_sram_addr(hkspi_sram_addr), + .hkspi_sram_rdata(hkspi_sram_rdata), + // Trap status .trap(trap) ); @@ -699,6 +711,11 @@ module caravel ( .pad_flash_io0_di(flash_io0_di), .pad_flash_io1_di(flash_io1_di), + .hkspi_sram_clk(hkspi_sram_clk), + .hkspi_sram_csb(hkspi_sram_csb), + .hkspi_sram_addr(hkspi_sram_addr), + .hkspi_sram_rdata(hkspi_sram_rdata), + .usr1_vcc_pwrgood(mprj_vcc_pwrgood), .usr2_vcc_pwrgood(mprj2_vcc_pwrgood), .usr1_vdd_pwrgood(mprj_vdd_pwrgood), diff --git a/verilog/rtl/housekeeping.v b/verilog/rtl/housekeeping.v index ed2ef54a..f0c3b544 100644 --- a/verilog/rtl/housekeeping.v +++ b/verilog/rtl/housekeeping.v @@ -168,6 +168,11 @@ module housekeeping #( input pad_flash_io0_di, input pad_flash_io1_di, + output hkspi_sram_clk, + output hkspi_sram_csb, + output [7:0] hkspi_sram_addr, + input [31:0] hkspi_sram_rdata, + // System signal monitoring input usr1_vcc_pwrgood, input usr2_vcc_pwrgood, @@ -195,6 +200,10 @@ module housekeeping #( reg serial_xfer; reg hkspi_disable; + reg hkspi_sram_clk; + reg hkspi_sram_csb; + reg [7:0] hkspi_sram_addr; + reg clk1_output_dest; reg clk2_output_dest; reg trap_output_dest; @@ -238,6 +247,8 @@ module housekeeping #( wire cwstb; // Combination of SPI write strobe and back door write strobe wire csclk; // Combination of SPI SCK and back door access trigger + wire [31:0] hkspi_sram_rdata; + // Housekeeping side 3-wire interface to GPIOs (see below) wire [`MPRJ_IO_PADS-1:0] mgmt_gpio_out_pre; @@ -365,6 +376,12 @@ module housekeeping #( serial_bb_resetn, serial_bb_enable, serial_busy}; /* To be added: SRAM read-only port (registers 14 to 19) */ + 8'h14 : fdata = {6'b000000, hkspi_sram_clk, hkspi_sram_csb}; + 8'h15 : fdata = hkspi_sram_addr; + 8'h16 : fdata = hkspi_sram_rdata[31:24]; + 8'h17 : fdata = hkspi_sram_rdata[23:16]; + 8'h18 : fdata = hkspi_sram_rdata[15:8]; + 8'h19 : fdata = hkspi_sram_rdata[7:0]; /* System monitoring */ 8'h1a : fdata = {4'b0000, usr1_vcc_pwrgood, usr2_vcc_pwrgood, @@ -502,6 +519,13 @@ module housekeeping #( spi_adr | 12'h020 : spiaddr = 8'h11; // PLL source spi_adr | 12'h024 : spiaddr = 8'h12; // PLL divider + spi_adr | 12'h02c : spiaddr = 8'h19; // SRAM read-only data + spi_adr | 12'h02d : spiaddr = 8'h18; // SRAM read-only data + spi_adr | 12'h02e : spiaddr = 8'h17; // SRAM read-only data + spi_adr | 12'h02f : spiaddr = 8'h16; // SRAM read-only data + spi_adr | 12'h030 : spiaddr = 8'h15; // SRAM read-only address + spi_adr | 12'h034 : spiaddr = 8'h14; // SRAM read-only control + gpio_adr | 12'h000 : spiaddr = 8'h13; // GPIO control /* To be added: SRAM read-only interface */ @@ -797,16 +821,25 @@ module housekeeping #( reg [5:0] pad_count_2; reg [1:0] xfer_state; - reg serial_clock; - reg serial_resetn; + reg serial_clock_pre; + reg serial_resetn_pre; reg serial_busy; wire serial_data_1; wire serial_data_2; + wire serial_clock; + wire serial_resetn; reg [IO_CTRL_BITS-1:0] serial_data_staging_1; reg [IO_CTRL_BITS-1:0] serial_data_staging_2; - assign serial_data_1 = serial_data_staging_1[IO_CTRL_BITS-1]; - assign serial_data_2 = serial_data_staging_2[IO_CTRL_BITS-1]; + assign serial_clock = (serial_bb_enable == 1'b1) ? + serial_bb_clock : serial_clock_pre; + assign serial_resetn = (serial_bb_enable == 1'b1) ? + serial_bb_resetn : serial_resetn_pre; + + assign serial_data_1 = (serial_bb_enable == 1'b1) ? + serial_bb_data_1 : serial_data_staging_1[IO_CTRL_BITS-1]; + assign serial_data_2 = (serial_bb_enable == 1'b1) ? + serial_bb_data_2 : serial_data_staging_2[IO_CTRL_BITS-1]; always @(posedge wb_clk_i or negedge porb) begin if (porb == 1'b0) begin @@ -818,8 +851,8 @@ module housekeeping #( */ pad_count_1 <= `MPRJ_IO_PADS_1 - 1; pad_count_2 <= `MPRJ_IO_PADS_1; - serial_resetn <= 1'b0; - serial_clock <= 1'b0; + serial_resetn_pre <= 1'b0; + serial_clock_pre <= 1'b0; serial_data_staging_1 <= 0; serial_data_staging_2 <= 0; serial_busy <= 1'b0; @@ -830,8 +863,8 @@ module housekeeping #( `GPIO_IDLE: begin pad_count_1 <= `MPRJ_IO_PADS_1 - 1; pad_count_2 <= `MPRJ_IO_PADS_1; - serial_resetn <= 1'b1; - serial_clock <= 1'b0; + serial_resetn_pre <= 1'b1; + serial_clock_pre <= 1'b0; if (serial_xfer == 1'b1) begin xfer_state <= `GPIO_START; serial_busy <= 1'b1; @@ -840,8 +873,8 @@ module housekeeping #( end end `GPIO_START: begin - serial_resetn <= 1'b1; - serial_clock <= 1'b0; + serial_resetn_pre <= 1'b1; + serial_clock_pre <= 1'b0; xfer_count <= 6'd0; pad_count_1 <= pad_count_1 - 1; pad_count_2 <= pad_count_2 + 1; @@ -850,8 +883,8 @@ module housekeeping #( serial_data_staging_2 <= gpio_configure[pad_count_2]; end `GPIO_XBYTE: begin - serial_resetn <= 1'b1; - serial_clock <= ~serial_clock; + serial_resetn_pre <= 1'b1; + serial_clock_pre <= ~serial_clock; if (serial_clock == 1'b0) begin if (xfer_count == IO_CTRL_BITS - 1) begin if (pad_count_2 == `MPRJ_IO_PADS) begin @@ -878,15 +911,15 @@ module housekeeping #( * Return to idle mode. */ if (xfer_count == 4'd0) begin - serial_clock <= 1'b1; - serial_resetn <= 1'b0; + serial_clock_pre <= 1'b1; + serial_resetn_pre <= 1'b0; end else if (xfer_count == 4'd1) begin - serial_clock <= 1'b1; - serial_resetn <= 1'b1; + serial_clock_pre <= 1'b1; + serial_resetn_pre <= 1'b1; end else if (xfer_count == 4'd2) begin serial_busy <= 1'b0; - serial_resetn <= 1'b1; - serial_clock <= 1'b0; + serial_resetn_pre <= 1'b1; + serial_clock_pre <= 1'b0; xfer_state <= `GPIO_IDLE; end end @@ -967,6 +1000,10 @@ module housekeeping #( serial_xfer <= 1'b0; hkspi_disable <= 1'b0; + hkspi_sram_clk <= 1'b0; + hkspi_sram_csb <= 1'b1; + hkspi_sram_addr <= 8'h00; + end else begin if (cwstb == 1'b1) begin case (caddr) @@ -1017,6 +1054,15 @@ module housekeeping #( end /* To be done: Add SRAM read-only interface */ + 8'h14: begin + hkspi_sram_clk <= cdata[1]; + hkspi_sram_csb <= cdata[0]; + end + 8'h15: begin + hkspi_sram_addr <= cdata; + end + + /* Registers 16 to 19 (SRAM data) are read-only */ /* Register 1a (power monitor) is read-only */