Skip to content

Commit

Permalink
target/sim: Add VCS simulation flow (#163)
Browse files Browse the repository at this point in the history
* vip: Various fixes for VCS, bump AXI

* cheshire_pkg: Replace parameter by variables inside function

* vcs: Add first version of vcs scripts

* ci: Add vcs to CI

* sim: Some cleanup

* docs: Document simulation using VCS

* Bender.yml: Update to newest AXI version

* make: Use Bender flags variable for VCS compile script

---------

Co-authored-by: Paul Scheffler <[email protected]>
  • Loading branch information
CyrilKoe and paulsc96 authored Jan 8, 2025
1 parent 709355b commit e27fb3e
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 28 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ target/sim/vsim/transcript
target/sim/vsim/vsim.wlf
target/sim/vsim/work/

# VCS generated files
target/sim/vcs/compile.*.sh
target/sim/vcs/*.log
target/sim/vcs/AN.DB
target/sim/vcs/simv*
target/sim/vcs/csrc
target/sim/vcs/ucli.key
target/sim/vcs/work*
target/sim/vcs/vc_hdrs.h

# Xilinx generated files
target/xilinx/build
target/xilinx/out
Expand Down
4 changes: 2 additions & 2 deletions Bender.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ packages:
- apb
- register_interface
axi:
revision: ac5deb3ff086aa34b168f392c051e92603d6c0e2
version: 0.39.2
revision: 39f5f2d51c5e524f6fc5cf8b6e901f7dcc5622d7
version: 0.39.6
source:
Git: https://github.com/pulp-platform/axi.git
dependencies:
Expand Down
2 changes: 1 addition & 1 deletion Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ package:

dependencies:
apb_uart: { git: "https://github.com/pulp-platform/apb_uart.git", version: 0.2.1 }
axi: { git: "https://github.com/pulp-platform/axi.git", version: 0.39.2 }
axi: { git: "https://github.com/pulp-platform/axi.git", version: 0.39.6 }
axi_llc: { git: "https://github.com/pulp-platform/axi_llc.git", version: 0.2.1 }
axi_riscv_atomics: { git: "https://github.com/pulp-platform/axi_riscv_atomics.git", version: 0.8.2 }
axi_rt: { git: "https://github.com/pulp-platform/axi_rt.git", version: 0.0.0-alpha.9 }
Expand Down
11 changes: 9 additions & 2 deletions cheshire.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
# Paul Scheffler <[email protected]>

BENDER ?= bender
VLOGAN ?= vlogan

# Caution: Questasim requires this to point to the *actual* compiler install path
CXX_PATH := $(shell which $(CXX))

VLOG_ARGS ?= -suppress 2583 -suppress 13314 -timescale 1ns/1ps
VLOG_ARGS ?= -suppress 2583 -suppress 13314 -timescale 1ns/1ps
VLOGAN_ARGS ?= -kdb -nc -assert svaext +v2k -timescale=1ns/1ps

# Common Bender flags for Cheshire RTL
CHS_BENDER_RTL_FLAGS ?= -t rtl -t cva6 -t cv64a6_imafdcsclic_sv39
Expand Down Expand Up @@ -61,7 +63,7 @@ chs-clean-deps:
######################

CHS_NONFREE_REMOTE ?= [email protected]:pulp-restricted/cheshire-nonfree.git
CHS_NONFREE_COMMIT ?= 99e58ec
CHS_NONFREE_COMMIT ?= 99aa8d9

CHS_PHONY += chs-nonfree-init
chs-nonfree-init:
Expand Down Expand Up @@ -149,6 +151,10 @@ $(CHS_ROOT)/target/sim/vsim/compile.cheshire_soc.tcl: $(CHS_ROOT)/Bender.yml
$(BENDER) script vsim -t sim -t test $(CHS_BENDER_RTL_FLAGS) --vlog-arg="$(VLOG_ARGS)" > $@
echo 'vlog "$(realpath $(CHS_ROOT))/target/sim/src/elfloader.cpp" -ccflags "-std=c++11" -cpppath "$(CXX_PATH)"' >> $@

$(CHS_ROOT)/target/sim/vcs/compile.cheshire_soc.sh: $(CHS_ROOT)/Bender.yml
$(BENDER) script vcs -t sim -t test $(CHS_BENDER_RTL_FLAGS) --vlog-arg="$(VLOGAN_ARGS)" --vlogan-bin="$(VLOGAN)" > $@
chmod +x $@

.PRECIOUS: $(CHS_ROOT)/target/sim/models
$(CHS_ROOT)/target/sim/models:
mkdir -p $@
Expand All @@ -167,6 +173,7 @@ $(CHS_ROOT)/target/sim/models/24FC1025.v: $(CHS_ROOT)/Bender.yml | $(CHS_ROOT)/t
CHS_SIM_ALL += $(CHS_ROOT)/target/sim/models/s25fs512s.v
CHS_SIM_ALL += $(CHS_ROOT)/target/sim/models/24FC1025.v
CHS_SIM_ALL += $(CHS_ROOT)/target/sim/vsim/compile.cheshire_soc.tcl
CHS_SIM_ALL += $(CHS_ROOT)/target/sim/vcs/compile.cheshire_soc.sh

###########
# DRAMSys #
Expand Down
26 changes: 23 additions & 3 deletions docs/tg/sim.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This page describes how to simulate Cheshire to *execute baremetal programs*. Pl
We currently provide working setups for:

- Questa Advanced Simulator (QuestaSim) `>= 2022.3`
- VCS `>= 2024.09`

We plan on supporting more simulators in the future. If your situation requires it, simulating Cheshire on other setups should be straightforward.

Expand All @@ -21,21 +22,21 @@ We provide a SystemVerilog testbench for `cheshire_soc` running baremetal progra

Preloading boot modes expect an ELF executable to be passed through `BINARY`, while autonomous boot modes expect a disk image (GPT formatted or raw code) to be passed through `IMAGE`. For more information on how to build software for Cheshire and its boot process, see [Software Stack](../um/sw.md).

The `SELCFG` environment variable selects the Cheshire configuration used in simulations. Possible configurations are specified in the `tb_cheshire_pkg` package. If not set or set to `0`, the default configuration is selected.
The `SELCFG` variable selects the Cheshire configuration used in simulations. Possible configurations are specified in the `tb_cheshire_pkg` package. If not set or set to `0`, the default configuration is selected.

| `SELCFG` | Configuration in (`tb_cheshire_pkg`) |
| -------- | ----------------------------------------- |
| 0 | Default configuration from `cheshire_pkg` |
| 1 | AXI-RT-enabled configuration |
| 2 | CLIC-enabled configuration |

The `USE_DRAMSYS` environment variable controls whether simulations are linked against and use DRAMSys for DRAM simulation. Note that before starting a simulation using DRAMSys, it must be built with `make chs-dramsys-all` first.
The `USE_DRAMSYS` variable controls whether simulations are linked against and use DRAMSys for DRAM simulation. Note that before starting a simulation using DRAMSys, it must be built with `make chs-dramsys-all` first.

For simulation of Cheshire in other designs, we provide the module `cheshire_vip` encapsulating all verification IPs and their interfaces. For details, see [Verifying Cheshire In-System](integr.md#verifying-cheshire-in-system).

## QuestaSim

After building Cheshire, start QuestaSim in `target/sim/vsim` and run:
Variables are read from QuestaSim's Tcl environment. After building Cheshire, start QuestaSim in `target/sim/vsim` and run:

```tcl
# Preload `helloworld.spm.elf` through serial link
Expand All @@ -52,3 +53,22 @@ run -all
```

The design needs to be recompiled only when hardware is changed. The simulation can be restarted by re-sourcing `start.cheshire_soc.tcl`, allowing binary (or image) and load method changes beforehand.

## VCS

Variables are read from your shell environment. After building Cheshire, start a POSIX-compliant shell in `target/sim/vcs` and run:

```sh
# Preload `helloworld.spm.elf` through serial link
export BINARY="../../../sw/tests/helloworld.spm.elf"
export BOOTMODE=0
export PRELMODE=1

# Compile design
./compile.cheshire_soc.sh

# Start and run simulation
./start.cheshire_soc.sh
```

The design needs to be recompiled only when hardware is changed. The simulation can be run repeatedly using `start.cheshire_soc.sh`, allowing binary (or image) and load method changes beforehand.
2 changes: 1 addition & 1 deletion hw/cheshire_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ package cheshire_pkg;

// Choose static colocation of IDs based on how heavily used and/or critical they are
function automatic cva6_id_map_t gen_cva6_id_map(cheshire_cfg_t cfg);
localparam int unsigned DefaultMapEntry[2] = '{0, 0};
int unsigned DefaultMapEntry[2] = '{0, 0};
case (cfg.AxiMstIdWidth)
// Provide exclusive ID to I-cache to prevent fetch blocking
1: return '{'{Cva6IdBypMmu, 0}, '{Cva6IdBypLoad, 0}, '{Cva6IdBypAccel, 0}, '{Cva6IdBypStore, 0},
Expand Down
43 changes: 24 additions & 19 deletions target/sim/src/vip_cheshire_soc.sv
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ module vip_cheshire_soc import cheshire_pkg::*; #(
assign jtag.tdo = jtag_tdo;

initial begin
@(negedge rst_n);
wait (!rst_n);
jtag_dbg.reset_master();
end

Expand Down Expand Up @@ -469,6 +469,7 @@ module vip_cheshire_soc import cheshire_pkg::*; #(
initial begin
static byte_bt uart_read_buf [$];
byte_bt bite;
string line;
wait_for_reset();
forever begin
uart_read_byte(bite);
Expand All @@ -477,7 +478,8 @@ module vip_cheshire_soc import cheshire_pkg::*; #(
uart_boot_ena = 0;
end else if (bite == "\n") begin
if (uart_read_buf.size() > 0) begin
$display("[UART] %s", {>>8{uart_read_buf}});
line = {>>8{uart_read_buf}};
$display("[UART] %s", line);
uart_read_buf.delete();
end else begin
$display("[UART]");
Expand Down Expand Up @@ -648,7 +650,7 @@ module vip_cheshire_soc import cheshire_pkg::*; #(
.AXI_DATA_WIDTH ( DutCfg.AxiDataWidth ),
.AXI_ID_WIDTH ( DutCfg.AxiMstIdWidth ),
.AXI_USER_WIDTH ( DutCfg.AxiUserWidth )
) slink_mst_ext(), slink_mst_vip(), slink_mst();
) slink_mst_ext(), slink_mst_vip(), slink_mst(), slink_slv_mux[1:0]();

AXI_BUS #(
.AXI_ADDR_WIDTH ( DutCfg.AddrWidth ),
Expand All @@ -666,6 +668,9 @@ module vip_cheshire_soc import cheshire_pkg::*; #(
.clk_i ( clk )
);

`AXI_ASSIGN (slink_slv_mux[0], slink_mst_ext)
`AXI_ASSIGN (slink_slv_mux[1], slink_mst_vip)

// Multiplex internal and external AXI requests
axi_mux_intf #(
.SLV_AXI_ID_WIDTH ( DutCfg.AxiMstIdWidth ),
Expand All @@ -678,8 +683,8 @@ module vip_cheshire_soc import cheshire_pkg::*; #(
.clk_i ( clk ),
.rst_ni ( rst_n ),
.test_i ( test_mode ),
.slv ( '{slink_mst_vip, slink_mst_ext} ),
.mst ( slink_mst_mux )
.slv ( slink_slv_mux ),
.mst ( slink_mst_mux )
);

// Serialize away added AXI index bits
Expand Down Expand Up @@ -785,7 +790,7 @@ module vip_cheshire_soc import cheshire_pkg::*; #(
slink_axi_driver_t slink_axi_driver = new (slink_mst_vip_dv);

initial begin
@(negedge rst_n);
wait (!rst_n);
slink_axi_driver.reset_master();
end

Expand Down Expand Up @@ -951,20 +956,20 @@ endmodule

module vip_cheshire_soc_tristate import cheshire_pkg::*; (
// I2C pad IO
output logic i2c_sda_i,
input logic i2c_sda_o,
input logic i2c_sda_en,
output logic i2c_scl_i,
input logic i2c_scl_o,
input logic i2c_scl_en,
output wire i2c_sda_i,
input wire i2c_sda_o,
input wire i2c_sda_en,
output wire i2c_scl_i,
input wire i2c_scl_o,
input wire i2c_scl_en,
// SPI host pad IO
input logic spih_sck_o,
input logic spih_sck_en,
input logic [SpihNumCs-1:0] spih_csb_o,
input logic [SpihNumCs-1:0] spih_csb_en,
output logic [ 3:0] spih_sd_i,
input logic [ 3:0] spih_sd_o,
input logic [ 3:0] spih_sd_en,
input wire spih_sck_o,
input wire spih_sck_en,
input wire [SpihNumCs-1:0] spih_csb_o,
input wire [SpihNumCs-1:0] spih_csb_en,
output wire [ 3:0] spih_sd_i,
input wire [ 3:0] spih_sd_o,
input wire [ 3:0] spih_sd_en,
// I2C wires
inout wire i2c_sda,
inout wire i2c_scl,
Expand Down
57 changes: 57 additions & 0 deletions target/sim/vcs/start.cheshire_soc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# #!/usr/bin/env bash
# Copyright 2022 ETH Zurich and University of Bologna.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
#
# Cyril Koenig <[email protected]>

TESTBENCH=tb_cheshire_soc

# Set full path to c++ compiler.
if [ -z "${CXX_PATH}" ]; then
if [ -z "${CXX}" ]; then
CXX="g++"
fi
CXX_PATH=`which ${CXX}`
fi

# Set default VCS binary
[[ -z "${VERDI_VERSION}" ]] && VERDI_VERSION=""
[[ -z "${VCS_VERSION}" ]] && VCS_VERSION=""
[[ -z "${VCS_BIN}" ]] && VCS_BIN="${VCS_VERSION} vcs"

flags="-full64 -kdb "
# Set default to fast simulation flags.
if [ -z "${VCSARGS}" ]; then
# Use -debug_access+all for waveform debugging
flags+="-O2 -debug_access=r -debug_region=1,${TESTBENCH} "
fi

flags+="-cpp ${CXX_PATH} "
[[ -n "${SELCFG}" ]] && flags+="-pvalue+SelectedCfg=${SELCFG} "

pargs=""
[[ -n "${BOOTMODE}" ]] && pargs+="+BOOTMODE=${BOOTMODE} "
[[ -n "${PRELMODE}" ]] && pargs+="+PRELMODE=${PRELMODE} "
[[ -n "${BINARY}" ]] && pargs+="+BINARY=${BINARY} "
[[ -n "${IMAGE}" ]] && pargs+="+IMAGE=${IMAGE} "

# DRAMSys
if [ -n "${USE_DRAMSYS}" ]; then
flags+="-pvalue UseDramSys=${USE_DRAMSYS} "
if [[ "${USE_DRAMSYS}" == 1 ]]; then
DRAMSYS_ROOT="../dramsys"
DRAMSYS_LIB="${DRAMSYS_ROOT}/build/lib"
pargs+="+DRAMSYS_RES=${DRAMSYS_ROOT}/configs "
pargs+="-sv_lib ${DRAMSYS_LIB}/libDRAMSys_Simulator "
fi
fi

COLOR_NC='\e[0m'
COLOR_BLUE='\e[0;34m'

${VCS_BIN} ${flags} ../src/elfloader.cpp ${TESTBENCH} | tee elaborate.log

# Start simulation
printf ${COLOR_BLUE}"${VCS_VERSION} ${VERDI_VERSION} ./simv ${pargs}"${COLOR_NC}"\n"
${VCS_VERSION} ${VERDI_VERSION} ./simv ${pargs} | tee simulate.log

0 comments on commit e27fb3e

Please sign in to comment.