diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..af8c0ad8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "verilog/rtl/multi_project_harness"] + path = verilog/rtl/multi_project_harness + url = https://github.com/mattvenn/mpw-multi-project-harness diff --git a/README.md b/README.md index 447fe6a9..903039b0 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,45 @@ -# CIIC Harness +# Multi Project Harness -A template SoC for Google SKY130 free shuttles. It is still WIP. The current SoC architecture is given below. +* This is a proposal for handling multiple projects in the user project area of the [Caravel harness](https://github.com/efabless/caravel) +* This is a fork of caravel with https://github.com/mattvenn/mpw-multi-project-harness added to /verilog/rtl/ +* user_project_wrapper is then adjusted to instantiate https://github.com/mattvenn/mpw-multi-project-harness/blob/main/multi_project_harness.v -

- -

+![multi project harness](doc/multi-project-harness.png) -## Managment SoC -The managment SoC runs firmware that can be used to: -- Configure Mega Project I/O pads -- Observe and control Mega Project signals (through on-chip logic analyzer probes) -- Control the Mega Project power supply +# Sub projects -The memory map of the management SoC can be found [here](verilog/rtl/README) +See https://github.com/mattvenn/mpw-multi-project-harness/blob/main/.gitmodules +for the list of currently included projects. -## Mega Project Area -This is the user space. It has limited silicon area (TBD, about 3.1mm x 3.8mm) as well as a fixed number of I/O pads (37) and power pads (10). See [the Caravel premliminary datasheet](doc/caravel_datasheet.pdf) for details. -The repository contains a [sample mega project](/verilog/rtl/user_proj_example.v) that contains a binary 32-bit up counter.
+# Preparation -

- -

