Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions .github/workflows/user_project_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ jobs:
- name: Install IPM dependencies
run: |
python3 -m pip install --upgrade --no-cache-dir cf-ipm
curl -fsSL -o /tmp/verified_IPs.json https://raw.githubusercontent.com/chipfoundry/ipm/main/verified_IPs.json
ipm install-dep --ip-root $GITHUB_WORKSPACE/ip --local-file /tmp/verified_IPs.json
ipm install-dep --ip-root $GITHUB_WORKSPACE/ip
test -f $GITHUB_WORKSPACE/ip/CF_gpio_config/rtl/CF_gpio_config.v

- name: Download PDK Tarball
uses: actions/download-artifact@v4
Expand Down Expand Up @@ -307,6 +307,13 @@ jobs:
sudo chown -R $USER:$USER ${{ env.MCW_ROOT }}
tar -xf /tmp/mgmt_core_wrapper.tar -C $MCW_ROOT .

- name: Install IPM dependencies
if: env.RUN_RTL == 'true'
run: |
python3 -m pip install --upgrade --no-cache-dir cf-ipm
ipm install-dep --ip-root $GITHUB_WORKSPACE/ip
test -f $GITHUB_WORKSPACE/ip/CF_gpio_config/rtl/CF_gpio_config.v

- name: install cocotb
if: env.RUN_RTL == 'true'
run: |
Expand All @@ -315,7 +322,7 @@ jobs:
- name: run RTL verification
if: env.RUN_RTL == 'true'
run: |
cd $GITHUB_WORKSPACE/verilog/dv/cocotb && $GITHUB_WORKSPACE/venv-cocotb/bin/caravel_cocotb -tl user_proj_tests/user_proj_tests.yaml -verbosity debug --CI -tag rtl_verification
cd $GITHUB_WORKSPACE/verilog/dv/cocotb && $GITHUB_WORKSPACE/venv-cocotb/bin/caravel_cocotb --openframe -tl user_proj_tests/user_proj_tests.yaml -verbosity debug --CI -tag rtl_verification
cnt=$(grep -c "failed" "$GITHUB_WORKSPACE/verilog/dv/cocotb/sim/rtl_verification/runs.log")
if ! [[ $cnt ]]; then cnt=0; fi
if [[ $cnt -eq 1 ]]; then exit 0; fi
Expand Down
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ install-caravel-cocotb:
rm -rf ./venv-cocotb
$(PYTHON_BIN) -m venv ./venv-cocotb
./venv-cocotb/bin/$(PYTHON_BIN) -m pip install --upgrade --no-cache-dir pip
./venv-cocotb/bin/$(PYTHON_BIN) -m pip install --upgrade --no-cache-dir caravel-cocotb
./venv-cocotb/bin/$(PYTHON_BIN) -m pip install --upgrade --no-cache-dir "git+https://github.com/chipfoundry/caravel-sim-infrastructure.git@main#subdirectory=cocotb"

.PHONY: setup-cocotb-env
setup-cocotb-env:
Expand All @@ -329,17 +329,17 @@ setup-cocotb: install-caravel-cocotb setup-cocotb-env simenv-cocotb

.PHONY: cocotb-verify-all-rtl
cocotb-verify-all-rtl:
@(cd $(PROJECT_ROOT)/verilog/dv/cocotb && $(PROJECT_ROOT)/venv-cocotb/bin/caravel_cocotb -tl user_proj_tests/user_proj_tests.yaml )
@(cd $(PROJECT_ROOT)/verilog/dv/cocotb && $(PROJECT_ROOT)/venv-cocotb/bin/caravel_cocotb --openframe -tl user_proj_tests/user_proj_tests.yaml )

.PHONY: cocotb-verify-all-gl
cocotb-verify-all-gl:
@(cd $(PROJECT_ROOT)/verilog/dv/cocotb && $(PROJECT_ROOT)/venv-cocotb/bin/caravel_cocotb -tl user_proj_tests/user_proj_tests_gl.yaml -sim GL)
@(cd $(PROJECT_ROOT)/verilog/dv/cocotb && $(PROJECT_ROOT)/venv-cocotb/bin/caravel_cocotb --openframe -tl user_proj_tests/user_proj_tests_gl.yaml -sim GL)

