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> + +# 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