3. Building the Core¶
The code is hosted on Gitlab and can be checked out using the following command:
$ git clone https://gitlab.incoresemi.com/core-generators/chromite.git
If you are cloning the chromite repo for the first time it would be best to install the dependencies first:
$ cd chromite/
$ pyenv activate venv # ignore this is you are not using pyenv
$ pip install -U -r requirements.txt
The Chromite core generator takes a specific YAML format as input. It makes specific checks to validate if the user has entered valid data and none of the parameters conflict with each other. For e.g., mentioning the ‘D’ extension without the ‘F’ will get captured by the generator as an invalid spec. More information on the exact parameters and constraints on each field are discussed here.
Once the input YAML has been validated, the generator then clones all the dependent repositories which enable building a test-soc, simulating it and performing verification of the core. This is an alternative to maintaining the repositories as submodules, which typically pollutes the commit history with bump commits.
At the end, the generator outputs a single makefile.inc
in the same folder that it was run,
which contains definitions of paths where relevant bluespec files are present, bsc command with
macro definitions, verilator simulation commands, etc.
A sample yaml input YAML (default.yaml) is available in the sample_config
directory of the
repository.
In this guide we will be building the core along with a sample test-soc which includes some basic peripherals to run sample applications. We also include a test-bench for the test-soc and the entire design has the following hierarchy structure (defined to a max of 5 levels of depth):
Description of the above modules:
Module-Name |
Description |
mkriscv |
Contains the stages of the core pipeline including the ALU units and only the interface to the memory subsystem |
mkdmem |
The Data memory subsystem. Includes the data-cache and data-tlbs |
mkimem |
The instruction memory subsystem. Includes the instruction-cache and the instruction-tlbs |
mkchromite_axi4 |
Contains the above modules and the integrations across them. Also provides 2 AXI-4 interfaces to be connected to the Cross-bar fabric |
mkuart |
UART module |
mkclint |
Core Level Interrupt |
mksignature_dump |
Signature dump module (for simulation only) |
mkSoc |
contains all the above modules and instantiates the AXI-4 crossbar fabric as well. The fabric has 2 additional slaves, which are brought out through the interface to connect to the boot-rom and bram-main-memory present in the Test-bench |
mkbram |
BRAM based memory acting as main-memory |
mkbootrom |
Bootrom slave |
mkTbSoC |
Testbench that instantiates the Soc, and integrates it with the bootrom and a bram memory |
The details of the devices can be found in devices
3.1. Address Map of Test SoC¶
Module
Address Range
BRAM-Memory
0x80000000 - 0x8FFFFFFF
BootROM
0x00001000 - 0x00010FFF
UART
0x00011300 - 0x00011340
CLINT
0x02000000 - 0x020BFFFF
Debug-Halt Loop
0x00000000 - 0x0000000F
Signature Dump
0x00002000 - 0x0000200c
To build the core with a sample test-soc we need to provide a few yaml configuration files as listed below:
isa.yaml : the riscv-config yaml capturing the ISA configurations of the core
custom.yaml: yaml capturing any chromite specific csrs (see riscv-config itself)
core.yaml: capturing all the micro-architecture specific configurations (see Section 5)
csr_grouping.yaml: capturing the csr grouping file required by csrbox
debug.yaml: captures all the debug related features
The Chromite repo provides a few sample configurations in the sample_configs
directory at the
root level and we will use the rv64imacsu config as follows:
$ python -m configure.main -ispec sample_config/rv64imacsu/isa.yaml
-customspec sample_config/rv64imacsu/custom.yaml -cspec sample_config/rv64imacsu/core.yaml
-gspec sample_config/rv64imacsu/csr_grouping.yaml
-dspec sample_config/rv64imacsu/debug.yaml --verbose debug
The above step generates a makefile.inc
file in the same folder and also
clones other dependent repositories to build a test-soc and carry out
verification. This should generate a log something similar to:
[INFO] : ************ Chromite Core Generator ************
[INFO] : ------ Copyright (c) InCore Semiconductors ------
[INFO] : ---------- Available under BSD License----------
[INFO] :
[INFO] : Checking pre-requisites
[INFO] : Cloning "cache_subsystem" from URL "https://gitlab.incoresemi.com/blocks/cache_subsystem"
[INFO] : Checking out "1.0.0" for repo "cache_subsystem"
[INFO] : Cloning "common_bsv" from URL "https://gitlab.incoresemi.com/blocks/common_bsv"
[INFO] : Checking out "master" for repo "common_bsv"
[INFO] : Cloning "fabrics" from URL "https://gitlab.incoresemi.com/blocks/fabrics"
[INFO] : Checking out "1.1.1" for repo "fabrics"
[INFO] : Cloning "bsvwrappers" from URL "https://gitlab.incoresemi.com/blocks/bsvwrappers"
[INFO] : Checking out "master" for repo "bsvwrappers"
[INFO] : Cloning "devices" from URL "https://gitlab.incoresemi.com/blocks/devices"
[INFO] : Checking out "1.0.0" for repo "devices"
[INFO] : Cloning "benchmarks" from URL "https://gitlab.incoresemi.com/core-generators/benchmarks"
[INFO] : Checking out "master" for repo "benchmarks"
[INFO] : Loading input file: /scratch/git-repo/incoresemi/core-generators/chromite/sample_config/default.yaml
[INFO] : Load Schema configure/schema.yaml
[INFO] : Initiating Validation
[INFO] : No Syntax errors in Input Yaml.
[INFO] : Performing Specific Checks
[INFO] : Generating BSC compile options
[INFO] : makefile.inc generated
[INFO] : Creating Dependency graph
[WARNING] : path: .:%/Libraries:src/:src/predictors:src/m_ext:src/fpu/:src/m_ext/..........
defines: Addr_space=25 ASSERT rtldump RV64 ibuswidth=64 dbuswidth=64 .......
builddir: build/hw/intermediate
topfile: test_soc/TbSoc.bsv
outputfile: depends.mk
argv:
generated make dependency rules for "test_soc/TbSoc.bsv" in: depends.mk
[INFO] : Dependency Graph Created
[INFO] : Cleaning previously built code
[WARNING] : rm -rf build/hw/intermediate/* *.log bin/* obj_dir build/hw/verilog/*
rm -f *.jou rm *.log *.mem log sim_main.h cds.lib hdl.var
[INFO] : Run make -j<jobs>
To compile the bluespec source and generate verilog
$ make -j<jobs> generate_verilog
If you are using the samples/default.yaml config file, this should generate the following folders:
build/hw/verilog: contains the generated verilog files.
build/hw/intermediate: contains all the intermediate and information files generated by bsc.
Congratulations - You have built your very first Chromite core !! :)
3.2. Building just the core¶
For integration in a separate SoC, or advanced simulations or synthesis, it might be required to
just generate the core instance alone without any of the other collaterals (uart, clint, etc). To do
this the procedure is the same as above except the following changes to be done in the core.yaml
fields:
bsc_compile_options:
trace_dump: false
top_module: mkchromite_axi4
top_file: chromite.bsv
top_dir: src
The top level module will be mkchromite_axi4
in the file build/hw/verilog/mkchromite_axi4.v
.
This module has the following port map
Signal name |
Direction |
Size |
Description |
resetpc |
Input |
64 |
indicates the program counter value once reset is deasserted |
CLK |
Input |
1 |
core clock |
RST_N |
Input |
1 |
core reset (active low) |
master_d_AWREADY |
Input |
1 |
AXI4 Master interface signals for the Data-Cache |
master_d_WREADY |
Input |
1 |
|
master_d_BVALID |
Input |
1 |
|
master_d_BID |
Input |
1 |
|
master_d_BRESP |
Input |
2 |
|
master_d_ARREADY |
Input |
1 |
|
master_d_RVALID |
Input |
1 |
|
master_d_RID |
Input |
1 |
|
master_d_RDATA |
Input |
64 |
|
master_d_RRESP |
Input |
2 |
|
master_d_RLAST |
Input |
1 |
|
master_i_AWREADY |
Input |
1 |
AXI4 Master interface signals for the Instruction-Cache |
master_i_WREADY |
Input |
1 |
|
master_i_BVALID |
Input |
1 |
|
master_i_BID |
Input |
1 |
|
master_i_BRESP |
Input |
2 |
|
master_i_ARREADY |
Input |
1 |
|
master_i_RVALID |
Input |
1 |
|
master_i_RID |
Input |
1 |
|
master_i_RDATA |
Input |
64 |
|
master_i_RRESP |
Input |
2 |
|
master_i_RLAST |
Input |
1 |
|
sb_clint_msip_m |
Input |
1 |
machine software interrupt from clint |
sb_clint_mtip_m |
Input |
1 |
machine timer interrupt from clint |
sb_clint_mtime_m |
Input |
64 |
machine mtime value from clint |
sb_plic_meip_ex_i |
Input |
1 |
machine external interrupt from plic |
sb_plic_seip_ex_i |
Input |
1 |
supervisor external interrupt from plic |
ma_debug_interrupt__int |
Input |
1 |
interrupt indicating debugger requesting a halt |
ma_debugger_available_avail |
Input |
1 |
single bit indicating if debugger is connected |
master_d_AWVALID |
Output |
1 |
AXI4 Master interface signals for the Data-Cache |
master_d_AWID |
Output |
1 |
|
master_d_AWADDR |
Output |
32 |
|
master_d_AWLEN |
Output |
8 |
|
master_d_AWSIZE |
Output |
3 |
|
master_d_AWBURST |
Output |
2 |
|
master_d_AWLOCK |
Output |
1 |
|
master_d_AWCACHE |
Output |
4 |
|
master_d_AWPROT |
Output |
3 |
|
master_d_AWQOS |
Output |
4 |
|
master_d_AWREGION |
Output |
4 |
|
master_d_WVALID |
Output |
1 |
|
master_d_WDATA |
Output |
64 |
|
master_d_WSTRB |
Output |
8 |
|
master_d_WLAST |
Output |
1 |
|
master_d_BREADY |
Output |
1 |
|
master_d_ARVALID |
Output |
1 |
|
master_d_ARID |
Output |
1 |
|
master_d_ARADDR |
Output |
32 |
|
master_d_ARLEN |
Output |
8 |
|
master_d_ARSIZE |
Output |
3 |
|
master_d_ARBURST |
Output |
2 |
|
master_d_ARLOCK |
Output |
1 |
|
master_d_ARCACHE |
Output |
4 |
|
master_d_ARPROT |
Output |
3 |
|
master_d_ARQOS |
Output |
4 |
|
master_d_ARREGION |
Output |
4 |
|
master_d_RREADY |
Output |
1 |
|
master_i_AWVALID |
Output |
1 |
AXI4 Master interface signals for the Data-Cache |
master_i_AWID |
Output |
1 |
|
master_i_AWADDR |
Output |
32 |
|
master_i_AWLEN |
Output |
8 |
|
master_i_AWSIZE |
Output |
3 |
|
master_i_AWBURST |
Output |
2 |
|
master_i_AWLOCK |
Output |
1 |
|
master_i_AWCACHE |
Output |
4 |
|
master_i_AWPROT |
Output |
3 |
|
master_i_AWQOS |
Output |
4 |
|
master_i_AWREGION |
Output |
4 |
|
master_i_WVALID |
Output |
1 |
|
master_i_WDATA |
Output |
64 |
|
master_i_WSTRB |
Output |
8 |
|
master_i_WLAST |
Output |
1 |
|
master_i_BREADY |
Output |
1 |
|
master_i_ARVALID |
Output |
1 |
|
master_i_ARID |
Output |
1 |
|
master_i_ARADDR |
Output |
32 |
|
master_i_ARLEN |
Output |
8 |
|
master_i_ARSIZE |
Output |
3 |
|
master_i_ARBURST |
Output |
2 |
|
master_i_ARLOCK |
Output |
1 |
|
master_i_ARCACHE |
Output |
4 |
|
master_i_ARPROT |
Output |
3 |
|
master_i_ARQOS |
Output |
4 |
|
master_i_ARREGION |
Output |
4 |
|
master_i_RREADY |
Output |
1 |
|
mv_core_is_reset |
Output |
1 |
indicates that the core is out of reset |
mv_core_debugenable |
Output |
1 |
indicates that the core is available for debug |
mv_stop_timer |
Output |
1 |
indicates that the clint should stop incrementing timer |
mv_stop_count |
Output |
1 |
indicates that all performance counters must be stoped |