$(cocotb-dv-targets-rtl): cocotb-verify-%-rtl:
@(cd $(PROJECT_ROOT)/verilog/dv/cocotb && $(PROJECT_ROOT)/venv-cocotb/bin/caravel_cocotb -t $* )
@(cd $(PROJECT_ROOT)/verilog/dv/cocotb && $(PROJECT_ROOT)/venv-cocotb/bin/caravel_cocotb --openframe -t $* )

$(cocotb-dv-targets-gl): cocotb-verify-%-gl:
@(cd $(PROJECT_ROOT)/verilog/dv/cocotb && $(PROJECT_ROOT)/venv-cocotb/bin/caravel_cocotb -t $* -sim GL)
@(cd $(PROJECT_ROOT)/verilog/dv/cocotb && $(PROJECT_ROOT)/venv-cocotb/bin/caravel_cocotb --openframe -t $* -sim GL)

./verilog/gl/user_project_wrapper.v:
$(error you don't have $@)
Expand Down
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,14 @@ cd <project_name>
cf init
```

This creates `.cf/project.json` with project metadata. **This must be run before any other commands**
This creates `.cf/project.json` with project metadata. **This must be run before any other commands.**

If you are logged in (`cf login`) and this repo is not yet linked to the platform, `cf init` asks which platform action to take:

1. **Link to an existing platform project** (the default). Use this when the design is already registered on the [ChipFoundry platform](https://platform.chipfoundry.io). Init lists your projects and stores the one you pick in `.cf/project.json`. Later commands, including submission, use that project. Linking is the default so a second platform project is not created by accident.
2. **Create a new platform project**. Use this the first time you register this design. Init asks you to pick a shuttle and creates a Draft project on the platform.

If you are not logged in, `cf init` only writes the local config. Log in, then run `cf init` again or `cf link`. You can change the link later with `cf link` and `cf unlink`.

### 3. Environment Setup
Install the ChipFoundry CLI tool and set up the local environment (PDKs, OpenLane, and OpenFrame):
Expand Down Expand Up @@ -138,24 +145,27 @@ cf harden openframe_project_wrapper
### Verification

#### 1. Simulation
We use cocotb for functional verification. Ensure your file lists are updated in `verilog/includes/`.
We use cocotb for functional verification. Tests live under `verilog/dv/cocotb/<test_name>/`. The template includes `hello_world` and `timer`, which checks the example 7-segment clock (`verilog/rtl/timer.v`) on GPIOs 0–12.

`cf verify --all` does not discover tests on its own. It runs the list in `verilog/dv/cocotb/user_proj_tests/user_proj_tests.yaml` (and `user_proj_tests_gl.yaml` for gate-level). Add one entry there for each test you want included. Run `cf setup` (cocotb is installed as part of setup) before the first verify.

Run RTL Simulation:
Run one RTL test:

```bash
cf verify <test_name>
cf verify timer
```

Run Gate-Level (GL) Simulation:
Run one Gate-Level (GL) test:

```bash
cf verify <test_name> --sim gl
cf verify timer --sim gl
```

Run all tests:
Run every test in the list:

```bash
cf verify --all
cf verify --all --sim gl
```

---
Expand Down
4 changes: 3 additions & 1 deletion verilog/dv/cocotb/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
*.pyc
**/.vscode/
**/.vscode/
sim/
design_info.yaml
2 changes: 2 additions & 0 deletions verilog/dv/cocotb/cocotb_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from hello_world.hello_world import hello_world
from timer.timer import timer
3 changes: 1 addition & 2 deletions verilog/dv/cocotb/hello_world/hello_world.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#include <common.h>
void main(){
return;
}
}
6 changes: 3 additions & 3 deletions verilog/dv/cocotb/hello_world/hello_world.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from cocotb_includes import test_configure
from cocotb_includes import report_test
from caravel_cocotb.caravel_interfaces import test_configure
from caravel_cocotb.caravel_interfaces import report_test
import cocotb

@cocotb.test()
@report_test
async def hello_world(dut):
caravelEnv = await test_configure(dut,timeout_cycles=9373)
cocotb.log.info("Hello World")
cocotb.log.info("Hello World")
98 changes: 98 additions & 0 deletions verilog/dv/cocotb/timer/timer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# SPDX-FileCopyrightText: 2026 ChipFoundry
#
# 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

"""Functional test for the example timer (verilog/rtl/timer.v).

The wrapper maps the timer as follows:
GPIO 0 user clock
GPIO 1 user reset (active high)
GPIO 5:2 digit enable
GPIO 12:6 seven-segment (common cathode, CC=1)
"""

from cocotb.triggers import Timer
import cocotb
from caravel_cocotb.caravel_interfaces import report_test, test_configure

# Common-cathode encodings produced by timer.v with CC=1.
SEG = {
0: 0b1111110,
1: 0b0110000,
}
DIGIT_ONES = 0b1110 # dig_cnt == 0, seconds ones
DIGIT_TENS = 0b1101 # dig_cnt == 1, seconds tens

CLK_GPIO = 0
RST_GPIO = 1
# FREQ=2000, so the ones digit increments on user cycle 2001 and is scanned
# out a few cycles later. 2500 clocks covers that without reaching 10 seconds.
USER_CLOCKS = 2500


async def user_clocks(env, count):
for _ in range(count):
env.drive_gpio(CLK_GPIO, 0)
await Timer(10, units="ns")
env.drive_gpio(CLK_GPIO, 1)
await Timer(10, units="ns")


def read_display(env):
digit_en = env.monitor_gpio_range((5, 2))
seven_seg = env.monitor_gpio_range((12, 6))
return digit_en, seven_seg


@cocotb.test()
@report_test
async def timer(dut):
env = await test_configure(dut, timeout_cycles=20000)

env.drive_gpio(RST_GPIO, 1)
await user_clocks(env, 4)
digit_en, seven_seg = read_display(env)
assert (digit_en, seven_seg) == (DIGIT_ONES, SEG[0]), (
f"reset display was digit_en={digit_en:04b} seven_seg={seven_seg:07b}, "
f"expected {DIGIT_ONES:04b} {SEG[0]:07b}"
)

env.drive_gpio(RST_GPIO, 0)
saw_zero = False
saw_one = False
for _ in range(USER_CLOCKS):
await user_clocks(env, 1)
digit_en, seven_seg = read_display(env)
if digit_en == DIGIT_ONES:
if seven_seg == SEG[0]:
saw_zero = True
elif seven_seg == SEG[1]:
if not saw_zero:
raise AssertionError("seconds ones showed 1 before 0")
saw_one = True
else:
raise AssertionError(
f"unexpected seconds-ones pattern {seven_seg:07b}"
)
elif digit_en == DIGIT_TENS and seven_seg != SEG[0]:
raise AssertionError(
f"seconds tens changed during the first second: {seven_seg:07b}"
)

assert saw_zero and saw_one, (
"seconds ones digit did not count from 0 to 1 "
f"(saw 0={saw_zero}, saw 1={saw_one})"
)
cocotb.log.info("[timer] seconds digit counted from 0 to 1")
3 changes: 3 additions & 0 deletions verilog/dv/cocotb/timer/timer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
Tests:
- {name: timer, sim: RTL}
6 changes: 6 additions & 0 deletions verilog/dv/cocotb/user_proj_tests/user_proj_tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
# Test list for `cf verify --all` (RTL).
# Add one entry per cocotb test under verilog/dv/cocotb/<name>/.
Tests:
- {name: hello_world, sim: RTL}
- {name: timer, sim: RTL}
6 changes: 6 additions & 0 deletions verilog/dv/cocotb/user_proj_tests/user_proj_tests_gl.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
# Test list for `cf verify --all --sim gl`.
# Add one entry per cocotb test under verilog/dv/cocotb/<name>/.
Tests:
- {name: hello_world, sim: GL}
- {name: timer, sim: GL}
5 changes: 5 additions & 0 deletions verilog/includes/includes.gl+sdf.caravel_user_project
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# OpenFrame user project GL+SDF includes
-v $(USER_PROJECT_VERILOG)/gl/vccd1_connection.v
-v $(USER_PROJECT_VERILOG)/gl/vssd1_connection.v
-v $(USER_PROJECT_VERILOG)/gl/user_proj_timer.v
-v $(USER_PROJECT_VERILOG)/gl/openframe_project_wrapper.v
5 changes: 5 additions & 0 deletions verilog/includes/includes.gl.caravel_user_project
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# OpenFrame user project GL includes
-v $(USER_PROJECT_VERILOG)/gl/vccd1_connection.v
-v $(USER_PROJECT_VERILOG)/gl/vssd1_connection.v
-v $(USER_PROJECT_VERILOG)/gl/user_proj_timer.v
-v $(USER_PROJECT_VERILOG)/gl/openframe_project_wrapper.v
30 changes: 6 additions & 24 deletions verilog/includes/includes.rtl.caravel_user_project
Original file line number Diff line number Diff line change
@@ -1,25 +1,7 @@
# Caravel user project includes
-v $(USER_PROJECT_VERILOG)/dv/firmware/spiflash.v
# OpenFrame user project RTL includes
-v $(USER_PROJECT_VERILOG)/../ip/CF_gpio_config/rtl/CF_gpio_config.v
-v $(USER_PROJECT_VERILOG)/rtl/openframe_project_wrapper.v
-v $(USER_PROJECT_VERILOG)/rtl/picosoc.v
-v $(USER_PROJECT_VERILOG)/rtl/picorv32.v
-v $(USER_PROJECT_VERILOG)/rtl/spimemio.v
-v $(USER_PROJECT_VERILOG)/rtl/simpleuart.v
-v $(USER_PROJECT_VERILOG)/rtl/clock_routing.v
-v $(USER_PROJECT_VERILOG)/rtl/clock_div.v
-v $(USER_PROJECT_VERILOG)/rtl/housekeeping.v
-v $(USER_PROJECT_VERILOG)/rtl/housekeeping_spi.v
-v $(USER_PROJECT_VERILOG)/rtl/digital_locked_loop.v
-v $(USER_PROJECT_VERILOG)/rtl/dll_controller.v
-v $(USER_PROJECT_VERILOG)/rtl/ring_osc2x13.v
-v $(USER_PROJECT_VERILOG)/rtl/simple_spi_master.v
-v $(USER_PROJECT_VERILOG)/rtl/counter_timer_high.v
-v $(USER_PROJECT_VERILOG)/rtl/counter_timer_low.v
-v $(USER_PROJECT_VERILOG)/rtl/intercon_wb.v
-v $(USER_PROJECT_VERILOG)/rtl/mem_wb.v
-v $(USER_PROJECT_VERILOG)/rtl/gpio_wb.v
-v $(USER_PROJECT_VERILOG)/rtl/gpio_vector_wb.v
-v $(USER_PROJECT_VERILOG)/rtl/debug_regs.v


-v $(USER_PROJECT_VERILOG)/rtl/vccd1_connection.v
-v $(USER_PROJECT_VERILOG)/rtl/vssd1_connection.v
-v $(USER_PROJECT_VERILOG)/rtl/timer.v
-v $(USER_PROJECT_VERILOG)/rtl/user_proj_timer.v
-v $(USER_PROJECT_VERILOG)/rtl/openframe_project_wrapper.v
2 changes: 1 addition & 1 deletion verilog/rtl/user_proj_timer.v
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ module user_proj_timer (
input wb_rst_i,

// IOs
output [10:0] io_out,
output [10:0] io_out
);

wire [6:0] seven_seg;
Expand Down
Loading