updated readme, info and user_project_wrapper.v
diff --git a/README.md b/README.md
index 15727b1..5137b51 100644
--- a/README.md
+++ b/README.md
@@ -1,149 +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
--->
-# CIIC Harness
+# Multi Project Harness - mpw-one-b
-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/multi-project-harness/tree/separate-macro added to /verilog/rtl/
+* user_project_wrapper is then adjusted to instantiate all the submodules.
-<p align="center">
-<img src="/doc/ciic_harness.png" width="75%" height="75%">
-</p>
+![multi project harness](doc/multi-project-harness.png)
+# Important!
-## Getting Started:
+* If you want to actually build the wrapper, you need to checkout the release branch.
+* This branch is just used to rebuild caravel.gds with 'make ship'
-* For information on tooling and versioning, please refer to [this][1].
+# Tests
-Start by cloning the repo and uncompressing the files.
-```bash
-git clone https://github.com/efabless/caravel.git
-cd caravel
-make uncompress
-```
+* Full system tests for each sub project: verilog/dv/caravel/user_proj_example
+* Separate projects: run make sim in root directory of multi_project_harness: https://github.com/mattvenn/multi-project-harness/blob/separate-macro/test_harness.py
-Then you need to install the open_pdks prerequisite:
- - [Magic VLSI Layout Tool](http://opencircuitdesign.com/magic/index.html) is needed to run open_pdks -- version >= 8.3.60*
+# OpenLane Configs
- > \* Note: You can avoid the need for the magic prerequisite by using the openlane docker to do the installation step in open_pdks. This could be done by cloning [openlane](https://github.com/efabless/openlane/tree/master) and following the instructions given there to use the Makefile.
+All the OpenLane configs for each project are here: https://github.com/mattvenn/multi-project-harness/tree/main/openlane/macroconfig
-Install the required version of the PDK by running the following commands:
+# Submodules
-```bash
-export PDK_ROOT=<The place where you want to install the pdk>
-make pdk
-```
+## seven-segment-seconds
-Then, you can learn more about the caravel chip by watching these video:
-- Caravel User Project Features -- https://youtu.be/zJhnmilXGPo
-- Aboard Caravel -- How to put your design on Caravel? -- https://youtu.be/9QV8SDelURk
-- Things to Clarify About Caravel -- What versions to use with Caravel? -- https://youtu.be/-LZ522mxXMw
- - You could only use openlane:rc6
- - Make sure you have the commit hashes provided here inside the [Makefile](./Makefile)
-## Aboard Caravel:
+description: shows seconds on a seven segment LED display.
-Your area is the full user_project_wrapper, so feel free to add your project there or create a differnt macro and harden it seperately then insert it into the user_project_wrapper. For example, if your design is analog or you're using a different tool other than OpenLANE.
+author: Matt Venn
-If you will use OpenLANE to harden your design, go through the instructions in this [README.md][0].
+url: https://github.com/mattvenn/seven-segment-seconds
-You must copy your synthesized gate-level-netlist for `user_project_wrapper` to `verilog/gl/` and overwrite `user_project_wrapper.v`. Otherwise, you can point to it in [info.yaml](info.yaml).
+## ws2812
-> Note: If you're using openlane to harden your design, this should happen automatically.
+description: ws2812 LED interface for 8 addressable LEDs
-Then, you will need to put your design aboard the Caravel chip. Make sure you have the following:
+author: Matt Venn
-- [Magic VLSI Layout Tool](http://opencircuitdesign.com/magic/index.html) installed on your machine. We may provide a Dockerized version later.\*
-- You have your user_project_wrapper.gds under `./gds/` in the Caravel directory.
+url: https://github.com/mattvenn/ws2812-core.git
- > \* **Note:** You can avoid the need for the magic prerequisite by using the openlane docker to run the make step. This [section](#running-make-using-openlane-magic) shows how.
+## vga-clock
-Run the following command:
+description: show the time on a VGA panel
-```bash
-export PDK_ROOT=<The place where the installed pdk resides. The same PDK_ROOT used in the pdk installation step>
-make
-```
+author: Matt Venn
-This should merge the GDSes using magic and you'll end up with your version of `./gds/caravel.gds`. You should expect ~90 magic DRC violations with the current "development" state of caravel.
+url: https://github.com/mattvenn/vga-clock.git
-## Running Make using OpenLANE Magic
+## spinet
-To use the magic installed inside Openlane to complete the final GDS streaming out step, export the following:
+description: multi node computer controller
-```bash
-export PDK_ROOT=<The location where the pdk is installed>
-export OPENLANE_ROOT=<the absolute path to the openlane directory cloned or to be cloned>
-export IMAGE_NAME=<the openlane image name installed on your machine. Preferably openlane:rc6>
-export CARAVEL_PATH=$(pwd)
-```
+author: Richard Miller
-Then, mount the docker:
+url: https://github.com/millerresearch/spinet
-```bash
-docker run -it -v $CARAVEL_PATH:$CARAVEL_PATH -v $OPENLANE_ROOT:/openLANE_flow -v $PDK_ROOT:$PDK_ROOT -e CARAVEL_PATH=$CARAVEL_PATH -e PDK_ROOT=$PDK_ROOT -u $(id -u $USER):$(id -g $USER) $IMAGE_NAME
-```
+## asicfreq
-Finally, once inside the docker run the following commands:
-```bash
-cd $CARAVEL_PATH
-make
-exit
-```
+description: Frequency counter
-This should merge the GDSes using magic and you'll end up with your version of `./gds/caravel.gds`. You should expect ~90 magic DRC violations with the current "development" state of caravel.
+author: Michael Betz & Vamsi Vytla
+url: https://git.sr.ht/~jersey99/asicfreq
-## IMPORTANT:
+## ASIC_watch
-Please make sure to run `make compress` before commiting anything to your repository. Avoid having 2 versions of the gds/user_project_wrapper.gds or gds/caravel.gds one compressed and the other not compressed.
+description: 4 digit 7 segment clock
-## Required Directory Structure
+author: Guillem Cabo
-- ./gds/ : includes all the gds files used or produced from the project.
-- ./def/ : includes all the def files used or produced from the project.
-- ./lef/ : includes all the lef files used or produced from the project.
-- ./mag/ : includes all the mag files used or produced from the project.
-- ./maglef/ : includes all the maglef files used or produced from the project.
-- ./spi/lvs/ : includes all the maglef files used or produced from the project.
-- ./verilog/dv/ : includes all the simulation test benches and how to run them.
-- ./verilog/gl/ : includes all the synthesized/elaborated netlists.
-- ./verilog/rtl/ : includes all the Verilog RTLs and source files.
-- ./openlane/`<macro>`/ : includes all configuration files used to run openlane on your project.
-- info.yaml: includes all the info required in [this example](info.yaml). Please make sure that you are pointing to an elaborated caravel netlist as well as a synthesized gate-level-netlist for the user_project_wrapper
+url: https://github.com/GuillemCabo/ASIC_watch.git
-## Managment SoC
-The managment SoC runs firmware that can be used to:
-- Configure User Project I/O pads
-- Observe and control User Project signals (through on-chip logic analyzer probes)
-- Control the User Project power supply
+## TPM2137
-The memory map of the management SoC can be found [here](verilog/rtl/README)
+description: Reverse Engineering challenge
-## User 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 user project](/verilog/rtl/user_proj_example.v) that contains a binary 32-bit up counter. </br>
+author: Q3K
-<p align="center">
-<img src="/doc/counter_32.png" width="50%" height="50%">
-</p>
+url: https://github.com/mattvenn/TPM2137
-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 User 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 User 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 User 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).
+## mm2hdmi
-[0]: openlane/README.md
-[1]: mpw-one-b.md
+description: HDMI driver
+
+author: Aleksandar Pajkanovic
+
+url: https://github.com/nanoluka/mm2hdmi.git
diff --git a/doc/multi-project-harness.png b/doc/multi-project-harness.png
new file mode 100644
index 0000000..4e6967f
--- /dev/null
+++ b/doc/multi-project-harness.png
Binary files differ
diff --git a/info.yaml b/info.yaml
index 685ee5e..fa59949 100644
--- a/info.yaml
+++ b/info.yaml
@@ -1,13 +1,13 @@
---
project:
- description: "A template SoC for Google sponsored Open MPW shuttles for SKY130."
+ description: "multi project harness"
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/caravel-mph"
+ organization: "Matt Venn"
+ organization_url: ""
+ owner: "Matt Venn"
process: "SKY130"
- project_name: "Caravel"
+ project_name: "multi project harness"
tags:
- "Open MPW"
- "Test Harness"
@@ -15,4 +15,4 @@
top_level_netlist: "verilog/gl/caravel.v"
user_level_netlist: "verilog/gl/user_project_wrapper.v"
version: "1.00"
- cover_image: "doc/ciic_harness.png"
+ cover_image: "doc/multi-project-harness.png"
diff --git a/verilog/dv/caravel/user_proj_example/.gitignore b/verilog/dv/caravel/user_proj_example/.gitignore
new file mode 100644
index 0000000..2e7e861
--- /dev/null
+++ b/verilog/dv/caravel/user_proj_example/.gitignore
@@ -0,0 +1,2 @@
+*vcd
+*hex
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 0000000..323d860
--- /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 0000000..9951781
--- /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 0000000..2a55901
--- /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 -DSIM -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/Makefile b/verilog/dv/caravel/user_proj_example/Makefile
index 7e37e02..6b5248c 100644
--- a/verilog/dv/caravel/user_proj_example/Makefile
+++ b/verilog/dv/caravel/user_proj_example/Makefile
@@ -1,19 +1,3 @@
-# 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
-
# ---- Test patterns for project striVe ----
.SUFFIXES:
diff --git a/verilog/dv/caravel/user_proj_example/README.md b/verilog/dv/caravel/user_proj_example/README.md
index 503b8f4..244df05 100644
--- a/verilog/dv/caravel/user_proj_example/README.md
+++ b/verilog/dv/caravel/user_proj_example/README.md
@@ -1,20 +1,3 @@
-<!---
-# 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
--->
# Mega-Project Counter Tests
The directory includes three tests for the counter mega-project example:
diff --git a/verilog/dv/caravel/user_proj_example/asicfreq/Makefile b/verilog/dv/caravel/user_proj_example/asicfreq/Makefile
new file mode 100644
index 0000000..7b5d620
--- /dev/null
+++ b/verilog/dv/caravel/user_proj_example/asicfreq/Makefile
@@ -0,0 +1,44 @@
+FIRMWARE_PATH = ../..
+RTL_PATH = ../../../../rtl
+IP_PATH = ../../../../ip
+BEHAVIOURAL_MODELS = ../../
+
+TOOLCHAIN_PREFIX?=riscv32-unknown-elf-
+PDK_PATH?=$(PDK_ROOT)/sky130A
+
+.SUFFIXES:
+
+PATTERN = asicfreq
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DSIM -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \
+ -I $(PDK_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 $<
+
+%.lst: %.elf
+ $(TOOLCHAIN_PREFIX)objdump -d $< > $@
+
+%.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/asicfreq/asicfreq.c b/verilog/dv/caravel/user_proj_example/asicfreq/asicfreq.c
new file mode 100644
index 0000000..85d8e25
--- /dev/null
+++ b/verilog/dv/caravel/user_proj_example/asicfreq/asicfreq.c
@@ -0,0 +1,70 @@
+#include "../../defs.h"
+
+// Test asicfreq frequency counter and 7-segment display interface
+
+#define reg_mprj_address_oeb0 (*(volatile uint32_t*)0x30000004)
+#define reg_mprj_address_oeb1 (*(volatile uint32_t*)0x30000008)
+
+#define reg_mprj_asicfreq_uart_div (*(volatile uint32_t*)0x30000400)
+// write UART clock divider (min. value = 4),
+
+#define reg_mprj_asicfreq_meas_period (*(volatile uint32_t*)0x30000404)
+// write frequency counter update period [sys_clks]
+
+#define reg_mprj_asicfreq_7seg_mode (*(volatile uint32_t*)0x30000408)
+// set 7-segment display mode,
+// 0: show meas. freq., 1: show wishbone value
+
+#define reg_mprj_asicfreq_7seg_digit0 (*(volatile uint32_t*)0x3000040C)
+// set 7-segment display value:
+// digit7 ... digit0 (4 bit each)
+
+#define reg_mprj_asicfreq_7seg_digit1 (*(volatile uint32_t*)0x30000410)
+// set 7-segment display value:
+// digit8
+
+#define reg_mprj_asicfreq_7seg_decs (*(volatile uint32_t*)0x30000414)
+// set 7-segment decimal points:
+// dec_point8 ... dec_point0 (1 bit each)
+
+#define reg_mprj_asicfreq_cnt (*(volatile uint32_t*)0x30000418)
+// read number of SUT edges over `meas_period`
+
+#define reg_mprj_asicfreq_cnt_cont (*(volatile uint32_t*)0x3000041C)
+// read number of SUT edges since reset
+
+int main()
+{
+ // Setup GPIOs
+ reg_mprj_io_6 = GPIO_MODE_USER_STD_OUTPUT;
+ volatile uint32_t *io = ®_mprj_io_8;
+ for (unsigned i=0; i<17; i++)
+ io[i] = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_25 = GPIO_MODE_USER_STD_INPUT_NOPULL;
+
+ // Apply configuration
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ // enable MPH outputs (all expect mprj_io[25], which is the SUT)
+ reg_mprj_address_oeb0 = (1 << 25);
+
+ // change to project 4
+ reg_mprj_slave = 4;
+
+ // 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
+
+ // write to 7 segment
+ reg_mprj_asicfreq_7seg_mode = 1;
+ reg_mprj_asicfreq_7seg_digit0 = 0xDEADBEEF;
+
+ // nonsense statement, to demonstrate wb reading works
+ // checked by testbench
+ reg_mprj_asicfreq_meas_period = reg_mprj_asicfreq_cnt_cont;
+
+ return 0;
+}
+
diff --git a/verilog/dv/caravel/user_proj_example/asicfreq/asicfreq.gtkw b/verilog/dv/caravel/user_proj_example/asicfreq/asicfreq.gtkw
new file mode 100644
index 0000000..9ffbc64
--- /dev/null
+++ b/verilog/dv/caravel/user_proj_example/asicfreq/asicfreq.gtkw
@@ -0,0 +1,86 @@
+[dumpfile] "asicfreq.vcd"
+[timestart] 520440000
+[size] 2044 1108
+[pos] -1 -1
+*-22.000000 548687500 -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] asicfreq_tb.
+[treeopen] asicfreq_tb.uut.
+[treeopen] asicfreq_tb.uut.mprj.
+[treeopen] asicfreq_tb.uut.mprj.mprj.
+[treeopen] asicfreq_tb.uut.mprj.mprj.proj_4.
+[treeopen] asicfreq_tb.uut.soc.
+[treeopen] asicfreq_tb.uut.soc.soc.
+[treeopen] asicfreq_tb.uut.soc.soc.cpu.
+[treeopen] asicfreq_tb.uut.soc.soc.cpu.picorv32_core.
+[sst_width] 285
+[signals_width] 363
+[sst_expanded] 1
+[sst_vpaned_height] 432
+@800200
+-CPU
+@22
+asicfreq_tb.uut.soc.soc.cpu.picorv32_core.dbg_insn_addr[31:0]
+asicfreq_tb.uut.soc.soc.cpu.picorv32_core.dbg_mem_addr[31:0]
+@28
+asicfreq_tb.uut.soc.soc.cpu.picorv32_core.dbg_mem_instr
+@22
+asicfreq_tb.uut.soc.soc.cpu.picorv32_core.dbg_mem_rdata[31:0]
+@28
+asicfreq_tb.uut.soc.soc.cpu.picorv32_core.dbg_mem_ready
+asicfreq_tb.uut.soc.soc.cpu.picorv32_core.dbg_mem_valid
+@22
+asicfreq_tb.uut.soc.soc.cpu.picorv32_core.dbg_mem_wdata[31:0]
+asicfreq_tb.uut.soc.soc.cpu.picorv32_core.dbg_mem_wstrb[3:0]
+@1000200
+-CPU
+@22
+asicfreq_tb.uut.mprj.mprj.active_project[7:0]
+@800200
+-proj_4
+@28
+asicfreq_tb.uut.mprj.mprj.proj_4.rst
+@200
+-
+@29
+asicfreq_tb.uut.mprj.mprj.proj_4.strobe
+@22
+asicfreq_tb.uut.mprj.mprj.proj_4.addr[3:0]
+asicfreq_tb.uut.mprj.mprj.proj_4.value[31:0]
+@200
+-
+@22
+asicfreq_tb.uut.mprj.mprj.proj_4.oc[31:0]
+asicfreq_tb.uut.mprj.mprj.proj_4.o[31:0]
+asicfreq_tb.uut.mprj.mprj.proj_4.f_meter_period[31:0]
+asicfreq_tb.uut.mprj.mprj.proj_4.f_meter.period_counter[31:0]
+@200
+-
+@22
+asicfreq_tb.uut.mprj.mprj.proj_4.col_drvs[8:0]
+@28
+asicfreq_tb.uut.mprj.mprj.proj_4.seg_man_mode
+@22
+asicfreq_tb.uut.mprj.mprj.proj_4.seg_man_value[35:0]
+@c00022
+asicfreq_tb.uut.mprj.mprj.proj_4.seven_seg_seg_drvs[7:0]
+@28
+(0)asicfreq_tb.uut.mprj.mprj.proj_4.seven_seg_seg_drvs[7:0]
+(1)asicfreq_tb.uut.mprj.mprj.proj_4.seven_seg_seg_drvs[7:0]
+(2)asicfreq_tb.uut.mprj.mprj.proj_4.seven_seg_seg_drvs[7:0]
+(3)asicfreq_tb.uut.mprj.mprj.proj_4.seven_seg_seg_drvs[7:0]
+(4)asicfreq_tb.uut.mprj.mprj.proj_4.seven_seg_seg_drvs[7:0]
+(5)asicfreq_tb.uut.mprj.mprj.proj_4.seven_seg_seg_drvs[7:0]
+(6)asicfreq_tb.uut.mprj.mprj.proj_4.seven_seg_seg_drvs[7:0]
+(7)asicfreq_tb.uut.mprj.mprj.proj_4.seven_seg_seg_drvs[7:0]
+@1401200
+-group_end
+@200
+-
+@820
+asicfreq_tb.uut.mprj.mprj.proj_4.serial.uart.tx_data[7:0]
+@28
+asicfreq_tb.uut.mprj.mprj.proj_4.serial_tx_out
+@1000200
+-proj_4
+[pattern_trace] 1
+[pattern_trace] 0
diff --git a/verilog/dv/caravel/user_proj_example/asicfreq/asicfreq_tb.v b/verilog/dv/caravel/user_proj_example/asicfreq/asicfreq_tb.v
new file mode 100644
index 0000000..932500a
--- /dev/null
+++ b/verilog/dv/caravel/user_proj_example/asicfreq/asicfreq_tb.v
@@ -0,0 +1,130 @@
+`default_nettype none
+
+`timescale 1 ns / 1 ps
+
+`include "caravel.v"
+`include "spiflash.v"
+
+module asicfreq_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("asicfreq.vcd");
+ $dumpvars(0, asicfreq_tb);
+
+ // Repeat cycles of 1000 clock edges as needed to complete testbench
+ repeat (44) 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);
+ $stop;
+ end
+
+ // apply a clock to the signal under test (SUT) pin
+ assign mprj_io[25] = clock;
+
+ // Check the last statement in the C program
+ always @(posedge clock) begin
+ if (
+ uut.mprj.mprj.proj_4.strobe &&
+ uut.mprj.mprj.proj_4.addr == 32'h1 &&
+ uut.mprj.mprj.proj_4.value >= 32'h300
+ // uut.mprj.mprj.proj_4.value == (uut.mprj.mprj.proj_4.oc - 32'h8)
+ ) begin
+ $display("PASS");
+ $finish;
+ end
+ 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("asicfreq.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/io_ports/io_ports.c b/verilog/dv/caravel/user_proj_example/io_ports/io_ports.c
index a159f0a..f6a829d 100644
--- a/verilog/dv/caravel/user_proj_example/io_ports/io_ports.c
+++ b/verilog/dv/caravel/user_proj_example/io_ports/io_ports.c
@@ -1,20 +1,3 @@
-/*
- * 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"
/*
diff --git a/verilog/dv/caravel/user_proj_example/io_ports/io_ports_tb.v b/verilog/dv/caravel/user_proj_example/io_ports/io_ports_tb.v
index c680a0b..63b7c93 100644
--- a/verilog/dv/caravel/user_proj_example/io_ports/io_ports_tb.v
+++ b/verilog/dv/caravel/user_proj_example/io_ports/io_ports_tb.v
@@ -1,18 +1,3 @@
-// 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
diff --git a/verilog/dv/caravel/user_proj_example/la_test1/Makefile b/verilog/dv/caravel/user_proj_example/la_test1/Makefile
index 968a74b..19fd4a1 100644
--- a/verilog/dv/caravel/user_proj_example/la_test1/Makefile
+++ b/verilog/dv/caravel/user_proj_example/la_test1/Makefile
@@ -1,19 +1,3 @@
-# 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 = ../..
RTL_PATH = ../../../../rtl
IP_PATH = ../../../../ip
@@ -23,8 +7,6 @@
GCC_PREFIX?=riscv32-unknown-elf
PDK_PATH?=/ef/tech/SW/sky130A
-SIM?=RTL
-
.SUFFIXES:
PATTERN = la_test1
@@ -34,15 +16,9 @@
hex: ${PATTERN:=.hex}
%.vvp: %_tb.v %.hex
-ifeq ($(SIM),RTL)
- iverilog -DFUNCTIONAL -DSIM -I $(BEHAVIOURAL_MODELS) \
+ iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \
-I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \
- $< -o $@
-else
- iverilog -DFUNCTIONAL -DSIM -DGL -I $(BEHAVIOURAL_MODELS) \
- -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \
- $< -o $@
-endif
+ -o $@ $<
%.vcd: %.vvp
vvp $<
diff --git a/verilog/dv/caravel/user_proj_example/la_test1/la_test1.c b/verilog/dv/caravel/user_proj_example/la_test1/la_test1.c
index 9759ed7..a564a9f 100644
--- a/verilog/dv/caravel/user_proj_example/la_test1/la_test1.c
+++ b/verilog/dv/caravel/user_proj_example/la_test1/la_test1.c
@@ -1,20 +1,3 @@
-/*
- * 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"
#include "../../stub.c"
diff --git a/verilog/dv/caravel/user_proj_example/la_test1/la_test1_tb.v b/verilog/dv/caravel/user_proj_example/la_test1/la_test1_tb.v
index 210098f..ed13c40 100644
--- a/verilog/dv/caravel/user_proj_example/la_test1/la_test1_tb.v
+++ b/verilog/dv/caravel/user_proj_example/la_test1/la_test1_tb.v
@@ -1,18 +1,3 @@
-// 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
diff --git a/verilog/dv/caravel/user_proj_example/la_test2/Makefile b/verilog/dv/caravel/user_proj_example/la_test2/Makefile
index 4980a08..d9d9a0d 100644
--- a/verilog/dv/caravel/user_proj_example/la_test2/Makefile
+++ b/verilog/dv/caravel/user_proj_example/la_test2/Makefile
@@ -1,19 +1,3 @@
-# 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 = ../..
RTL_PATH = ../../../../rtl
IP_PATH = ../../../../ip
@@ -23,8 +7,6 @@
GCC_PREFIX?=riscv32-unknown-elf
PDK_PATH?=/ef/tech/SW/sky130A
-SIM?=RTL
-
.SUFFIXES:
PATTERN = la_test2
@@ -34,15 +16,9 @@
hex: ${PATTERN:=.hex}
%.vvp: %_tb.v %.hex
-ifeq ($(SIM),RTL)
- iverilog -DFUNCTIONAL -DSIM -I $(BEHAVIOURAL_MODELS) \
+ iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS) \
-I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \
- $< -o $@
-else
- iverilog -DFUNCTIONAL -DSIM -DGL -I $(BEHAVIOURAL_MODELS) \
- -I $(PDK_PATH) -I $(IP_PATH) -I $(RTL_PATH) \
- $< -o $@
-endif
+ -o $@ $<
%.vcd: %.vvp
vvp $<
diff --git a/verilog/dv/caravel/user_proj_example/la_test2/la_test2.c b/verilog/dv/caravel/user_proj_example/la_test2/la_test2.c
index 0267d25..18e185b 100644
--- a/verilog/dv/caravel/user_proj_example/la_test2/la_test2.c
+++ b/verilog/dv/caravel/user_proj_example/la_test2/la_test2.c
@@ -1,20 +1,3 @@
-/*
- * 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"
#include "../../stub.c"
diff --git a/verilog/dv/caravel/user_proj_example/la_test2/la_test2_tb.v b/verilog/dv/caravel/user_proj_example/la_test2/la_test2_tb.v
index b9e5c80..9c549de 100644
--- a/verilog/dv/caravel/user_proj_example/la_test2/la_test2_tb.v
+++ b/verilog/dv/caravel/user_proj_example/la_test2/la_test2_tb.v
@@ -1,18 +1,3 @@
-// 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
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 0000000..d93f72d
--- /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 -DSIM -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 0000000..4ae44af
--- /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 0000000..d081a58
--- /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 0000000..57b8b3c
--- /dev/null
+++ b/verilog/dv/caravel/user_proj_example/seven-segment-counter/seven_segment_tb.v
@@ -0,0 +1,143 @@
+`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 = mprj_io[14: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 #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 0000000..890d235
--- /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 -DSIM -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 0000000..29997e6
--- /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 0000000..35f98a0
--- /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 0000000..0bb601f
--- /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 -DSIM -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 0000000..a6fe3fc
--- /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 0000000..78a082e
--- /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 0000000..730469b
--- /dev/null
+++ b/verilog/dv/caravel/user_proj_example/vga-clock/vga_clock_tb.v
@@ -0,0 +1,147 @@
+`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 = mprj_io[11];
+ assign vsync = mprj_io[12];
+ assign rrggbb = mprj_io[18:13];
+
+ 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;
+
+ // 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 0000000..bd8cd22
--- /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?=riscv32-unknown-elf-
+PDK_PATH?=$(PDK_ROOT)/sky130A/
+
+.SUFFIXES:
+
+PATTERN = ws2812
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+%.vvp: %_tb.v %.hex
+ iverilog -DSIM -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 0000000..b04ef42
--- /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 0000000..65cbad9
--- /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 0000000..2f12b51
--- /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/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 47d92f4..c5f1aaf 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -1,19 +1,8 @@
-// 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
+`include "multi_project_harness/includes.v"
+`ifdef COCOTB_SIM
+ `define MPRJ_IO_PADS 38
+`endif
/*
*-------------------------------------------------------------
*
@@ -78,8 +67,8 @@
/*--------------------------------------*/
/* User project is instantiated here */
/*--------------------------------------*/
-
- user_proj_example mprj (
+ parameter num_projects = 8;
+ multi_project_harness #(.num_projects(num_projects)) mprj (
`ifdef USE_POWER_PINS
.vdda1(vdda1), // User area 1 3.3V power
.vdda2(vdda2), // User area 2 3.3V power
@@ -116,9 +105,200 @@
// IO Pads
.io_in (io_in),
- .io_out(io_out),
- .io_oeb(io_oeb)
+ .io_out(io_out),
+ .io_oeb(io_oeb),
+
+ .proj0_wb_update (proj0_wb_update),
+ .proj0_clk (proj0_clk),
+ .proj0_reset (proj0_reset),
+ .proj0_io_in (proj0_io_in),
+ .proj0_io_out (proj0_io_out),
+
+ .proj1_wb_update (proj1_wb_update),
+ .proj1_clk (proj1_clk),
+ .proj1_reset (proj1_reset),
+ .proj1_io_in (proj1_io_in),
+ .proj1_io_out (proj1_io_out),
+
+ .proj2_clk (proj2_clk),
+ .proj2_reset (proj2_reset),
+ .proj2_io_in (proj2_io_in),
+ .proj2_io_out (proj2_io_out),
+
+ .proj3_clk (proj3_clk),
+ .proj3_reset (proj3_reset),
+ .proj3_io_in (proj3_io_in),
+ .proj3_io_out (proj3_io_out),
+
+ .proj4_clk (proj4_clk),
+ .proj4_reset (proj4_reset),
+ .proj4_io_in (proj4_io_in),
+ .proj4_io_out (proj4_io_out),
+ .proj4_cnt (proj4_cnt),
+ .proj4_cnt_cont (proj4_cnt_cont),
+ .proj4_wb_update (proj4_wb_update),
+
+ .proj5_wb_update (proj5_wb_update),
+ .proj5_clk (proj5_clk),
+ .proj5_reset (proj5_reset),
+ .proj5_io_in (proj5_io_in),
+ .proj5_io_out (proj5_io_out),
+
+ .proj6_clk (proj6_clk),
+ .proj6_io_in (proj6_io_in),
+ .proj6_io_out (proj6_io_out),
+
+ .proj7_reset (proj7_reset),
+ .proj7_io_in (proj7_io_in),
+ .proj7_io_out (proj7_io_out)
+
);
+ `ifdef COCOTB_SIM
+ initial begin
+ $dumpfile ("user_project_wrapper.vcd");
+ $dumpvars (0, user_project_wrapper);
+ #1;
+ end
+ `endif
+
+ wire [`MPRJ_IO_PADS-1:0] proj0_io_in;
+ wire [`MPRJ_IO_PADS-1:0] proj0_io_out;
+ wire proj0_wb_update;
+ wire proj0_clk;
+ wire proj0_reset;
+
+ `ifndef NO_PROJ0
+ seven_segment_seconds proj_0 (.clk(proj0_clk), .reset(proj0_reset), .led_out(proj0_io_out[14:8]), .compare_in(wbs_dat_i[23:0]), .update_compare(proj0_wb_update));
+ `endif
+
+ wire [`MPRJ_IO_PADS-1:0] proj1_io_in;
+ wire [`MPRJ_IO_PADS-1:0] proj1_io_out;
+ wire proj1_wb_update;
+ wire proj1_clk;
+ wire proj1_reset;
+
+ `ifndef NO_PROJ1
+ ws2812 proj_1 (.clk(proj1_clk), .reset(proj1_reset), .led_num(wbs_dat_i[31:24]), .rgb_data(wbs_dat_i[23:0]), .write(proj1_wb_update), .data(proj1_io_out[8]));
+ `endif
+
+ wire [`MPRJ_IO_PADS-1:0] proj2_io_in;
+ wire [`MPRJ_IO_PADS-1:0] proj2_io_out;
+ wire proj2_clk;
+ wire proj2_reset;
+
+ `ifndef NO_PROJ2
+ vga_clock proj_2 (.clk(proj2_clk), .reset_n(proj2_reset), .adj_hrs(proj2_io_in[8]), .adj_min(proj2_io_in[9]), .adj_sec(proj2_io_in[10]), .hsync(proj2_io_out[11]), .vsync(proj2_io_out[12]), .rrggbb(proj2_io_out[18:13]));
+ `endif
+
+ wire [`MPRJ_IO_PADS-1:0] proj3_io_in;
+ wire [`MPRJ_IO_PADS-1:0] proj3_io_out;
+ wire proj3_clk;
+ wire proj3_reset;
+
+ `ifndef NO_PROJ3
+ spinet5 proj_3 ( .clk(proj3_clk), .rst(proj3_reset), .io_in(proj3_io_in), .io_out(proj3_io_out));
+ `endif
+
+ wire [`MPRJ_IO_PADS-1:0] proj4_io_in;
+ wire [`MPRJ_IO_PADS-1:0] proj4_io_out;
+ wire proj4_clk;
+ wire proj4_reset;
+ wire [31:0] proj4_cnt;
+ wire [31:0] proj4_cnt_cont;
+ wire proj4_wb_update;
+
+ `ifndef NO_PROJ4
+ asic_freq proj_4(
+ .clk(proj4_clk),
+ .rst(proj4_reset),
+
+ // register write interface (ignores < 32 bit writes):
+ // 30000400:
+ // write UART clock divider (min. value = 4),
+ // 30000404:
+ // write frequency counter update period [sys_clks]
+ // 30000408
+ // set 7-segment display mode,
+ // 0: show meas. freq., 1: show wishbone value
+ // 3000040C
+ // set 7-segment display value:
+ // digit7 ... digit0 (4 bit each)
+ // 30000410
+ // set 7-segment display value:
+ // digit8
+ // 30000414
+ // set 7-segment decimal points:
+ // dec_point8 ... dec_point0 (1 bit each)
+ // 30000418
+ // read periodically reset freq. counter value
+ // 3000041C
+ // read continuous freq. counter value
+ .addr(wbs_adr_i[5:2]),
+ .value(wbs_dat_i),
+ .strobe(proj4_wb_update),
+
+ // signal under test input
+ .samplee(proj4_io_in[25]),
+
+ // periodic counter output to wishbone
+ .o(proj4_cnt),
+
+ // continuous counter output to wishbone
+ .oc(proj4_cnt_cont),
+
+ // UART output to FTDI input
+ .tx(proj4_io_out[6]),
+
+ // 7 segment display outputs
+ .col_drvs(proj4_io_out[16:8]), // 9 x column drivers
+ .seg_drvs(proj4_io_out[24:17]) // 8 x segment drivers
+ );
+ `endif
+
+ wire [`MPRJ_IO_PADS-1:0] proj5_io_in;
+ wire [`MPRJ_IO_PADS-1:0] proj5_io_out;
+ wire proj5_clk;
+ wire proj5_reset;
+ wire proj5_wb_update;
+
+ `ifndef NO_PROJ5
+ watch_hhmm proj_5 (
+ .sysclk_i (proj5_clk),
+ .smode_i (proj5_io_in[36]),
+ .sclk_i (proj5_io_in[37]),
+ .dvalid_i (proj5_wb_update),
+ .cfg_i (wbs_dat_i[11:0]),
+ .rstn_i (proj5_reset),
+ .segment_hxxx (proj5_io_out[14:8]),
+ .segment_xhxx (proj5_io_out[21:15]),
+ .segment_xxmx (proj5_io_out[28:22]),
+ .segment_xxxm (proj5_io_out[35:29])
+ );
+ `endif
+
+ wire [`MPRJ_IO_PADS-1:0] proj6_io_in;
+ wire [`MPRJ_IO_PADS-1:0] proj6_io_out;
+ wire proj6_clk;
+ `ifndef NO_PROJ6
+ challenge proj_6 (.uart(proj6_io_in[8]), .clk_10(proj6_clk), .led_green(proj6_io_out[9]), .led_red(proj6_io_out[10]));
+ `endif
+
+
+ wire [`MPRJ_IO_PADS-1:0] proj7_io_in;
+ wire [`MPRJ_IO_PADS-1:0] proj7_io_out;
+ wire proj7_reset;
+
+ `ifndef NO_PROJ7
+ MM2hdmi proj_7 (
+ .clock(proj7_io_in[35]),
+ .reset(proj7_reset),
+ .io_data(proj7_io_in[23:8]),
+ .io_newData(proj7_io_in[24]),
+ .io_red(proj7_io_out[32:25]),
+ .io_hSync(proj7_io_out[33]),
+ .io_vSync(proj7_io_out[34])
+ );
+ `endif
endmodule // user_project_wrapper
`default_nettype wire