Quickstart Guide
This project aims to provide a user friendly environment for adding and running cocotb tests for Caravel user projects.
Prerequisites
Docker: Linux || Windows || Mac with Intel Chip || Mac with M1 Chip
Python 3.6+ with PIP
docker pull efabless/dv:cocotb
Clone of Caravel
Clone of Caravel management repo
Clone of PDK from volare
Clone of Caravel user project
caravel_cocotb
How to install caravel_cocotb
This is temporary, it will soon be released to PyPi
git clone git@github.com:efabless/caravel-sim-infrastructure.git
cd caravel-sim-infrastructure/cocotb
pip install .
cd ../..
caravel_cocotb usage
caravel_cocotb provides a flow and APIs to run simulation on user_project after integerated with caravel. This is so helpful in detecting any bug in the connection between the user project and Caravel IOs, wishbone interface or logic analyzers. Also since it’s easy to add and run tests with this flow it can be used to test the whole user project.
Creating a Test
Requirements
install cocotb_caravel
update netlist for RTL and GL files at
<caravel_user_project>/verilog/includes/
with the design netlistupdate the design_info file at
<caravel_user_project>/verilog/dv/cocotb/design_info.yaml
Adding a test
This section explains the steps needed to create a test.
A typical test for Caravel consists of 2 parts: Python/cocotb
code and C
code.
Python/cocotb
code is for communicating with Caravel hardware interface inputs, outputs, clock, reset, and power ports/bins.cocotb
here replaces theverilog
code.C
code provides firmware code that would be loaded into the Caravel CPU.
Tests files has to located under <caravel_user_project>/verilog/dv/cocotb/
| dv
| ├── cocotb
| │ ├── <new_test>
| │ │ └── <new_test.py>
| │ │ └── <new_test.c>
| │ └── cocotb_tests.py
| │ └── design_info.yaml
|
Note: The name of
C
file must match the name ofcocotb
test function
Python Template
The template for python
test:
from caravel_cocotb.caravel_interfaces import test_configure
from caravel_cocotb.caravel_interfaces import report_test
from caravel_cocotb.caravel_interfaces import UART
from caravel_cocotb.caravel_interfaces import SPI
import cocotb
@cocotb.test() # decorator to mark the test function as cocotb test
@report_test # wrapper for configure test reporting files
async def <test_name>(dut):
caravelEnv = await test_configure(dut) #configure, start up and reset Caravel
######################## add test sequence ######################
Commonly used APIs to monitor or drive the hardware can be found in in Python APIs
! Warning: New test python function should be imported into cocotb_tests.py
from <new_test>.<new_test> import <new_test>
C Template
The template for Code test:
#include <firmware_apis.h> // include required APIs
void main(){
//////////////////////add test here//////////////////////
return;
}
Commonly used APIs for firmware can be found in Firmware APIs
Test Examples
Refer to this directory for tests example generated for 16-bit counter
Running a Test
Run with ChipCraft
chipcraft verify <testname> --design <design name>
Todo
Add how to run test using chipcraft
Run without ChipCraft
Check prerequisites
Docker: Linux || Windows || Mac with Intel Chip || Mac with M1 Chip
Python 3.6+ with PIP
docker pull efabless/dv:cocotb
Clone of Caravel
Clone of Caravel management repo
Clone of PDK from volare
Clone of Caravel user project
Configure the repo
Run test/tests
Tests can run individually or as a test group using testlist
. Tests can also run in RTL, GL or SDF sims with 9 different corners.
To run use caravel_cocotb in the location that has the design_info.yaml file or pass the path to the design_info.yaml file as a command -design_info:
usage: caravel_cocotb [-h] [-test TEST [TEST ...]] [-design_info DESIGN_INFO]
[-sim SIM [SIM ...]] [-testlist TESTLIST [TESTLIST ...]]
[-tag TAG] [-maxerr MAXERR] [-vcs]
[-corner CORNER [CORNER ...]] [-zip_passed]
[-emailto EMAILTO [EMAILTO ...]] [-seed SEED] [-no_wave]
[-sdf_setup] [-clk CLK] [-lint]
[-macros MACROS [MACROS ...]] [-sim_path SIM_PATH]
[-verbosity VERBOSITY] [-openframe] [-no_pull]
[-no_docker]
Run cocotb tests
optional arguments:
-h, --help show this help message and exit
-test TEST [TEST ...], -t TEST [TEST ...]
name of test or tests.if no --sim provided RTL will be
run <takes list as input>
-design_info DESIGN_INFO, -di DESIGN_INFO
path to design_info.yaml file
-sim SIM [SIM ...] Simulation type RTL,GL & GL_SDF provided only when run
-test<takes list as input>
-testlist TESTLIST [TESTLIST ...], -tl TESTLIST [TESTLIST ...]
path of testlist to be run
-tag TAG provide tag of the run default would be regression
name and if no regression is provided would be
run_<random float>_<timestamp>_
-maxerr MAXERR max number of errors for every test before simulation
breaks default = 3
-vcs, -v use VCS as compiler if not used iverilog would be used
-corner CORNER [CORNER ...], -c CORNER [CORNER ...]
Corner type in case of GL_SDF run has to be provided
-zip_passed zip the waves and logs of passed tests. by default if
the run has more than 7 tests pass tests results would
be zipped automatically
-emailto EMAILTO [EMAILTO ...], -mail EMAILTO [EMAILTO ...]
mails to send results to when results finish
-seed SEED run with specific seed
-no_wave disable dumping waves
-sdf_setup targeting setup violations by taking the SDF maximum
values
-clk CLK define the clock period in ns default defined at
design_info.yaml
-lint generate lint log VCS must be used
-macros MACROS [MACROS ...]
Add additional verilog macros for the design
-sim_path SIM_PATH directory where simulation result directory "sim"
would be created if None it would be created under
cocotb folder
-verbosity VERBOSITY verbosity of the console output it can have one of 3
value debug, normal or quiet the default value is
normal
-openframe use openframe for the simulation rather than caravel
-no_pull use to ignore checking if repos are up to date
-no_docker run iverilog without docker
Example
Run one test in RTL
caravel_cocotb -t <testname> -tag run_one_test
Run 2 tests in GL
caravel_cocotb -t <test1> <test2> -sim GL
Run testlist
caravel_cocotb -tl <path to testlist> -tag all_rtl
Creating a Testlist
Testlist is a file that contains a collection of test names to run together.
The syntax is simple as YAML
is used to write the testlist
# Testlist Can has only 2 elements Tests or includes
# Test element has list of dictionaries of tests to include
Tests:
- {name: <test1>, sim: RTL}
- {name: <test1>, sim: GL}
- {name: <test2>, sim: RTL}
# include has paths for other testlist to include in this test list
# paths are relative to the location of this yaml file
includes:
- <test4>/<testlist>.yaml
- <testlist>.yaml
- ../<test5>/<testlist>.yaml
Results
New directory named sim
would be created under <repo root>/cocotb/
or to the path passed to -sim_path
and it will have all the results.
| sim # directory get generate when run a test
│ ├── <tag> # tag of the run
│ │ ├── <sim type>-<test name> # test result directory contain all logs and wave related to the test
│ │ │ └── <test name>.hex # hex file used in running this test
│ │ │ └── <test name>.log # log file generated from cocotb
│ │ │ └── compilation.log # log file has all the commands used to run iverilog and any compilation error or warning
│ │ │ └── firmware.log # log file has all the commands used to compile the C code and any compilation error or warning
│ │ │ └── <test name>.vcd # waves can be opened by gtkwave
│ │ │ └── rerun.py # script to rerun the test
│ │ └── command.log # command use for this run
│ │ └── repos_info.log # contain information about the repos used to run these tests
│ │ └── configs.yaml # contain information about the repos used to run these tests
│ │ └── runs.log # contains status of the run fails and passes tests
│ ├── hex_files # directory contain all the generated hex files for the runs
│
│
Update design_info.yaml
design_info.yaml
are used to reference all the needed repos and paths needed to run the tests:
fill it like the following
#yaml file contain general design information that would mostly need to be updated in the first run only
#eg CARAVEL_ROOT: "/usr/Desktop/caravel_project/caravel/"
#like repo https://github.com/efabless/caravel
CARAVEL_ROOT: "/usr/caravel_project/caravel/"
#eg MCW_ROOT: "/usr/Desktop/caravel_project/caravel_mgmt_soc_litex/"
#like repo https://github.com/efabless/caravel_mgmt_soc_litex
# MCW_ROOT: "/home/rady/caravel/swift/swift2"
MCW_ROOT: "/usr/caravel_project/caravel_mgmt_soc_litex/"
#eg USER_PROJECT_ROOT: "/usr/Desktop/caravel_project/caravel_user_project/"
#like repo https://github.com/efabless/caravel_user_project
USER_PROJECT_ROOT: "/usr/caravel_project/"
#eg PDK_ROOT: "/usr/Desktop/caravel_project/pdk/"
#exported by volare
PDK_ROOT: "/usr/pdk"
#eg PDK: "sky130A"
PDK: sky130A
#PDK: gf180mcuC
#clock in ns
clk: 25
# true when caravan are simulated instead of Caravel
caravan: false
# optional email address to send the results to
emailto: [None]
Note: This step is required only in the first run.