+See https://github.com/mattvenn/mpw-multi-project-harness for details on adding new projects. -The firmware running on the Management Area SoC, configures the I/O pads used by the counter and uses the logic probes to observe/control the counter. Three firmware examples are provided: -1. Configure the Mega Project I/O pads as o/p. Observe the counter value in the testbench: [IO_Ports Test](verilog/dv/caravel/user_proj_example/io_ports). -2. Configure the Mega Project I/O pads as o/p. Use the Chip LA to load the counter and observe the o/p till it reaches 500: [LA_Test1](verilog/dv/caravel/user_proj_example/la_test1). -3. Configure the Mega Project I/O pads as o/p. Use the Chip LA to control the clock source and reset signals and observe the counter value for five clock cylcles: [LA_Test2](verilog/dv/caravel/user_proj_example/la_test2). +# Simulation / Verification. + +For formal and cocotb simulation of each module see https://github.com/mattvenn/mpw-multi-project-harness + +For caravel system simulation see the tests under verilog/dv/caravel/user_proj_example/ + +# GDS + +See https://github.com/mattvenn/mpw-multi-project-harness/blob/main/docs/hardening.md for details on hardening each module into the main macro. +This macro's GDS/LEF is then added to openlane/user_project_wrapper + +For configuration sees: + +* openlane/user_project_wrapper/config.tcl +* openlane/user_project_wrapper/interactive.tcl + +To generate the final GDS, run this command: + + make user_project_wrapper OPENLANE_IMAGE_NAME=openlane:rc5 + +# Todo + +* when the toolchain is working, generate the GDS and add it to the repo +* info.yaml : update user_level_netlist field +* add some logo art +* test input pins in the system simulation +* how clean does the DRC result need to be? +* adapt ws2812 for default 10mhz clock rate or be able to update the timing reg diff --git a/doc/multi-project-harness.png b/doc/multi-project-harness.png new file mode 100644 index 00000000..4e6967f5 Binary files /dev/null and b/doc/multi-project-harness.png differ diff --git a/info.yaml b/info.yaml index ffd05202..8ba42fd4 100644 --- a/info.yaml +++ b/info.yaml @@ -1,18 +1,17 @@ --- project: - description: "A template SoC for Google sponsored Open MPW shuttles for SKY130." + description: "Multi project including designs from Matt Venn, Michael Betz & Richard Miller" foundry: "SkyWater" - git_url: "https://github.com/efabless/caravel.git" - organization: "Efabless" - organization_url: "http://efabless.com" - owner: "Tim Edwards" + git_url: "https://github.com/mattvenn/multi-project-harness.git" + organization: "" + organization_url: "" + owner: "Matt Venn" process: "SKY130" - project_name: "Caravel" + project_name: "multi-project-harness" tags: - "Open MPW" - - "Test Harness" - category: "Test Harness" + category: "multi project" top_level_netlist: "verilog/rtl/caravel.v" - user_level_netlist: "verilog/gl/user_project_wrapper.v" + user_level_netlist: "verilog/rtl/multi_project_harness/multi_project_harness.v" version: "1.00" cover_image: "doc/ciic_harness.png" diff --git a/openlane/user_project_wrapper/config.tcl b/openlane/user_project_wrapper/config.tcl index 50e0bd17..30e400a0 100644 --- a/openlane/user_project_wrapper/config.tcl +++ b/openlane/user_project_wrapper/config.tcl @@ -21,10 +21,10 @@ set ::env(VERILOG_FILES) "\ set ::env(VERILOG_FILES_BLACKBOX) "\ $script_dir/../../verilog/rtl/defines.v \ - $script_dir/../../verilog/rtl/user_proj_example.v" + $script_dir/../../verilog/rtl/multi_project_harness/multi_project_harness.v" set ::env(EXTRA_LEFS) "\ - $script_dir/../../lef/user_proj_example.lef" + $script_dir/multi_project_harness.lef" set ::env(EXTRA_GDS_FILES) "\ - $script_dir/../../gds/user_proj_example.gds" + $script_dir/multi_project_harness.gds" diff --git a/openlane/user_project_wrapper/interactive.tcl b/openlane/user_project_wrapper/interactive.tcl index dd5c0d12..c22a9a7d 100644 --- a/openlane/user_project_wrapper/interactive.tcl +++ b/openlane/user_project_wrapper/interactive.tcl @@ -10,7 +10,7 @@ init_floorplan place_io_ol -add_macro_placement mprj 1150 1700 N +add_macro_placement mprj 500 500 N manual_macro_placement f diff --git a/verilog/dv/caravel/user_proj_example/ASIC_watch/ASIC_watch.c b/verilog/dv/caravel/user_proj_example/ASIC_watch/ASIC_watch.c new file mode 100644 index 00000000..323d8607 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/ASIC_watch/ASIC_watch.c @@ -0,0 +1,66 @@ +#include "../../defs.h" + +#define PROJECT 5 +#define NB_OUTPUTS 28 + +#define reg_mprj_oeb0 (*(volatile uint32_t*)0x30000004) +#define reg_mprj_oeb1 (*(volatile uint32_t*)0x30000008) +#define reg_mprj_ws2812 (*(volatile uint32_t*)0x30000500) +/* + IO Test: + - Configures MPRJ pins +*/ + +void main() +{ + /* + IO Control Registers + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 3-bits | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | + Output: 0000_0110_0000_1110 (0x1808) = GPIO_MODE_USER_STD_OUTPUT + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | + Output: 0000_0110_0000_1111 (0x1809) = GPIO_MODE_MGNT_STD_OUTPUT + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | + + + Input: 0000_0001_0000_1111 (0x0402) = GPIO_MODE_USER_STD_INPUT_NOPULL + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | + */ + + /* + Inputs + 36 - Safe mode + 37 - 2^15Hz crystal clock + + Outputs + 8 - 14 segment_hxxx + 15 - 21 segment_xhxx + 22 - 28 segment_xxmx + 29 - 35 segment_xxxm + */ + volatile uint32_t *io = ®_mprj_io_0; + for (int i = 8 ; i < 8+NB_OUTPUTS ; i++) { + io[i] = GPIO_MODE_USER_STD_OUTPUT; + } + + io[36] = GPIO_MODE_USER_STD_INPUT_NOPULL; + io[37] = GPIO_MODE_USER_STD_INPUT_NOPULL; + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + // change to project + reg_mprj_slave = PROJECT; + + reg_mprj_oeb1 = (1 << 4) + (1 << 5); //GPIO 36 and 37 as inputs + + // use logic analyser bit 0 as reset + reg_la0_ena = 0x00000000; // bits 31:0 outputs + reg_la0_data = 0x00000001; // reset high is on bit 0 + reg_la0_data = 0x00000000; // low + +} diff --git a/verilog/dv/caravel/user_proj_example/ASIC_watch/ASIC_watch_tb.v b/verilog/dv/caravel/user_proj_example/ASIC_watch/ASIC_watch_tb.v new file mode 100644 index 00000000..99517815 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/ASIC_watch/ASIC_watch_tb.v @@ -0,0 +1,162 @@ +`default_nettype none + +`timescale 1 ns / 1 ps + +`include "caravel.v" +`include "spiflash.v" + +module ASIC_watch_tb; + reg clock; + reg RSTB; + reg power1, power2; + reg power3, power4; + + wire gpio; + wire [37:0] mprj_io; + // inputs + reg clk_32768; + reg safemode; + + // outputs + wire [6:0] segment_hxxx; + wire [6:0] segment_xhxx; + wire [6:0] segment_xxhx; + wire [6:0] segment_xxxh; + + assign segment_hxxx[0] = uut.gpio_control_in[8].pad_gpio_out; + assign segment_hxxx[1] = uut.gpio_control_in[9].pad_gpio_out; + assign segment_hxxx[2] = uut.gpio_control_in[10].pad_gpio_out; + assign segment_hxxx[3] = uut.gpio_control_in[11].pad_gpio_out; + assign segment_hxxx[4] = uut.gpio_control_in[12].pad_gpio_out; + assign segment_hxxx[5] = uut.gpio_control_in[13].pad_gpio_out; + assign segment_hxxx[6] = uut.gpio_control_in[14].pad_gpio_out; + + assign segment_xhxx[0] = uut.gpio_control_in[15].pad_gpio_out; + assign segment_xhxx[1] = uut.gpio_control_in[16].pad_gpio_out; + assign segment_xhxx[2] = uut.gpio_control_in[17].pad_gpio_out; + assign segment_xhxx[3] = uut.gpio_control_in[18].pad_gpio_out; + assign segment_xhxx[4] = uut.gpio_control_in[19].pad_gpio_out; + assign segment_xhxx[5] = uut.gpio_control_in[20].pad_gpio_out; + assign segment_xhxx[6] = uut.gpio_control_in[21].pad_gpio_out; + + assign segment_xxhx[0] = uut.gpio_control_in[22].pad_gpio_out; + assign segment_xxhx[1] = uut.gpio_control_in[23].pad_gpio_out; + assign segment_xxhx[2] = uut.gpio_control_in[24].pad_gpio_out; + assign segment_xxhx[3] = uut.gpio_control_in[25].pad_gpio_out; + assign segment_xxhx[4] = uut.gpio_control_in[26].pad_gpio_out; + assign segment_xxhx[5] = uut.gpio_control_in[27].pad_gpio_out; + assign segment_xxhx[6] = uut.gpio_control_in[28].pad_gpio_out; + + assign segment_xxxh[0] = uut.gpio_control_in[29].pad_gpio_out; + assign segment_xxxh[1] = uut.gpio_control_in[30].pad_gpio_out; + assign segment_xxxh[2] = uut.gpio_control_in[31].pad_gpio_out; + assign segment_xxxh[3] = uut.gpio_control_in[32].pad_gpio_out; + assign segment_xxxh[4] = uut.gpio_control_in[33].pad_gpio_out; + assign segment_xxxh[5] = uut.gpio_control_in[34].pad_gpio_out; + assign segment_xxxh[6] = uut.gpio_control_in[35].pad_gpio_out; + + assign mprj_io[36] = safemode ; + assign mprj_io[37] = clk_32768; + + // 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 #12.5 clock <= (clock === 1'b0); + always #12.5 clk_32768 <= (clk_32768 === 1'b0); + + initial begin + clock = 0; + clk_32768 = 0; + safemode = 0; + end + + + initial begin + $dumpfile("ASIC_watch.vcd"); + $dumpvars(0, ASIC_watch_tb); + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (15) begin + repeat (1000) @(posedge clock); + // $display("+1000 cycles"); + end + $display("%c[1;31m",27); + $display ("Monitor: Timeout, Test Mega-Project IO Ports (RTL) Failed"); + $display("%c[0m",27); + $finish; + end + + initial begin + RSTB <= 1'b0; + #2000; + RSTB <= 1'b1; // Release reset + end + + initial begin // Power-up sequence + power1 <= 1'b0; + power2 <= 1'b0; + power3 <= 1'b0; + power4 <= 1'b0; + #200; + power1 <= 1'b1; + #200; + power2 <= 1'b1; + #200; + power3 <= 1'b1; + #200; + power4 <= 1'b1; + end + + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + + wire VDD1V8; + wire VDD3V3; + wire VSS; + + assign VDD3V3 = power1; + assign VDD1V8 = power2; + wire USER_VDD3V3 = power3; + wire USER_VDD1V8 = power4; + assign VSS = 1'b0; + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (USER_VDD3V3), + .vdda2 (USER_VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (USER_VDD1V8), + .vccd2 (USER_VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clock), + .gpio (gpio), + .mprj_io (mprj_io), + .flash_csb(flash_csb), + .flash_clk(flash_clk), + .flash_io0(flash_io0), + .flash_io1(flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("ASIC_watch.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule diff --git a/verilog/dv/caravel/user_proj_example/ASIC_watch/Makefile b/verilog/dv/caravel/user_proj_example/ASIC_watch/Makefile new file mode 100644 index 00000000..1e6a2559 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/ASIC_watch/Makefile @@ -0,0 +1,42 @@ +FIRMWARE_PATH = ../.. +RTL_PATH = ../../../../rtl +IP_PATH = ../../../../ip +#MP_PATH = ../../../../rtl/multi_project_harness +BEHAVIOURAL_MODELS = ../../ + +TOOLCHAIN_PREFIX?=/opt/riscv32ic/bin/riscv32-unknown-elf- +PDK_PATH?=/home/bscuser/hacking/skywater-pdk + +.SUFFIXES: + +PATTERN = ASIC_watch + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex + iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \ + $< -o $@ + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s + $(TOOLCHAIN_PREFIX)gcc -mabi=ilp32 -march=rv32imc -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + $(TOOLCHAIN_PREFIX)objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + $(TOOLCHAIN_PREFIX)objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all diff --git a/verilog/dv/caravel/user_proj_example/seven-segment-counter/Makefile b/verilog/dv/caravel/user_proj_example/seven-segment-counter/Makefile new file mode 100644 index 00000000..359c89cf --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/seven-segment-counter/Makefile @@ -0,0 +1,42 @@ +FIRMWARE_PATH = ../.. +RTL_PATH = ../../../../rtl +IP_PATH = ../../../../ip +#MP_PATH = ../../../../rtl/multi_project_harness +BEHAVIOURAL_MODELS = ../../ + +TOOLCHAIN_PREFIX?=/opt/riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf- +PDK_PATH?=~/work/asic-workshop/pdks/sky130A + +.SUFFIXES: + +PATTERN = seven_segment + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex + iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \ + $< -o $@ + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s + $(TOOLCHAIN_PREFIX)gcc -mabi=ilp32 -march=rv32imc -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + $(TOOLCHAIN_PREFIX)objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + $(TOOLCHAIN_PREFIX)objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all diff --git a/verilog/dv/caravel/user_proj_example/seven-segment-counter/seven_segment.c b/verilog/dv/caravel/user_proj_example/seven-segment-counter/seven_segment.c new file mode 100644 index 00000000..4ae44afd --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/seven-segment-counter/seven_segment.c @@ -0,0 +1,67 @@ +#include "../../defs.h" + +/* + IO Test: + - Configures MPRJ pins + - Observes counter value through the LED digits +*/ + +#define reg_mprj_7seg (*(volatile uint32_t*)0x30000200) + +void main() +{ + /* + IO Control Registers + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 3-bits | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | + + Output: 0000_0110_0000_1110 (0x1808) = GPIO_MODE_USER_STD_OUTPUT + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | + + Output: 0000_0110_0000_1111 (0x1809) = GPIO_MODE_MGNT_STD_OUTPUT + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | + + + Input: 0000_0001_0000_1111 (0x0402) = GPIO_MODE_USER_STD_INPUT_NOPULL + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | + + */ + + /* + Inputs + + system clock + system reset + + Outputs + + 14:8 seven segment LEDs + */ + + reg_mprj_io_8 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_9 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_10 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_11 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_12 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_13 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_14 = GPIO_MODE_USER_STD_OUTPUT; + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + // change to project 0 + reg_mprj_slave = 0; + + // use logic analyser to reset the counter + reg_la0_ena = 0x00000000; // bits 31:0 outputs + reg_la0_data = 0x00000001; // reset high is on bit 0 + reg_la0_data = 0x00000000; // low + + // update 7seg compare reg to 10 + reg_mprj_7seg = 10; +} + diff --git a/verilog/dv/caravel/user_proj_example/seven-segment-counter/seven_segment.gtkw b/verilog/dv/caravel/user_proj_example/seven-segment-counter/seven_segment.gtkw new file mode 100644 index 00000000..d081a58a --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/seven-segment-counter/seven_segment.gtkw @@ -0,0 +1,314 @@ +[*] +[*] GTKWave Analyzer v3.3.108 (w)1999-2020 BSI +[*] Thu Nov 26 15:54:45 2020 +[*] +[dumpfile] "/home/matt/work/asic-workshop/caravel/verilog/dv/caravel/user_proj_example/seven-segment-counter/seven_segment.vcd" +[dumpfile_mtime] "Thu Nov 26 15:53:35 2020" +[dumpfile_size] 101461023 +[savefile] "/home/matt/work/asic-workshop/caravel/verilog/dv/caravel/user_proj_example/seven-segment-counter/seven_segment.gtkw" +[timestart] 0 +[size] 2488 1529 +[pos] -1 -1 +*-26.000000 192362500 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] seven_segment_tb. +[treeopen] seven_segment_tb.uut. +[treeopen] seven_segment_tb.uut.gpio_control_bidir[0]. +[treeopen] seven_segment_tb.uut.gpio_control_bidir[0].gpio_in_buf. +[treeopen] seven_segment_tb.uut.gpio_control_bidir[0].gpio_logic_high. +[treeopen] seven_segment_tb.uut.gpio_control_in[2]. +[treeopen] seven_segment_tb.uut.gpio_control_in[3]. +[treeopen] seven_segment_tb.uut.gpio_control_in[4]. +[treeopen] seven_segment_tb.uut.gpio_control_in[4].gpio_in_buf. +[treeopen] seven_segment_tb.uut.gpio_control_in[4].gpio_logic_high. +[treeopen] seven_segment_tb.uut.gpio_control_in[8]. +[treeopen] seven_segment_tb.uut.gpio_control_in[9]. +[treeopen] seven_segment_tb.uut.mprj. +[treeopen] seven_segment_tb.uut.mprj.mprj. +[treeopen] seven_segment_tb.uut.mprj.mprj.proj_0. +[treeopen] seven_segment_tb.uut.soc. +[treeopen] seven_segment_tb.uut.soc.housekeeping. +[treeopen] seven_segment_tb.uut.soc.soc. +[treeopen] seven_segment_tb.uut.soc.soc.cpu. +[treeopen] seven_segment_tb.uut.soc.soc.cpu.picorv32_core. +[treeopen] seven_segment_tb.uut.soc.soc.gpio_wb. +[treeopen] seven_segment_tb.uut.soc.soc.mprj_ctrl. +[sst_width] 719 +[signals_width] 1098 +[sst_expanded] 1 +[sst_vpaned_height] 710 +@28 +seven_segment_tb.clock +seven_segment_tb.RSTB +@200 +- +@800200 +-wbs +@28 +seven_segment_tb.uut.mprj.mprj.wb_rst_i +seven_segment_tb.uut.mprj.mprj.wb_clk_i +seven_segment_tb.uut.mprj.mprj.wbs_ack_o +@22 +seven_segment_tb.uut.mprj.mprj.wbs_adr_i[31:0] +@28 +seven_segment_tb.uut.mprj.mprj.wbs_cyc_i +@24 +seven_segment_tb.uut.mprj.mprj.wbs_dat_i[31:0] +@22 +seven_segment_tb.uut.mprj.mprj.wbs_dat_o[31:0] +seven_segment_tb.uut.mprj.mprj.wbs_sel_i[3:0] +@28 +seven_segment_tb.uut.mprj.mprj.wbs_stb_i +seven_segment_tb.uut.mprj.mprj.wbs_we_i +@1000200 +-wbs +@800200 +-multi proj control +@28 +seven_segment_tb.uut.soc.soc.mprj_ctrl.mprj_ctrl.xfer_ctrl +@1000200 +-multi proj control +@800200 +-la +@22 +seven_segment_tb.uut.mprj.mprj.la_data_in[127:0] +seven_segment_tb.uut.mprj.mprj.la_data_out[127:0] +seven_segment_tb.uut.mprj.mprj.la_oen[127:0] +@1000200 +-la +@22 +seven_segment_tb.uut.soc.soc.cpu.picorv32_core.next_insn_opcode[31:0] +@200 +- +@800200 +-multi project +@22 +seven_segment_tb.uut.mprj.mprj.active_project[7:0] +@28 +seven_segment_tb.uut.mprj.mprj.wb_rst_i +@c00022 +seven_segment_tb.uut.mprj.io_in[37:0] +@28 +(0)seven_segment_tb.uut.mprj.io_in[37:0] +(1)seven_segment_tb.uut.mprj.io_in[37:0] +(2)seven_segment_tb.uut.mprj.io_in[37:0] +(3)seven_segment_tb.uut.mprj.io_in[37:0] +(4)seven_segment_tb.uut.mprj.io_in[37:0] +(5)seven_segment_tb.uut.mprj.io_in[37:0] +(6)seven_segment_tb.uut.mprj.io_in[37:0] +(7)seven_segment_tb.uut.mprj.io_in[37:0] +(8)seven_segment_tb.uut.mprj.io_in[37:0] +(9)seven_segment_tb.uut.mprj.io_in[37:0] +(10)seven_segment_tb.uut.mprj.io_in[37:0] +(11)seven_segment_tb.uut.mprj.io_in[37:0] +(12)seven_segment_tb.uut.mprj.io_in[37:0] +(13)seven_segment_tb.uut.mprj.io_in[37:0] +(14)seven_segment_tb.uut.mprj.io_in[37:0] +(15)seven_segment_tb.uut.mprj.io_in[37:0] +(16)seven_segment_tb.uut.mprj.io_in[37:0] +(17)seven_segment_tb.uut.mprj.io_in[37:0] +(18)seven_segment_tb.uut.mprj.io_in[37:0] +(19)seven_segment_tb.uut.mprj.io_in[37:0] +(20)seven_segment_tb.uut.mprj.io_in[37:0] +(21)seven_segment_tb.uut.mprj.io_in[37:0] +(22)seven_segment_tb.uut.mprj.io_in[37:0] +(23)seven_segment_tb.uut.mprj.io_in[37:0] +(24)seven_segment_tb.uut.mprj.io_in[37:0] +(25)seven_segment_tb.uut.mprj.io_in[37:0] +(26)seven_segment_tb.uut.mprj.io_in[37:0] +(27)seven_segment_tb.uut.mprj.io_in[37:0] +(28)seven_segment_tb.uut.mprj.io_in[37:0] +(29)seven_segment_tb.uut.mprj.io_in[37:0] +(30)seven_segment_tb.uut.mprj.io_in[37:0] +(31)seven_segment_tb.uut.mprj.io_in[37:0] +(32)seven_segment_tb.uut.mprj.io_in[37:0] +(33)seven_segment_tb.uut.mprj.io_in[37:0] +(34)seven_segment_tb.uut.mprj.io_in[37:0] +(35)seven_segment_tb.uut.mprj.io_in[37:0] +(36)seven_segment_tb.uut.mprj.io_in[37:0] +(37)seven_segment_tb.uut.mprj.io_in[37:0] +@1401200 +-group_end +@800022 +seven_segment_tb.uut.mprj.mprj.io_out[37:0] +@28 +(0)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(1)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(2)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(3)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(4)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(5)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(6)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(7)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(8)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(9)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(10)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(11)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(12)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(13)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(14)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(15)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(16)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(17)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(18)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(19)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(20)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(21)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(22)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(23)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(24)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(25)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(26)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(27)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(28)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(29)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(30)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(31)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(32)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(33)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(34)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(35)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(36)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(37)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +@1001200 +-group_end +@22 +seven_segment_tb.uut.mprj.mprj.io_oeb[37:0] +@1000200 +-multi project +@c00022 +seven_segment_tb.mprj_io[37:0] +@28 +(0)seven_segment_tb.mprj_io[37:0] +(1)seven_segment_tb.mprj_io[37:0] +(2)seven_segment_tb.mprj_io[37:0] +(3)seven_segment_tb.mprj_io[37:0] +(4)seven_segment_tb.mprj_io[37:0] +(5)seven_segment_tb.mprj_io[37:0] +(6)seven_segment_tb.mprj_io[37:0] +(7)seven_segment_tb.mprj_io[37:0] +(8)seven_segment_tb.mprj_io[37:0] +(9)seven_segment_tb.mprj_io[37:0] +(10)seven_segment_tb.mprj_io[37:0] +(11)seven_segment_tb.mprj_io[37:0] +(12)seven_segment_tb.mprj_io[37:0] +(13)seven_segment_tb.mprj_io[37:0] +(14)seven_segment_tb.mprj_io[37:0] +(15)seven_segment_tb.mprj_io[37:0] +(16)seven_segment_tb.mprj_io[37:0] +(17)seven_segment_tb.mprj_io[37:0] +(18)seven_segment_tb.mprj_io[37:0] +(19)seven_segment_tb.mprj_io[37:0] +(20)seven_segment_tb.mprj_io[37:0] +(21)seven_segment_tb.mprj_io[37:0] +(22)seven_segment_tb.mprj_io[37:0] +(23)seven_segment_tb.mprj_io[37:0] +(24)seven_segment_tb.mprj_io[37:0] +(25)seven_segment_tb.mprj_io[37:0] +(26)seven_segment_tb.mprj_io[37:0] +(27)seven_segment_tb.mprj_io[37:0] +(28)seven_segment_tb.mprj_io[37:0] +(29)seven_segment_tb.mprj_io[37:0] +(30)seven_segment_tb.mprj_io[37:0] +(31)seven_segment_tb.mprj_io[37:0] +(32)seven_segment_tb.mprj_io[37:0] +(33)seven_segment_tb.mprj_io[37:0] +(34)seven_segment_tb.mprj_io[37:0] +(35)seven_segment_tb.mprj_io[37:0] +(36)seven_segment_tb.mprj_io[37:0] +(37)seven_segment_tb.mprj_io[37:0] +@c00022 +seven_segment_tb.uut.mprj.mprj.io_out[37:0] +@28 +(0)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(1)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(2)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(3)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(4)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(5)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(6)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(7)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(8)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(9)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(10)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(11)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(12)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(13)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(14)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(15)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(16)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(17)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(18)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(19)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(20)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(21)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(22)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(23)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(24)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(25)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(26)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(27)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(28)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(29)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(30)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(31)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(32)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(33)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(34)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(35)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(36)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +(37)seven_segment_tb.uut.mprj.mprj.io_out[37:0] +@1401200 +-group_end +@22 +seven_segment_tb.uut.mprj.mprj.io_oeb[37:0] +seven_segment_tb.uut.mprj.mprj.io_in[37:0] +@1401200 +-group_end +@800200 +-seven seg +@28 +seven_segment_tb.uut.mprj.mprj.proj_0.clk +@22 +seven_segment_tb.uut.mprj.mprj.proj_0.second_counter[23:0] +@24 +seven_segment_tb.uut.mprj.mprj.proj_0.compare[23:0] +@28 +seven_segment_tb.uut.mprj.mprj.proj_0.reset +@800022 +seven_segment_tb.uut.mprj.mprj.proj_0.digit[3:0] +@28 +(0)seven_segment_tb.uut.mprj.mprj.proj_0.digit[3:0] +(1)seven_segment_tb.uut.mprj.mprj.proj_0.digit[3:0] +(2)seven_segment_tb.uut.mprj.mprj.proj_0.digit[3:0] +(3)seven_segment_tb.uut.mprj.mprj.proj_0.digit[3:0] +@200 +- +@800022 +seven_segment_tb.uut.mprj.mprj.proj_0.led_out[6:0] +@28 +(0)seven_segment_tb.uut.mprj.mprj.proj_0.led_out[6:0] +(1)seven_segment_tb.uut.mprj.mprj.proj_0.led_out[6:0] +(2)seven_segment_tb.uut.mprj.mprj.proj_0.led_out[6:0] +(3)seven_segment_tb.uut.mprj.mprj.proj_0.led_out[6:0] +(4)seven_segment_tb.uut.mprj.mprj.proj_0.led_out[6:0] +(5)seven_segment_tb.uut.mprj.mprj.proj_0.led_out[6:0] +(6)seven_segment_tb.uut.mprj.mprj.proj_0.led_out[6:0] +@1001200 +-group_end +-group_end +@1000200 +-seven seg +@800022 +seven_segment_tb.segments[6:0] +@28 +(0)seven_segment_tb.segments[6:0] +(1)seven_segment_tb.segments[6:0] +(2)seven_segment_tb.segments[6:0] +(3)seven_segment_tb.segments[6:0] +(4)seven_segment_tb.segments[6:0] +(5)seven_segment_tb.segments[6:0] +(6)seven_segment_tb.segments[6:0] +@1001200 +-group_end +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/verilog/dv/caravel/user_proj_example/seven-segment-counter/seven_segment_tb.v b/verilog/dv/caravel/user_proj_example/seven-segment-counter/seven_segment_tb.v new file mode 100644 index 00000000..4bef7724 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/seven-segment-counter/seven_segment_tb.v @@ -0,0 +1,151 @@ +`default_nettype none + +`timescale 1 ns / 1 ps + +`include "caravel.v" +`include "spiflash.v" + +module seven_segment_tb; + reg clock; + reg RSTB; + reg power1, power2; + reg power3, power4; + + wire gpio; + wire [37:0] mprj_io; + wire [6:0] segments; + + + assign segments = { + uut.gpio_control_in[14].pad_gpio_out, + uut.gpio_control_in[13].pad_gpio_out, + uut.gpio_control_in[12].pad_gpio_out, + uut.gpio_control_in[11].pad_gpio_out, + uut.gpio_control_in[10].pad_gpio_out, + uut.gpio_control_in[ 9].pad_gpio_out, + uut.gpio_control_in[ 8].pad_gpio_out + }; + + // 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 #12.5 clock <= (clock === 1'b0); + + initial begin + clock = 0; + end + + initial begin + $dumpfile("seven_segment.vcd"); + $dumpvars(0, seven_segment_tb); + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (15) begin + repeat (1000) @(posedge clock); + // $display("+1000 cycles"); + end + $display("%c[1;31m",27); + $display ("Monitor: Timeout, Test Mega-Project IO Ports (RTL) Failed"); + $display("%c[0m",27); + $finish; + end + + initial begin + // Observe segments counting from 0 to 9 + + wait(segments == 7'b0111111); + wait(segments == 7'b0000110); + wait(segments == 7'b1011011); + wait(segments == 7'b1001111); + wait(segments == 7'b1100110); + wait(segments == 7'b1101101); + wait(segments == 7'b1111100); + wait(segments == 7'b0000111); + wait(segments == 7'b1111111); + wait(segments == 7'b1111111); + wait(segments == 7'b1100111); + + $display("Monitor: Test 1 Mega-Project IO (RTL) Passed"); + $finish; + end + + initial begin + RSTB <= 1'b0; + #2000; + RSTB <= 1'b1; // Release reset + end + + initial begin // Power-up sequence + power1 <= 1'b0; + power2 <= 1'b0; + power3 <= 1'b0; + power4 <= 1'b0; + #200; + power1 <= 1'b1; + #200; + power2 <= 1'b1; + #200; + power3 <= 1'b1; + #200; + power4 <= 1'b1; + end + + /* + always @(mprj_io) begin + #1 $display("MPRJ-IO state = %b ", mprj_io[7:0]); + end + */ + + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + + wire VDD1V8; + wire VDD3V3; + wire VSS; + + assign VDD3V3 = power1; + assign VDD1V8 = power2; + wire USER_VDD3V3 = power3; + wire USER_VDD1V8 = power4; + assign VSS = 1'b0; + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (USER_VDD3V3), + .vdda2 (USER_VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (USER_VDD1V8), + .vccd2 (USER_VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clock), + .gpio (gpio), + .mprj_io (mprj_io), + .flash_csb(flash_csb), + .flash_clk(flash_clk), + .flash_io0(flash_io0), + .flash_io1(flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("seven_segment.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule diff --git a/verilog/dv/caravel/user_proj_example/spinet/Makefile b/verilog/dv/caravel/user_proj_example/spinet/Makefile new file mode 100644 index 00000000..cee341c5 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/spinet/Makefile @@ -0,0 +1,42 @@ +FIRMWARE_PATH = ../.. +RTL_PATH = ../../../../rtl +IP_PATH = ../../../../ip +#MP_PATH = ../../../../rtl/multi_project_harness +BEHAVIOURAL_MODELS = ../../ + +TOOLCHAIN_PREFIX?=/opt/gcc-riscv/bin/riscv32-unknown-elf- +PDK_PATH?=/mnt/extra/vlsi/sky130A + +.SUFFIXES: + +PATTERN = spinet + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex + iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \ + $< -o $@ + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s + $(TOOLCHAIN_PREFIX)gcc -O2 -mabi=ilp32 -march=rv32imc -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + $(TOOLCHAIN_PREFIX)objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + $(TOOLCHAIN_PREFIX)objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all diff --git a/verilog/dv/caravel/user_proj_example/spinet/spinet.c b/verilog/dv/caravel/user_proj_example/spinet/spinet.c new file mode 100644 index 00000000..29997e67 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/spinet/spinet.c @@ -0,0 +1,66 @@ +#include "../../defs.h" + +/* + IO Test: + - Configures MPRJ pins + - Nothing else to do: spinet is autonomous +*/ + +#define PROJECT 3 +#define NUMNODES 6 + +void main() +{ + /* + IO Control Registers + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 3-bits | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | + + Output: 0000_0110_0000_1110 (0x1808) = GPIO_MODE_USER_STD_OUTPUT + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | + + Output: 0000_0110_0000_1111 (0x1809) = GPIO_MODE_MGNT_STD_OUTPUT + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | + + + Input: 0000_0001_0000_1111 (0x0402) = GPIO_MODE_USER_STD_INPUT_NOPULL + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | + + */ + + /* + Inputs | Outputs + Node MOSI SCK SS MISO TXRDY RXRDY + 0 0 6 12 18 24 30 + 1 1 7 13 19 25 31 + 2 2 8 14 20 26 32 + 3 3 9 15 21 27 33 + 4 4 10 16 22 28 34 + 5 5 11 17 23 29 35 + + */ + + volatile uint32_t *io = ®_mprj_io_0; + for (int i = 0; i < NUMNODES; i++) { + for (int j = 0; j <= 12; j += 6) + io[i + j] = GPIO_MODE_USER_STD_INPUT_NOPULL; + for (int j = 18; j <= 30; j += 6) + io[i + j] = GPIO_MODE_USER_STD_OUTPUT; + } + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + // change to project + reg_mprj_slave = PROJECT; + + // use logic analyser bit 0 as reset + reg_la0_ena = 0x00000000; // bits 31:0 outputs + reg_la0_data = 0x00000001; // reset high is on bit 0 + reg_la0_data = 0x00000000; // low + +} diff --git a/verilog/dv/caravel/user_proj_example/spinet/spinet_tb.v b/verilog/dv/caravel/user_proj_example/spinet/spinet_tb.v new file mode 100644 index 00000000..35f98a0a --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/spinet/spinet_tb.v @@ -0,0 +1,240 @@ +`default_nettype none + +`timescale 1 ns / 1 ps + +`include "caravel.v" +`include "spiflash.v" + +module spinet_tb; + reg clock; + reg ext_clock; + reg RSTB; + reg power1, power2; + reg power3, power4; + + wire gpio; + wire [37:0] mprj_io; + + localparam N = 6; + + // SPI signals for each node + reg mosi0, sck0, ss0; + wire [N-1:0] mosi, sck, ss; + wire [N-1:0] miso, txrdy, rxrdy; + assign mprj_io[5:0] = {mosi[5:1],mosi0}; + assign mprj_io[11:6] = {sck[5:1],sck0}; + assign mprj_io[17:12] = {ss[5:1],ss0}; + assign miso = mprj_io[23:18]; + assign txrdy = mprj_io[29:24]; + assign rxrdy = mprj_io[35:30]; + + initial begin + sck0 = 0; + ss0 = ~0; + mosi0 = 0; + end + + // External clock is used by default. Make this artificially fast for the + // simulation. Normally this would be a slow clock and the digital PLL + // would be the fast clock. + + always #12.5 clock <= (clock === 1'b0); + always #6.25 ext_clock <= (ext_clock === 1'b0); + + initial begin + clock = 0; + ext_clock = 0; + end + + initial begin + $dumpfile("spinet.vcd"); + $dumpvars(0, spinet_tb); + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (50) begin + repeat (1000) @(posedge clock); + end + $display("%c[1;31m",27); + $display ("Monitor: Timeout, Test Failed"); + $display("%c[0m",27); + $finish; + end + + reg [15:0] snd, rcv, sent; + reg [N-1:0] echoed = 1; + initial begin + // Wait for initial reset + wait (uut.la_data_in_mprj[0] === 1'b1); + wait (uut.la_data_in_mprj[0] === 1'b0); + // Node 0 sends one packet to each other node + for (integer i = 1; i < N; i = i + 1) begin + snd <= {2'b10,3'h0,3'h0,8'h40}; + snd[13:11] <= i; + snd[2:0] <= i; + #100 ss0 <= 0; + sent <= snd; + #50; + repeat (16) begin + #50 mosi0 <= snd[15]; + sck0 <= 1; + #50 rcv <= {rcv[14:0],miso[0]}; + sck0 <= 0; + snd <= snd << 1; + end + #100 ss0 <= 1; + $display("sent %h received: %h", sent, rcv); + if (rcv[15]) + echoed[rcv[10:8]] = 1; + + end + #100 ss0 <= 1; + // Read packets echoed back by other nodes + snd <= 0; + while (&echoed == 0) begin + wait (rxrdy[0] === 1'b1); + ss0 <= 0; + #50; + repeat (16) begin + #50 mosi0 <= snd[15]; + sck0 <= 1; + #50 rcv <= {rcv[14:0],miso[0]}; + sck0 <= 0; + snd <= snd << 1; + end + sent <= snd; + #100 ss0 <= 1; + $display("sent %h received: %h", sent, rcv); + if (rcv[15]) + echoed[rcv[10:8]] = 1; + end + $display("Monitor: Test Passed"); + $finish; + end + + genvar node; + generate for (node = 1; node < N; node = node + 1) + echo ECHO (mosi[node], sck[node], ss[node], miso[node], txrdy[node], rxrdy[node]); + endgenerate + + initial begin + RSTB <= 1'b0; + #2000; + RSTB <= 1'b1; // Release reset + end + + initial begin // Power-up sequence + power1 <= 1'b0; + power2 <= 1'b0; + power3 <= 1'b0; + power4 <= 1'b0; + #200; + power1 <= 1'b1; + #200; + power2 <= 1'b1; + #200; + power3 <= 1'b1; + #200; + power4 <= 1'b1; + end + + /* + always @(mprj_io) begin + #1 $display("MPRJ-IO state = %b ", mprj_io[7:0]); + end + */ + + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + + wire VDD1V8; + wire VDD3V3; + wire VSS; + + assign VDD3V3 = power1; + assign VDD1V8 = power2; + assign USER_VDD3V3 = power3; + assign USER_VDD1V8 = power4; + assign VSS = 1'b0; + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (USER_VDD3V3), + .vdda2 (USER_VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (USER_VDD1V8), + .vccd2 (USER_VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clock), + .gpio (gpio), + .mprj_io (mprj_io), + .flash_csb(flash_csb), + .flash_clk(flash_clk), + .flash_io0(flash_io0), + .flash_io1(flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("spinet.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule + +// SPI host emulation to read and echo packets +module echo ( + output reg mosi, + output reg sck, + output reg ss, + input miso, + input txrdy, + input rxrdy); + + reg [15:0] pkt = 0; + initial begin + ss = 1; + sck = 0; + mosi = 0; + end + always @(posedge rxrdy) begin + // receive a packet + ss <= 0; + sck <= 0; + mosi <= 0; + #50; + repeat (16) begin + #50 sck <= 1; + #50 pkt <= {pkt[14:0],miso}; + sck <= 0; + end + #100 ss <= 1; + // swap sender and receiver address + pkt[13:8] <= {pkt[10:8],pkt[13:11]}; + // send the packet back + #50 ss <= 0; + #50; + repeat (16) begin + #50 mosi <= pkt[15]; + sck <= 1; + #50 sck <= 0; + pkt <= pkt << 1; + end + #100 ss <= 1; + end + +endmodule diff --git a/verilog/dv/caravel/user_proj_example/vga-clock/Makefile b/verilog/dv/caravel/user_proj_example/vga-clock/Makefile new file mode 100644 index 00000000..b53df602 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/vga-clock/Makefile @@ -0,0 +1,42 @@ +FIRMWARE_PATH = ../.. +RTL_PATH = ../../../../rtl +IP_PATH = ../../../../ip +#MP_PATH = ../../../../rtl/multi_project_harness +BEHAVIOURAL_MODELS = ../../ + +TOOLCHAIN_PREFIX?=/opt/riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf- +PDK_PATH?=~/work/asic-workshop/pdks/sky130A + +.SUFFIXES: + +PATTERN = vga_clock + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex + iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \ + $< -o $@ + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s + $(TOOLCHAIN_PREFIX)gcc -mabi=ilp32 -march=rv32imc -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + $(TOOLCHAIN_PREFIX)objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + $(TOOLCHAIN_PREFIX)objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all diff --git a/verilog/dv/caravel/user_proj_example/vga-clock/vga_clock.c b/verilog/dv/caravel/user_proj_example/vga-clock/vga_clock.c new file mode 100644 index 00000000..a6fe3fc8 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/vga-clock/vga_clock.c @@ -0,0 +1,77 @@ +#include "../../defs.h" + +#define reg_mprj_oeb0 (*(volatile uint32_t*)0x30000004) +#define reg_mprj_oeb1 (*(volatile uint32_t*)0x30000008) +/* + IO Test: + - Configures MPRJ pins + - Observes counter value through the LED digits +*/ + +void main() +{ + /* + IO Control Registers + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 3-bits | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | + + Output: 0000_0110_0000_1110 (0x1808) = GPIO_MODE_USER_STD_OUTPUT + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | + + Output: 0000_0110_0000_1111 (0x1809) = GPIO_MODE_MGNT_STD_OUTPUT + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | + + + Input: 0000_0001_0000_1111 (0x0402) = GPIO_MODE_USER_STD_INPUT_NOPULL + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | + + */ + + /* + Inputs + + system clock + system reset + 8 adj hours + 9 adj min + 10 adj sec + + Outputs + + 11 hsync + 12 vsync + 13-18 rrggbb + */ + + reg_mprj_io_8 = GPIO_MODE_USER_STD_INPUT_NOPULL; + reg_mprj_io_9 = GPIO_MODE_USER_STD_INPUT_NOPULL; + reg_mprj_io_10 = GPIO_MODE_USER_STD_INPUT_NOPULL; + + reg_mprj_io_11 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_12 = GPIO_MODE_USER_STD_OUTPUT; + + reg_mprj_io_13 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_14 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_15 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_16 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_17 = GPIO_MODE_USER_STD_OUTPUT; + reg_mprj_io_18 = GPIO_MODE_USER_STD_OUTPUT; + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + // change to project 2 + reg_mprj_slave = 2; + + // setup oeb, low for output, high for input + reg_mprj_oeb0 = (1 << 8) + (1 << 9) + (1 << 10); + + // use logic analyser to reset the design + reg_la0_ena = 0x00000000; // bits 31:0 outputs + reg_la0_data = 0x00000001; // reset high is on bit 0 + reg_la0_data = 0x00000000; // low +} diff --git a/verilog/dv/caravel/user_proj_example/vga-clock/vga_clock.gtkw b/verilog/dv/caravel/user_proj_example/vga-clock/vga_clock.gtkw new file mode 100644 index 00000000..78a082e6 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/vga-clock/vga_clock.gtkw @@ -0,0 +1,197 @@ +[*] +[*] GTKWave Analyzer v3.3.108 (w)1999-2020 BSI +[*] Thu Nov 26 13:29:36 2020 +[*] +[dumpfile] "/home/matt/work/asic-workshop/caravel/verilog/dv/caravel/user_proj_example/vga-clock/vga_clock.vcd" +[dumpfile_mtime] "Thu Nov 26 13:28:55 2020" +[dumpfile_size] 194298414 +[savefile] "/home/matt/work/asic-workshop/caravel/verilog/dv/caravel/user_proj_example/vga-clock/vga_clock.gtkw" +[timestart] 0 +[size] 1700 1529 +[pos] -1 -1 +*-28.000000 253000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] vga_clock_tb. +[treeopen] vga_clock_tb.uut. +[treeopen] vga_clock_tb.uut.gpio_control_bidir[0].gpio_in_buf. +[treeopen] vga_clock_tb.uut.gpio_control_in[4].gpio_in_buf. +[treeopen] vga_clock_tb.uut.gpio_control_in[4].gpio_logic_high. +[treeopen] vga_clock_tb.uut.gpio_control_in[8]. +[treeopen] vga_clock_tb.uut.gpio_control_in[8].gpio_in_buf. +[treeopen] vga_clock_tb.uut.mprj. +[treeopen] vga_clock_tb.uut.mprj.mprj. +[treeopen] vga_clock_tb.uut.mprj.mprj.proj_0. +[treeopen] vga_clock_tb.uut.mprj.mprj.proj_2. +[treeopen] vga_clock_tb.uut.soc. +[treeopen] vga_clock_tb.uut.soc.housekeeping. +[treeopen] vga_clock_tb.uut.soc.soc. +[treeopen] vga_clock_tb.uut.soc.soc.cpu. +[treeopen] vga_clock_tb.uut.soc.soc.cpu.picorv32_core. +[treeopen] vga_clock_tb.uut.soc.soc.gpio_wb. +[treeopen] vga_clock_tb.uut.soc.soc.mprj_ctrl. +[sst_width] 506 +[signals_width] 741 +[sst_expanded] 1 +[sst_vpaned_height] 862 +@28 +vga_clock_tb.clock +vga_clock_tb.RSTB +@200 +- +@800200 +-wbs +@28 +vga_clock_tb.uut.mprj.mprj.wb_rst_i +vga_clock_tb.uut.mprj.mprj.wb_clk_i +vga_clock_tb.uut.mprj.mprj.wbs_ack_o +@22 +vga_clock_tb.uut.mprj.mprj.wbs_adr_i[31:0] +@28 +vga_clock_tb.uut.mprj.mprj.wbs_cyc_i +@24 +vga_clock_tb.uut.mprj.mprj.wbs_dat_i[31:0] +@22 +vga_clock_tb.uut.mprj.mprj.wbs_dat_o[31:0] +vga_clock_tb.uut.mprj.mprj.wbs_sel_i[3:0] +@28 +vga_clock_tb.uut.mprj.mprj.wbs_stb_i +vga_clock_tb.uut.mprj.mprj.wbs_we_i +@1000200 +-wbs +@800200 +-multi proj control +@28 +vga_clock_tb.uut.soc.soc.mprj_ctrl.mprj_ctrl.xfer_ctrl +@1000200 +-multi proj control +@800200 +-la +@22 +vga_clock_tb.uut.mprj.mprj.la_data_in[127:0] +vga_clock_tb.uut.mprj.mprj.la_data_out[127:0] +vga_clock_tb.uut.mprj.mprj.la_oen[127:0] +@1000200 +-la +@22 +vga_clock_tb.uut.soc.soc.cpu.picorv32_core.next_insn_opcode[31:0] +@200 +- +@800200 +-multi project +@22 +vga_clock_tb.uut.mprj.mprj.active_project[7:0] +@23 +vga_clock_tb.uut.mprj.mprj.reg_oeb[37:0] +@28 +vga_clock_tb.uut.mprj.mprj.wb_rst_i +@c00022 +vga_clock_tb.uut.mprj.io_in[37:0] +@28 +(0)vga_clock_tb.uut.mprj.io_in[37:0] +(1)vga_clock_tb.uut.mprj.io_in[37:0] +(2)vga_clock_tb.uut.mprj.io_in[37:0] +(3)vga_clock_tb.uut.mprj.io_in[37:0] +(4)vga_clock_tb.uut.mprj.io_in[37:0] +(5)vga_clock_tb.uut.mprj.io_in[37:0] +(6)vga_clock_tb.uut.mprj.io_in[37:0] +(7)vga_clock_tb.uut.mprj.io_in[37:0] +(8)vga_clock_tb.uut.mprj.io_in[37:0] +(9)vga_clock_tb.uut.mprj.io_in[37:0] +(10)vga_clock_tb.uut.mprj.io_in[37:0] +(11)vga_clock_tb.uut.mprj.io_in[37:0] +(12)vga_clock_tb.uut.mprj.io_in[37:0] +(13)vga_clock_tb.uut.mprj.io_in[37:0] +(14)vga_clock_tb.uut.mprj.io_in[37:0] +(15)vga_clock_tb.uut.mprj.io_in[37:0] +(16)vga_clock_tb.uut.mprj.io_in[37:0] +(17)vga_clock_tb.uut.mprj.io_in[37:0] +(18)vga_clock_tb.uut.mprj.io_in[37:0] +(19)vga_clock_tb.uut.mprj.io_in[37:0] +(20)vga_clock_tb.uut.mprj.io_in[37:0] +(21)vga_clock_tb.uut.mprj.io_in[37:0] +(22)vga_clock_tb.uut.mprj.io_in[37:0] +(23)vga_clock_tb.uut.mprj.io_in[37:0] +(24)vga_clock_tb.uut.mprj.io_in[37:0] +(25)vga_clock_tb.uut.mprj.io_in[37:0] +(26)vga_clock_tb.uut.mprj.io_in[37:0] +(27)vga_clock_tb.uut.mprj.io_in[37:0] +(28)vga_clock_tb.uut.mprj.io_in[37:0] +(29)vga_clock_tb.uut.mprj.io_in[37:0] +(30)vga_clock_tb.uut.mprj.io_in[37:0] +(31)vga_clock_tb.uut.mprj.io_in[37:0] +(32)vga_clock_tb.uut.mprj.io_in[37:0] +(33)vga_clock_tb.uut.mprj.io_in[37:0] +(34)vga_clock_tb.uut.mprj.io_in[37:0] +(35)vga_clock_tb.uut.mprj.io_in[37:0] +(36)vga_clock_tb.uut.mprj.io_in[37:0] +(37)vga_clock_tb.uut.mprj.io_in[37:0] +@1401200 +-group_end +@c00022 +vga_clock_tb.uut.mprj.mprj.io_out[37:0] +@28 +(0)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(1)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(2)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(3)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(4)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(5)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(6)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(7)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(8)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(9)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(10)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(11)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(12)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(13)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(14)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(15)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(16)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(17)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(18)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(19)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(20)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(21)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(22)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(23)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(24)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(25)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(26)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(27)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(28)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(29)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(30)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(31)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(32)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(33)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(34)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(35)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(36)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +(37)vga_clock_tb.uut.mprj.mprj.io_out[37:0] +@1401200 +-group_end +@1000200 +-multi project +@28 +vga_clock_tb.uut.mprj.mprj.proj_2.reset +@22 +vga_clock_tb.uut.mprj.mprj.proj_2.hrs_u[3:0] +@28 +vga_clock_tb.uut.mprj.mprj.proj_2.hrs_d[1:0] +vga_clock_tb.adj_hrs +vga_clock_tb.uut.gpio_control_in[8].pad_gpio_in +vga_clock_tb.uut.gpio_control_in[8].pad_gpio_in +vga_clock_tb.uut.gpio_control_in[8].pad_gpio_inenb +vga_clock_tb.uut.gpio_control_in[8].pad_gpio_outenb +vga_clock_tb.uut.mprj.mprj.proj_2.adj_hrs +vga_clock_tb.uut.mprj.mprj.proj_2.px_clk +@24 +vga_clock_tb.uut.mprj.mprj.proj_2.y_px[9:0] +vga_clock_tb.uut.mprj.mprj.proj_2.x_px[9:0] +@28 +vga_clock_tb.uut.mprj.mprj.proj_2.activevideo +vga_clock_tb.uut.mprj.mprj.proj_2.vsync +vga_clock_tb.hsync +@22 +vga_clock_tb.rrggbb[5:0] +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/verilog/dv/caravel/user_proj_example/vga-clock/vga_clock_tb.v b/verilog/dv/caravel/user_proj_example/vga-clock/vga_clock_tb.v new file mode 100644 index 00000000..6bb03c4a --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/vga-clock/vga_clock_tb.v @@ -0,0 +1,159 @@ +`default_nettype none + +`timescale 1 ns / 1 ps + +`include "caravel.v" +`include "spiflash.v" + +module vga_clock_tb; + reg clock; + reg RSTB; + reg power1, power2; + reg power3, power4; + + wire gpio; + wire [37:0] mprj_io; + wire [5:0] rrggbb; + wire hsync, vsync; + + assign hsync = uut.gpio_control_in[11].pad_gpio_out; + assign vsync = uut.gpio_control_in[12].pad_gpio_out; + assign rrggbb = { + uut.gpio_control_in[13].pad_gpio_out, + uut.gpio_control_in[14].pad_gpio_out, + uut.gpio_control_in[15].pad_gpio_out, + uut.gpio_control_in[16].pad_gpio_out, + uut.gpio_control_in[17].pad_gpio_out, + uut.gpio_control_in[18].pad_gpio_out + }; + + reg adj_hrs = 0; + reg adj_min = 0; + reg adj_sec = 0; + assign mprj_io[8] = adj_hrs; + assign mprj_io[9] = adj_min; + assign mprj_io[10] = adj_sec; +/* this doesn't work + assign uut.gpio_control_in[ 8].pad_gpio_in = adj_hrs; + assign uut.gpio_control_in[ 9].pad_gpio_in = adj_min; + assign uut.gpio_control_in[10].pad_gpio_in = adj_sec; + */ + + // 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 #12.5 clock <= (clock === 1'b0); + + initial begin + clock = 0; + end + + initial begin + $dumpfile("vga_clock.vcd"); + $dumpvars(0, vga_clock_tb); + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (15) begin + repeat (1000) @(posedge clock); + // $display("+1000 cycles"); + end + $display("%c[1;31m",27); + $display ("Monitor: Timeout, Test Mega-Project IO Ports (RTL) Failed"); + $display("%c[0m",27); + $finish; + end + + initial begin + // wait for reset, we have 2 before the project is ready + wait(uut.mprj.mprj.proj_2.reset == 1); + wait(uut.mprj.mprj.proj_2.reset == 0); + wait(uut.mprj.mprj.proj_2.reset == 1); + wait(uut.mprj.mprj.proj_2.reset == 0); + + // press all the buttons! button clk_en deboucing is slow so don't want to wait around + adj_hrs = 1; + adj_min = 1; + adj_sec = 1; + wait(uut.mprj.mprj.proj_2.hrs_u == 1); + $display ("adjusted hours ok"); + wait(uut.mprj.mprj.proj_2.min_u == 1); + $display ("adjusted min ok"); + wait(uut.mprj.mprj.proj_2.sec_u == 1); + $display ("adjusted sec ok"); + + end + + initial begin + RSTB <= 1'b0; + #2000; + RSTB <= 1'b1; // Release reset + end + + initial begin // Power-up sequence + power1 <= 1'b0; + power2 <= 1'b0; + power3 <= 1'b0; + power4 <= 1'b0; + #200; + power1 <= 1'b1; + #200; + power2 <= 1'b1; + #200; + power3 <= 1'b1; + #200; + power4 <= 1'b1; + end + + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + + wire VDD1V8; + wire VDD3V3; + wire VSS; + + assign VDD3V3 = power1; + assign VDD1V8 = power2; + wire USER_VDD3V3 = power3; + wire USER_VDD1V8 = power4; + assign VSS = 1'b0; + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (USER_VDD3V3), + .vdda2 (USER_VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (USER_VDD1V8), + .vccd2 (USER_VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clock), + .gpio (gpio), + .mprj_io (mprj_io), + .flash_csb(flash_csb), + .flash_clk(flash_clk), + .flash_io0(flash_io0), + .flash_io1(flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("vga_clock.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule diff --git a/verilog/dv/caravel/user_proj_example/ws2812/Makefile b/verilog/dv/caravel/user_proj_example/ws2812/Makefile new file mode 100644 index 00000000..3a007484 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/ws2812/Makefile @@ -0,0 +1,42 @@ +FIRMWARE_PATH = ../.. +RTL_PATH = ../../../../rtl +IP_PATH = ../../../../ip +#MP_PATH = ../../../../rtl/multi_project_harness +BEHAVIOURAL_MODELS = ../../ + +TOOLCHAIN_PREFIX?=/opt/riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf- +PDK_PATH?=~/work/asic-workshop/pdks/sky130A + +.SUFFIXES: + +PATTERN = ws2812 + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex + iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \ + -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \ + $< -o $@ + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s + $(TOOLCHAIN_PREFIX)gcc -mabi=ilp32 -march=rv32imc -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + $(TOOLCHAIN_PREFIX)objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + $(TOOLCHAIN_PREFIX)objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all diff --git a/verilog/dv/caravel/user_proj_example/ws2812/ws2812.c b/verilog/dv/caravel/user_proj_example/ws2812/ws2812.c new file mode 100644 index 00000000..b04ef429 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/ws2812/ws2812.c @@ -0,0 +1,68 @@ +#include "../../defs.h" + +/* + IO Test: + - Configures MPRJ pins + - Observes counter value through the LED digits +*/ +#define reg_mprj_oeb0 (*(volatile uint32_t*)0x30000004) +#define reg_mprj_oeb1 (*(volatile uint32_t*)0x30000008) + +#define reg_mprj_ws2812 (*(volatile uint32_t*)0x30000100) + +void main() +{ + /* + IO Control Registers + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 3-bits | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | + + Output: 0000_0110_0000_1110 (0x1808) = GPIO_MODE_USER_STD_OUTPUT + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | + + Output: 0000_0110_0000_1111 (0x1809) = GPIO_MODE_MGNT_STD_OUTPUT + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | + + + Input: 0000_0001_0000_1111 (0x0402) = GPIO_MODE_USER_STD_INPUT_NOPULL + | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | + | 001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | + + */ + + /* + Inputs + + system clock + system reset + + Outputs + + 8 data for ws2812 + */ + + reg_mprj_io_8 = GPIO_MODE_USER_STD_OUTPUT; + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + // change to project 1 + reg_mprj_slave = 1; + // all outputs enabled + reg_mprj_oeb0 = 0; + + // use logic analyser to reset the design + reg_la0_ena = 0x00000000; // bits 31:0 outputs + reg_la0_data = 0x00000001; // reset high is on bit 0 + reg_la0_data = 0x00000000; // low + + // update led 7 + uint8_t led_num = 7; + uint8_t r = 255; + uint8_t g = 10; + uint8_t b = 100; + reg_mprj_ws2812 = (led_num << 24) + (r << 16) + (g << 8) + b; +} diff --git a/verilog/dv/caravel/user_proj_example/ws2812/ws2812.gtkw b/verilog/dv/caravel/user_proj_example/ws2812/ws2812.gtkw new file mode 100644 index 00000000..65cbad90 --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/ws2812/ws2812.gtkw @@ -0,0 +1,250 @@ +[*] +[*] GTKWave Analyzer v3.3.108 (w)1999-2020 BSI +[*] Fri Nov 20 10:34:36 2020 +[*] +[dumpfile] "/home/matt/work/asic-workshop/caravel/verilog/dv/caravel/user_proj_example/ws2812/ws2812.vcd" +[dumpfile_mtime] "Fri Nov 20 10:32:17 2020" +[dumpfile_size] 192131563 +[savefile] "/home/matt/work/asic-workshop/caravel/verilog/dv/caravel/user_proj_example/ws2812/ws2812.gtkw" +[timestart] 0 +[size] 2488 1529 +[pos] -1 -1 +*-26.000000 138637500 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] ws2812_tb. +[treeopen] ws2812_tb.uut. +[treeopen] ws2812_tb.uut.gpio_control_bidir[0].gpio_in_buf. +[treeopen] ws2812_tb.uut.gpio_control_in[4].gpio_in_buf. +[treeopen] ws2812_tb.uut.gpio_control_in[4].gpio_logic_high. +[treeopen] ws2812_tb.uut.mprj. +[treeopen] ws2812_tb.uut.mprj.mprj. +[treeopen] ws2812_tb.uut.mprj.mprj.proj_0. +[treeopen] ws2812_tb.uut.mprj.mprj.proj_2. +[treeopen] ws2812_tb.uut.soc. +[treeopen] ws2812_tb.uut.soc.housekeeping. +[treeopen] ws2812_tb.uut.soc.soc. +[treeopen] ws2812_tb.uut.soc.soc.cpu. +[treeopen] ws2812_tb.uut.soc.soc.cpu.picorv32_core. +[treeopen] ws2812_tb.uut.soc.soc.gpio_wb. +[treeopen] ws2812_tb.uut.soc.soc.mprj_ctrl. +[sst_width] 719 +[signals_width] 682 +[sst_expanded] 1 +[sst_vpaned_height] 862 +@28 +ws2812_tb.clock +ws2812_tb.RSTB +@200 +- +@800200 +-wbs +@28 +ws2812_tb.uut.mprj.mprj.wb_rst_i +ws2812_tb.uut.mprj.mprj.wb_clk_i +ws2812_tb.uut.mprj.mprj.wbs_ack_o +@22 +ws2812_tb.uut.mprj.mprj.wbs_adr_i[31:0] +@28 +ws2812_tb.uut.mprj.mprj.wbs_cyc_i +@24 +ws2812_tb.uut.mprj.mprj.wbs_dat_i[31:0] +@22 +ws2812_tb.uut.mprj.mprj.wbs_dat_o[31:0] +ws2812_tb.uut.mprj.mprj.wbs_sel_i[3:0] +@28 +ws2812_tb.uut.mprj.mprj.wbs_stb_i +ws2812_tb.uut.mprj.mprj.wbs_we_i +ws2812_tb.uut.mprj.mprj.valid +@24 +ws2812_tb.uut.mprj.mprj.wstrb[3:0] +@1000200 +-wbs +@800200 +-multi proj control +@28 +ws2812_tb.uut.soc.soc.mprj_ctrl.mprj_ctrl.xfer_ctrl +@1000200 +-multi proj control +@800200 +-la +@22 +ws2812_tb.uut.mprj.mprj.la_data_in[127:0] +ws2812_tb.uut.mprj.mprj.la_data_out[127:0] +ws2812_tb.uut.mprj.mprj.la_oen[127:0] +@1000200 +-la +@22 +ws2812_tb.uut.soc.soc.cpu.picorv32_core.next_insn_opcode[31:0] +@200 +- +@800200 +-multi project +@22 +ws2812_tb.uut.mprj.mprj.active_project[7:0] +@28 +ws2812_tb.uut.mprj.mprj.wb_rst_i +@c00022 +ws2812_tb.uut.mprj.io_in[37:0] +@28 +(0)ws2812_tb.uut.mprj.io_in[37:0] +(1)ws2812_tb.uut.mprj.io_in[37:0] +(2)ws2812_tb.uut.mprj.io_in[37:0] +(3)ws2812_tb.uut.mprj.io_in[37:0] +(4)ws2812_tb.uut.mprj.io_in[37:0] +(5)ws2812_tb.uut.mprj.io_in[37:0] +(6)ws2812_tb.uut.mprj.io_in[37:0] +(7)ws2812_tb.uut.mprj.io_in[37:0] +(8)ws2812_tb.uut.mprj.io_in[37:0] +(9)ws2812_tb.uut.mprj.io_in[37:0] +(10)ws2812_tb.uut.mprj.io_in[37:0] +(11)ws2812_tb.uut.mprj.io_in[37:0] +(12)ws2812_tb.uut.mprj.io_in[37:0] +(13)ws2812_tb.uut.mprj.io_in[37:0] +(14)ws2812_tb.uut.mprj.io_in[37:0] +(15)ws2812_tb.uut.mprj.io_in[37:0] +(16)ws2812_tb.uut.mprj.io_in[37:0] +(17)ws2812_tb.uut.mprj.io_in[37:0] +(18)ws2812_tb.uut.mprj.io_in[37:0] +(19)ws2812_tb.uut.mprj.io_in[37:0] +(20)ws2812_tb.uut.mprj.io_in[37:0] +(21)ws2812_tb.uut.mprj.io_in[37:0] +(22)ws2812_tb.uut.mprj.io_in[37:0] +(23)ws2812_tb.uut.mprj.io_in[37:0] +(24)ws2812_tb.uut.mprj.io_in[37:0] +(25)ws2812_tb.uut.mprj.io_in[37:0] +(26)ws2812_tb.uut.mprj.io_in[37:0] +(27)ws2812_tb.uut.mprj.io_in[37:0] +(28)ws2812_tb.uut.mprj.io_in[37:0] +(29)ws2812_tb.uut.mprj.io_in[37:0] +(30)ws2812_tb.uut.mprj.io_in[37:0] +(31)ws2812_tb.uut.mprj.io_in[37:0] +(32)ws2812_tb.uut.mprj.io_in[37:0] +(33)ws2812_tb.uut.mprj.io_in[37:0] +(34)ws2812_tb.uut.mprj.io_in[37:0] +(35)ws2812_tb.uut.mprj.io_in[37:0] +(36)ws2812_tb.uut.mprj.io_in[37:0] +(37)ws2812_tb.uut.mprj.io_in[37:0] +@1401200 +-group_end +@c00022 +ws2812_tb.uut.mprj.mprj.io_out[37:0] +@28 +(0)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(1)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(2)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(3)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(4)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(5)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(6)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(7)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(8)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(9)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(10)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(11)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(12)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(13)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(14)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(15)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(16)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(17)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(18)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(19)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(20)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(21)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(22)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(23)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(24)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(25)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(26)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(27)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(28)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(29)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(30)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(31)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(32)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(33)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(34)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(35)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(36)ws2812_tb.uut.mprj.mprj.io_out[37:0] +(37)ws2812_tb.uut.mprj.mprj.io_out[37:0] +@1401200 +-group_end +@1000200 +-multi project +@800022 +ws2812_tb.mprj_io[37:0] +@28 +(0)ws2812_tb.mprj_io[37:0] +(1)ws2812_tb.mprj_io[37:0] +(2)ws2812_tb.mprj_io[37:0] +(3)ws2812_tb.mprj_io[37:0] +(4)ws2812_tb.mprj_io[37:0] +(5)ws2812_tb.mprj_io[37:0] +(6)ws2812_tb.mprj_io[37:0] +(7)ws2812_tb.mprj_io[37:0] +(8)ws2812_tb.mprj_io[37:0] +(9)ws2812_tb.mprj_io[37:0] +(10)ws2812_tb.mprj_io[37:0] +(11)ws2812_tb.mprj_io[37:0] +(12)ws2812_tb.mprj_io[37:0] +(13)ws2812_tb.mprj_io[37:0] +(14)ws2812_tb.mprj_io[37:0] +(15)ws2812_tb.mprj_io[37:0] +(16)ws2812_tb.mprj_io[37:0] +(17)ws2812_tb.mprj_io[37:0] +(18)ws2812_tb.mprj_io[37:0] +(19)ws2812_tb.mprj_io[37:0] +(20)ws2812_tb.mprj_io[37:0] +(21)ws2812_tb.mprj_io[37:0] +(22)ws2812_tb.mprj_io[37:0] +(23)ws2812_tb.mprj_io[37:0] +(24)ws2812_tb.mprj_io[37:0] +(25)ws2812_tb.mprj_io[37:0] +(26)ws2812_tb.mprj_io[37:0] +(27)ws2812_tb.mprj_io[37:0] +(28)ws2812_tb.mprj_io[37:0] +(29)ws2812_tb.mprj_io[37:0] +(30)ws2812_tb.mprj_io[37:0] +(31)ws2812_tb.mprj_io[37:0] +(32)ws2812_tb.mprj_io[37:0] +(33)ws2812_tb.mprj_io[37:0] +(34)ws2812_tb.mprj_io[37:0] +(35)ws2812_tb.mprj_io[37:0] +(36)ws2812_tb.mprj_io[37:0] +(37)ws2812_tb.mprj_io[37:0] +@1001200 +-group_end +@c00200 +-seven seg +@28 +ws2812_tb.uut.mprj.mprj.proj_0.clk +@22 +ws2812_tb.uut.mprj.mprj.proj_0.second_counter[23:0] +@24 +ws2812_tb.uut.mprj.mprj.proj_0.compare[23:0] +@28 +ws2812_tb.uut.mprj.mprj.proj_0.reset +@800022 +ws2812_tb.uut.mprj.mprj.proj_0.digit[3:0] +@28 +(0)ws2812_tb.uut.mprj.mprj.proj_0.digit[3:0] +(1)ws2812_tb.uut.mprj.mprj.proj_0.digit[3:0] +(2)ws2812_tb.uut.mprj.mprj.proj_0.digit[3:0] +(3)ws2812_tb.uut.mprj.mprj.proj_0.digit[3:0] +@22 +ws2812_tb.uut.mprj.mprj.proj_0.led_out[6:0] +@1001200 +-group_end +@1401200 +-seven seg +@29 +ws2812_tb.uut.mprj.mprj.proj_1.reset +@800200 +-ws2812 +@24 +ws2812_tb.uut.mprj.mprj.proj_1.bit_counter[11:0] +ws2812_tb.uut.mprj.mprj.proj_1.rgb_counter[4:0] +ws2812_tb.uut.mprj.mprj.proj_1.led_counter[2:0] +@1000200 +-ws2812 +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/verilog/dv/caravel/user_proj_example/ws2812/ws2812_tb.v b/verilog/dv/caravel/user_proj_example/ws2812/ws2812_tb.v new file mode 100644 index 00000000..2f12b51c --- /dev/null +++ b/verilog/dv/caravel/user_proj_example/ws2812/ws2812_tb.v @@ -0,0 +1,115 @@ +`default_nettype none + +`timescale 1 ns / 1 ps + +`include "caravel.v" +`include "spiflash.v" + +module ws2812_tb; + reg clock; + reg RSTB; + reg power1, power2; + reg power3, power4; + + wire gpio; + wire [37:0] mprj_io; + + // 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 #12.5 clock <= (clock === 1'b0); + + initial begin + clock = 0; + end + + + initial begin + $dumpfile("ws2812.vcd"); + $dumpvars(0, ws2812_tb); + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (15) begin + repeat (1000) @(posedge clock); + // $display("+1000 cycles"); + end + $display("%c[1;31m",27); + $display ("Monitor: Timeout, Test Mega-Project IO Ports (RTL) Failed"); + $display("%c[0m",27); + $finish; + end + + initial begin + RSTB <= 1'b0; + #2000; + RSTB <= 1'b1; // Release reset + end + + initial begin // Power-up sequence + power1 <= 1'b0; + power2 <= 1'b0; + power3 <= 1'b0; + power4 <= 1'b0; + #200; + power1 <= 1'b1; + #200; + power2 <= 1'b1; + #200; + power3 <= 1'b1; + #200; + power4 <= 1'b1; + end + + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + + wire VDD1V8; + wire VDD3V3; + wire VSS; + + assign VDD3V3 = power1; + assign VDD1V8 = power2; + wire USER_VDD3V3 = power3; + wire USER_VDD1V8 = power4; + assign VSS = 1'b0; + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (USER_VDD3V3), + .vdda2 (USER_VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (USER_VDD1V8), + .vccd2 (USER_VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clock), + .gpio (gpio), + .mprj_io (mprj_io), + .flash_csb(flash_csb), + .flash_clk(flash_clk), + .flash_io0(flash_io0), + .flash_io1(flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("ws2812.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule diff --git a/verilog/rtl/caravel.v b/verilog/rtl/caravel.v index 95ca327d..1c04f3b4 100644 --- a/verilog/rtl/caravel.v +++ b/verilog/rtl/caravel.v @@ -51,7 +51,7 @@ /*------------------------------*/ /* Include user project here */ /*------------------------------*/ -`include "user_proj_example.v" +`include "multi_project_harness/includes.v" // `ifdef USE_OPENRAM // `include "sram_1rw1r_32_256_8_sky130.v" diff --git a/verilog/rtl/multi_project_harness b/verilog/rtl/multi_project_harness new file mode 160000 index 00000000..7cbb5a63 --- /dev/null +++ b/verilog/rtl/multi_project_harness @@ -0,0 +1 @@ +Subproject commit 7cbb5a632675e8c28a86d177f8e2075fdf64da80 diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v index b5460f50..c7ef2caa 100644 --- a/verilog/rtl/user_project_wrapper.v +++ b/verilog/rtl/user_project_wrapper.v @@ -62,7 +62,7 @@ module user_project_wrapper #( /* User project is instantiated here */ /*--------------------------------------*/ - user_proj_example mprj ( + multi_project_harness mprj ( .vdda1(vdda1), // User area 1 3.3V power .vdda2(vdda2), // User area 2 3.3V power .vssa1(vssa1), // User area 1 analog ground