From 2dcb7417b4ef28ed77b13ee11c7f19a939de04c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me?= <124148386+cathales@users.noreply.github.com> Date: Wed, 10 Jul 2024 23:33:49 +0200 Subject: [PATCH 001/183] make cv32a65x superscalar (#2348) --- .gitlab-ci/expected_synth.yml | 2 +- .gitlab-ci/scripts/report_benchmark.py | 2 +- core/include/cv32a65x_config_pkg.sv | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci/expected_synth.yml b/.gitlab-ci/expected_synth.yml index d9fa51864e..1e2a363202 100644 --- a/.gitlab-ci/expected_synth.yml +++ b/.gitlab-ci/expected_synth.yml @@ -1,2 +1,2 @@ cv32a65x: - gates: 129171 + gates: 162333 diff --git a/.gitlab-ci/scripts/report_benchmark.py b/.gitlab-ci/scripts/report_benchmark.py index c471190956..04097ed341 100644 --- a/.gitlab-ci/scripts/report_benchmark.py +++ b/.gitlab-ci/scripts/report_benchmark.py @@ -18,7 +18,7 @@ # Will fail if the number of cycles is different from this one valid_cycles = { 'dhrystone': 217900, - 'coremark': 686072, + 'coremark': 549055, } for arg in sys.argv[1:]: diff --git a/core/include/cv32a65x_config_pkg.sv b/core/include/cv32a65x_config_pkg.sv index 10b7e88afa..a1fd6c83d1 100644 --- a/core/include/cv32a65x_config_pkg.sv +++ b/core/include/cv32a65x_config_pkg.sv @@ -18,13 +18,13 @@ package cva6_config_pkg; localparam CVA6ConfigAxiDataWidth = 64; // axi_pkg.sv localparam CVA6ConfigDataUserWidth = 32; // axi_pkg.sv - localparam CVA6ConfigNrScoreboardEntries = 4; // cvxif_pkg.sv + localparam CVA6ConfigNrScoreboardEntries = 8; // cvxif_pkg.sv localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(0), TechnoCut: bit'(1), - SuperscalarEn: bit'(0), + SuperscalarEn: bit'(1), NrCommitPorts: unsigned'(1), AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth), AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth), From 48ef515ba06caf64d3c43d50e75aacb6f74e0611 Mon Sep 17 00:00:00 2001 From: Zbigniew Chamski <107464696+zchamski@users.noreply.github.com> Date: Thu, 11 Jul 2024 08:37:37 +0200 Subject: [PATCH 002/183] [Spike Yaml] Integrate Spike Yaml support. (#2304) --- .gitlab-ci.yml | 1 - Makefile | 4 +++- .../cv32a65x/spike/spike.yaml | 16 +++++++++------- corev_apu/tb/common/spike.sv | 3 ++- verif/core-v-verif | 2 +- verif/regress/install-spike.sh | 4 ++++ verif/sim/Makefile | 14 ++++++++------ verif/sim/cva6.py | 1 + verif/sim/cva6.yaml | 2 +- verif/sim/cva6_spike_log_to_trace_csv.py | 6 +++++- 10 files changed, 34 insertions(+), 19 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 99fe7be953..a7d1f30ad4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -476,7 +476,6 @@ simu-gate: - git -C verif/core-v-verif fetch --unshallow - mkdir -p tools - mv artifacts/tools/spike tools - - echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC - echo $PERIOD - source ./verif/sim/setup-env.sh - git clone ${SYNTH_SCRIPT} ${SYNTH_SCRIPT_PATH} diff --git a/Makefile b/Makefile index ea6920f168..f191dff5d5 100644 --- a/Makefile +++ b/Makefile @@ -275,7 +275,9 @@ compile_flag += -incr -64 -nologo -quiet -suppress 13262 -suppress 8607 -per vopt_flag += -suppress 2085 -suppress 7063 -suppress 2698 -suppress 13262 uvm-flags += +UVM_NO_RELNOTES +UVM_VERBOSITY=UVM_LOW -questa-flags += -t 1ns -64 $(gui-sim) $(QUESTASIM_FLAGS) +tohost_addr=$(tohost_addr) +define+QUESTA -suppress 3356 -suppress 3579 +questa-flags += -t 1ns -64 $(gui-sim) $(QUESTASIM_FLAGS) \ + +tohost_addr=$(hell ${RISCV}/bin/${CV_SW_PREFIX}nm -B $(elf) | grep -w tohost | cut -d' ' -f1) \ + +core_name=$(target) +define+QUESTA -suppress 3356 -suppress 3579 compile_flag_vhd += -64 -nologo -quiet -2008 # Iterate over all include directories and write them with +incdir+ prefixed diff --git a/config/gen_from_riscv_config/cv32a65x/spike/spike.yaml b/config/gen_from_riscv_config/cv32a65x/spike/spike.yaml index c6b7c26ee1..08fb6f2af2 100644 --- a/config/gen_from_riscv_config/cv32a65x/spike/spike.yaml +++ b/config/gen_from_riscv_config/cv32a65x/spike/spike.yaml @@ -9,9 +9,10 @@ spike_param_tree: max_steps: 200000 max_steps_enabled: false isa: rv32imc_zba_zbb_zbs_zbc_zicsr_zifencei - priv: MSU - core_configs: + priv: M + cores: - isa: rv32imc_zba_zbb_zbs_zbc_zicsr_zifencei + boot_addr: 0x80000000 marchid: 0x3 misa_we: false misa_we_enable: true @@ -21,8 +22,9 @@ spike_param_tree: pmpaddr0: 0x0 pmpcfg0: 0x0 pmpregions: 0x0 - priv: MSU - status_fs_field_we: false - status_fs_field_we_enable: false - status_vs_field_we: false - status_vs_field_we_enable: false + priv: M + misa_we: false + mstatus_write_mask: 0x00000088 + mstatus_override_mask: 0x00001800 + mtval_write_mask: 0x00000000 + unified_traps: true diff --git a/corev_apu/tb/common/spike.sv b/corev_apu/tb/common/spike.sv index 3250ce9ec4..1d1fb9ceda 100644 --- a/corev_apu/tb/common/spike.sv +++ b/corev_apu/tb/common/spike.sv @@ -49,15 +49,16 @@ module spike #( st_core_cntrl_cfg st; bit sim_finished; + string core_name = "cva6"; initial begin - string core_name = "cva6"; st = cva6pkg_to_core_cntrl_cfg(st); st.boot_addr_valid = 1'b1; st.boot_addr = 64'h0x10000; if ($test$plusargs("core_name")) begin $value$plusargs("core_name=%s", core_name); + `uvm_info("SPIKE", $sformatf("### core_name = '%s'", core_name), UVM_LOW); end rvfi_initialize(st); diff --git a/verif/core-v-verif b/verif/core-v-verif index 2d9f96e513..66cd091b84 160000 --- a/verif/core-v-verif +++ b/verif/core-v-verif @@ -1 +1 @@ -Subproject commit 2d9f96e513a4004b2536fe4062e1e2dd7665464d +Subproject commit 66cd091b84489d855dc0542b0d7f8337e82e2ef3 diff --git a/verif/regress/install-spike.sh b/verif/regress/install-spike.sh index 538e86a5a9..0ace2559df 100755 --- a/verif/regress/install-spike.sh +++ b/verif/regress/install-spike.sh @@ -48,6 +48,10 @@ if ! [ -f "$SPIKE_INSTALL_DIR/bin/spike" ]; then if [[ ! -f config.log ]]; then ../configure --prefix="$SPIKE_INSTALL_DIR" ${WITH_BOOST} fi + # Build both shared and static versions of the yaml-cpp library in sequence + # prior to building Spike. + make yaml-cpp + make yaml-cpp-static make -j${NUM_JOBS} echo "Installing Spike in '$SPIKE_INSTALL_DIR'..." make install diff --git a/verif/sim/Makefile b/verif/sim/Makefile index 8b3affca4f..8c792cb566 100644 --- a/verif/sim/Makefile +++ b/verif/sim/Makefile @@ -63,8 +63,9 @@ endif spike_yaml ?= $(CVA6_REPO_DIR)/config/gen_from_riscv_config/$(target)/spike/spike.yaml # Set up flags for Spike solo and tandem invocations, but only if parameter file exists. +spike_params_final = $(spike_params) ifneq ($(wildcard $(spike_yaml)),) - spike_params += --yaml-param $(spike_yaml) + spike_params_final := $(spike_params_final) --param-file $(spike_yaml) spike-yaml-plusarg = +config_file=$(CVA6_REPO_DIR)/config/gen_from_riscv_config/$(target)/spike/spike.yaml endif @@ -139,8 +140,8 @@ endif ############################################################################### spike: LD_LIBRARY_PATH="$$(realpath ../../tools/spike/lib):$$LD_LIBRARY_PATH" \ - $(tool_path)/spike $(spike_stepout) $(spike_extension) --log-commits --isa=$(variant) --priv=$(priv) $(spike_params) -l $(elf) - cp $(log).iss $(log) + $(tool_path)/spike $(spike_stepout) $(spike_extension) --log-commits --isa=$(variant) --priv=$(priv) $(spike_params_final) -l $(elf) + grep -v '^\([[]\|/top/\)' $(log).iss > $(log) ############################################################################### # UVM specific commands, variables @@ -185,15 +186,16 @@ export SPIKE_PATH = $(CORE_V_VERIF)/vendor/riscv/riscv-isa-sim/ COMMON_COMP_UVM_FLAGS = \ +incdir+$(CVA6_REPO_DIR)/verif/env/uvme +incdir+$(CVA6_REPO_DIR)/verif/tb/uvmt \ + +core_name=$(target) \ $(if $(spike-tandem), +define+SPIKE_TANDEM=1) COMMON_PLUS_ARGS = \ ++$(elf) \ +elf_file=$(elf) \ + +core_name=$(target) \ $(spike-yaml-plusarg) \ +tohost_addr=$(shell $$RISCV/bin/$(CV_SW_PREFIX)nm -B $(elf) | grep -w tohost | cut -d' ' -f1) \ +signature=$(elf).signature_output +UVM_TESTNAME=uvmt_cva6_firmware_test_c \ - $(spike-yaml-plusarg) \ +report_file=$(log).yaml +core_name=$(target) ifneq ($(UVM_VERBOSITY),) @@ -428,7 +430,7 @@ xrun-testharness: questa-testharness: mkdir -p $(path_var)/tmp - make -C $(path_var) sim target=$(target) defines=$(subst +define+,,$(isscomp_opts)) batch-mode=1 elf_file=$(elf) \ + make -C $(path_var) sim target=$(target) defines=$(subst +define+,,$(isscomp_opts)+core_name=$(target)) batch-mode=1 elf_file=$(elf) \ # TODO: Add support for waveform collection. $(tool_path)/spike-dasm --isa=$(variant) < $(path_var)/trace_rvfi_hart_00.dasm > $(log) grep $(isspostrun_opts) $(path_var)/trace_rvfi_hart_00.dasm @@ -437,7 +439,7 @@ questa-testharness: # Common targets and rules ############################################################################### -clean_all: vcs_clean_all +clean_all: vcs_clean_all rm -f *.txt rm -f trace*.log rm -f trace*.dasm diff --git a/verif/sim/cva6.py b/verif/sim/cva6.py index bdcd83c183..92ea1bcf5e 100644 --- a/verif/sim/cva6.py +++ b/verif/sim/cva6.py @@ -158,6 +158,7 @@ def parse_iss_yaml(iss, iss_yaml, isa, target, setting_dir, debug_cmd, priv, spi else: cmd = re.sub(r"\", isa, cmd) cmd = re.sub(r"\", priv, cmd) + cmd = re.sub(r"\", target, cmd) return cmd logging.error("Cannot find ISS %0s" % iss) sys.exit(RET_FAIL) diff --git a/verif/sim/cva6.yaml b/verif/sim/cva6.yaml index 551707db89..ddfaa230ae 100644 --- a/verif/sim/cva6.yaml +++ b/verif/sim/cva6.yaml @@ -18,7 +18,7 @@ # Always keep this value in sync with the settings of RTL simulators (cf. # values below). cmd: > - make spike steps=2000000 variant= priv= elf= tool_path= log= spike_params='' + make spike steps=2000000 target= variant= priv= elf= tool_path= log= spike_params='' ############################################################################### # Verilator diff --git a/verif/sim/cva6_spike_log_to_trace_csv.py b/verif/sim/cva6_spike_log_to_trace_csv.py index a16b515e66..f7558a4382 100644 --- a/verif/sim/cva6_spike_log_to_trace_csv.py +++ b/verif/sim/cva6_spike_log_to_trace_csv.py @@ -121,9 +121,10 @@ def read_spike_trace(path, full_trace): # true. Otherwise, we are in state EFFECT if instr is not None, otherwise we # are in state INSTR. + start_trampoline_re = re.compile(r'core.*: 0x0*10000 ') end_trampoline_re = re.compile(r'core.*: 0x0*10010 ') - in_trampoline = True + in_trampoline = False instr = None with open(path, 'r') as handle: @@ -133,6 +134,9 @@ def read_spike_trace(path, full_trace): if end_trampoline_re.match(line): in_trampoline = False continue + elif start_trampoline_re.match(line): + in_trampoline = True + continue if instr is None: # The INSTR state. We expect to see a line matching CORE_RE. From 18bfc238f9495ffb9a23e1dbbb6057ada53ba48d Mon Sep 17 00:00:00 2001 From: Mathieu Gouttenoire Date: Thu, 11 Jul 2024 13:44:56 +0000 Subject: [PATCH 003/183] Change sh to bash in toolchain-builder README (#2355) --- util/toolchain-builder/README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/util/toolchain-builder/README.md b/util/toolchain-builder/README.md index 2a1bf35d00..f6b56e5dcb 100644 --- a/util/toolchain-builder/README.md +++ b/util/toolchain-builder/README.md @@ -48,10 +48,10 @@ upstream toolchain (default: GCC 13.1.0) for bare-metal 32-bit and 64-bit applic INSTALL_DIR=$RISCV # 2. Fetch the source code of the toolchain (assumes Internet access.) - sh get-toolchain.sh + bash get-toolchain.sh # 3. Build and install the toolchain (requires write+create permissions for $INSTALL_DIR.) - sh build-toolchain.sh $INSTALL_DIR + bash build-toolchain.sh $INSTALL_DIR ## File and directory structure @@ -93,9 +93,9 @@ missing directories of the installation location._ Once a configuration name `CONFIG_NAME` and an installation location `INSTALL_DIR` are chosen, use - sh get-toolchain.sh CONFIG_NAME + bash get-toolchain.sh CONFIG_NAME # E.g., - # sh get-toolchain.sh gcc-13.1.0-baremetal + # bash get-toolchain.sh gcc-13.1.0-baremetal to fetch/update the source code and to check out the matching baseline of code. @@ -109,9 +109,9 @@ will be selected implicitly. _The default configuration is currently named To build the toolchain from the retrieved source baseline, use - sh build-toolchain.sh CONFIG_NAME INSTALL_DIR + bash build-toolchain.sh CONFIG_NAME INSTALL_DIR # E.g., - # sh build-toolchain.sh gcc-13.1.0-baremetal $RISCV + # bash build-toolchain.sh gcc-13.1.0-baremetal $RISCV To speedup the building it is recommended to set the number of threads to use @@ -126,9 +126,9 @@ code such as a change of baseline configuration. _Whenever the source configuration is changed, please use the `-f` (or `--force`) option to forcibly rebuild the entire toolchain_: - sh build-toolchain.sh -f CONFIG_NAME INSTALL_DIR + bash build-toolchain.sh -f CONFIG_NAME INSTALL_DIR # E.g., - # sh build-toolchain.sh -f gcc-13.1.0-baremetal $RISCV + # bash build-toolchain.sh -f gcc-13.1.0-baremetal $RISCV ## Defining new configurations From 5fcc39dbeee8dab428f971f3af1ad299b996a29c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me?= <124148386+cathales@users.noreply.github.com> Date: Thu, 11 Jul 2024 17:35:03 +0200 Subject: [PATCH 004/183] remove round interval (#2353) --- .gitlab-ci/expected_synth.yml | 2 +- Bender.yml | 1 - Flist.ariane | 1 - core/Flist.cva6 | 1 - core/round_interval.sv | 53 ----------------------------------- core/scoreboard.sv | 16 ++--------- 6 files changed, 3 insertions(+), 71 deletions(-) delete mode 100644 core/round_interval.sv diff --git a/.gitlab-ci/expected_synth.yml b/.gitlab-ci/expected_synth.yml index 1e2a363202..c09468919c 100644 --- a/.gitlab-ci/expected_synth.yml +++ b/.gitlab-ci/expected_synth.yml @@ -1,2 +1,2 @@ cv32a65x: - gates: 162333 + gates: 162197 diff --git a/Bender.yml b/Bender.yml index 56f3b8135b..fdd7f12735 100644 --- a/Bender.yml +++ b/Bender.yml @@ -110,7 +110,6 @@ sources: - core/ariane_regfile_ff.sv - core/ariane_regfile_fpga.sv - core/scoreboard.sv - - core/round_interval.sv - core/store_buffer.sv - core/amo_buffer.sv - core/store_unit.sv diff --git a/Flist.ariane b/Flist.ariane index 8163532785..12b4629404 100644 --- a/Flist.ariane +++ b/Flist.ariane @@ -94,7 +94,6 @@ core/mmu_sv39x4/ptw_sv39x4.sv core/ariane_regfile_ff.sv core/re_name.sv core/scoreboard.sv -core/round_interval.sv core/store_buffer.sv core/amo_buffer.sv core/store_unit.sv diff --git a/core/Flist.cva6 b/core/Flist.cva6 index aa885261a1..de27ed54d3 100644 --- a/core/Flist.cva6 +++ b/core/Flist.cva6 @@ -126,7 +126,6 @@ ${CVA6_REPO_DIR}/core/ariane_regfile_ff.sv ${CVA6_REPO_DIR}/core/ariane_regfile_fpga.sv // NOTE: scoreboard.sv modified for DSIM (unchanged for other simulators) ${CVA6_REPO_DIR}/core/scoreboard.sv -${CVA6_REPO_DIR}/core/round_interval.sv ${CVA6_REPO_DIR}/core/store_buffer.sv ${CVA6_REPO_DIR}/core/amo_buffer.sv ${CVA6_REPO_DIR}/core/store_unit.sv diff --git a/core/round_interval.sv b/core/round_interval.sv deleted file mode 100644 index 9026347bcd..0000000000 --- a/core/round_interval.sv +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2024 Thales Silicon Security -// -// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 -// You may obtain a copy of the License at https://solderpad.org/licenses/ -// -// Original Author: Côme ALLART - Thales - -module round_interval #( - parameter int unsigned S = 1, - parameter int unsigned L = 1 << S -) ( - // Start index - // Included in the interval - input logic [S-1:0] start_i, - // Stop index - // Not included in the interval - input logic [S-1:0] stop_i, - - // The interval from start to stop, rounding - // Considered full when start_i == stop_i - output logic [L-1:0] active_o -); - - // Bit high at index start/stop - logic [L-1:0] a; - logic [L-1:0] b; - - for (genvar i = 0; i < L; i++) begin - assign a[i] = start_i == i; - assign b[i] = stop_i == i; - end - - // Propagation to the higher indexes: >= - logic [L-1:0] ge_a; - logic [L-1:0] ge_b; - - assign ge_b[0] = b[0]; - assign ge_a[0] = a[0]; - for (genvar i = 1; i < L; i++) begin - assign ge_b[i] = ge_b[i-1] || b[i]; - assign ge_a[i] = ge_a[i-1] || a[i]; - end - - // < is the negation of >= - logic [L-1:0] lt_b; - assign lt_b = ~ge_b; - - // Build the interval - assign active_o = (start_i <= stop_i) ? lt_b & ge_a : lt_b | ge_a; - -endmodule diff --git a/core/scoreboard.sv b/core/scoreboard.sv index 5e74b1511f..b483cb5d6e 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -242,10 +242,8 @@ module scoreboard #( // ------------ if (CVA6Cfg.SpeculativeSb) begin if (bmiss) begin - for (int unsigned i = 0; i < CVA6Cfg.NR_SB_ENTRIES; i++) begin - if (speculative_instrs[i]) begin - mem_n[i].cancelled = 1'b1; - end + if (after_flu_wb != issue_pointer[0]) begin + mem_n[after_flu_wb].cancelled = 1'b1; end end end @@ -280,16 +278,6 @@ module scoreboard #( assign bmiss = resolved_branch_i.valid && resolved_branch_i.is_mispredict; assign after_flu_wb = trans_id_i[ariane_pkg::FLU_WB] + 'd1; - if (CVA6Cfg.SpeculativeSb) begin : find_speculative_instrs - round_interval #( - .S(CVA6Cfg.TRANS_ID_BITS) - ) i_speculative_instrs ( - .start_i (after_flu_wb), - .stop_i (issue_pointer_q), - .active_o(speculative_instrs) - ); - end - // FIFO counter updates if (CVA6Cfg.NrCommitPorts == 2) begin : gen_commit_ports assign num_commit = commit_ack_i[1] + commit_ack_i[0]; From 8fa590b5c360de6ac7f867a5b872d6ef2c7b4167 Mon Sep 17 00:00:00 2001 From: Guillaume Chauvon <94678394+Gchauvon@users.noreply.github.com> Date: Fri, 12 Jul 2024 10:53:18 +0200 Subject: [PATCH 005/183] CVXIF 1.0.0 (#2340) --- .gitlab-ci.yml | 4 +- .gitlab-ci/expected_synth.yml | 2 +- Bender.yml | 1 - core/Flist.cva6 | 5 +- core/Flist.cva6_gate | 5 +- core/cva6.sv | 213 ++++++++++----- core/cvxif_compressed_if_driver.sv | 74 ++++++ .../cvxif_example/compressed_instr_decoder.sv | 50 ++++ core/cvxif_example/copro_alu.sv | 135 ++++++++++ .../cvxif_example_coprocessor.sv | 247 +++++++++--------- core/cvxif_example/include/cvxif_instr_pkg.sv | 158 +++++++++-- core/cvxif_example/instr_decoder.sv | 84 ++++-- core/cvxif_fu.sv | 141 +++------- core/cvxif_issue_register_commit_if_driver.sv | 68 +++++ core/decoder.sv | 21 +- core/ex_stage.sv | 43 +-- core/id_stage.sv | 81 +++++- core/include/build_config_pkg.sv | 12 + core/include/config_pkg.sv | 11 + core/include/cv32a65x_config_pkg.sv | 4 +- core/include/cvxif_pkg.sv | 110 -------- core/include/cvxif_types.svh | 73 ++++++ core/issue_read_operands.sv | 138 ++++++++-- core/issue_stage.sv | 138 ++++++---- core/scoreboard.sv | 23 +- corev_apu/src/ariane.sv | 52 +++- docs/riscv-isa/riscv-isa-manual | 2 +- verif/env/uvme/cov/uvme_cva6_cov_model.sv | 7 - .../custom_instructions_cvxif_1_0_0.rst | 137 ++++++++++ verif/env/uvme/uvme_cva6_cfg.sv | 15 -- verif/env/uvme/uvme_cva6_cntxt.sv | 1 - verif/env/uvme/uvme_cva6_env.sv | 14 - verif/env/uvme/uvme_cva6_pkg.flist | 1 - verif/env/uvme/uvme_cva6_pkg.sv | 3 - verif/env/uvme/uvme_cva6_vsqr.sv | 1 - verif/regress/smoke-tests.sh | 2 + verif/sim/Makefile | 1 - verif/tb/uvmt/cva6_tb_wrapper.sv | 49 +++- verif/tb/uvmt/uvmt_cva6.flist | 1 - verif/tb/uvmt/uvmt_cva6_dut_wrap.sv | 15 -- verif/tb/uvmt/uvmt_cva6_tb.sv | 13 +- verif/tests/custom/cv_xif/cvxif_add_nop.S | 37 ++- verif/tests/custom/cv_xif/cvxif_full.S | 104 ++++++++ verif/tests/custom/cv_xif/cvxif_macros.h | 21 +- verif/tests/testlist_cvxif.yaml | 9 +- 45 files changed, 1660 insertions(+), 666 deletions(-) create mode 100644 core/cvxif_compressed_if_driver.sv create mode 100644 core/cvxif_example/compressed_instr_decoder.sv create mode 100644 core/cvxif_example/copro_alu.sv create mode 100644 core/cvxif_issue_register_commit_if_driver.sv delete mode 100644 core/include/cvxif_pkg.sv create mode 100644 core/include/cvxif_types.svh create mode 100644 verif/env/uvme/cvxif_vseq/custom_instructions_cvxif_1_0_0.rst create mode 100644 verif/tests/custom/cv_xif/cvxif_full.S diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a7d1f30ad4..bda97a29d9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -398,7 +398,7 @@ generated_tests: - mv verif/sim/seedlist.yaml artifacts/coverage - python3 .gitlab-ci/scripts/report_pass.py -generated_xif_tests: +.generated_xif_tests: extends: - .verif_test variables: @@ -519,7 +519,7 @@ code_coverage-report: needs: - generated_tests - directed_isacov-tests - - generated_xif_tests +# - generated_xif_tests - csr_embedded_tests variables: DASHBOARD_JOB_TITLE: "Report merge coverage" diff --git a/.gitlab-ci/expected_synth.yml b/.gitlab-ci/expected_synth.yml index c09468919c..431cbfff27 100644 --- a/.gitlab-ci/expected_synth.yml +++ b/.gitlab-ci/expected_synth.yml @@ -1,2 +1,2 @@ cv32a65x: - gates: 162197 + gates: 163431 diff --git a/Bender.yml b/Bender.yml index fdd7f12735..5ef388dad7 100644 --- a/Bender.yml +++ b/Bender.yml @@ -76,7 +76,6 @@ sources: - core/include/std_cache_pkg.sv # Extension Interface - - core/include/cvxif_pkg.sv - core/cvxif_example/include/cvxif_instr_pkg.sv - core/cvxif_fu.sv - core/cvxif_example/cvxif_example_coprocessor.sv diff --git a/core/Flist.cva6 b/core/Flist.cva6 index de27ed54d3..cde9326997 100644 --- a/core/Flist.cva6 +++ b/core/Flist.cva6 @@ -71,11 +71,14 @@ ${CVA6_REPO_DIR}/core/include/instr_tracer_pkg.sv ${CVA6_REPO_DIR}/core/include/build_config_pkg.sv //CVXIF -${CVA6_REPO_DIR}/core/include/cvxif_pkg.sv +${CVA6_REPO_DIR}/core/cvxif_compressed_if_driver.sv +${CVA6_REPO_DIR}/core/cvxif_issue_register_commit_if_driver.sv ${CVA6_REPO_DIR}/core/cvxif_example/include/cvxif_instr_pkg.sv ${CVA6_REPO_DIR}/core/cvxif_fu.sv ${CVA6_REPO_DIR}/core/cvxif_example/cvxif_example_coprocessor.sv ${CVA6_REPO_DIR}/core/cvxif_example/instr_decoder.sv +${CVA6_REPO_DIR}/core/cvxif_example/compressed_instr_decoder.sv +${CVA6_REPO_DIR}/core/cvxif_example/copro_alu.sv // Common Cells ${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/cf_math_pkg.sv diff --git a/core/Flist.cva6_gate b/core/Flist.cva6_gate index 4b743fa19c..ecc3f0b405 100644 --- a/core/Flist.cva6_gate +++ b/core/Flist.cva6_gate @@ -27,12 +27,11 @@ ${CVA6_REPO_DIR}/core/include/instr_tracer_pkg.sv ${CVA6_REPO_DIR}/core/include/build_config_pkg.sv //CVXIF -${CVA6_REPO_DIR}/core/include/cvxif_pkg.sv ${CVA6_REPO_DIR}/core/cvxif_example/include/cvxif_instr_pkg.sv -${CVA6_REPO_DIR}/core/cvxif_fu.sv ${CVA6_REPO_DIR}/core/cvxif_example/cvxif_example_coprocessor.sv ${CVA6_REPO_DIR}/core/cvxif_example/instr_decoder.sv -${CVA6_REPO_DIR}/core/cva6_fifo_v3.sv +${CVA6_REPO_DIR}/core/cvxif_example/compressed_instr_decoder.sv +${CVA6_REPO_DIR}/core/cvxif_example/copro_alu.sv // Common Cells diff --git a/core/cva6.sv b/core/cva6.sv index a0c6b2e845..0bc4a9a449 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -13,6 +13,7 @@ // Description: CVA6 Top-level module `include "rvfi_types.svh" +`include "cvxif_types.svh" module cva6 import ariane_pkg::*; @@ -272,8 +273,22 @@ module cva6 // parameter type acc_cfg_t = logic, parameter acc_cfg_t AccCfg = '0, - parameter type cvxif_req_t = cvxif_pkg::cvxif_req_t, - parameter type cvxif_resp_t = cvxif_pkg::cvxif_resp_t + // CVXIF Types + parameter type readregflags_t = `READREGFLAGS_T(CVA6Cfg), + parameter type writeregflags_t = `WRITEREGFLAGS_T(CVA6Cfg), + parameter type id_t = `ID_T(CVA6Cfg), + parameter type hartid_t = `HARTID_T(CVA6Cfg), + parameter type x_compressed_req_t = `X_COMPRESSED_REQ_T(CVA6Cfg, hartid_t), + parameter type x_compressed_resp_t = `X_COMPRESSED_RESP_T(CVA6Cfg), + parameter type x_issue_req_t = `X_ISSUE_REQ_T(CVA6Cfg, hartit_t, id_t), + parameter type x_issue_resp_t = `X_ISSUE_RESP_T(CVA6Cfg, writeregflags_t, readregflags_t), + parameter type x_register_t = `X_REGISTER_T(CVA6Cfg, hartid_t, id_t, readregflags_t), + parameter type x_commit_t = `X_COMMIT_T(CVA6Cfg, hartid_t, id_t), + parameter type x_result_t = `X_RESULT_T(CVA6Cfg, hartid_t, id_t, writeregflags_t), + parameter type cvxif_req_t = + `CVXIF_REQ_T(CVA6Cfg, x_compressed_req_t, x_issue_req_t, x_register_req_t, x_commit_t), + parameter type cvxif_resp_t = + `CVXIF_RESP_T(CVA6Cfg, x_compressed_resp_t, x_issue_resp_t, x_result_t) ) ( // Subsystem Clock - SUBSYSTEM input logic clk_i, @@ -343,8 +358,27 @@ module cva6 logic [CVA6Cfg.NrCommitPorts-1:0] commit_macro_ack; localparam NumPorts = 4; - cvxif_pkg::cvxif_req_t cvxif_req; - cvxif_pkg::cvxif_resp_t cvxif_resp; + + // CVXIF + cvxif_req_t cvxif_req; + // CVXIF OUTPUTS + logic x_compressed_valid; + x_compressed_req_t x_compressed_req; + logic x_issue_valid; + x_issue_req_t x_issue_req; + logic x_register_valid; + x_register_t x_register; + logic x_commit_valid; + x_commit_t x_commit; + logic x_result_ready; + // CVXIF INPUTS + logic x_compressed_ready; + x_compressed_resp_t x_compressed_resp; + logic x_issue_ready; + x_issue_resp_t x_issue_resp; + logic x_register_ready; + logic x_result_valid; + x_result_t x_result; // -------------- // PCGEN <-> CSR @@ -437,9 +471,11 @@ module cva6 logic x_valid_ex_id; exception_t x_exception_ex_id; logic x_we_ex_id; + logic [4:0] x_rd_ex_id; logic [CVA6Cfg.NrIssuePorts-1:0] x_issue_valid_id_ex; logic x_issue_ready_ex_id; logic [31:0] x_off_instr_id_ex; + logic x_transaction_rejected; // -------------- // EX <-> COMMIT // -------------- @@ -633,7 +669,9 @@ module cva6 .irq_ctrl_t(irq_ctrl_t), .scoreboard_entry_t(scoreboard_entry_t), .interrupts_t(interrupts_t), - .INTERRUPTS(INTERRUPTS) + .INTERRUPTS(INTERRUPTS), + .x_compressed_req_t(x_compressed_req_t), + .x_compressed_resp_t(x_compressed_resp_t) ) id_stage_i ( .clk_i, .rst_ni, @@ -652,20 +690,25 @@ module cva6 .rvfi_is_compressed_o(rvfi_is_compressed), - .priv_lvl_i (priv_lvl), - .v_i (v), - .fs_i (fs), - .vfs_i (vfs), - .frm_i (frm_csr_id_issue_ex), - .vs_i (vs), - .irq_i (irq_i), - .irq_ctrl_i (irq_ctrl_csr_id), - .debug_mode_i(debug_mode), - .tvm_i (tvm_csr_id), - .tw_i (tw_csr_id), - .vtw_i (vtw_csr_id), - .tsr_i (tsr_csr_id), - .hu_i (hu) + .priv_lvl_i (priv_lvl), + .v_i (v), + .fs_i (fs), + .vfs_i (vfs), + .frm_i (frm_csr_id_issue_ex), + .vs_i (vs), + .irq_i (irq_i), + .irq_ctrl_i (irq_ctrl_csr_id), + .debug_mode_i (debug_mode), + .tvm_i (tvm_csr_id), + .tw_i (tw_csr_id), + .vtw_i (vtw_csr_id), + .tsr_i (tsr_csr_id), + .hu_i (hu), + .hart_id_i (hart_id_i), + .compressed_ready_i(x_compressed_ready), + .compressed_resp_i (x_compressed_resp), + .compressed_valid_o(x_compressed_valid), + .compressed_req_o (x_compressed_req) ); logic [CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_ex_id; @@ -693,16 +736,39 @@ module cva6 assign ex_ex_ex_id[FPU_WB] = fpu_exception_ex_id; assign wt_valid_ex_id[FPU_WB] = fpu_valid_ex_id; + always_comb begin : gen_cvxif_input_assignement + x_compressed_ready = cvxif_resp_i.compressed_ready; + x_compressed_resp = cvxif_resp_i.compressed_resp; + x_issue_ready = cvxif_resp_i.issue_ready; + x_issue_resp = cvxif_resp_i.issue_resp; + x_register_ready = cvxif_resp_i.register_ready; + x_result_valid = cvxif_resp_i.result_valid; + x_result = cvxif_resp_i.result; + end if (CVA6Cfg.CvxifEn) begin + always_comb begin : gen_cvxif_output_assignement + cvxif_req.compressed_valid = x_compressed_valid; + cvxif_req.compressed_req = x_compressed_req; + cvxif_req.issue_valid = x_issue_valid; + cvxif_req.issue_req = x_issue_req; + cvxif_req.register_valid = x_register_valid; + cvxif_req.register = x_register; + cvxif_req.commit_valid = x_commit_valid; + cvxif_req.commit = x_commit; + cvxif_req.result_ready = x_result_ready; + end assign trans_id_ex_id[X_WB] = x_trans_id_ex_id; assign wbdata_ex_id[X_WB] = x_result_ex_id; assign ex_ex_ex_id[X_WB] = x_exception_ex_id; assign wt_valid_ex_id[X_WB] = x_valid_ex_id; end else if (CVA6Cfg.EnableAccelerator) begin + assign cvxif_req = '0; assign trans_id_ex_id[ACC_WB] = acc_trans_id_ex_id; assign wbdata_ex_id[ACC_WB] = acc_result_ex_id; assign ex_ex_ex_id[ACC_WB] = acc_exception_ex_id; assign wt_valid_ex_id[ACC_WB] = acc_valid_ex_id; + end else begin + assign cvxif_req = '0; end if (CVA6Cfg.CvxifEn && CVA6Cfg.EnableAccelerator) begin : gen_err_xif_and_acc @@ -718,63 +784,79 @@ module cva6 .branchpredict_sbe_t(branchpredict_sbe_t), .exception_t(exception_t), .fu_data_t(fu_data_t), - .scoreboard_entry_t(scoreboard_entry_t) + .scoreboard_entry_t(scoreboard_entry_t), + .x_issue_req_t(x_issue_req_t), + .x_issue_resp_t(x_issue_resp_t), + .x_register_t(x_register_t), + .x_commit_t(x_commit_t) ) issue_stage_i ( .clk_i, .rst_ni, - .sb_full_o (sb_full), - .flush_unissued_instr_i(flush_unissued_instr_ctrl_id), - .flush_i (flush_ctrl_id), - .stall_i (stall_acc_id), + .sb_full_o (sb_full), + .flush_unissued_instr_i (flush_unissued_instr_ctrl_id), + .flush_i (flush_ctrl_id), + .stall_i (stall_acc_id), // ID Stage - .decoded_instr_i (issue_entry_id_issue), - .orig_instr_i (orig_instr_id_issue), - .decoded_instr_valid_i (issue_entry_valid_id_issue), - .is_ctrl_flow_i (is_ctrl_fow_id_issue), - .decoded_instr_ack_o (issue_instr_issue_id), + .decoded_instr_i (issue_entry_id_issue), + .orig_instr_i (orig_instr_id_issue), + .decoded_instr_valid_i (issue_entry_valid_id_issue), + .is_ctrl_flow_i (is_ctrl_fow_id_issue), + .decoded_instr_ack_o (issue_instr_issue_id), // Functional Units - .rs1_forwarding_o (rs1_forwarding_id_ex), - .rs2_forwarding_o (rs2_forwarding_id_ex), - .fu_data_o (fu_data_id_ex), - .pc_o (pc_id_ex), - .is_compressed_instr_o (is_compressed_instr_id_ex), - .tinst_o (tinst_ex), + .rs1_forwarding_o (rs1_forwarding_id_ex), + .rs2_forwarding_o (rs2_forwarding_id_ex), + .fu_data_o (fu_data_id_ex), + .pc_o (pc_id_ex), + .is_compressed_instr_o (is_compressed_instr_id_ex), + .tinst_o (tinst_ex), // fixed latency unit ready - .flu_ready_i (flu_ready_ex_id), + .flu_ready_i (flu_ready_ex_id), // ALU - .alu_valid_o (alu_valid_id_ex), + .alu_valid_o (alu_valid_id_ex), // Branches and Jumps - .branch_valid_o (branch_valid_id_ex), // branch is valid - .branch_predict_o (branch_predict_id_ex), // branch predict to ex - .resolve_branch_i (resolve_branch_ex_id), // in order to resolve the branch + .branch_valid_o (branch_valid_id_ex), // branch is valid + .branch_predict_o (branch_predict_id_ex), // branch predict to ex + .resolve_branch_i (resolve_branch_ex_id), // in order to resolve the branch // LSU - .lsu_ready_i (lsu_ready_ex_id), - .lsu_valid_o (lsu_valid_id_ex), + .lsu_ready_i (lsu_ready_ex_id), + .lsu_valid_o (lsu_valid_id_ex), // Multiplier - .mult_valid_o (mult_valid_id_ex), + .mult_valid_o (mult_valid_id_ex), // FPU - .fpu_ready_i (fpu_ready_ex_id), - .fpu_valid_o (fpu_valid_id_ex), - .fpu_fmt_o (fpu_fmt_id_ex), - .fpu_rm_o (fpu_rm_id_ex), + .fpu_ready_i (fpu_ready_ex_id), + .fpu_valid_o (fpu_valid_id_ex), + .fpu_fmt_o (fpu_fmt_id_ex), + .fpu_rm_o (fpu_rm_id_ex), // ALU2 - .alu2_valid_o (alu2_valid_id_ex), + .alu2_valid_o (alu2_valid_id_ex), // CSR - .csr_valid_o (csr_valid_id_ex), + .csr_valid_o (csr_valid_id_ex), // CVXIF - .x_issue_valid_o (x_issue_valid_id_ex), - .x_issue_ready_i (x_issue_ready_ex_id), - .x_off_instr_o (x_off_instr_id_ex), + .xfu_valid_o (x_issue_valid_id_ex), + .xfu_ready_i (x_issue_ready_ex_id), + .x_off_instr_o (x_off_instr_id_ex), + .hart_id_i (hart_id_i), + .x_issue_ready_i (x_issue_ready), + .x_issue_resp_i (x_issue_resp), + .x_issue_valid_o (x_issue_valid), + .x_issue_req_o (x_issue_req), + .x_register_ready_i (x_register_ready), + .x_register_valid_o (x_register_valid), + .x_register_o (x_register), + .x_commit_valid_o (x_commit_valid), + .x_commit_o (x_commit), + .x_transaction_rejected_o(x_transaction_rejected), // Accelerator - .issue_instr_o (issue_instr_id_acc), - .issue_instr_hs_o (issue_instr_hs_id_acc), + .issue_instr_o (issue_instr_id_acc), + .issue_instr_hs_o (issue_instr_hs_id_acc), // Commit - .resolved_branch_i (resolved_branch), - .trans_id_i (trans_id_ex_id), - .wbdata_i (wbdata_ex_id), - .ex_ex_i (ex_ex_ex_id), - .wt_valid_i (wt_valid_ex_id), - .x_we_i (x_we_ex_id), + .resolved_branch_i (resolved_branch), + .trans_id_i (trans_id_ex_id), + .wbdata_i (wbdata_ex_id), + .ex_ex_i (ex_ex_ex_id), + .wt_valid_i (wt_valid_ex_id), + .x_we_i (x_we_ex_id), + .x_rd_i (x_rd_ex_id), .waddr_i (waddr_commit_id), .wdata_i (wdata_commit_id), @@ -806,7 +888,8 @@ module cva6 .icache_arsp_t(icache_arsp_t), .icache_dreq_t(icache_dreq_t), .icache_drsp_t(icache_drsp_t), - .lsu_ctrl_t(lsu_ctrl_t) + .lsu_ctrl_t(lsu_ctrl_t), + .x_result_t(x_result_t) ) ex_stage_i ( .clk_i(clk_i), .rst_ni(rst_ni), @@ -877,13 +960,16 @@ module cva6 .x_valid_i (x_issue_valid_id_ex), .x_ready_o (x_issue_ready_ex_id), .x_off_instr_i (x_off_instr_id_ex), + .x_transaction_rejected_i(x_transaction_rejected), .x_trans_id_o (x_trans_id_ex_id), .x_exception_o (x_exception_ex_id), .x_result_o (x_result_ex_id), .x_valid_o (x_valid_ex_id), .x_we_o (x_we_ex_id), - .cvxif_req_o (cvxif_req), - .cvxif_resp_i (cvxif_resp), + .x_rd_o (x_rd_ex_id), + .x_result_valid_i (x_result_valid), + .x_result_i (x_result), + .x_result_ready_o (x_result_ready), // Accelerator .acc_valid_i (acc_valid_acc_ex), // Performance counters @@ -1432,7 +1518,6 @@ module cva6 // Feed through cvxif assign cvxif_req_o = cvxif_req; - assign cvxif_resp = cvxif_resp_i; end : gen_no_accelerator // ------------------- diff --git a/core/cvxif_compressed_if_driver.sv b/core/cvxif_compressed_if_driver.sv new file mode 100644 index 0000000000..e874b9b190 --- /dev/null +++ b/core/cvxif_compressed_if_driver.sv @@ -0,0 +1,74 @@ +// Copyright 2024 Thales DIS France SAS +// +// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 +// You may obtain a copy of the License at https://solderpad.org/licenses/ +// +// Original Author: Guillaume Chauvon + +module cvxif_compressed_if_driver #( + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, + parameter type x_compressed_req_t = logic, + parameter type x_compressed_resp_t = logic +) ( + // Subsystem Clock - SUBSYSTEM + input logic clk_i, + // Asynchronous reset active low - SUBSYSTEM + input logic rst_ni, + // CVA6 Hart id + input logic [CVA6Cfg.XLEN-1:0] hart_id_i, + + input logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_i, + input logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_i, + input logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_i, + + output logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_o, + output logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_o, + output logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_o, + input logic stall_i, + output logic stall_o, + // CVXIF Compressed interface + input logic compressed_ready_i, + input x_compressed_resp_t compressed_resp_i, + output logic compressed_valid_o, + output x_compressed_req_t compressed_req_o +); + + + always_comb begin + is_illegal_o = is_illegal_i; + instruction_o = instruction_i; + is_compressed_o = is_compressed_i; + compressed_valid_o = 1'b0; + compressed_req_o.instr = '0; + compressed_req_o.hartid = hart_id_i; + stall_o = stall_i; + if (is_illegal_i[0]) begin + compressed_valid_o = is_illegal_i[0]; + compressed_req_o.instr = instruction_i[0][15:0]; + is_illegal_o[0] = ~compressed_resp_i.accept; + instruction_o[0] = compressed_resp_i.accept ? compressed_resp_i.instr : instruction_i[0]; + is_compressed_o[0] = compressed_resp_i.accept ? 1'b0 : is_compressed_i[0]; + if (~stall_i) begin + // Propagate stall from macro decoder or wait for compressed ready if compressed transaction is happening. + // Stall if both instruction are illegal + if (CVA6Cfg.SuperscalarEn) begin + stall_o = is_illegal_i[1]; + end else begin + stall_o = (compressed_valid_o && ~compressed_ready_i); + end + end + end + if (CVA6Cfg.SuperscalarEn) begin + if (~is_illegal_i[0] && is_illegal_i[1]) begin // 2nd instruction is illegal + compressed_valid_o = is_illegal_i[1]; + compressed_req_o.instr = instruction_i[1][15:0]; + is_illegal_o[1] = ~compressed_resp_i.accept; + instruction_o[1] = compressed_resp_i.accept ? compressed_resp_i.instr : instruction_i[1]; + is_compressed_o[1] = compressed_resp_i.accept ? 1'b0 : is_compressed_i[1]; + end + end + end + +endmodule diff --git a/core/cvxif_example/compressed_instr_decoder.sv b/core/cvxif_example/compressed_instr_decoder.sv new file mode 100644 index 0000000000..861f05d5be --- /dev/null +++ b/core/cvxif_example/compressed_instr_decoder.sv @@ -0,0 +1,50 @@ +// Copyright 2024 Thales DIS France SAS +// +// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 +// You may obtain a copy of the License at https://solderpad.org/licenses/ +// +// Original Author: Guillaume Chauvon + +module compressed_instr_decoder + import cvxif_instr_pkg::*; +#( + parameter int NbInstr = 1, + parameter copro_compressed_resp_t CoproInstr [NbInstr] = {0}, + parameter type x_compressed_req_t = logic, + parameter type x_compressed_resp_t = logic +) ( + input logic clk_i, + input logic rst_ni, + input logic compressed_valid_i, + input x_compressed_req_t compressed_req_i, + output logic compressed_ready_o, + output x_compressed_resp_t compressed_resp_o +); + + logic [NbInstr-1:0] sel; + + for (genvar i = 0; i < NbInstr; i++) begin : gen_predecoder_selector + assign sel[i] = ((CoproInstr[i].mask & compressed_req_i.instr) == CoproInstr[i].instr); + end + + always_comb begin + compressed_ready_o = '1; + compressed_resp_o.accept = '0; + compressed_resp_o.instr = '0; + for (int unsigned i = 0; i < NbInstr; i++) begin + if (sel[i] && compressed_valid_i) begin + compressed_resp_o.accept = CoproInstr[i].resp.accept; + compressed_resp_o.instr = CoproInstr[i].resp.instr; + // Remap rs1 and rs2 + compressed_resp_o.instr[19:15] = compressed_req_i.instr[11:7]; + compressed_resp_o.instr[24:20] = compressed_req_i.instr[6:2]; + end + end + end + + assert property (@(posedge clk_i) $onehot0(sel)) + else $warning("This offloaded instruction is valid for multiple coprocessor instructions !"); + +endmodule diff --git a/core/cvxif_example/copro_alu.sv b/core/cvxif_example/copro_alu.sv new file mode 100644 index 0000000000..cad4914610 --- /dev/null +++ b/core/cvxif_example/copro_alu.sv @@ -0,0 +1,135 @@ +// Copyright 2024 Thales DIS France SAS +// +// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 +// You may obtain a copy of the License at https://solderpad.org/licenses/ +// +// Original Author: Guillaume Chauvon + +module copro_alu + import cvxif_instr_pkg::*; +#( + parameter int unsigned NrRgprPorts = 2, + parameter type hartid_t = logic, + parameter type id_t = logic, + parameter type registers_t = logic + +) ( + input logic clk_i, + input logic rst_ni, + input registers_t registers_i, + input opcode_t opcode_i, + input hartid_t hartid_i, + input id_t id_i, + input logic [ 4:0] rd_i, + output logic [31:0] result_o, // TODO parametrize to 64 bits + output hartid_t hartid_o, + output id_t id_o, + output logic [ 4:0] rd_o, + output logic valid_o, + output logic we_o +); + + logic [31:0] result_n, result_q; + hartid_t hartid_n, hartid_q; + id_t id_n, id_q; + logic valid_n, valid_q; + logic [4:0] rd_n, rd_q; + logic we_n, we_q; + + assign result_o = result_q; + assign hartid_o = hartid_q; + assign id_o = id_q; + assign valid_o = valid_q; + assign rd_o = rd_q; + assign we_o = we_q; + + always_comb begin + case (opcode_i) + cvxif_instr_pkg::NOP: begin + result_n = '0; + hartid_n = hartid_i; + id_n = id_i; + valid_n = 1'b1; + rd_n = '0; + we_n = '0; + end + cvxif_instr_pkg::ADD: begin + result_n = registers_i[1] + registers_i[0]; + hartid_n = hartid_i; + id_n = id_i; + valid_n = 1'b1; + rd_n = rd_i; + we_n = 1'b1; + end + cvxif_instr_pkg::DOUBLE_RS1: begin + result_n = registers_i[0] + registers_i[0]; + hartid_n = hartid_i; + id_n = id_i; + valid_n = 1'b1; + rd_n = rd_i; + we_n = 1'b1; + end + cvxif_instr_pkg::DOUBLE_RS2: begin + result_n = registers_i[1] + registers_i[1]; + hartid_n = hartid_i; + id_n = id_i; + valid_n = 1'b1; + rd_n = rd_i; + we_n = 1'b1; + end + cvxif_instr_pkg::ADD_MULTI: begin + result_n = registers_i[1] + registers_i[0]; + hartid_n = hartid_i; + id_n = id_i; + valid_n = 1'b1; + rd_n = rd_i; + we_n = 1'b1; + end + cvxif_instr_pkg::ADD_RS3_R4: begin + result_n = NrRgprPorts == 3 ? registers_i[2] + registers_i[1] + registers_i[0] : registers_i[1] + registers_i[0]; + hartid_n = hartid_i; + id_n = id_i; + valid_n = 1'b1; + rd_n = rd_i; + we_n = 1'b1; + end + cvxif_instr_pkg::ADD_RS3_R: begin + result_n = NrRgprPorts == 3 ? registers_i[2] + registers_i[1] + registers_i[0] : registers_i[1] + registers_i[0]; + hartid_n = hartid_i; + id_n = id_i; + valid_n = 1'b1; + rd_n = 5'b01010; + we_n = 1'b1; + end + default: begin + result_n = '0; + hartid_n = '0; + id_n = '0; + valid_n = '0; + rd_n = '0; + we_n = '0; + end + endcase + end + + always_ff @(posedge clk_i, negedge rst_ni) begin + if (~rst_ni) begin + result_q <= '0; + hartid_q <= '0; + id_q <= '0; + valid_q <= '0; + rd_q <= '0; + we_q <= '0; + end else begin + result_q <= result_n; + hartid_q <= hartid_n; + id_q <= id_n; + valid_q <= valid_n; + rd_q <= rd_n; + we_q <= we_n; + end + end + +endmodule diff --git a/core/cvxif_example/cvxif_example_coprocessor.sv b/core/cvxif_example/cvxif_example_coprocessor.sv index 921fdfd0e0..6b30e5d833 100644 --- a/core/cvxif_example/cvxif_example_coprocessor.sv +++ b/core/cvxif_example/cvxif_example_coprocessor.sv @@ -1,19 +1,31 @@ -// Copyright 2021 Thales DIS design services SAS +// Copyright 2024 Thales DIS France SAS // // Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 // You may obtain a copy of the License at https://solderpad.org/licenses/ // -// Original Author: Guillaume Chauvon (guillaume.chauvon@thalesgroup.com) -// Example coprocessor adds rs1,rs2(,rs3) together and gives back the result to the CPU via the CoreV-X-Interface. -// Coprocessor delays the sending of the result depending on result least significant bits. +// Original Author: Guillaume Chauvon module cvxif_example_coprocessor - import cvxif_pkg::*; import cvxif_instr_pkg::*; #( - parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty + // CVXIF Types + parameter int unsigned NrRgprPorts = 2, + parameter type readregflags_t = logic, + parameter type writeregflags_t = logic, + parameter type id_t = logic, + parameter type hartid_t = logic, + parameter type x_compressed_req_t = logic, + parameter type x_compressed_resp_t = logic, + parameter type x_issue_req_t = logic, + parameter type x_issue_resp_t = logic, + parameter type x_register_t = logic, + parameter type x_commit_t = logic, + parameter type x_result_t = logic, + parameter type cvxif_req_t = logic, + parameter type cvxif_resp_t = logic, + localparam type registers_t = logic [NrRgprPorts-1:0][31:0] ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -21,138 +33,115 @@ module cvxif_example_coprocessor output cvxif_resp_t cvxif_resp_o ); - //Compressed interface - logic x_compressed_valid_i; - logic x_compressed_ready_o; - x_compressed_req_t x_compressed_req_i; - x_compressed_resp_t x_compressed_resp_o; - //Issue interface - logic x_issue_valid_i; - logic x_issue_ready_o; - x_issue_req_t x_issue_req_i; - x_issue_resp_t x_issue_resp_o; - //Commit interface - logic x_commit_valid_i; - x_commit_t x_commit_i; - //Memory interface - logic x_mem_valid_o; - logic x_mem_ready_i; - x_mem_req_t x_mem_req_o; - x_mem_resp_t x_mem_resp_i; - //Memory result interface - logic x_mem_result_valid_i; - x_mem_result_t x_mem_result_i; - //Result interface - logic x_result_valid_o; - logic x_result_ready_i; - x_result_t x_result_o; - - assign x_compressed_valid_i = cvxif_req_i.x_compressed_valid; - assign x_compressed_req_i = cvxif_req_i.x_compressed_req; - assign x_issue_valid_i = cvxif_req_i.x_issue_valid; - assign x_issue_req_i = cvxif_req_i.x_issue_req; - assign x_commit_valid_i = cvxif_req_i.x_commit_valid; - assign x_commit_i = cvxif_req_i.x_commit; - assign x_mem_ready_i = cvxif_req_i.x_mem_ready; - assign x_mem_resp_i = cvxif_req_i.x_mem_resp; - assign x_mem_result_valid_i = cvxif_req_i.x_mem_result_valid; - assign x_mem_result_i = cvxif_req_i.x_mem_result; - assign x_result_ready_i = cvxif_req_i.x_result_ready; - - assign cvxif_resp_o.x_compressed_ready = x_compressed_ready_o; - assign cvxif_resp_o.x_compressed_resp = x_compressed_resp_o; - assign cvxif_resp_o.x_issue_ready = x_issue_ready_o; - assign cvxif_resp_o.x_issue_resp = x_issue_resp_o; - assign cvxif_resp_o.x_mem_valid = x_mem_valid_o; - assign cvxif_resp_o.x_mem_req = x_mem_req_o; - assign cvxif_resp_o.x_result_valid = x_result_valid_o; - assign cvxif_resp_o.x_result = x_result_o; - - //Compressed interface - assign x_compressed_ready_o = '0; - assign x_compressed_resp_o.instr = '0; - assign x_compressed_resp_o.accept = '0; + // Compressed interface signals + x_compressed_req_t compressed_req; + x_compressed_resp_t compressed_resp; + logic compressed_valid, compressed_ready; + // Issue interface signals + x_issue_req_t issue_req; + x_issue_resp_t issue_resp; + logic issue_valid, issue_ready; + + // Register interface signals + x_register_t register; + logic register_valid; + + // Decoder and alu signals + registers_t registers; + opcode_t opcode; + hartid_t issue_hartid, hartid; + id_t issue_id, id; + logic [4:0] issue_rd, rd; + logic [31:0] result; + logic we; + + // Issue and Register interface + // Mandatory when X_ISSUE_REGISTER_SPLIT = 0 + assign cvxif_resp_o.compressed_ready = compressed_ready; + assign cvxif_resp_o.compressed_resp = compressed_resp; + assign cvxif_resp_o.issue_ready = issue_ready; + assign cvxif_resp_o.issue_resp = issue_resp; + assign cvxif_resp_o.register_ready = cvxif_resp_o.issue_ready; + + assign compressed_req = cvxif_req_i.compressed_req; + assign compressed_valid = cvxif_req_i.compressed_valid; + assign issue_req = cvxif_req_i.issue_req; + assign issue_valid = cvxif_req_i.issue_valid; + assign register = cvxif_req_i.register; + assign register_valid = cvxif_req_i.register_valid; + + compressed_instr_decoder #( + .NbInstr(cvxif_instr_pkg::NbCompInstr), + .CoproInstr(cvxif_instr_pkg::CoproCompInstr), + .x_compressed_req_t(x_compressed_req_t), + .x_compressed_resp_t(x_compressed_resp_t) + ) compressed_instr_decoder_i ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .compressed_valid_i(compressed_valid), + .compressed_req_i (compressed_req), + .compressed_ready_o(compressed_ready), + .compressed_resp_o (compressed_resp) + ); instr_decoder #( .NbInstr (cvxif_instr_pkg::NbInstr), - .CoproInstr(cvxif_instr_pkg::CoproInstr) + .CoproInstr(cvxif_instr_pkg::CoproInstr), + .NrRgprPorts(NrRgprPorts), + .hartid_t (hartid_t), + .id_t (id_t), + .x_issue_req_t (x_issue_req_t), + .x_issue_resp_t (x_issue_resp_t), + .x_register_t (x_register_t), + .registers_t (registers_t) ) instr_decoder_i ( - .clk_i (clk_i), - .x_issue_req_i (x_issue_req_i), - .x_issue_resp_o(x_issue_resp_o) + .clk_i (clk_i), + .rst_ni (rst_ni), + .issue_valid_i (issue_valid), + .issue_req_i (issue_req), + .issue_ready_o (issue_ready), + .issue_resp_o (issue_resp), + .register_valid_i(register_valid), + .register_i (register), + .registers_o (registers), + .opcode_o (opcode), + .hartid_o (issue_hartid), + .id_o (issue_id), + .rd_o (issue_rd) ); - typedef struct packed { - x_issue_req_t req; - x_issue_resp_t resp; - } x_issue_t; - - logic fifo_full, fifo_empty; - logic x_issue_ready_q; - logic instr_push, instr_pop; - x_issue_t req_i; - x_issue_t req_o; - - - - assign instr_push = x_issue_resp_o.accept ? 1 : 0; - assign instr_pop = (x_commit_i.x_commit_kill && x_commit_valid_i) || x_result_valid_o; - assign x_issue_ready_q = ~fifo_full; // if something is in the fifo, the instruction is being processed - // so we can't receive anything else - assign req_i.req = x_issue_req_i; - assign req_i.resp = x_issue_resp_o; - - always_ff @(posedge clk_i or negedge rst_ni) begin : regs - if (!rst_ni) begin - x_issue_ready_o <= 1; - end else begin - x_issue_ready_o <= x_issue_ready_q; - end - end - - cva6_fifo_v3 #( - .FALL_THROUGH(1), //data_o ready and pop in the same cycle - .DATA_WIDTH (64), - .DEPTH (8), - .dtype (x_issue_t), - .FPGA_EN (CVA6Cfg.FpgaEn) - ) fifo_commit_i ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .flush_i (1'b0), - .testmode_i(1'b0), - .full_o (fifo_full), - .empty_o (fifo_empty), - .usage_o (), - .data_i (req_i), - .push_i (instr_push), - .data_o (req_o), - .pop_i (instr_pop) - ); - - logic [3:0] c; - counter #( - .WIDTH(4) - ) counter_i ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .clear_i (~x_commit_i.x_commit_kill && x_commit_valid_i), - .en_i (1'b1), - .load_i (), - .down_i (), - .d_i (), - .q_o (c), - .overflow_o() + logic alu_valid; + // Result interface + copro_alu #( + .NrRgprPorts(NrRgprPorts), + .hartid_t(hartid_t), + .id_t(id_t), + .registers_t(registers_t) + ) i_copro_alu ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .registers_i(registers), + .opcode_i (opcode), + .hartid_i (issue_hartid), + .id_i (issue_id), + .rd_i (issue_rd), + .hartid_o (hartid), + .id_o (id), + .result_o (result), + .valid_o (alu_valid), + .rd_o (rd), + .we_o (we) ); always_comb begin - x_result_o.data = req_o.req.rs[0] + req_o.req.rs[1] + (X_NUM_RS == 3 ? req_o.req.rs[2] : 0); - x_result_valid_o = (c == x_result_o.data[3:0]) && ~fifo_empty ? 1 : 0; - x_result_o.id = req_o.req.id; - x_result_o.rd = req_o.req.instr[11:7]; - x_result_o.we = req_o.resp.writeback & x_result_valid_o; - x_result_o.exc = 0; - x_result_o.exccode = 0; + cvxif_resp_o.result_valid = alu_valid; //TODO Should wait for ready from CPU + cvxif_resp_o.result.hartid = hartid; + cvxif_resp_o.result.id = id; + cvxif_resp_o.result.data = result; + cvxif_resp_o.result.rd = rd; + cvxif_resp_o.result.we = we; end + + endmodule diff --git a/core/cvxif_example/include/cvxif_instr_pkg.sv b/core/cvxif_example/include/cvxif_instr_pkg.sv index 035cb0488f..2c0c8a34bd 100644 --- a/core/cvxif_example/include/cvxif_instr_pkg.sv +++ b/core/cvxif_example/include/cvxif_instr_pkg.sv @@ -7,40 +7,144 @@ // // Original Author: Guillaume Chauvon (guillaume.chauvon@thalesgroup.com) + + package cvxif_instr_pkg; + typedef enum logic [3:0] { + ILLEGAL = 4'b0000, + NOP = 4'b0001, + ADD = 4'b0010, + DOUBLE_RS1 = 4'b0011, + DOUBLE_RS2 = 4'b0100, + ADD_MULTI = 4'b0101, + ADD_RS3_R4 = 4'b0110, + ADD_RS3_R = 4'b0111 + } opcode_t; + + typedef struct packed { - logic [31:0] instr; - logic [31:0] mask; - cvxif_pkg::x_issue_resp_t resp; + logic accept; + logic writeback; // TODO depends on dualwrite + logic [2:0] register_read; // TODO Nr read ports + } issue_resp_t; + + typedef struct packed { + logic accept; + logic [31:0] instr; + } compressed_resp_t; + + typedef struct packed { + logic [31:0] instr; + logic [31:0] mask; + issue_resp_t resp; + opcode_t opcode; } copro_issue_resp_t; - // 2 Possible RISCV instructions for Coprocessor - parameter int unsigned NbInstr = 2; + + typedef struct packed { + logic [15:0] instr; + logic [15:0] mask; + compressed_resp_t resp; + } copro_compressed_resp_t; + + // 4 Possible RISCV instructions for Coprocessor + parameter int unsigned NbInstr = 10; parameter copro_issue_resp_t CoproInstr[NbInstr] = '{ '{ - instr: 32'b00000_00_00000_00000_0_00_00000_0101011, // custom1 opcode - mask: 32'b00000_00_00000_00000_0_00_00000_1111111, - resp : '{ - accept : 1'b1, - writeback : 1'b0, - dualwrite : 1'b0, - dualread : 1'b0, - loadstore : 1'b0, - exc : 1'b0 - } - }, - '{ - instr: 32'b00000_00_00000_00000_0_00_00000_1011011, // custom2 opcode - mask: 32'b00000_00_00000_00000_0_00_00000_1111111, - resp : '{ - accept : 1'b1, - writeback : 1'b1, - dualwrite : 1'b0, - dualread : 1'b0, - loadstore : 1'b0, - exc : 1'b0 - } + // Custom Nop + instr: + 32'b00000_00_00000_00000_0_00_00000_1111011, // custom3 opcode + mask: 32'b11111_11_00000_00000_1_11_00000_1111111, + resp : '{accept : 1'b1, writeback : 1'b0, register_read : {1'b0, 1'b0, 1'b0}}, + opcode : NOP + }, + '{ + // Custom Add : cus_add rd, rs1, rs2 + instr: + 32'b00000_00_00000_00000_0_01_00000_1111011, // custom3 opcode + mask: 32'b11111_11_00000_00000_1_11_00000_1111111, + resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b0, 1'b1, 1'b1}}, + opcode : ADD + }, + '{ + // Custom Add rs1 : cus_add rd, rs1, rs1 + instr: + 32'b00000_01_00000_00000_0_01_00000_1111011, // custom3 opcode + mask: 32'b11111_11_00000_00000_1_11_00000_1111111, + resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b0, 1'b0, 1'b1}}, + opcode : DOUBLE_RS1 + }, + '{ + // Custom Add rs2 : cus_add rd, rs2, rs2 + instr: + 32'b00000_10_00000_00000_0_01_00000_1111011, // custom3 opcode + mask: 32'b11111_11_00000_00000_1_11_00000_1111111, + resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b0, 1'b1, 1'b0}}, + opcode : DOUBLE_RS2 + }, + '{ + // Custom Add Multi rs1 : cus_add rd, rs1, rs1 + instr: + 32'b00000_11_00000_00000_0_01_00000_1111011, // custom3 opcode + mask: 32'b11111_11_00000_00000_1_11_00000_1111111, + resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b0, 1'b1, 1'b1}}, + opcode : ADD_MULTI + }, + '{ + // Custom Add Multi rs1 : cus_add rd, rs1, rs1 + instr: + 32'b00001_00_00000_00000_0_01_00000_1111011, // custom3 opcode + mask: 32'b11111_11_00000_00000_1_11_00000_1111111, + resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}}, + opcode : ADD_RS3_R + }, + '{ + // Custom Add Multi rs1 : cus_add rd, rs1, rs1 + instr: + 32'b00000_00_00000_00000_0_00_00000_1000011, // MADD opcode + mask: 32'b00000_11_00000_00000_1_11_00000_1111111, + resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}}, + opcode : ADD_RS3_R4 + }, + '{ + // Custom Add Multi rs1 : cus_add rd, rs1, rs1 + instr: + 32'b00000_00_00000_00000_0_00_00000_1000111, // MSUB opcode + mask: 32'b00000_11_00000_00000_1_11_00000_1111111, + resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}}, + opcode : ADD_RS3_R4 + }, + '{ + // Custom Add Multi rs1 : cus_add rd, rs1, rs1 + instr: + 32'b00000_00_00000_00000_0_00_00000_1001011, // NMSUB opcode + mask: 32'b00000_11_00000_00000_1_11_00000_1111111, + resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}}, + opcode : ADD_RS3_R4 + }, + '{ + // Custom Add Multi rs1 : cus_add rd, rs1, rs1 + instr: + 32'b00000_00_00000_00000_0_00_00000_1001111, // NMADD opcode + mask: 32'b00000_11_00000_00000_1_11_00000_1111111, + resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}}, + opcode : ADD_RS3_R4 + } + }; + + parameter int unsigned NbCompInstr = 2; + parameter copro_compressed_resp_t CoproCompInstr[NbCompInstr] = '{ + // C_NOP + '{ + instr : 16'b111_0_00000_00000_00, + mask : 16'b111_1_00000_00000_11, + resp : '{accept : 1'b1, instr : 32'b00000_00_00000_00000_0_00_00000_1111011} + }, + '{ + instr : 16'b111_1_00000_00000_00, + mask : 16'b111_1_00000_00000_11, + resp : '{accept : 1'b1, instr : 32'b00000_00_00000_00000_0_01_01010_1111011} } }; diff --git a/core/cvxif_example/instr_decoder.sv b/core/cvxif_example/instr_decoder.sv index 0cf1bdf32d..6f271695f2 100644 --- a/core/cvxif_example/instr_decoder.sv +++ b/core/cvxif_example/instr_decoder.sv @@ -1,46 +1,86 @@ -// Copyright 2021 Thales DIS design services SAS +// Copyright 2024 Thales DIS France SAS // // Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 // You may obtain a copy of the License at https://solderpad.org/licenses/ // -// Original Author: Guillaume Chauvon (guillaume.chauvon@thalesgroup.com) +// Original Author: Guillaume Chauvon module instr_decoder - import cvxif_pkg::*; + import cvxif_instr_pkg::*; #( - parameter int NbInstr = 1, - parameter cvxif_instr_pkg::copro_issue_resp_t CoproInstr[NbInstr] = {0} + parameter int NbInstr = 1, + parameter copro_issue_resp_t CoproInstr [NbInstr] = {0}, + parameter int unsigned NrRgprPorts = 2, + parameter type hartid_t = logic, + parameter type id_t = logic, + parameter type x_issue_req_t = logic, + parameter type x_issue_resp_t = logic, + parameter type x_register_t = logic, + parameter type registers_t = logic ) ( - input logic clk_i, - input x_issue_req_t x_issue_req_i, - output x_issue_resp_t x_issue_resp_o + input logic clk_i, + input logic rst_ni, + input logic issue_valid_i, + input x_issue_req_t issue_req_i, + output logic issue_ready_o, + output x_issue_resp_t issue_resp_o, + input logic register_valid_i, + input x_register_t register_i, + output registers_t registers_o, + output opcode_t opcode_o, + output hartid_t hartid_o, + output id_t id_o, + output logic [4:0] rd_o ); logic [NbInstr-1:0] sel; + logic rs1_ready; + logic rs2_ready; + logic rs3_ready; for (genvar i = 0; i < NbInstr; i++) begin : gen_predecoder_selector - assign sel[i] = ((CoproInstr[i].mask & x_issue_req_i.instr) == CoproInstr[i].instr); + assign sel[i] = ((CoproInstr[i].mask & issue_req_i.instr) == CoproInstr[i].instr); end always_comb begin - x_issue_resp_o.accept = '0; - x_issue_resp_o.writeback = '0; - x_issue_resp_o.dualwrite = '0; - x_issue_resp_o.dualread = '0; - x_issue_resp_o.loadstore = '0; - x_issue_resp_o.exc = '0; + rs1_ready = '0; + rs2_ready = '0; + rs3_ready = '0; + issue_ready_o = '0; + issue_resp_o.accept = '0; + issue_resp_o.writeback = '0; + issue_resp_o.register_read = '0; + registers_o = '0; + opcode_o = ILLEGAL; + hartid_o = '0; + id_o = '0; + rd_o = '0; for (int unsigned i = 0; i < NbInstr; i++) begin - if (sel[i]) begin - x_issue_resp_o.accept = CoproInstr[i].resp.accept; - x_issue_resp_o.writeback = CoproInstr[i].resp.writeback; - x_issue_resp_o.dualwrite = CoproInstr[i].resp.dualwrite; - x_issue_resp_o.dualread = CoproInstr[i].resp.dualread; - x_issue_resp_o.loadstore = CoproInstr[i].resp.loadstore; - x_issue_resp_o.exc = CoproInstr[i].resp.exc; + if (sel[i] && issue_valid_i) begin + issue_resp_o.accept = CoproInstr[i].resp.accept; + issue_resp_o.writeback = CoproInstr[i].resp.writeback; + issue_resp_o.register_read = CoproInstr[i].resp.register_read; // Warning : potential 3 bits vector into 2 bits one + if (issue_resp_o.accept) begin + rs1_ready = (~CoproInstr[i].resp.register_read[0] || register_i.rs_valid[0]); + rs2_ready = (~CoproInstr[i].resp.register_read[1] || register_i.rs_valid[1]); + rs3_ready = NrRgprPorts == 3 ? (~CoproInstr[i].resp.register_read[2] || register_i.rs_valid[2]) : 1'b1; + issue_ready_o = rs1_ready && rs2_ready && rs3_ready; + end + opcode_o = CoproInstr[i].opcode; + id_o = issue_req_i.id; + hartid_o = issue_req_i.hartid; + rd_o = issue_req_i.instr[11:7]; + for (int unsigned j = 0; j < NrRgprPorts; j++) begin + registers_o[j] = issue_resp_o.register_read[j] ? register_i.rs[j] : '0; + end end end + // Coprocessor could not decode offloaded instruction -> instruction is not accepted + if (issue_valid_i && ~(|sel)) begin + issue_ready_o = 1'b1; + end end assert property (@(posedge clk_i) $onehot0(sel)) diff --git a/core/cvxif_fu.sv b/core/cvxif_fu.sv index 4630be9e1a..255504cd1e 100644 --- a/core/cvxif_fu.sv +++ b/core/cvxif_fu.sv @@ -1,13 +1,14 @@ -// Copyright 2021 Thales DIS design services SAS +// Copyright 2024 Thales DIS France SAS // // Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 // You may obtain a copy of the License at https://solderpad.org/licenses/ // -// Original Author: Guillaume CHAUVON (guillaume.chauvon@thalesgroup.com) +// Original Author: Guillaume Chauvon -// Functional Unit for the logic of the CoreV-X-Interface +// Functional Unit for the CoreV-X-Interface +// Handles Result interface and exception forwarding to next stages. module cvxif_fu @@ -15,116 +16,60 @@ module cvxif_fu #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type exception_t = logic, - parameter type fu_data_t = logic + parameter type x_result_t = logic ) ( // Subsystem Clock - SUBSYSTEM - input logic clk_i, + input logic clk_i, // Asynchronous reset active low - SUBSYSTEM - input logic rst_ni, - // FU data needed to execute instruction - ISSUE_STAGE - input fu_data_t fu_data_i, - // Current privilege mode - CSR_REGFILE - input riscv::priv_lvl_t priv_lvl_i, + input logic rst_ni, // CVXIF instruction is valid - ISSUE_STAGE - input logic x_valid_i, - // CVXIF is ready - ISSUE_STAGE - output logic x_ready_o, + input logic x_valid_i, + // Transaction ID - ISSUE_STAGE + input logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_i, + // Instruction is illegal, determined during CVXIF issue transaction - ISSUE_STAGE + input logic x_illegal_i, // Offloaded instruction - ISSUE_STAGE - input logic [ 31:0] x_off_instr_i, - // CVXIF transaction ID - ISSUE_STAGE - output logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_o, + input logic [ 31:0] x_off_instr_i, + // CVXIF is ready - ISSUE_STAGE + output logic x_ready_o, + // CVXIF result transaction ID - ISSUE_STAGE + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_o, // CVXIF exception - ISSUE_STAGE - output exception_t x_exception_o, + output exception_t x_exception_o, // CVXIF FU result - ISSUE_STAGE - output logic [ CVA6Cfg.XLEN-1:0] x_result_o, + output logic [ CVA6Cfg.XLEN-1:0] x_result_o, // CVXIF result valid - ISSUE_STAGE - output logic x_valid_o, + output logic x_valid_o, // CVXIF write enable - ISSUE_STAGE - output logic x_we_o, - // CVXIF request - SUBSYSTEM - output cvxif_pkg::cvxif_req_t cvxif_req_o, - // CVXIF response - SUBSYSTEM - input cvxif_pkg::cvxif_resp_t cvxif_resp_i + output logic x_we_o, + // CVXIF destination register - ISSUE_STAGE + output logic [ 4:0] x_rd_o, + // CVXIF result interface + input logic result_valid_i, + input x_result_t result_i, + output logic result_ready_o ); - localparam X_NUM_RS = ariane_pkg::NR_RGPR_PORTS; - logic illegal_n, illegal_q; - logic [CVA6Cfg.TRANS_ID_BITS-1:0] illegal_id_n, illegal_id_q; - logic [31:0] illegal_instr_n, illegal_instr_q; - logic [X_NUM_RS-1:0] rs_valid; - if (cvxif_pkg::X_NUM_RS == 3) begin : gen_third_operand - assign rs_valid = 3'b111; - end else begin : gen_no_third_operand - assign rs_valid = 2'b11; - end - always_comb begin - cvxif_req_o = '0; - cvxif_req_o.x_result_ready = 1'b1; - x_ready_o = cvxif_resp_i.x_issue_ready; - if (x_valid_i) begin - cvxif_req_o.x_issue_valid = x_valid_i; - cvxif_req_o.x_issue_req.instr = x_off_instr_i; - cvxif_req_o.x_issue_req.mode = priv_lvl_i; - cvxif_req_o.x_issue_req.id = fu_data_i.trans_id; - cvxif_req_o.x_issue_req.rs[0] = fu_data_i.operand_a; - cvxif_req_o.x_issue_req.rs[1] = fu_data_i.operand_b; - if (cvxif_pkg::X_NUM_RS == 3) begin - cvxif_req_o.x_issue_req.rs[2] = fu_data_i.imm; - end - cvxif_req_o.x_issue_req.rs_valid = rs_valid; - cvxif_req_o.x_commit_valid = x_valid_i; - cvxif_req_o.x_commit.id = fu_data_i.trans_id; - cvxif_req_o.x_commit.x_commit_kill = 1'b0; - end - end + assign result_ready_o = 1'b1; - always_comb begin - illegal_n = illegal_q; - illegal_id_n = illegal_id_q; - illegal_instr_n = illegal_instr_q; - if (~cvxif_resp_i.x_issue_resp.accept && cvxif_req_o.x_issue_valid && cvxif_resp_i.x_issue_ready && ~illegal_n) begin - illegal_n = 1'b1; - illegal_id_n = cvxif_req_o.x_issue_req.id; - illegal_instr_n = cvxif_req_o.x_issue_req.instr; - end - x_valid_o = cvxif_resp_i.x_result_valid; //Read result only when CVXIF is enabled - x_trans_id_o = x_valid_o ? cvxif_resp_i.x_result.id : '0; - x_result_o = x_valid_o ? cvxif_resp_i.x_result.data : '0; - x_exception_o.cause = x_valid_o ? {{(CVA6Cfg.XLEN-6){1'b0}}, cvxif_resp_i.x_result.exccode} : '0; - x_exception_o.valid = x_valid_o ? cvxif_resp_i.x_result.exc : '0; - x_exception_o.tval = '0; - x_exception_o.tinst = '0; - x_exception_o.tval2 = '0; - x_exception_o.gva = '0; - x_we_o = x_valid_o ? cvxif_resp_i.x_result.we : '0; - if (illegal_n) begin - if (~x_valid_o) begin - x_trans_id_o = illegal_id_n; - x_result_o = '0; - x_valid_o = 1'b1; - x_exception_o.cause = riscv::ILLEGAL_INSTR; - x_exception_o.valid = 1'b1; - if (CVA6Cfg.TvalEn) x_exception_o.tval = illegal_instr_n; - x_exception_o.tinst = '0; - x_exception_o.tval2 = '0; - x_exception_o.gva = '0; - x_we_o = '0; - illegal_n = '0; // Reset flag for illegal instr. illegal_id and illegal instr values are a don't care, no need to reset it. - end - end - end + assign x_ready_o = 1'b1; // Readyness of cvxif_fu is determined in issue stage by CVXIF issue interface + // Result signals + assign x_valid_o = x_illegal_i ? 1'b1 : result_valid_i; + assign x_result_o = result_i.data; + assign x_trans_id_o = x_illegal_i ? x_trans_id_i : result_i.id; + assign x_we_o = result_i.we; + assign x_rd_o = result_i.rd; - always_ff @(posedge clk_i, negedge rst_ni) begin - if (~rst_ni) begin - illegal_q <= 1'b0; - illegal_id_q <= '0; - illegal_instr_q <= '0; - end else begin - illegal_q <= illegal_n; - illegal_id_q <= illegal_id_n; - illegal_instr_q <= illegal_instr_n; + // Handling of illegal instruction exception + always_comb begin + x_exception_o = '0; // No exception in this interface + if (x_illegal_i) begin + x_exception_o.valid = '1; + x_exception_o.cause = riscv::ILLEGAL_INSTR; + if (CVA6Cfg.TvalEn) + x_exception_o.tval = x_off_instr_i; // TODO Optimization : Set exception in IRO. end end diff --git a/core/cvxif_issue_register_commit_if_driver.sv b/core/cvxif_issue_register_commit_if_driver.sv new file mode 100644 index 0000000000..e550d773d1 --- /dev/null +++ b/core/cvxif_issue_register_commit_if_driver.sv @@ -0,0 +1,68 @@ +// Copyright 2024 Thales DIS France SAS +// +// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 +// You may obtain a copy of the License at https://solderpad.org/licenses/ +// +// Original Author: Guillaume Chauvon + +module cvxif_issue_register_commit_if_driver #( + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, + parameter type x_issue_req_t = logic, + parameter type x_issue_resp_t = logic, + parameter type x_register_t = logic, + parameter type x_commit_t = logic +) ( + // CVA6 inputs + input logic clk_i, + input logic rst_ni, + input logic flush_i, + input logic [ CVA6Cfg.XLEN-1:0] hart_id_i, + // CVXIF Issue interface + input logic issue_ready_i, + input x_issue_resp_t issue_resp_i, + output logic issue_valid_o, + output x_issue_req_t issue_req_o, + // CVXIF Register interface + input logic register_ready_i, + output logic register_valid_o, + output x_register_t register_o, + // CVXIF Commit interface + output logic commit_valid_o, + output x_commit_t commit_o, + // IRO in/out + input logic valid_i, + input logic [ 31:0] x_off_instr_i, + input logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_i, + input logic [ CVA6Cfg.NrRgprPorts-1:0][CVA6Cfg.XLEN-1:0] register_i, + input logic [ CVA6Cfg.NrRgprPorts-1:0] rs_valid_i, + output logic cvxif_busy_o +); + // X_ISSUE_REGISTER_SPLIT = 0 : Issue and register transactions are synchrone + // Mandatory assignement + assign register_valid_o = issue_valid_o; + assign register_o.hartid = issue_req_o.hartid; + assign register_o.id = issue_req_o.id; + // cvxif can not take any more instruction if issue transaction is still up. + assign cvxif_busy_o = issue_valid_o && ~issue_ready_i; + always_comb begin + issue_valid_o = valid_i && ~flush_i; + issue_req_o.instr = x_off_instr_i; + issue_req_o.hartid = hart_id_i; + issue_req_o.id = x_trans_id_i; + register_o.rs = register_i; + register_o.rs_valid = rs_valid_i; + end + + /* WARNING */ + // Always commit since speculation in execute in not possible : TODO to be verified + + // Always do commit transaction with issue + // If instruction goes to execute then it is not speculative + assign commit_valid_o = issue_valid_o; + assign commit_o.hartid = issue_req_o.hartid; + assign commit_o.id = issue_req_o.id; + assign commit_o.commit_kill = 1'b0; + +endmodule diff --git a/core/decoder.sv b/core/decoder.sv index 703ab7c074..5f30ac8880 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -112,7 +112,8 @@ module decoder SBIMM, UIMM, JIMM, - RS3 + RS3, + MUX_RD_RS3 } imm_select; logic [CVA6Cfg.XLEN-1:0] imm_i_type; @@ -1422,13 +1423,16 @@ module decoder endcase end if (CVA6Cfg.CvxifEn) begin - if (is_illegal_i || illegal_instr) begin - instruction_o.fu = CVXIF; + if (~ex_i.valid && (is_illegal_i || illegal_instr)) begin + instruction_o.fu = CVXIF; instruction_o.rs1[4:0] = instr.r4type.rs1; instruction_o.rs2[4:0] = instr.r4type.rs2; - instruction_o.rd[4:0] = instr.r4type.rd; - instruction_o.op = ariane_pkg::OFFLOAD; - imm_select = RS3; + instruction_o.rd[4:0] = instr.r4type.rd; + instruction_o.op = ariane_pkg::OFFLOAD; + imm_select = instr.rtype.opcode == riscv::OpcodeMadd || + instr.rtype.opcode == riscv::OpcodeMsub || + instr.rtype.opcode == riscv::OpcodeNmadd || + instr.rtype.opcode == riscv::OpcodeNmsub ? RS3 : MUX_RD_RS3; end end @@ -1504,6 +1508,11 @@ module decoder instruction_o.result = {{CVA6Cfg.XLEN - 5{1'b0}}, instr.r4type.rs3}; instruction_o.use_imm = 1'b0; end + MUX_RD_RS3: begin + // result holds address of operand rs3 which is in rd field + instruction_o.result = {{CVA6Cfg.XLEN - 5{1'b0}}, instr.rtype.rd}; + instruction_o.use_imm = 1'b0; + end default: begin instruction_o.result = {CVA6Cfg.XLEN{1'b0}}; instruction_o.use_imm = 1'b0; diff --git a/core/ex_stage.sv b/core/ex_stage.sv index d44aa5ea05..5f11ebe3c0 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -28,7 +28,8 @@ module ex_stage parameter type icache_arsp_t = logic, parameter type icache_dreq_t = logic, parameter type icache_drsp_t = logic, - parameter type lsu_ctrl_t = logic + parameter type lsu_ctrl_t = logic, + parameter type x_result_t = logic ) ( // Subsystem Clock - SUBSYSTEM input logic clk_i, @@ -136,7 +137,7 @@ module ex_stage input logic [CVA6Cfg.NrIssuePorts-1:0] x_valid_i, // CVXIF is ready - ISSUE_STAGE output logic x_ready_o, - // undecoded instruction - ISSUE_STAGE + // CVXIF undecoded instruction input logic [31:0] x_off_instr_i, // CVXIF transaction ID - ISSUE_STAGE output logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_o, @@ -148,10 +149,14 @@ module ex_stage output logic x_valid_o, // CVXIF write enable - ISSUE_STAGE output logic x_we_o, - // CVXIF request - SUBSYSTEM - output cvxif_pkg::cvxif_req_t cvxif_req_o, - // CVXIF response - SUBSYSTEM - input cvxif_pkg::cvxif_resp_t cvxif_resp_i, + // CVXIF destination register - ISSUE_STAGE + output logic [4:0] x_rd_o, + // CVXIF Result interface - SUBSYSTEM + input logic x_result_valid_i, + input x_result_t x_result_i, + output logic x_result_ready_o, + // CVXIF Issue transaction rejected -> illegal instruction - ISSUE_STAGE + input logic x_transaction_rejected_i, // accelerate port result is valid - ACC_DISPATCHER input logic acc_valid_i, // Enable virtual memory translation - CSR_REGFILE @@ -592,29 +597,31 @@ module ex_stage cvxif_fu #( .CVA6Cfg(CVA6Cfg), .exception_t(exception_t), - .fu_data_t(fu_data_t) + .x_result_t(x_result_t) ) cvxif_fu_i ( .clk_i, .rst_ni, - .fu_data_i (cvxif_data), - .priv_lvl_i(ld_st_priv_lvl_i), - .x_valid_i (|x_valid_i), - .x_ready_o, + .x_valid_i(|x_valid_i), + .x_trans_id_i(cvxif_data.trans_id), + .x_illegal_i(x_transaction_rejected_i), .x_off_instr_i, + .x_ready_o, .x_trans_id_o, .x_exception_o, .x_result_o, .x_valid_o, .x_we_o, - .cvxif_req_o, - .cvxif_resp_i + .x_rd_o, + .result_valid_i(x_result_valid_i), + .result_i(x_result_i), + .result_ready_o(x_result_ready_o) ); end else begin : gen_no_cvxif - assign cvxif_req_o = '0; - assign x_trans_id_o = '0; - assign x_exception_o = '0; - assign x_result_o = '0; - assign x_valid_o = '0; + assign x_result_ready_o = '0; + assign x_trans_id_o = '0; + assign x_exception_o = '0; + assign x_result_o = '0; + assign x_valid_o = '0; end if (CVA6Cfg.RVS) begin diff --git a/core/id_stage.sv b/core/id_stage.sv index b11f758ab3..864c74b329 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -21,7 +21,9 @@ module id_stage #( parameter type irq_ctrl_t = logic, parameter type scoreboard_entry_t = logic, parameter type interrupts_t = logic, - parameter interrupts_t INTERRUPTS = '0 + parameter interrupts_t INTERRUPTS = '0, + parameter type x_compressed_req_t = logic, + parameter type x_compressed_resp_t = logic ) ( // Subsystem Clock - SUBSYSTEM input logic clk_i, @@ -76,7 +78,13 @@ module id_stage #( // Trap sret - CSR_REGFILE input logic tsr_i, // Hypervisor user mode - CSR_REGFILE - input logic hu_i + input logic hu_i, + // CVXIF Compressed interface + input logic [CVA6Cfg.XLEN-1:0] hart_id_i, + input logic compressed_ready_i, + input x_compressed_resp_t compressed_resp_i, + output logic compressed_valid_o, + output x_compressed_req_t compressed_req_o ); // ID/ISSUE register stage typedef struct packed { @@ -93,12 +101,17 @@ module id_stage #( logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal; logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cmp; + logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cvxif; logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction; logic [CVA6Cfg.NrIssuePorts-1:0][31:0] compressed_instr; + logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_cvxif; logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed; logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cmp; + logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cvxif; + logic [CVA6Cfg.NrIssuePorts-1:0] is_macro_instr_i; logic stall_instr_fetch; + logic stall_macro_deco; logic is_last_macro_instr_o; logic is_double_rd_macro_instr_o; @@ -126,25 +139,64 @@ module id_stage #( .is_macro_instr_i (is_macro_instr_i[0]), .clk_i (clk_i), .rst_ni (rst_ni), - .instr_o (instruction[0]), + .instr_o (instruction_cvxif[0]), .illegal_instr_i (is_illegal[0]), .is_compressed_i (is_compressed[0]), .issue_ack_i (issue_instr_ack_i[0]), - .illegal_instr_o (is_illegal_cmp[0]), - .is_compressed_o (is_compressed_cmp[0]), - .fetch_stall_o (stall_instr_fetch), + .illegal_instr_o (is_illegal_cvxif[0]), + .is_compressed_o (is_compressed_cvxif[0]), + .fetch_stall_o (stall_macro_deco), .is_last_macro_instr_o (is_last_macro_instr_o), .is_double_rd_macro_instr_o(is_double_rd_macro_instr_o) ); if (CVA6Cfg.SuperscalarEn) begin - assign instruction[CVA6Cfg.NrIssuePorts-1] = '0; - assign is_illegal_cmp[CVA6Cfg.NrIssuePorts-1] = '0; - assign is_compressed_cmp[CVA6Cfg.NrIssuePorts-1] = '0; + assign instruction_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; + assign is_illegal_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; + assign is_compressed_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; end + cvxif_compressed_if_driver #( + .CVA6Cfg(CVA6Cfg), + .x_compressed_req_t(x_compressed_req_t), + .x_compressed_resp_t(x_compressed_resp_t) + ) i_cvxif_compressed_if_driver_i ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .hart_id_i (hart_id_i), + .is_compressed_i (is_compressed_cvxif), + .is_illegal_i (is_illegal_cvxif), + .instruction_i (instruction_cvxif), + .is_compressed_o (is_compressed_cmp), + .is_illegal_o (is_illegal_cmp), + .instruction_o (instruction), + .stall_i (stall_macro_deco), + .stall_o (stall_instr_fetch), + .compressed_ready_i(compressed_ready_i), + .compressed_resp_i (compressed_resp_i), + .compressed_valid_o(compressed_valid_o), + .compressed_req_o (compressed_req_o) + ); end else begin - assign instruction = compressed_instr; - assign is_illegal_cmp = is_illegal; - assign is_compressed_cmp = is_compressed; + cvxif_compressed_if_driver #( + .CVA6Cfg(CVA6Cfg), + .x_compressed_req_t(x_compressed_req_t), + .x_compressed_resp_t(x_compressed_resp_t) + ) i_cvxif_compressed_if_driver_i ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .hart_id_i (hart_id_i), + .is_compressed_i (is_compressed), + .is_illegal_i (is_illegal), + .instruction_i (compressed_instr), + .is_compressed_o (is_compressed_cmp), + .is_illegal_o (is_illegal_cmp), + .instruction_o (instruction), + .stall_i (1'b0), + .stall_o (stall_instr_fetch), + .compressed_ready_i(compressed_ready_i), + .compressed_resp_i (compressed_resp_i), + .compressed_valid_o(compressed_valid_o), + .compressed_req_o (compressed_req_o) + ); assign is_last_macro_instr_o = '0; assign is_double_rd_macro_instr_o = '0; end @@ -157,6 +209,11 @@ module id_stage #( assign is_macro_instr_i = '0; assign is_last_macro_instr_o = '0; assign is_double_rd_macro_instr_o = '0; + if (CVA6Cfg.CvxifEn) begin + assign compressed_valid_o = '0; + assign compressed_req_o.instr = '0; + assign compressed_req_o.hartid = hart_id_i; + end // TODO Add else to map x_compressed_if outputs to '0 ? end assign rvfi_is_compressed_o = is_compressed_cmp; diff --git a/core/include/build_config_pkg.sv b/core/include/build_config_pkg.sv index fdfd4c0a6a..1da077eba5 100644 --- a/core/include/build_config_pkg.sv +++ b/core/include/build_config_pkg.sv @@ -84,7 +84,9 @@ package build_config_pkg; cfg.XF16Vec = bit'(XF16Vec); cfg.XF16ALTVec = bit'(XF16ALTVec); cfg.XF8Vec = bit'(XF8Vec); + // Can take 2 or 3 in single issue. 4 or 6 in dual issue. cfg.NrRgprPorts = unsigned'(CVA6Cfg.SuperscalarEn ? 4 : 2); + // cfg.NrRgprPorts = unsigned'(CVA6Cfg.SuperscalarEn ? 6 : 3); cfg.NrWbPorts = unsigned'(NrWbPorts); cfg.EnableAccelerator = bit'(EnableAccelerator); cfg.PerfCounterEn = CVA6Cfg.PerfCounterEn; @@ -165,6 +167,16 @@ package build_config_pkg; cfg.VpnLen = VpnLen; cfg.PtLevels = PtLevels; + cfg.X_NUM_RS = cfg.NrRgprPorts; + cfg.X_ID_WIDTH = cfg.TRANS_ID_BITS; + cfg.X_RFR_WIDTH = cfg.XLEN; + cfg.X_RFW_WIDTH = cfg.XLEN; + cfg.X_NUM_HARTS = 1; + cfg.X_HARTID_WIDTH = cfg.XLEN; + cfg.X_DUALREAD = 0; + cfg.X_DUALWRITE = 0; + cfg.X_ISSUE_REGISTER_SPLIT = 0; + return cfg; endfunction diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index 7021162e4c..4186f91210 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -337,6 +337,17 @@ package config_pkg; vm_mode_t MODE_SV; int unsigned SV; int unsigned SVX; + + int unsigned X_NUM_RS; + int unsigned X_ID_WIDTH; + int unsigned X_RFR_WIDTH; + int unsigned X_RFW_WIDTH; + int unsigned X_NUM_HARTS; + int unsigned X_HARTID_WIDTH; + int unsigned X_DUALREAD; + int unsigned X_DUALWRITE; + int unsigned X_ISSUE_REGISTER_SPLIT; + } cva6_cfg_t; /// Empty configuration to sanity check proper parameter passing. Whenever diff --git a/core/include/cv32a65x_config_pkg.sv b/core/include/cv32a65x_config_pkg.sv index a1fd6c83d1..c5056aa3a6 100644 --- a/core/include/cv32a65x_config_pkg.sv +++ b/core/include/cv32a65x_config_pkg.sv @@ -18,8 +18,6 @@ package cva6_config_pkg; localparam CVA6ConfigAxiDataWidth = 64; // axi_pkg.sv localparam CVA6ConfigDataUserWidth = 32; // axi_pkg.sv - localparam CVA6ConfigNrScoreboardEntries = 8; // cvxif_pkg.sv - localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{ XLEN: unsigned'(CVA6ConfigXlen), FpgaEn: bit'(0), @@ -49,7 +47,7 @@ package cva6_config_pkg; RVZiCond: bit'(0), RVZicntr: bit'(0), RVZihpm: bit'(0), - NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries), + NrScoreboardEntries: unsigned'(8), PerfCounterEn: bit'(0), MmuPresent: bit'(0), RVS: bit'(0), diff --git a/core/include/cvxif_pkg.sv b/core/include/cvxif_pkg.sv deleted file mode 100644 index 57bd40b01e..0000000000 --- a/core/include/cvxif_pkg.sv +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2021 Thales DIS design services SAS -// -// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 -// You may obtain a copy of the License at https://solderpad.org/licenses/ -// -// Original Author: Guillaume CHAUVON (guillaume.chauvon@thalesgroup.com) - -// Package for the CoreV-X-Interface for the CVA6 - -package cvxif_pkg; - - localparam X_DATAWIDTH = riscv::XLEN; - localparam X_NUM_RS = ariane_pkg::NR_RGPR_PORTS; //2 or 3 - localparam X_ID_WIDTH = $clog2(cva6_config_pkg::CVA6ConfigNrScoreboardEntries); - localparam X_MEM_WIDTH = 64; - localparam X_RFR_WIDTH = riscv::XLEN; - localparam X_RFW_WIDTH = riscv::XLEN; - - typedef struct packed { - logic [15:0] instr; - logic [1:0] mode; - logic [X_ID_WIDTH-1:0] id; - } x_compressed_req_t; - - typedef struct packed { - logic [31:0] instr; - logic accept; - } x_compressed_resp_t; - - typedef struct packed { - logic [31:0] instr; - logic [1:0] mode; - logic [X_ID_WIDTH-1:0] id; - logic [X_NUM_RS-1:0][X_RFR_WIDTH-1:0] rs; - logic [X_NUM_RS-1:0] rs_valid; - } x_issue_req_t; - - typedef struct packed { - logic accept; - logic writeback; - logic dualwrite; - logic dualread; - logic loadstore; - logic exc; - } x_issue_resp_t; - - typedef struct packed { - logic [X_ID_WIDTH-1:0] id; - logic x_commit_kill; - } x_commit_t; - - typedef struct packed { - logic [X_ID_WIDTH-1:0] id; - logic [31:0] addr; - logic [1:0] mode; - logic we; - logic [1:0] size; - logic [X_MEM_WIDTH-1:0] wdata; - logic last; - logic spec; - } x_mem_req_t; - - typedef struct packed { - logic exc; - logic [5:0] exccode; - } x_mem_resp_t; - - typedef struct packed { - logic [X_ID_WIDTH-1:0] id; - logic [X_MEM_WIDTH-1:0] rdata; - logic err; - } x_mem_result_t; - - typedef struct packed { - logic [X_ID_WIDTH-1:0] id; - logic [X_RFW_WIDTH-1:0] data; - logic [4:0] rd; - logic we; - logic exc; - logic [5:0] exccode; - } x_result_t; - - typedef struct packed { - logic x_compressed_valid; - x_compressed_req_t x_compressed_req; - logic x_issue_valid; - x_issue_req_t x_issue_req; - logic x_commit_valid; - x_commit_t x_commit; - logic x_mem_ready; - x_mem_resp_t x_mem_resp; - logic x_mem_result_valid; - x_mem_result_t x_mem_result; - logic x_result_ready; - } cvxif_req_t; - - typedef struct packed { - logic x_compressed_ready; - x_compressed_resp_t x_compressed_resp; - logic x_issue_ready; - x_issue_resp_t x_issue_resp; - logic x_mem_valid; - x_mem_req_t x_mem_req; - logic x_result_valid; - x_result_t x_result; - } cvxif_resp_t; - -endpackage diff --git a/core/include/cvxif_types.svh b/core/include/cvxif_types.svh new file mode 100644 index 0000000000..211742e05a --- /dev/null +++ b/core/include/cvxif_types.svh @@ -0,0 +1,73 @@ +`ifndef CVXIF_TYPES_SVH +`define CVXIF_TYPES_SVH + +//CVXIF +`define READREGFLAGS_T(Cfg) logic [Cfg.X_NUM_RS+Cfg.X_DUALREAD-1:0] +`define WRITEREGFLAGS_T(Cfg) logic [Cfg.X_DUALWRITE:0] +`define ID_T(Cfg) logic [Cfg.X_ID_WIDTH-1:0] +`define HARTID_T(Cfg) logic [Cfg.X_HARTID_WIDTH-1:0] + +`define X_COMPRESSED_REQ_T(Cfg, hartid_t) struct packed { \ + logic [15:0] instr; /*Offloaded compressed instruction*/ \ + hartid_t hartid; /*Identification of the hart offloading the instruction*/ \ +} +`define X_COMPRESSED_RESP_T(Cfg) struct packed { \ + logic [31:0] instr; /*Uncompressed instruction*/ \ + logic accept; /*Is the offloaded compressed instruction (id) accepted by the coprocessor?*/ \ +} + +`define X_ISSUE_REQ_T(Cfg, hartit_t, id_t) struct packed { \ + logic [31:0] instr; /*Offloaded instruction*/ \ + hartid_t hartid; /*Identification of the hart offloading the instruction*/ \ + id_t id; /*Identification of the offloaded instruction*/ \ +} +`define X_ISSUE_RESP_T(Cfg, writeregflags_t, readregflags_t) struct packed { \ + logic accept; /*Is the offloaded instruction (id) accepted by the coprocessor?*/ \ + writeregflags_t writeback; /*Will the coprocessor perform a writeback in the core to rd?*/ \ + readregflags_t register_read; /*Will the coprocessor perform require specific registers to be read?*/ \ +} + +`define X_REGISTER_T(Cfg, hartid_t, id_t, readregflags_t) struct packed { \ + hartid_t hartid; /*Identification of the hart offloading the instruction*/ \ + id_t id; /*Identification of the offloaded instruction*/ \ + logic [Cfg.X_NUM_RS-1:0][Cfg.X_RFR_WIDTH-1:0] rs; /*Register file source operands for the offloaded instruction.*/ \ + readregflags_t rs_valid; /*Validity of the register file source operand(s).*/ \ +} + +`define X_COMMIT_T(Cfg, hartid_t, id_t) struct packed { \ + hartid_t hartid; /*Identification of the hart offloading the instruction*/ \ + id_t id; /*Identification of the offloaded instruction*/ \ + logic commit_kill; /*Shall an offloaded instruction be killed?*/ \ +} + +`define X_RESULT_T(Cfg, hartid_t, id_t, writeregflags_t) struct packed { \ + hartid_t hartid; /*Identification of the hart offloading the instruction*/ \ + id_t id; /*Identification of the offloaded instruction*/ \ + logic [Cfg.X_RFW_WIDTH-1:0] data; /*Register file write data value(s)*/ \ + logic [4:0] rd; /*Register file destination address(es)*/ \ + writeregflags_t we; /*Register file write enable(s)*/ \ +} + +`define CVXIF_REQ_T(Cfg, x_compressed_req_t, x_issue_req_t, x_register_req_t, x_commit_t) struct packed { \ + logic compressed_valid; \ + x_compressed_req_t compressed_req; \ + logic issue_valid; \ + x_issue_req_t issue_req; \ + logic register_valid; \ + x_register_t register; \ + logic commit_valid; \ + x_commit_t commit; \ + logic result_ready; \ +} + +`define CVXIF_RESP_T(Cfg, x_compressed_resp_t, x_issue_resp_t, x_result_t) struct packed { \ + logic compressed_ready; \ + x_compressed_resp_t compressed_resp; \ + logic issue_ready; \ + x_issue_resp_t issue_resp; \ + logic register_ready; \ + logic result_valid; \ + x_result_t result; \ +} + +`endif // CVXIF_TYPES_SVH diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index f119c7a2b4..12cb04faa0 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -21,7 +21,12 @@ module issue_read_operands parameter type branchpredict_sbe_t = logic, parameter type fu_data_t = logic, parameter type scoreboard_entry_t = logic, - parameter type rs3_len_t = logic + parameter type rs3_len_t = logic, + parameter type x_issue_req_t = logic, + parameter type x_issue_resp_t = logic, + parameter type x_register_t = logic, + parameter type x_commit_t = logic + ) ( // Subsystem Clock - SUBSYSTEM input logic clk_i, @@ -106,6 +111,25 @@ module issue_read_operands input logic cvxif_ready_i, // CVXIF offloaded instruction - TO_BE_COMPLETED output logic [31:0] cvxif_off_instr_o, + // CVA6 Hart ID - SUBSYSTEM + input logic [CVA6Cfg.XLEN-1:0] hart_id_i, + // CVXIF Issue interface + input logic x_issue_ready_i, + input x_issue_resp_t x_issue_resp_i, + output logic x_issue_valid_o, + output x_issue_req_t x_issue_req_o, + // CVXIF Register interface + input logic x_register_ready_i, + output logic x_register_valid_o, + output x_register_t x_register_o, + // CVXIF Commit interface + output logic x_commit_valid_o, + output x_commit_t x_commit_o, + // Writeback Handling of CVXIF + output logic x_transaction_accepted_o, + output logic x_transaction_rejected_o, + output logic x_issue_writeback_o, + output logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_id_o, // TO_BE_COMPLETED - TO_BE_COMPLETED input logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr_i, // TO_BE_COMPLETED - TO_BE_COMPLETED @@ -125,7 +149,7 @@ module issue_read_operands logic none, load, store, alu, alu2, ctrl_flow, mult, csr, fpu, fpu_vec, cvxif, accel; } fus_busy_t; - logic [CVA6Cfg.NrIssuePorts-1:0] stall; + logic [CVA6Cfg.NrIssuePorts-1:0] stall, stall_rs1, stall_rs2, stall_rs3; logic [CVA6Cfg.NrIssuePorts-1:0] fu_busy; // functional unit is busy fus_busy_t [CVA6Cfg.NrIssuePorts-1:0] fus_busy; // which functional units are considered busy // operands coming from regfile @@ -148,6 +172,8 @@ module issue_read_operands logic [CVA6Cfg.NrIssuePorts-1:0] branch_valid_q; logic [CVA6Cfg.NrIssuePorts-1:0] cvxif_valid_q; logic [ 31:0] cvxif_off_instr_q; + logic cvxif_instruction_valid; + logic [CVA6Cfg.NrIssuePorts-1:0][31:0] tinst_n, tinst_q; // transformed instruction @@ -158,6 +184,54 @@ module issue_read_operands riscv::instruction_t orig_instr; assign orig_instr = riscv::instruction_t'(orig_instr_i[0]); + // CVXIF Signals + logic cvxif_busy; + logic x_transaction_rejected; + logic [CVA6Cfg.NrRgprPorts-1:0] rs_valid; + logic [CVA6Cfg.NrRgprPorts-1:0][CVA6Cfg.XLEN-1:0] rs; + + cvxif_issue_register_commit_if_driver #( + .CVA6Cfg (CVA6Cfg), + .x_issue_req_t (x_issue_req_t), + .x_issue_resp_t(x_issue_resp_t), + .x_register_t (x_register_t), + .x_commit_t (x_commit_t) + ) i_cvxif_issue_register_commit_if_driver ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .flush_i (flush_i), + .hart_id_i (hart_id_i), + .issue_ready_i (x_issue_ready_i), + .issue_resp_i (x_issue_resp_i), + .issue_valid_o (x_issue_valid_o), + .issue_req_o (x_issue_req_o), + .register_ready_i(x_register_ready_i), + .register_valid_o(x_register_valid_o), + .register_o (x_register_o), + .commit_valid_o (x_commit_valid_o), + .commit_o (x_commit_o), + .valid_i (cvxif_instruction_valid), + .x_off_instr_i (orig_instr_i[0]), + .x_trans_id_i (issue_instr_i[0].trans_id), + .register_i (rs), + .rs_valid_i (rs_valid), + .cvxif_busy_o (cvxif_busy) + ); + if (OPERANDS_PER_INSTR == 3) begin + assign rs_valid = {~stall_rs3[0], ~stall_rs2[0], ~stall_rs1[0]}; + assign rs = {fu_data_n[0].imm, fu_data_n[0].operand_b, fu_data_n[0].operand_a}; + end else begin + assign rs_valid = {~stall_rs2[0], ~stall_rs1[0]}; + assign rs = {fu_data_n[0].operand_b, fu_data_n[0].operand_a}; + end + + // TODO check only for 1st instruction ?? + assign cvxif_instruction_valid = (!issue_instr_i[0].ex.valid && issue_instr_valid_i[0] && (issue_instr_i[0].fu == CVXIF)); + assign x_transaction_accepted_o = x_issue_valid_o && x_issue_ready_i && x_issue_resp_i.accept; + assign x_transaction_rejected = x_issue_valid_o && x_issue_ready_i && ~x_issue_resp_i.accept; + assign x_issue_writeback_o = x_issue_resp_i.writeback; + assign x_id_o = x_issue_req_o.id; + // ID <-> EX registers for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin @@ -212,7 +286,7 @@ module issue_read_operands fus_busy[0].store = 1'b1; end - if (!cvxif_ready_i) begin + if (cvxif_busy) begin fus_busy[0].cvxif = 1'b1; end @@ -310,6 +384,9 @@ module issue_read_operands // forward corresponding register always_comb begin : operands_available stall = '{default: stall_i}; + stall_rs1 = '{default: stall_i}; + stall_rs2 = '{default: stall_i}; + stall_rs3 = '{default: stall_i}; // operand forwarding signals forward_rs1 = '0; forward_rs2 = '0; @@ -323,12 +400,16 @@ module issue_read_operands // 0. check that we are not using the zimm type in RS1 // as this is an immediate we do not have to wait on anything here + // 0.bis check that rs1 is required by coprocessor if not do not wait here // 1. check if the source registers are clobbered --> check appropriate clobber list (gpr/fpr) // 2. poll the scoreboard if (!issue_instr_i[i].use_zimm && ((CVA6Cfg.FpPresent && is_rs1_fpr( issue_instr_i[i].op )) ? rd_clobber_fpr_i[issue_instr_i[i].rs1] != NONE : - rd_clobber_gpr_i[issue_instr_i[i].rs1] != NONE)) begin + rd_clobber_gpr_i[issue_instr_i[i].rs1] != NONE) || + ((CVA6Cfg.CvxifEn && x_issue_valid_o && + x_issue_resp_i.accept && x_issue_resp_i.register_read[0]) && + rd_clobber_gpr_i[issue_instr_i[i].rs1] != NONE)) begin // check if the clobbering instruction is not a CSR instruction, CSR instructions can only // be fetched through the register file since they can't be forwarded // if the operand is available, forward it. CSRs don't write to/from FPR @@ -339,13 +420,17 @@ module issue_read_operands forward_rs1[i] = 1'b1; end else begin // the operand is not available -> stall stall[i] = 1'b1; + stall_rs1[i] = 1'b1; end end - if ((CVA6Cfg.FpPresent && is_rs2_fpr( + if (((CVA6Cfg.FpPresent && is_rs2_fpr( issue_instr_i[i].op )) ? rd_clobber_fpr_i[issue_instr_i[i].rs2] != NONE : - rd_clobber_gpr_i[issue_instr_i[i].rs2] != NONE) begin + rd_clobber_gpr_i[issue_instr_i[i].rs2] != NONE) || + ((CVA6Cfg.CvxifEn && + x_issue_valid_o && x_issue_resp_i.accept && x_issue_resp_i.register_read[1]) && + rd_clobber_gpr_i[issue_instr_i[i].rs2] != NONE)) begin // if the operand is available, forward it. CSRs don't write to/from FPR if (rs2_valid_i[i] && (CVA6Cfg.FpPresent && is_rs2_fpr( issue_instr_i[i].op @@ -354,20 +439,23 @@ module issue_read_operands forward_rs2[i] = 1'b1; end else begin // the operand is not available -> stall stall[i] = 1'b1; + stall_rs2[i] = 1'b1; end end // Only check clobbered gpr for OFFLOADED instruction - if ((CVA6Cfg.FpPresent && is_imm_fpr( + if (((CVA6Cfg.FpPresent && is_imm_fpr( issue_instr_i[i].op - )) ? rd_clobber_fpr_i[issue_instr_i[i].result[REG_ADDR_SIZE-1:0]] != NONE : - issue_instr_i[i].op == OFFLOAD && CVA6Cfg.NrRgprPorts == 3 ? - rd_clobber_gpr_i[issue_instr_i[i].result[REG_ADDR_SIZE-1:0]] != NONE : 0) begin + )) ? rd_clobber_fpr_i[issue_instr_i[i].result[REG_ADDR_SIZE-1:0]] != NONE : 0) || + ((CVA6Cfg.CvxifEn && OPERANDS_PER_INSTR == 3 && + x_issue_valid_o && x_issue_resp_i.accept && x_issue_resp_i.register_read[2]) && + rd_clobber_gpr_i[issue_instr_i[i].result] != NONE)) begin // if the operand is available, forward it. CSRs don't write to/from FPR so no need to check if (rs3_valid_i[i]) begin forward_rs3[i] = 1'b1; end else begin // the operand is not available -> stall stall[i] = 1'b1; + stall_rs3[i] = 1'b1; end end end @@ -395,7 +483,7 @@ module issue_read_operands )) ? is_rd_fpr( issue_instr_i[0].op ) && issue_instr_i[0].rd == issue_instr_i[1].result[REG_ADDR_SIZE-1:0] : - issue_instr_i[1].op == OFFLOAD && CVA6Cfg.NrRgprPorts == 3 ? + issue_instr_i[1].op == OFFLOAD && OPERANDS_PER_INSTR == 3 ? issue_instr_i[0].rd == issue_instr_i[1].result[REG_ADDR_SIZE-1:0] : 1'b0) begin stall[1] = 1'b1; end @@ -403,7 +491,7 @@ module issue_read_operands end // third operand from fp regfile or gp regfile if NR_RGPR_PORTS == 3 - if (CVA6Cfg.NrRgprPorts == 3) begin : gen_gp_rs3 + if (OPERANDS_PER_INSTR == 3) begin : gen_gp_rs3 assign imm_forward_rs3 = rs3_i[0]; end else begin : gen_fp_rs3 assign imm_forward_rs3 = {{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, rs3_i[0]}; @@ -418,7 +506,7 @@ module issue_read_operands // immediates are the third operands in the store case // for FP operations, the imm field can also be the third operand from the regfile - if (CVA6Cfg.NrRgprPorts == 3) begin + if (OPERANDS_PER_INSTR == 3) begin fu_data_n[i].imm = (CVA6Cfg.FpPresent && is_imm_fpr(issue_instr_i[i].op)) ? {{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, operand_c_regfile[i]} : issue_instr_i[i].op == OFFLOAD ? operand_c_regfile[i] : issue_instr_i[i].result; @@ -440,7 +528,7 @@ module issue_read_operands if (forward_rs2[i]) begin fu_data_n[i].operand_b = rs2_i[i]; end - if (CVA6Cfg.FpPresent && forward_rs3[i]) begin + if ((CVA6Cfg.FpPresent || (CVA6Cfg.CvxifEn && OPERANDS_PER_INSTR == 3)) && forward_rs3[i]) begin fu_data_n[i].imm = imm_forward_rs3; end @@ -555,7 +643,7 @@ module issue_read_operands case (issue_instr_i[i].fu) CVXIF: begin cvxif_valid_q[i] <= 1'b1; - cvxif_off_instr_q <= orig_instr; + cvxif_off_instr_q <= orig_instr[i]; end default: ; endcase @@ -619,6 +707,9 @@ module issue_read_operands if (issue_instr_i[i].fu == NONE) begin issue_ack_o[i] = 1'b1; end + if (issue_instr_i[i].fu == CVXIF) begin + issue_ack_o[i] = (x_transaction_accepted_o || x_transaction_rejected); + end end end @@ -749,14 +840,14 @@ module issue_read_operands end endgenerate - if (CVA6Cfg.NrRgprPorts == 3) begin : gen_operand_c + if (OPERANDS_PER_INSTR == 3) begin : gen_operand_c assign operand_c_fpr = {{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, fprdata[2]}; end else begin assign operand_c_fpr = fprdata[2]; end for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin - if (CVA6Cfg.NrRgprPorts == 3) begin : gen_operand_c + if (OPERANDS_PER_INSTR == 3) begin : gen_operand_c assign operand_c_gpr[i] = rdata[i*OPERANDS_PER_INSTR+2]; end @@ -766,7 +857,7 @@ module issue_read_operands assign operand_b_regfile[i] = (CVA6Cfg.FpPresent && is_rs2_fpr( issue_instr_i[i].op )) ? {{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, fprdata[1]} : rdata[i*OPERANDS_PER_INSTR+1]; - assign operand_c_regfile[i] = (CVA6Cfg.NrRgprPorts == 3) ? ((CVA6Cfg.FpPresent && is_imm_fpr( + assign operand_c_regfile[i] = (OPERANDS_PER_INSTR == 3) ? ((CVA6Cfg.FpPresent && is_imm_fpr( issue_instr_i[i].op )) ? operand_c_fpr : operand_c_gpr[i]) : operand_c_fpr; end @@ -780,9 +871,10 @@ module issue_read_operands if (CVA6Cfg.RVH) begin tinst_q <= '0; end - pc_o <= '0; - is_compressed_instr_o <= 1'b0; - branch_predict_o <= {cf_t'(0), {CVA6Cfg.VLEN{1'b0}}}; + pc_o <= '0; + is_compressed_instr_o <= 1'b0; + branch_predict_o <= {cf_t'(0), {CVA6Cfg.VLEN{1'b0}}}; + x_transaction_rejected_o <= 1'b0; end else begin fu_data_q <= fu_data_n; if (CVA6Cfg.RVH) begin @@ -800,6 +892,10 @@ module issue_read_operands is_compressed_instr_o <= issue_instr_i[0].is_compressed; branch_predict_o <= issue_instr_i[0].bp; end + x_transaction_rejected_o <= 1'b0; + if (issue_instr_i[0].fu == CVXIF) begin + x_transaction_rejected_o <= x_transaction_rejected; + end end end diff --git a/core/issue_stage.sv b/core/issue_stage.sv index d17f8f3af9..426a5b23cc 100644 --- a/core/issue_stage.sv +++ b/core/issue_stage.sv @@ -22,7 +22,11 @@ module issue_stage parameter type branchpredict_sbe_t = logic, parameter type exception_t = logic, parameter type fu_data_t = logic, - parameter type scoreboard_entry_t = logic + parameter type scoreboard_entry_t = logic, + parameter type x_issue_req_t = logic, + parameter type x_issue_resp_t = logic, + parameter type x_register_t = logic, + parameter type x_commit_t = logic ) ( // Subsystem Clock - SUBSYSTEM input logic clk_i, @@ -87,11 +91,27 @@ module issue_stage // CSR is valid - EX_STAGE output logic [CVA6Cfg.NrIssuePorts-1:0] csr_valid_o, // CVXIF FU is valid - EX_STAGE - output logic [CVA6Cfg.NrIssuePorts-1:0] x_issue_valid_o, + output logic [CVA6Cfg.NrIssuePorts-1:0] xfu_valid_o, // CVXIF is FU ready - EX_STAGE - input logic x_issue_ready_i, + input logic xfu_ready_i, // CVXIF offloader instruction value - EX_STAGE output logic [31:0] x_off_instr_o, + // CVA6 Hart ID - SUBSYSTEM + input logic [CVA6Cfg.XLEN-1:0] hart_id_i, + // CVXIF Issue interface + input logic x_issue_ready_i, + input x_issue_resp_t x_issue_resp_i, + output logic x_issue_valid_o, + output x_issue_req_t x_issue_req_o, + // CVXIF Register interface + input logic x_register_ready_i, + output logic x_register_valid_o, + output x_register_t x_register_o, + // CVXIF Commit interface + output logic x_commit_valid_o, + output x_commit_t x_commit_o, + // CVXIF Transaction rejected -> instruction is illegal - EX_STAGE + output logic x_transaction_rejected_o, // Issue scoreboard entry - ACC_DISPATCHER output scoreboard_entry_t issue_instr_o, // TO_BE_COMPLETED - ACC_DISPATCHER @@ -108,6 +128,8 @@ module issue_stage input logic [CVA6Cfg.NrWbPorts-1:0] wt_valid_i, // CVXIF write enable - EX_STAGE input logic x_we_i, + // CVXIF destination register - ISSUE_STAGE + input logic [4:0] x_rd_i, // TO_BE_COMPLETED - EX_STAGE input logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr_i, // TO_BE_COMPLETED - EX_STAGE @@ -165,6 +187,9 @@ module issue_stage assign issue_instr_o = issue_instr_sb_iro[0]; assign issue_instr_hs_o = issue_instr_valid_sb_iro[0] & issue_ack_iro_sb[0]; + logic x_transaction_accepted_iro_sb, x_issue_writeback_iro_sb; + logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_id_iro_sb; + // --------------------------------------------------------- // 2. Manage instructions in a scoreboard @@ -176,18 +201,21 @@ module issue_stage .exception_t(exception_t), .scoreboard_entry_t(scoreboard_entry_t) ) i_scoreboard ( - .sb_full_o (sb_full_o), - .rd_clobber_gpr_o(rd_clobber_gpr_sb_iro), - .rd_clobber_fpr_o(rd_clobber_fpr_sb_iro), - .rs1_i (rs1_iro_sb), - .rs1_o (rs1_sb_iro), - .rs1_valid_o (rs1_valid_sb_iro), - .rs2_i (rs2_iro_sb), - .rs2_o (rs2_sb_iro), - .rs2_valid_o (rs2_valid_iro_sb), - .rs3_i (rs3_iro_sb), - .rs3_o (rs3_sb_iro), - .rs3_valid_o (rs3_valid_iro_sb), + .sb_full_o (sb_full_o), + .rd_clobber_gpr_o (rd_clobber_gpr_sb_iro), + .rd_clobber_fpr_o (rd_clobber_fpr_sb_iro), + .x_transaction_accepted_i(x_transaction_accepted_iro_sb), + .x_issue_writeback_i (x_issue_writeback_iro_sb), + .x_id_i (x_id_iro_sb), + .rs1_i (rs1_iro_sb), + .rs1_o (rs1_sb_iro), + .rs1_valid_o (rs1_valid_sb_iro), + .rs2_i (rs2_iro_sb), + .rs2_o (rs2_sb_iro), + .rs2_valid_o (rs2_valid_iro_sb), + .rs3_i (rs3_iro_sb), + .rs3_o (rs3_sb_iro), + .rs3_valid_o (rs3_valid_iro_sb), .decoded_instr_i (decoded_instr_i), .decoded_instr_valid_i(decoded_instr_valid_i), @@ -212,38 +240,56 @@ module issue_stage .branchpredict_sbe_t(branchpredict_sbe_t), .fu_data_t(fu_data_t), .scoreboard_entry_t(scoreboard_entry_t), - .rs3_len_t(rs3_len_t) + .rs3_len_t(rs3_len_t), + .x_issue_req_t(x_issue_req_t), + .x_issue_resp_t(x_issue_resp_t), + .x_register_t(x_register_t), + .x_commit_t(x_commit_t) ) i_issue_read_operands ( - .flush_i (flush_unissued_instr_i), - .issue_instr_i (issue_instr_sb_iro), - .orig_instr_i (orig_instr_sb_iro), - .issue_instr_valid_i(issue_instr_valid_sb_iro), - .issue_ack_o (issue_ack_iro_sb), - .fu_data_o (fu_data_o), - .flu_ready_i (flu_ready_i), - .rs1_o (rs1_iro_sb), - .rs1_i (rs1_sb_iro), - .rs1_valid_i (rs1_valid_sb_iro), - .rs2_o (rs2_iro_sb), - .rs2_i (rs2_sb_iro), - .rs2_valid_i (rs2_valid_iro_sb), - .rs3_o (rs3_iro_sb), - .rs3_i (rs3_sb_iro), - .rs3_valid_i (rs3_valid_iro_sb), - .rd_clobber_gpr_i (rd_clobber_gpr_sb_iro), - .rd_clobber_fpr_i (rd_clobber_fpr_sb_iro), - .alu_valid_o (alu_valid_o), - .alu2_valid_o (alu2_valid_o), - .branch_valid_o (branch_valid_o), - .csr_valid_o (csr_valid_o), - .cvxif_valid_o (x_issue_valid_o), - .cvxif_ready_i (x_issue_ready_i), - .cvxif_off_instr_o (x_off_instr_o), - .mult_valid_o (mult_valid_o), - .rs1_forwarding_o (rs1_forwarding_xlen), - .rs2_forwarding_o (rs2_forwarding_xlen), - .stall_issue_o (stall_issue_o), - .tinst_o (tinst_o), + .flush_i (flush_unissued_instr_i), + .issue_instr_i (issue_instr_sb_iro), + .orig_instr_i (orig_instr_sb_iro), + .issue_instr_valid_i (issue_instr_valid_sb_iro), + .issue_ack_o (issue_ack_iro_sb), + .fu_data_o (fu_data_o), + .flu_ready_i (flu_ready_i), + .rs1_o (rs1_iro_sb), + .rs1_i (rs1_sb_iro), + .rs1_valid_i (rs1_valid_sb_iro), + .rs2_o (rs2_iro_sb), + .rs2_i (rs2_sb_iro), + .rs2_valid_i (rs2_valid_iro_sb), + .rs3_o (rs3_iro_sb), + .rs3_i (rs3_sb_iro), + .rs3_valid_i (rs3_valid_iro_sb), + .rd_clobber_gpr_i (rd_clobber_gpr_sb_iro), + .rd_clobber_fpr_i (rd_clobber_fpr_sb_iro), + .alu_valid_o (alu_valid_o), + .alu2_valid_o (alu2_valid_o), + .branch_valid_o (branch_valid_o), + .csr_valid_o (csr_valid_o), + .cvxif_valid_o (xfu_valid_o), + .cvxif_ready_i (xfu_ready_i), + .hart_id_i (hart_id_i), + .x_issue_ready_i (x_issue_ready_i), + .x_issue_resp_i (x_issue_resp_i), + .x_issue_valid_o (x_issue_valid_o), + .x_issue_req_o (x_issue_req_o), + .x_register_ready_i (x_register_ready_i), + .x_register_valid_o (x_register_valid_o), + .x_register_o (x_register_o), + .x_commit_valid_o (x_commit_valid_o), + .x_commit_o (x_commit_o), + .x_transaction_accepted_o(x_transaction_accepted_iro_sb), + .x_transaction_rejected_o(x_transaction_rejected_o), + .x_issue_writeback_o (x_issue_writeback_iro_sb), + .x_id_o (x_id_iro_sb), + .cvxif_off_instr_o (x_off_instr_o), + .mult_valid_o (mult_valid_o), + .rs1_forwarding_o (rs1_forwarding_xlen), + .rs2_forwarding_o (rs2_forwarding_xlen), + .stall_issue_o (stall_issue_o), + .tinst_o (tinst_o), .* ); diff --git a/core/scoreboard.sv b/core/scoreboard.sv index b483cb5d6e..1496b1ad17 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -33,13 +33,16 @@ module scoreboard #( output ariane_pkg::fu_t [2**ariane_pkg::REG_ADDR_SIZE-1:0] rd_clobber_gpr_o, // TO_BE_COMPLETED - TO_BE_COMPLETED output ariane_pkg::fu_t [2**ariane_pkg::REG_ADDR_SIZE-1:0] rd_clobber_fpr_o, - + // Writeback Handling of CVXIF + input logic x_transaction_accepted_i, + input logic x_issue_writeback_i, + input logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_id_i, // rs1 operand address - issue_read_operands - input logic [CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] rs1_i, + input logic [CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] rs1_i, // rs1 operand - issue_read_operands - output logic [CVA6Cfg.NrIssuePorts-1:0][ CVA6Cfg.XLEN-1:0] rs1_o, + output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs1_o, // rs1 operand is valid - issue_read_operands - output logic [CVA6Cfg.NrIssuePorts-1:0] rs1_valid_o, + output logic [CVA6Cfg.NrIssuePorts-1:0] rs1_valid_o, // rs2 operand address - issue_read_operands input logic [CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] rs2_i, @@ -96,6 +99,8 @@ module scoreboard #( input logic [CVA6Cfg.NrWbPorts-1:0] wt_valid_i, // Cvxif we for writeback - TO_BE_COMPLETED input logic x_we_i, + // CVXIF destination register - ISSUE_STAGE + input logic [4:0] x_rd_i, // TO_BE_COMPLETED - RVFI output logic [ CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_issue_pointer_o, @@ -225,8 +230,9 @@ module scoreboard #( if (CVA6Cfg.DebugEn) begin mem_n[trans_id_i[i]].sbe.bp.predict_address = resolved_branch_i.target_address; end - if (mem_n[trans_id_i[i]].sbe.fu == ariane_pkg::CVXIF && ~x_we_i) begin - mem_n[trans_id_i[i]].sbe.rd = 5'b0; + if (mem_n[trans_id_i[i]].sbe.fu == ariane_pkg::CVXIF) begin + if (x_we_i) mem_n[trans_id_i[i]].sbe.rd = x_rd_i; + else mem_n[trans_id_i[i]].sbe.rd = 5'b0; end // write the exception back if it is valid if (ex_i[i].valid) mem_n[trans_id_i[i]].sbe.ex = ex_i[i]; @@ -492,8 +498,9 @@ module scoreboard #( commit_pointer_q <= '0; issue_pointer_q <= '0; end else begin - issue_pointer_q <= issue_pointer_n; - mem_q <= mem_n; + issue_pointer_q <= issue_pointer_n; + mem_q <= mem_n; + mem_q[x_id_i].sbe.rd <= (x_transaction_accepted_i && ~x_issue_writeback_i) ? 5'b0 : mem_n[x_id_i].sbe.rd; commit_pointer_q <= commit_pointer_n; end end diff --git a/corev_apu/src/ariane.sv b/corev_apu/src/ariane.sv index 38b3281bb9..de0941f2bb 100644 --- a/corev_apu/src/ariane.sv +++ b/corev_apu/src/ariane.sv @@ -12,6 +12,7 @@ // Date: 19.03.2017 // Description: Ariane Top-level module +`include "cvxif_types.svh" module ariane import ariane_pkg::*; #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, @@ -21,6 +22,21 @@ module ariane import ariane_pkg::*; #( logic csr; logic instr; }, + // CVXIF Types + localparam type readregflags_t = `READREGFLAGS_T(CVA6Cfg), + localparam type writeregflags_t = `WRITEREGFLAGS_T(CVA6Cfg), + localparam type id_t = `ID_T(CVA6Cfg), + localparam type hartid_t = `HARTID_T(CVA6Cfg), + localparam type x_compressed_req_t = `X_COMPRESSED_REQ_T(CVA6Cfg, hartid_t), + localparam type x_compressed_resp_t = `X_COMPRESSED_RESP_T(CVA6Cfg), + localparam type x_issue_req_t = `X_ISSUE_REQ_T(CVA6Cfg, hartit_t, id_t), + localparam type x_issue_resp_t = `X_ISSUE_RESP_T(CVA6Cfg, writeregflags_t, readregflags_t), + localparam type x_register_t = `X_REGISTER_T(CVA6Cfg, hartid_t, id_t, readregflags_t), + localparam type x_commit_t = `X_COMMIT_T(CVA6Cfg, hartid_t, id_t), + localparam type x_result_t = `X_RESULT_T(CVA6Cfg, hartid_t, id_t, writeregflags_t), + localparam type cvxif_req_t = `CVXIF_REQ_T(CVA6Cfg, x_compressed_req_t, x_issue_req_t, x_register_req_t, x_commit_t), + localparam type cvxif_resp_t = `CVXIF_RESP_T(CVA6Cfg, x_compressed_resp_t, x_issue_resp_t, x_result_t), + // AXI Types parameter int unsigned AxiAddrWidth = ariane_axi::AddrWidth, parameter int unsigned AxiDataWidth = ariane_axi::DataWidth, parameter int unsigned AxiIdWidth = ariane_axi::IdWidth, @@ -50,8 +66,8 @@ module ariane import ariane_pkg::*; #( input noc_resp_t noc_resp_i ); - cvxif_pkg::cvxif_req_t cvxif_req; - cvxif_pkg::cvxif_resp_t cvxif_resp; + cvxif_req_t cvxif_req; + cvxif_resp_t cvxif_resp; cva6 #( .CVA6Cfg ( CVA6Cfg ), @@ -62,7 +78,20 @@ module ariane import ariane_pkg::*; #( .axi_aw_chan_t (axi_aw_chan_t), .axi_w_chan_t (axi_w_chan_t), .noc_req_t (noc_req_t), - .noc_resp_t (noc_resp_t) + .noc_resp_t (noc_resp_t), + .readregflags_t (readregflags_t), + .writeregflags_t (writeregflags_t), + .id_t (id_t), + .hartid_t (hartid_t), + .x_compressed_req_t (x_compressed_req_t), + .x_compressed_resp_t (x_compressed_resp_t), + .x_issue_req_t (x_issue_req_t), + .x_issue_resp_t (x_issue_resp_t), + .x_register_t (x_register_t), + .x_commit_t (x_commit_t), + .x_result_t (x_result_t), + .cvxif_req_t (cvxif_req_t), + .cvxif_resp_t (cvxif_resp_t) ) i_cva6 ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -81,7 +110,20 @@ module ariane import ariane_pkg::*; #( if (CVA6Cfg.CvxifEn) begin : gen_example_coprocessor cvxif_example_coprocessor #( - .CVA6Cfg ( CVA6Cfg ) + .NrRgprPorts (CVA6Cfg.NrRgprPorts), + .readregflags_t (readregflags_t), + .writeregflags_t (writeregflags_t), + .id_t (id_t), + .hartid_t (hartid_t), + .x_compressed_req_t (x_compressed_req_t), + .x_compressed_resp_t (x_compressed_resp_t), + .x_issue_req_t (x_issue_req_t), + .x_issue_resp_t (x_issue_resp_t), + .x_register_t (x_register_t), + .x_commit_t (x_commit_t), + .x_result_t (x_result_t), + .cvxif_req_t (cvxif_req_t), + .cvxif_resp_t (cvxif_resp_t) ) i_cvxif_coprocessor ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -90,4 +132,6 @@ module ariane import ariane_pkg::*; #( ); end + + endmodule // ariane diff --git a/docs/riscv-isa/riscv-isa-manual b/docs/riscv-isa/riscv-isa-manual index ebf2e3a0b4..c8c8075a6a 160000 --- a/docs/riscv-isa/riscv-isa-manual +++ b/docs/riscv-isa/riscv-isa-manual @@ -1 +1 @@ -Subproject commit ebf2e3a0b402cd56fd4b571b705b31f3be62c2cc +Subproject commit c8c8075a6a71be67ac723528070e3e50ff7586b2 diff --git a/verif/env/uvme/cov/uvme_cva6_cov_model.sv b/verif/env/uvme/cov/uvme_cva6_cov_model.sv index 63edcd4c5d..93d0ebb5a6 100644 --- a/verif/env/uvme/cov/uvme_cva6_cov_model.sv +++ b/verif/env/uvme/cov/uvme_cva6_cov_model.sv @@ -30,7 +30,6 @@ class uvme_cva6_cov_model_c extends uvm_component; uvme_cva6_cntxt_c cntxt; // Components - uvme_cvxif_covg_c cvxif_covg; uvme_isa_cov_model_c isa_covg; uvme_cva6_config_covg_c config_covg; uvme_illegal_instr_cov_model_c illegal_covg; @@ -102,12 +101,6 @@ function void uvme_cva6_cov_model_c::build_phase(uvm_phase phase); `uvm_fatal("CNTXT", "Context handle is null") end - if (cfg.cvxif_cfg.cov_model_enabled) begin - cvxif_covg = uvme_cvxif_covg_c::type_id::create("cvxif_covg", this); - uvm_config_db#(uvme_cva6_cfg_c)::set(this, "cvxif_covg", "cfg", cfg); - uvm_config_db#(uvme_cva6_cntxt_c)::set(this, "cvxif_covg", "cntxt", cntxt); - end - if (cfg.isacov_cfg.cov_model_enabled) begin isa_covg = uvme_isa_cov_model_c::type_id::create("isa_covg", this); illegal_covg = uvme_illegal_instr_cov_model_c::type_id::create("illegal_covg", this); diff --git a/verif/env/uvme/cvxif_vseq/custom_instructions_cvxif_1_0_0.rst b/verif/env/uvme/cvxif_vseq/custom_instructions_cvxif_1_0_0.rst new file mode 100644 index 0000000000..cbd49d071f --- /dev/null +++ b/verif/env/uvme/cvxif_vseq/custom_instructions_cvxif_1_0_0.rst @@ -0,0 +1,137 @@ +.. + Copyright (c) 2023 OpenHW Group + + Copyright (c) 2023 Thales DIS design services SAS + + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + +.. + +Custom Instruction to challenge CV-X-IF protocol +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This section describes some custom instruction, for stress or challenge the CV-X-IF protocol for the 3 implemented interfaces, it's just to interact with the cvxif agent. +All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). +- **CUS_NOP**: Custom No Operation + + **Format**: cus_nop -> |0000000000000000000000000|111_1011| + + **Description**: do nothing, it's just a hint instruction. + + **Pseudocode**: cus_nop + + **Invalid values**: NONE + +- **CUS_ADD**: Custom Add + + **Format**: cus_add rd, rs1, rs2 -> |0000000|rs2|rs1|001|rd|111_1011| + + **Description**: add register rs1 to rs2, and store the result in rd. + + **Pseudocode**: x[rd] = x[rs1] + x[rs2] + + **Invalid values**: NONE + +- **CUS_DOUBLE_RS1**: Custom Double RS1 + + **Format**: cus_add rd, rs1, rs1 -> |0000001|rs2|rs1|001|rd|111_1011| + + **Description**: add register rs1 to rs1, and store the result in rd. + Any rs2 value can be given. It should be ignored by CPU. + Exists to check that register depedencies is well implemented in CPU. + + **Pseudocode**: x[rd] = x[rs1] + x[rs1] + + **Invalid values**: NONE + +- **CUS_DOUBLE_RS2**: Custom Double RS2 + + **Format**: cus_add rd, rs2, rs2 -> |0000010|rs2|rs1|001|rd|111_1011| + + **Description**: add register rs2 to rs2, and store the result in rd. + Any rs1 value can be given. It should be ignored by CPU. + Exists to check that register depedencies is well implemented in CPU. + + **Pseudocode**: x[rd] = x[rs2] + x[rs2] + + **Invalid values**: NONE + +- **CUS_ADD_MULTI**: Custom Multicycle Add + + **Format**: addi rd, rs1, rs2 -> |0000011|rs2|rs1|001|rd|111_1011| + + **Description**: add register rs1 to rs2, and store the result in rd. Coprocessor should randomly delays the result + + **Pseudocode**: x[rd] = x[rs1] + x[rs2] + + **Invalid values**: NONE + +- **CUS_ADD_RS3_MADD**: Custom Add with RS3 opcode == MADD + + **Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_0011| + + **Description**: add register rs1, rs2 to rs3, and store the result in rd. + + **Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3] + + **Invalid values**: NONE + +- **CUS_ADD_RS3_MSUB**: Custom Add with RS3 opcode == MSUB + + **Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_0111| + + **Description**: add register rs1, rs2 to rs3, and store the result in rd. + + **Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3] + + **Invalid values**: NONE + +- **CUS_ADD_RS3_NMADD**: Custom Add with RS3 opcode == NMADD + + **Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_1111| + + **Description**: add register rs1, rs2 to rs3, and store the result in rd. + + **Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3] + + **Invalid values**: NONE + +- **CUS_ADD_RS3_NMADD**: Custom Add with RS3 opcode == NMSUB + + **Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_0011| + + **Description**: add register rs1, rs2 to rs3, and store the result in rd. + + **Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3] + + **Invalid values**: NONE + +- **CUS_ADD_RS3_RTYPE**: Custom Add with RS3, rd is x10 (a0) + + **Format**: addi a0, rs1, rs2, rs3 -> |0000100|rs2|rs1|001|rs3|100_0011| + + **Description**: add register rs1, rs2 to rs3, and store the result in x10 (a0). + + **Pseudocode**: x[10] = x[rs1] + x[rs2] + x[rs3] + + **Invalid values**: NONE + +- **CUS_CNOP** : Custom Compressed NOP + + **Format**: cus_cnop -> |111|0|00000|00000|00| + + **Description**: Extends to CUS_NOP : do nothing, it's just a hint instruction. + + **Pseudocode**: cus_cnop + + **Invalid values**: NONE + +- **CUS_CADD** : Custom Compressed ADD + + **Format**: cus_cnop -> |111|1|rs1|rs2|00| + + **Description**: Extends to CUS_ADD rs1, rs2 -> x10 : Add rs1 + rs2 into x10 (a0). + + **Pseudocode**: cus_cadd + + **Invalid values**: NONE \ No newline at end of file diff --git a/verif/env/uvme/uvme_cva6_cfg.sv b/verif/env/uvme/uvme_cva6_cfg.sv index 1168799e37..3b12bad585 100644 --- a/verif/env/uvme/uvme_cva6_cfg.sv +++ b/verif/env/uvme/uvme_cva6_cfg.sv @@ -39,7 +39,6 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c; // Agent cfg handles rand uvma_clknrst_cfg_c clknrst_cfg; - rand uvma_cvxif_cfg_c cvxif_cfg; rand uvma_axi_cfg_c axi_cfg; rand uvma_rvfi_cfg_c#(ILEN,XLEN) rvfi_cfg; rand uvma_isacov_cfg_c isacov_cfg; @@ -75,8 +74,6 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c; `uvm_field_object(clknrst_cfg, UVM_DEFAULT) - `uvm_field_object(cvxif_cfg, UVM_DEFAULT) - `uvm_field_object(axi_cfg, UVM_DEFAULT) `uvm_field_object(rvfi_cfg, UVM_DEFAULT) @@ -97,19 +94,9 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c; soft sys_clk_period == uvme_cva6_sys_default_clk_period; // see uvme_cva6_constants.sv } - constraint cvxif_feature { //CV32A65X do not support dual read & write also the memory interface - cvxif_cfg.dual_read_write_support_x == 0; - cvxif_cfg.load_store_support_x == 0; - cvxif_cfg.seq_cus_instr_x2_enabled == 1; - cvxif_cfg.reg_cus_crosses_enabled == 0; - cvxif_cfg.mode_s_supported == CVA6Cfg.RVS; - cvxif_cfg.mode_u_supported == CVA6Cfg.RVU; - } - constraint cva6_riscv_cons { xlen == CVA6Cfg.XLEN; ilen == 32; - ext_i_supported == 1; ext_a_supported == CVA6Cfg.RVA; ext_m_supported == 1; @@ -227,7 +214,6 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c; } if (cov_model_enabled) { - cvxif_cfg.cov_model_enabled == 1; isacov_cfg.cov_model_enabled == 1; axi_cfg.cov_model_enabled == 1; interrupt_cfg.cov_model_enabled == 1; @@ -258,7 +244,6 @@ function uvme_cva6_cfg_c::new(string name="uvme_cva6_cfg"); super.new(name); clknrst_cfg = uvma_clknrst_cfg_c::type_id::create("clknrst_cfg"); - cvxif_cfg = uvma_cvxif_cfg_c::type_id::create("cvxif_cfg"); axi_cfg = uvma_axi_cfg_c::type_id::create("axi_cfg"); rvfi_cfg = uvma_rvfi_cfg_c#(ILEN,XLEN)::type_id::create("rvfi_cfg"); isacov_cfg = uvma_isacov_cfg_c::type_id::create("isacov_cfg"); diff --git a/verif/env/uvme/uvme_cva6_cntxt.sv b/verif/env/uvme/uvme_cva6_cntxt.sv index 0ad5a5bfcb..90a5f474fb 100644 --- a/verif/env/uvme/uvme_cva6_cntxt.sv +++ b/verif/env/uvme/uvme_cva6_cntxt.sv @@ -31,7 +31,6 @@ class uvme_cva6_cntxt_c extends uvm_object; // Agent context handles uvma_clknrst_cntxt_c clknrst_cntxt; - uvma_cvxif_cntxt_c cvxif_cntxt; uvma_axi_cntxt_c axi_cntxt; uvma_cva6_core_cntrl_cntxt_c core_cntrl_cntxt; uvma_rvfi_cntxt_c rvfi_cntxt; diff --git a/verif/env/uvme/uvme_cva6_env.sv b/verif/env/uvme/uvme_cva6_env.sv index 8a25ef2de3..99268590ed 100644 --- a/verif/env/uvme/uvme_cva6_env.sv +++ b/verif/env/uvme/uvme_cva6_env.sv @@ -42,7 +42,6 @@ class uvme_cva6_env_c extends uvm_env; // Agents uvma_clknrst_agent_c clknrst_agent; - uvma_cvxif_agent_c cvxif_agent; uvma_axi_agent_c axi_agent; uvma_cva6_core_cntrl_agent_c core_cntrl_agent; uvma_rvfi_agent_c#(ILEN,XLEN) rvfi_agent; @@ -246,8 +245,6 @@ function void uvme_cva6_env_c::assign_cfg(); uvm_config_db#(uvma_clknrst_cfg_c)::set(this, "*clknrst_agent", "cfg", cfg.clknrst_cfg); - uvm_config_db#(uvma_cvxif_cfg_c)::set(this, "*cvxif_agent", "cfg", cfg.cvxif_cfg); - uvm_config_db#(uvma_axi_cfg_c)::set(this, "*axi_agent", "cfg", cfg.axi_cfg); uvm_config_db#(uvma_core_cntrl_cfg_c)::set(this, "core_cntrl_agent", "cfg", cfg); @@ -278,7 +275,6 @@ endfunction: assign_cntxt function void uvme_cva6_env_c::create_agents(); clknrst_agent = uvma_clknrst_agent_c::type_id::create("clknrst_agent", this); - cvxif_agent = uvma_cvxif_agent_c::type_id::create("cvxif_agent", this); axi_agent = uvma_axi_agent_c::type_id::create("axi_agent", this); core_cntrl_agent = uvma_cva6_core_cntrl_agent_c::type_id::create("core_cntrl_agent", this); rvfi_agent = uvma_rvfi_agent_c#(ILEN,XLEN)::type_id::create("rvfi_agent", this); @@ -361,7 +357,6 @@ endfunction: connect_scoreboard function void uvme_cva6_env_c::assemble_vsequencer(); vsequencer.clknrst_sequencer = clknrst_agent.sequencer; - vsequencer.cvxif_vsequencer = cvxif_agent.vsequencer; vsequencer.axi_vsequencer = axi_agent.vsequencer; vsequencer.interrupt_sequencer = interrupt_agent.sequencer; @@ -372,12 +367,6 @@ task uvme_cva6_env_c::run_phase(uvm_phase phase); fork - begin - uvme_cvxif_vseq_c cvxif_vseq; - cvxif_vseq = uvme_cvxif_vseq_c::type_id::create("cvxif_vseq"); - cvxif_vseq.start(cvxif_agent.vsequencer); - end - begin if(cfg.axi_cfg.is_active == UVM_ACTIVE) begin uvma_axi_vseq_c axi_vseq; @@ -398,9 +387,6 @@ endtask function void uvme_cva6_env_c::connect_coverage_model(); - if (cfg.cvxif_cfg.cov_model_enabled) begin - cvxif_agent.monitor.req_ap.connect(cov_model.cvxif_covg.req_item_fifo.analysis_export); - end if (cfg.isacov_cfg.cov_model_enabled) begin isacov_agent.monitor.ap.connect(cov_model.isa_covg.mon_trn_fifo.analysis_export); isacov_agent.monitor.ap.connect(cov_model.illegal_covg.mon_trn_fifo.analysis_export); diff --git a/verif/env/uvme/uvme_cva6_pkg.flist b/verif/env/uvme/uvme_cva6_pkg.flist index 4d8cf4274a..a4cb9fe372 100644 --- a/verif/env/uvme/uvme_cva6_pkg.flist +++ b/verif/env/uvme/uvme_cva6_pkg.flist @@ -21,7 +21,6 @@ +incdir+${CVA6_UVME_PATH} +incdir+${CVA6_UVME_PATH}/cov +incdir+${CVA6_UVME_PATH}/vseq -+incdir+${CVA6_UVME_PATH}/cvxif_vseq +incdir+${CVA6_UVME_PATH}/uvma_interrupt // Files diff --git a/verif/env/uvme/uvme_cva6_pkg.sv b/verif/env/uvme/uvme_cva6_pkg.sv index 3093b6c94b..4f700620e8 100644 --- a/verif/env/uvme/uvme_cva6_pkg.sv +++ b/verif/env/uvme/uvme_cva6_pkg.sv @@ -30,7 +30,6 @@ `include "uvml_mem_macros.sv" `include "uvma_axi_macros.sv" `include "uvma_clknrst_macros.sv" -`include "uvma_cvxif_macros.sv" `include "uvma_isacov_macros.sv" `include "uvme_cva6_macros.sv" @@ -46,7 +45,6 @@ package uvme_cva6_pkg; import uvml_sb_pkg ::*; import uvml_trn_pkg ::*; import uvma_clknrst_pkg::*; - import uvma_cvxif_pkg::*; import uvma_axi_pkg::*; import uvml_mem_pkg ::*; import uvma_core_cntrl_pkg::*; @@ -100,7 +98,6 @@ package uvme_cva6_pkg; `include "uvma_cva6_core_cntrl_agent.sv" `include "uvme_cva6_sb.sv" `include "uvme_cva6_vsqr.sv" - `include "uvme_cvxif_covg.sv" `include "uvme_isa_covg.sv" `include "uvme_illegal_instr_covg.sv" `include "uvme_exception_covg.sv" diff --git a/verif/env/uvme/uvme_cva6_vsqr.sv b/verif/env/uvme/uvme_cva6_vsqr.sv index aaef996f12..2b4464dc3e 100644 --- a/verif/env/uvme/uvme_cva6_vsqr.sv +++ b/verif/env/uvme/uvme_cva6_vsqr.sv @@ -36,7 +36,6 @@ class uvme_cva6_vsqr_c extends uvm_sequencer#( // Sequencer handles uvma_clknrst_sqr_c clknrst_sequencer; - uvma_cvxif_vsqr_c cvxif_vsequencer; uvma_axi_vsqr_c axi_vsequencer; uvma_interrupt_sqr_c interrupt_sequencer; diff --git a/verif/regress/smoke-tests.sh b/verif/regress/smoke-tests.sh index 7f3a2ebdf8..68334485a6 100644 --- a/verif/regress/smoke-tests.sh +++ b/verif/regress/smoke-tests.sh @@ -36,6 +36,7 @@ if ! [ -n "$UVM_VERBOSITY" ]; then export UVM_VERBOSITY=UVM_NONE fi +export cvxif=1 # For CVXIF in Spike export DV_OPTS="$DV_OPTS --issrun_opts=+debug_disable=1+UVM_VERBOSITY=$UVM_VERBOSITY" CC_OPTS="-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -lgcc" @@ -61,6 +62,7 @@ make clean_all python3 cva6.py --testlist=../tests/testlist_riscv-compliance-cv32a60x.yaml --test rv32i-I-ADD-01 --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS python3 cva6.py --testlist=../tests/testlist_riscv-tests-cv32a60x-p.yaml --test rv32ui-p-add --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS python3 cva6.py --testlist=../tests/testlist_riscv-arch-test-cv32a60x.yaml --test rv32im-cadd-01 --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS --linker=../tests/riscv-arch-test/riscv-target/spike/link.ld +python3 cva6.py --testlist=../tests/testlist_cvxif.yaml --test cvxif_add_nop --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS python3 cva6.py --c_tests ../tests/custom/hello_world/hello_world.c --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS --linker=../tests/custom/common/test.ld --gcc_opts="$CC_OPTS" $DV_OPTS make -C ../.. clean make clean_all diff --git a/verif/sim/Makefile b/verif/sim/Makefile index 8c792cb566..ac605ddc71 100644 --- a/verif/sim/Makefile +++ b/verif/sim/Makefile @@ -163,7 +163,6 @@ export DV_UVMA_CORE_CNTRL_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_core_cntrl export DV_UVMA_RVFI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_rvfi export DV_UVMA_ISACOV_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_isacov export DV_UVMA_CLKNRST_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_clknrst -export DV_UVMA_CVXIF_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_cvxif export DV_UVMA_AXI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_axi5 export DV_UVMA_INTERRUPT_PATH = $(DV_UVME_PATH)/uvma_interrupt export DV_UVMA_DEBUG_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_debug diff --git a/verif/tb/uvmt/cva6_tb_wrapper.sv b/verif/tb/uvmt/cva6_tb_wrapper.sv index a592d45c90..f13bb39e79 100644 --- a/verif/tb/uvmt/cva6_tb_wrapper.sv +++ b/verif/tb/uvmt/cva6_tb_wrapper.sv @@ -29,6 +29,8 @@ import uvm_pkg::*; `include "uvm_macros.svh" +`include "cvxif_types.svh" + `ifndef DPI_FESVR_SPIKE_UTILS `define DPI_FESVR_SPIKE_UTILS @@ -46,6 +48,20 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( parameter type rvfi_probes_instr_t = logic, parameter type rvfi_probes_csr_t = logic, parameter type rvfi_probes_t = logic, + // CVXIF Types + localparam type readregflags_t = `READREGFLAGS_T(CVA6Cfg), + localparam type writeregflags_t = `WRITEREGFLAGS_T(CVA6Cfg), + localparam type id_t = `ID_T(CVA6Cfg), + localparam type hartid_t = `HARTID_T(CVA6Cfg), + localparam type x_compressed_req_t = `X_COMPRESSED_REQ_T(CVA6Cfg, hartid_t), + localparam type x_compressed_resp_t = `X_COMPRESSED_RESP_T(CVA6Cfg), + localparam type x_issue_req_t = `X_ISSUE_REQ_T(CVA6Cfg, hartit_t, id_t), + localparam type x_issue_resp_t = `X_ISSUE_RESP_T(CVA6Cfg, writeregflags_t, readregflags_t), + localparam type x_register_t = `X_REGISTER_T(CVA6Cfg, hartid_t, id_t, readregflags_t), + localparam type x_commit_t = `X_COMMIT_T(CVA6Cfg, hartid_t, id_t), + localparam type x_result_t = `X_RESULT_T(CVA6Cfg, hartid_t, id_t, writeregflags_t), + localparam type cvxif_req_t = `CVXIF_REQ_T(CVA6Cfg, x_compressed_req_t, x_issue_req_t, x_register_req_t, x_commit_t), + localparam type cvxif_resp_t = `CVXIF_RESP_T(CVA6Cfg, x_compressed_resp_t, x_issue_resp_t, x_result_t), // parameter int unsigned AXI_USER_EN = 0, parameter int unsigned NUM_WORDS = 2**25 @@ -56,8 +72,6 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( output logic [31:0] tb_exit_o, output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o, output rvfi_csr_t rvfi_csr_o, - input cvxif_pkg::cvxif_resp_t cvxif_resp, - output cvxif_pkg::cvxif_req_t cvxif_req, input logic [2:0] irq_i, uvma_axi_intf axi_slave, uvmt_axi_switch_intf axi_switch_vif, @@ -76,6 +90,9 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( assign rvfi_o = rvfi_instr; assign rvfi_csr_o = rvfi_csr; + cvxif_req_t cvxif_req; + cvxif_resp_t cvxif_resp; + cva6 #( .CVA6Cfg ( CVA6Cfg ), .rvfi_probes_instr_t ( rvfi_probes_instr_t ), @@ -93,10 +110,34 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( .rvfi_probes_o ( rvfi_probes ), .cvxif_req_o ( cvxif_req ), .cvxif_resp_i ( cvxif_resp ), - .noc_req_o ( axi_ariane_req ), - .noc_resp_i ( axi_ariane_resp ) + .noc_req_o ( axi_ariane_req ), + .noc_resp_i ( axi_ariane_resp ) ); + if (CVA6Cfg.CvxifEn) begin : gen_example_coprocessor + cvxif_example_coprocessor #( + .NrRgprPorts (CVA6Cfg.NrRgprPorts), + .readregflags_t (readregflags_t), + .writeregflags_t (writeregflags_t), + .id_t (id_t), + .hartid_t (hartid_t), + .x_compressed_req_t (x_compressed_req_t), + .x_compressed_resp_t (x_compressed_resp_t), + .x_issue_req_t (x_issue_req_t), + .x_issue_resp_t (x_issue_resp_t), + .x_register_t (x_register_t), + .x_commit_t (x_commit_t), + .x_result_t (x_result_t), + .cvxif_req_t (cvxif_req_t), + .cvxif_resp_t (cvxif_resp_t) + ) i_cvxif_coprocessor ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .cvxif_req_i ( cvxif_req ), + .cvxif_resp_o ( cvxif_resp ) + ); + end + //---------------------------------------------------------------------------- // RVFI //---------------------------------------------------------------------------- diff --git a/verif/tb/uvmt/uvmt_cva6.flist b/verif/tb/uvmt/uvmt_cva6.flist index c42ca778eb..1b3096b1bc 100644 --- a/verif/tb/uvmt/uvmt_cva6.flist +++ b/verif/tb/uvmt/uvmt_cva6.flist @@ -23,7 +23,6 @@ // Agents -f ${DV_UVMA_CLKNRST_PATH}/uvma_clknrst_pkg.flist --f ${DV_UVMA_CVXIF_PATH}/src/uvma_cvxif_pkg.flist -f ${DV_UVMA_AXI_PATH}/src/uvma_axi_pkg.flist -f ${DV_UVMA_CORE_CNTRL_PATH}/uvma_core_cntrl_pkg.flist -f ${DV_UVMA_RVFI_PATH}/uvma_rvfi_pkg.flist diff --git a/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv b/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv index 9e8bb9d2e4..67508f2006 100644 --- a/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv +++ b/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv @@ -29,7 +29,6 @@ module uvmt_cva6_dut_wrap # ( ( uvma_clknrst_if clknrst_if, - uvma_cvxif_intf cvxif_if, uvma_axi_intf axi_if, uvmt_axi_switch_intf axi_switch_vif, uvmt_default_inputs_intf default_inputs_vif, @@ -59,8 +58,6 @@ module uvmt_cva6_dut_wrap # ( .clk_i ( clknrst_if.clk ), .rst_ni ( clknrst_if.reset_n ), .boot_addr_i ( boot_addr ), - .cvxif_resp ( cvxif_if.cvxif_resp_o ), - .cvxif_req ( cvxif_if.cvxif_req_i ), .irq_i ( interrupt_vif.irq ), .axi_slave ( axi_if ), .axi_switch_vif ( axi_switch_vif ), @@ -70,16 +67,4 @@ module uvmt_cva6_dut_wrap # ( .rvfi_o ( rvfi_o ) ); - assign cvxif_if.cvxif_resp_o.x_compressed_ready = 0; - assign cvxif_if.cvxif_resp_o.x_compressed_resp = 0; - assign cvxif_if.cvxif_resp_o.x_issue_ready = 1; - assign cvxif_if.cvxif_resp_o.x_issue_resp = 0; - assign cvxif_if.cvxif_resp_o.x_result_valid = 0; - assign cvxif_if.cvxif_resp_o.x_result.id = 0; - assign cvxif_if.cvxif_resp_o.x_result.data = 0; - assign cvxif_if.cvxif_resp_o.x_result.rd = 0; - assign cvxif_if.cvxif_resp_o.x_result.we = 0; - assign cvxif_if.cvxif_resp_o.x_result.exc = 0; - assign cvxif_if.cvxif_resp_o.x_result.exccode = 0; - endmodule diff --git a/verif/tb/uvmt/uvmt_cva6_tb.sv b/verif/tb/uvmt/uvmt_cva6_tb.sv index 11c0e54f9e..5e100905ce 100644 --- a/verif/tb/uvmt/uvmt_cva6_tb.sv +++ b/verif/tb/uvmt/uvmt_cva6_tb.sv @@ -59,10 +59,7 @@ module uvmt_cva6_tb; // Agent interfaces uvma_clknrst_if clknrst_if(); // clock and resets from the clknrst agent - uvma_cvxif_intf cvxif_if( - .clk(clknrst_if.clk), - .reset_n(clknrst_if.reset_n) - ); // cvxif from the cvxif agent + uvma_axi_intf axi_if( .clk(clknrst_if.clk), .rst_n(clknrst_if.reset_n) @@ -83,12 +80,6 @@ module uvmt_cva6_tb; uvmt_default_inputs_intf default_inputs_vif(); - //bind assertion module for cvxif interface - bind uvmt_cva6_dut_wrap - uvma_cvxif_assert cvxif_assert(.cvxif_assert(cvxif_if), - .clk(clknrst_if.clk), - .reset_n(clknrst_if.reset_n) - ); //bind assertion module for axi interface bind uvmt_cva6_dut_wrap uvmt_axi_assert #(CVA6Cfg.DCacheType) axi_assert(.axi_assert_if(axi_if)); @@ -122,7 +113,6 @@ module uvmt_cva6_tb; .NUM_WORDS (NUM_WORDS) ) cva6_dut_wrap ( .clknrst_if(clknrst_if), - .cvxif_if (cvxif_if), .axi_if (axi_if), .axi_switch_vif (axi_switch_vif), .default_inputs_vif (default_inputs_vif), @@ -371,7 +361,6 @@ module uvmt_cva6_tb; // Add interfaces handles to uvm_config_db uvm_config_db#(virtual uvma_clknrst_if )::set(.cntxt(null), .inst_name("*.env.clknrst_agent"), .field_name("vif"), .value(clknrst_if)); - uvm_config_db#(virtual uvma_cvxif_intf )::set(.cntxt(null), .inst_name("*.env.cvxif_agent"), .field_name("vif"), .value(cvxif_if) ); uvm_config_db#(virtual uvma_axi_intf )::set(.cntxt(null), .inst_name("*"), .field_name("axi_vif"), .value(axi_if)); uvm_config_db#(virtual uvmt_axi_switch_intf )::set(.cntxt(null), .inst_name("*.env"), .field_name("axi_switch_vif"), .value(axi_switch_vif)); uvm_config_db#(virtual uvmt_rvfi_if#( .CVA6Cfg(CVA6Cfg), .rvfi_instr_t(rvfi_instr_t), .rvfi_csr_t (rvfi_csr_t)))::set(.cntxt(null), .inst_name("*"), .field_name("rvfi_vif"), .value(rvfi_if)); diff --git a/verif/tests/custom/cv_xif/cvxif_add_nop.S b/verif/tests/custom/cv_xif/cvxif_add_nop.S index 6a88eaa667..525df19e8d 100644 --- a/verif/tests/custom/cv_xif/cvxif_add_nop.S +++ b/verif/tests/custom/cv_xif/cvxif_add_nop.S @@ -21,16 +21,36 @@ main: # core of the test +start0: LOAD_RS(a0, 0x332211); LOAD_RS(a1, 0xDEADBEEF); LOAD_RS(a2, 0xDEADBEEF); + CUS_NOP(); + CUS_ADD(01010, 01010, 01011); + CUS_ADD(01011, 01010, 01011); + CUS_ADD(01010, 01011, 01011); + lw a0, num1; + CUS_ADD_RS1(01000,01010,01011); + lw a1, num2; + CUS_ADD(01010,01011,00000); - CUS_ADD(01010,01010,01010,01011); - CUS_NOP(00000,00000,00000,00000); - CUS_NOP(00000,00000,00000,00000); - CUS_ADD(01010,01010,01010,01011); - CUS_NOP(00000,00000,00000,00000); - CUS_ADD(01010,01010,01010,01011); +# Take branch to check for instruction kill + li a0, 0xCAFE; + li a1, 0xCAFE; + xor a2, a0, a1; + beqz a2, branch2; + +branch1: + CUS_ADD(00000, 00000, 01011); + CUS_NOP(); + CUS_NOP(); + +branch2: + CUS_ADD(01010, 01010, 01011); + lw a0, num1; + CUS_ADD_RS1(01000,01010,01011); + lw a1, num2; + CUS_ADD(01010,01011,00000); # (example of) final self-check test li a0, 0xCAFE; @@ -47,3 +67,8 @@ pass: # Success post-processing (messages, ecall setup etc.) li a0, 0x0; jal exit; + +.data + num1: .word 5 // First number + num2: .word 7 // Second number + result: .word 12 // Result \ No newline at end of file diff --git a/verif/tests/custom/cv_xif/cvxif_full.S b/verif/tests/custom/cv_xif/cvxif_full.S new file mode 100644 index 0000000000..c0e64d2178 --- /dev/null +++ b/verif/tests/custom/cv_xif/cvxif_full.S @@ -0,0 +1,104 @@ +# See LICENSE for license details. + +#***************************************************************************** +# Copyright 2022 Thales DIS design services SAS +# +# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 +# You may obtain a copy of the License at https:#solderpad.org/licenses/ +# +#---------------------------------------------------------------------------------- + +#include "cvxif_macros.h" + + #------------------------------------------------------------- + # Custom tests + #------------------------------------------------------------- + + .globl main +main: + +# core of the test + +start0: + LOAD_RS(a0, 0x332211); + LOAD_RS(a1, 0xDEADBEEF); + LOAD_RS(a2, 0xDEADBEEF); + CUS_NOP(); + CUS_ADD(01010, 01010, 01011); + CUS_ADD(01011, 01010, 01011); + CUS_ADD(01010, 01011, 01011); + lw a0, num1; + CUS_ADD_RS1(01000,01010,01011); + lw a1, num2; + CUS_ADD(01010,01011,00000); + +# R4-Type RS3 Instructions + LOAD_RS(a0, 0x111111); + LOAD_RS(a1, 0x222222); + LOAD_RS(a2, 0x333333); + CUS_ADD_RS3_MADD(01010,01011,01100,01101); + CUS_ADD_RS3_MSUB(01010,01011,01100,01101); + CUS_ADD_RS3_NMADD(01010,01011,01100,01101); + CUS_ADD_RS3_NMSUB(01010,01011,01100,01101); + +# R-type RS3 Instruction + LOAD_RS(a0, 0x111111); + LOAD_RS(a1, 0x222222); + LOAD_RS(a2, 0x333333); + CUS_ADD_RS3_RTYPE(01010,01011,01100); # --> result in 0b01010 + CUS_ADD_RS3_RTYPE(01010,01011,01100); # --> result in 0b01010 + CUS_ADD_RS3_RTYPE(01010,01011,01100); # --> result in 0b01010 + +# Take branch to check for instruction kill + li a0, 0xCAFE; + li a1, 0xCAFE; + xor a2, a0, a1; + beqz a2, branch2; + +branch1: + CUS_ADD(00000, 00000, 01011); + CUS_NOP(); + CUS_NOP(); + +branch2: + CUS_ADD(01010, 01010, 01011); + lw a0, num1; + CUS_ADD_RS1(01000,01010,01011); + lw a1, num2; + CUS_ADD(01010,01011,00000); + +# Compressed instruction leads to error in spike + LOAD_RS(a0, 0x111111); + LOAD_RS(a1, 0x222222); + LOAD_RS(a2, 0x333333); + CUS_CNOP(); + CUS_CADD(01011,01010); + xor a1, a0, a2; + beqz a2, pass; + +# Should raise an exception +# .half 0x0000; +# .word 0xFFFFFFFF; + +# (example of) final self-check test +# li a0, 0xCAFE; +# li a1, 0xCAFE; +# xor a2, a0, a1; +# beqz a2, pass; + +fail: + # Failure post-processing (messages, ecall setup etc.) + li a0, 0x0; + jal exit; + +pass: + # Success post-processing (messages, ecall setup etc.) + li a0, 0x0; + jal exit; + +.data + num1: .word 5 // First number + num2: .word 7 // Second number + result: .word 12 // Result \ No newline at end of file diff --git a/verif/tests/custom/cv_xif/cvxif_macros.h b/verif/tests/custom/cv_xif/cvxif_macros.h index f7e4448ce8..be2a692c26 100644 --- a/verif/tests/custom/cv_xif/cvxif_macros.h +++ b/verif/tests/custom/cv_xif/cvxif_macros.h @@ -6,14 +6,23 @@ // You may obtain a copy of the License at https://solderpad.org/licenses/ // // Original Author: Zineb EL KACIMI (zineb.el-kacimi@external.thalesgroup.com) +// Contributor : Guillaume Chauvon #define LOAD_RS(rs,value) li rs, value #define COMP_RS(rs1,rs2,rd) xor rd, rs1, rs2 + +#define CUS_NOP() .word 0b##0000000##00000####00000##000##00000##1111011 #define CUS_ADD(rs1,rs2,rd) .word 0b##0000000##rs2####rs1##001##rd##1111011 -#define CUS_NOP(rs1,rs2,rd) .word 0b##0000000##00000####00000##000##00000##1111011 -#define CUS_ADD_RS3(rs1,rs2,rs3,rd) .word 0b##rs3##01##rs2####rs1##000##rd##1111011 -#define CUS_ADD_MULTI(rs1,rs2,rd) .word 0b##0001000##rs2####rs1##000##rd##1111011 -#define CUS_EXC(rs1,rs2,rs3,rd) .word 0b####1100000##rs2####rs1##010##rd##1111011 -#define CUS_U_ADD(rs1,rs2,rd) .word 0b####0000010##rs2####rs1##000##rd##1111011 -#define CUS_S_ADD(rs1,rs2,rd) .word 0b####0000110##rs2####rs1##000##rd##1111011 +#define CUS_ADD_RS1(rs1,rs2,rd) .word 0b##0000001##rs2####rs1##001##rd##1111011 // only use rs1 : rs1 + rs1 => rd +#define CUS_ADD_RS2(rs1,rs2,rd) .word 0b##0000010##rs2####rs1##001##rd##1111011 // only use rs2 : rs2 + rs2 => rd +#define CUS_ADD_MULTI(rs1,rs2,rd) .word 0b##0000011##rs2####rs1##001##rd##1111011 + +#define CUS_ADD_RS3_MADD(rs1,rs2,rs3,rd) .word 0b##rs3##00##rs2####rs1##000##rd##1000011 //MADD +#define CUS_ADD_RS3_MSUB(rs1,rs2,rs3,rd) .word 0b##rs3##00##rs2####rs1##000##rd##1000111 //MSUB +#define CUS_ADD_RS3_NMSUB(rs1,rs2,rs3,rd) .word 0b##rs3##00##rs2####rs1##000##rd##1001011 //NMSUB +#define CUS_ADD_RS3_NMADD(rs1,rs2,rs3,rd) .word 0b##rs3##00##rs2####rs1##000##rd##1001111 //NMADD +#define CUS_ADD_RS3_RTYPE(rs1,rs2,rs3) .word 0b##0000100##rs2####rs1##001##rs3##1111011 + +#define CUS_CADD(rs1, rs2) .half 0b##111##1##rs1##rs2##00 // -> Extend to CUS_ADD(rs1,rs2,x10) +#define CUS_CNOP() .half 0b##111##0##00000##00000##00 // -> Extend to CUS_NOP diff --git a/verif/tests/testlist_cvxif.yaml b/verif/tests/testlist_cvxif.yaml index ac6d6ef213..1f6f45eb43 100644 --- a/verif/tests/testlist_cvxif.yaml +++ b/verif/tests/testlist_cvxif.yaml @@ -36,10 +36,15 @@ common_test_config_lgcc: &common_test_config_lgcc testlist: - test: cvxif_add_nop - <<: *common_test_config - iterations: 0 + <<: *common_test_config_lgcc + iterations: 1 asm_tests: /custom/cv_xif/cvxif_add_nop.S + - test: cvxif_full + <<: *common_test_config_lgcc + iterations: 1 + asm_tests: /custom/cv_xif/cvxif_full.S + - test: cvxif_multi <<: *common_test_config iterations: 0 From 3e62b0b910585af1aa1c83f3a48cc724d60cb7d5 Mon Sep 17 00:00:00 2001 From: Zbigniew Chamski <107464696+zchamski@users.noreply.github.com> Date: Fri, 12 Jul 2024 11:52:01 +0200 Subject: [PATCH 006/183] [Spike Yaml] HOTFIX: Add libyaml-cpp to preload list of RTL simulators. (#2358) --- verif/sim/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/verif/sim/Makefile b/verif/sim/Makefile index ac605ddc71..6d8e2d1676 100644 --- a/verif/sim/Makefile +++ b/verif/sim/Makefile @@ -206,6 +206,7 @@ COMMON_RUN_ARGS = \ -sv_lib $(SPIKE_INSTALL_DIR)/lib/libcustomext \ -sv_lib $(SPIKE_INSTALL_DIR)/lib/libriscv \ -sv_lib $(SPIKE_INSTALL_DIR)/lib/libfesvr \ + -sv_lib $(SPIKE_INSTALL_DIR)/lib/libyaml-cpp \ -sv_lib $(SPIKE_INSTALL_DIR)/lib/libdisasm ALL_UVM_FLAGS = -lca -sverilog +incdir+$(VCS_HOME)/etc/uvm/src \ @@ -314,6 +315,7 @@ xrun_uvm_run: $(XRUN_RUN) \ +sv_lib=$(SPIKE_INSTALL_DIR)/lib/libriscv \ +sv_lib=$(SPIKE_INSTALL_DIR)/lib/libfesvr \ + +sv_lib=$(SPIKE_INSTALL_DIR)/lib/libyaml-cpp \ +sv_lib=$(SPIKE_INSTALL_DIR)/lib/libdisasm \ ++$(elf) \ +elf_file=$(elf) \ From e53c669df12d00e904e699e5f415c21c697337bb Mon Sep 17 00:00:00 2001 From: valentinThomazic Date: Fri, 12 Jul 2024 14:05:02 +0000 Subject: [PATCH 007/183] Enable tandem on smoke-gen tests in ci (#2357) --- .gitlab-ci.yml | 5 +---- verif/sim/cva6.py | 3 +++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bda97a29d9..74db1b28b6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -155,6 +155,7 @@ gen_smoke: DASHBOARD_SORT_INDEX: 0 DASHBOARD_JOB_CATEGORY: "Basic" DV_SIMULATORS: "vcs-uvm,spike" + SPIKE_TANDEM: 1 COLLECT_SIMU_LOGS: 1 script: - bash verif/regress/smoke-gen_tests.sh @@ -296,7 +297,6 @@ riscv_arch_test: DASHBOARD_SORT_INDEX: 0 DASHBOARD_JOB_CATEGORY: "Test suites" DV_SIMULATORS: "veri-testharness,spike" - COLLECT_SIMU_LOGS: 1 script: source verif/regress/dv-riscv-arch-test.sh after_script: *simu_after_script @@ -309,7 +309,6 @@ compliance: DASHBOARD_SORT_INDEX: 2 DASHBOARD_JOB_CATEGORY: "Test suites" DV_SIMULATORS: "veri-testharness,spike" - COLLECT_SIMU_LOGS: 1 script: source verif/regress/dv-riscv-compliance.sh after_script: *simu_after_script @@ -324,7 +323,6 @@ riscv-tests-v: DV_SIMULATORS: "veri-testharness,spike" DV_TARGET: cv64a6_imafdc_sv39 DV_TESTLISTS: "../tests/testlist_riscv-tests-$DV_TARGET-v.yaml" - COLLECT_SIMU_LOGS: 1 script: source verif/regress/dv-riscv-tests.sh after_script: *simu_after_script @@ -338,7 +336,6 @@ riscv-tests-p: DASHBOARD_JOB_CATEGORY: "Test suites" DV_SIMULATORS: "veri-testharness,spike" DV_TESTLISTS: "../tests/testlist_riscv-tests-$DV_TARGET-p.yaml" - COLLECT_SIMU_LOGS: 1 script: source verif/regress/dv-riscv-tests.sh after_script: *simu_after_script diff --git a/verif/sim/cva6.py b/verif/sim/cva6.py index 92ea1bcf5e..e8c1744541 100644 --- a/verif/sim/cva6.py +++ b/verif/sim/cva6.py @@ -704,6 +704,7 @@ def iss_sim(test_list, output_dir, iss_list, iss_yaml, iss_opts, elf = prefix + ".o" log = ("%s/%s_%d.%s.log" % (log_dir, test['test'], i, target)) cmd = get_iss_cmd(base_cmd, elf, target, log) + yaml = ("%s/%s_%s.%s.log.yaml" % (log_dir, test['test'], i, target)) if 'iss_opts' in test: cmd += ' ' cmd += test['iss_opts'] @@ -713,6 +714,8 @@ def iss_sim(test_list, output_dir, iss_list, iss_yaml, iss_opts, else: run_cmd(cmd, timeout_s, debug_cmd = debug_cmd) logging.debug(cmd) + if (iss != "spike" and os.environ.get('SPIKE_TANDEM') != None): + analize_result_yaml(yaml) def iss_cmp(test_list, iss, target, output_dir, stop_on_first_error, exp, debug_cmd): From da1c7477ed1d32c49bf667914484d225b689323c Mon Sep 17 00:00:00 2001 From: Jalali <110232072+AyoubJalali@users.noreply.github.com> Date: Fri, 12 Jul 2024 14:21:04 +0000 Subject: [PATCH 008/183] Increase simulation time on CSR tests (#2361) --- verif/regress/dv-csr-embedded-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verif/regress/dv-csr-embedded-tests.sh b/verif/regress/dv-csr-embedded-tests.sh index 82752d40d3..13ee55b41c 100644 --- a/verif/regress/dv-csr-embedded-tests.sh +++ b/verif/regress/dv-csr-embedded-tests.sh @@ -31,6 +31,6 @@ if ! [ -n "$DV_SIMULATORS" ]; then fi cd verif/sim/ -python3 cva6.py --testlist=../tests/testlist_csr_embedded.yaml --iss_yaml cva6.yaml --target $DV_TARGET --iss=$DV_SIMULATORS $DV_OPTS --priv=m -i 1 +python3 cva6.py --testlist=../tests/testlist_csr_embedded.yaml --iss_yaml cva6.yaml --target $DV_TARGET --iss=$DV_SIMULATORS $DV_OPTS --priv=m --iss_timeout 600 cd - From 71653038d7ef4db6e8777377879c9252147292b2 Mon Sep 17 00:00:00 2001 From: jzthales Date: Fri, 12 Jul 2024 14:49:02 +0000 Subject: [PATCH 009/183] Doc lsu (#2359) --- core/load_unit.sv | 44 +++++++-------- .../design/images/schema_fsm_load_control.png | Bin 0 -> 42749 bytes .../design/source/cv32a6_execute.rst | 21 ++++++-- .../design/source/port_load_unit.rst | 50 +++++++++--------- 4 files changed, 63 insertions(+), 52 deletions(-) create mode 100644 docs/04_cv32a65x/design/images/schema_fsm_load_control.png diff --git a/core/load_unit.sv b/core/load_unit.sv index beb953cbd5..cea27c6b27 100644 --- a/core/load_unit.sv +++ b/core/load_unit.sv @@ -31,53 +31,53 @@ module load_unit input logic clk_i, // Asynchronous reset active low - SUBSYSTEM input logic rst_ni, - // TO_BE_COMPLETED - TO_BE_COMPLETED + // Flush signal - CONTROLLER input logic flush_i, - // Load unit input port - TO_BE_COMPLETED + // Load request is valid - LSU_BYPASS input logic valid_i, - // TO_BE_COMPLETED - TO_BE_COMPLETED + // Load request input - LSU_BYPASS input lsu_ctrl_t lsu_ctrl_i, - // TO_BE_COMPLETED - TO_BE_COMPLETED + // Pop the load request from the LSU bypass FIFO - LSU_BYPASS output logic pop_ld_o, - // Load unit result is valid - TO_BE_COMPLETED + // Load unit result is valid - ISSUE_STAGE output logic valid_o, - // Load transaction ID - TO_BE_COMPLETED + // Load transaction ID - ISSUE_STAGE output logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_o, - // Load result - TO_BE_COMPLETED + // Load result - ISSUE_STAGE output logic [CVA6Cfg.XLEN-1:0] result_o, - // Load exception - TO_BE_COMPLETED + // Load exception - ISSUE_STAGE output exception_t ex_o, - // Request address translation - TO_BE_COMPLETED + // Request address translation - MMU output logic translation_req_o, - // Virtual address - TO_BE_COMPLETED + // Virtual address - MMU output logic [CVA6Cfg.VLEN-1:0] vaddr_o, - // Transformed trap instruction out - TO_BE_COMPLETED + // Transformed trap instruction out - MMU output logic [31:0] tinst_o, - // Instruction is a hyp load store instruction - TO_BE_COMPLETED + // Instruction is a hyp load store instruction - MMU output logic hs_ld_st_inst_o, - // Hyp load store with execute permissions - TO_BE_COMPLETED + // Hyp load store with execute permissions - MMU output logic hlvx_inst_o, - // Physical address - TO_BE_COMPLETED + // Physical address - MMU input logic [CVA6Cfg.PLEN-1:0] paddr_i, - // Excepted which appears before load - TO_BE_COMPLETED + // Excepted which appears before load - MMU input exception_t ex_i, - // Data TLB hit - lsu + // Data TLB hit - MMU input logic dtlb_hit_i, - // TO_BE_COMPLETED - TO_BE_COMPLETED + // Physical page number from the DTLB - MMU input logic [CVA6Cfg.PPNW-1:0] dtlb_ppn_i, - // TO_BE_COMPLETED - TO_BE_COMPLETED + // Page offset for address checking - STORE_UNIT output logic [11:0] page_offset_o, - // TO_BE_COMPLETED - TO_BE_COMPLETED + // Indicates if the page offset matches a store unit entry - STORE_UNIT input logic page_offset_matches_i, - // Store buffer is empty - TO_BE_COMPLETED + // Store buffer is empty - STORE_UNIT input logic store_buffer_empty_i, - // TO_BE_COMPLETED - TO_BE_COMPLETED + // Transaction ID of the committing instruction - COMMIT_STAGE input logic [CVA6Cfg.TRANS_ID_BITS-1:0] commit_tran_id_i, // Data cache request out - CACHES input dcache_req_o_t req_port_i, // Data cache request in - CACHES output dcache_req_i_t req_port_o, - // TO_BE_COMPLETED - TO_BE_COMPLETED + // Presence of non-idempotent operations in the D$ write buffer - CACHES input logic dcache_wbuffer_not_ni_i ); enum logic [3:0] { diff --git a/docs/04_cv32a65x/design/images/schema_fsm_load_control.png b/docs/04_cv32a65x/design/images/schema_fsm_load_control.png new file mode 100644 index 0000000000000000000000000000000000000000..a5907072eae979de9fe80c366922313e6f501605 GIT binary patch literal 42749 zcmeFa2Ut_tx<5=)f`WjkfJh0|k={a+7P>SQ0qG#2M4I#_O+gf?Q9(gO6h);62)(EX zC{0mHK#FBRnt(K=erp3!6rGtfXYT!qiRT^?B;z#L_`uq9xBH@oP2E2jy6PGqDpI5 zT%s!A8ils9bF*^d5)pE?aDZNScru<-hGpaDI! z-}(-Oh1REeqER;P>#MB|dAPVZdZ15zKWOdZ>}+H0@!do#H#ZmW@2Ah(>wXug#SdkyzUcG+W&UZD&t-vM^$mC?Y~mR)opxCvms8Lb-Ua z-M>1tN;o$c7jUb}Do>Pb93kQn=(2X7>M#EKb^mTQ&g&2V;~ON_x9nx*=(&D4Ej|6U zW4L?x5)SO{jdpUhat1Sy-u7q@8@*Fj*3fisz+W(C@8RSKJ_&9PB|G|-53j(`g%pH-IqoPCn( zYiyvm-Z9;yDqws1IvU3|5#G(k(-~z0NvF`C(|$8?zOwf(Q%87RQrD>?EU}q7!XiJR zj^z5-ze5};v9%LyAP$!Z!Vw5E($)pYvxtzji=&I%sTztt^42zkotn~eVJY!LZ>$p>L! zZ~*8G-!TFj*Z>JO&L~9)N&z>l9j)Bm(bnMT?jBZd9-D_Z;KTOuPF8-m_ByQ~_ejjFglWaWsqa|Q&n z2A0qUU0xicc21)1IKL0%x2Tp;2*gEqe z83k(!ONk2*c(Os3L?i?V`T5|9Eq z1po{hScNIVhhKoy_q1KT?XZm-8n`f!46j1o+QEOoqMzHFjllMm&6|;JGm!ne2t{zz z*SSRiRf3rQ0#|_Hu!0;l!n9Km?ybt-&w)@x;(PpBf6Oo8PIMiUzu(n2&u#7b-|*~T zggEidR@2el)56-r&CvqANsIn7kZo;So1EvLiPL5&S+_?b66*(Fr>ponS2pP8&-`fu zHwfJRTi7MOZdU$SHNV%YUnnX-n2m}GuvL^W@C#-Asd^Gz8X*B-me*XDuZsUmpXP7s zG{G_1sM70tzL{J9rcVE;Y{Ei6ghRhjYA2r`ybckm@73^Yh(Qp9U$`&-DmsV?eUA>p z!fPA;=k$GZxN^$nl!YV8!sS0y+c)?zkn{YHC_lleC4lOGpYlts3*ZL7MMF&b-^0Ma?6~~PnFfN{BjDn?+;6}|Q342V^y~hSPg8}*P7Ly-|A||w1P<~1j0`dMG zq6iDE=VCWV$|f=SX{^7&jDAlsf(3*UfY9}-`TJ%KzZp}=972NdHIV;FRKI3K{~)a2 z82W)^5JJdGN*J=_-^Yn48(S;S)lAab;WmbD1n+)B7T{-wl^{Mpc;1^0?FLyUfa6B> zCXD@?_E?M%wh_>Upf&_)_=OqWWRJyu&`B|ZeI_jQ3&Z}mvH+W5X}{QS0I(fhtWXv} z1kwMw#`Bkgv&nnjED{7yS?Y&)Ut-;T-5@dq>TeVof|Vd}$146KcWQQY~TeU@ZZRbbuaR3 zkovcHL9jai4(JkKRtThw#J+=CA>bLULGLfH769*$S%t4D3w|L1A>i777YeN}_y;Kb z(@^M_8nZDk@jn1+#YMi4B*Y1h9YG)eD%6VqkgyOJ{cADQ-+@{}F8BYZBK99*r8oI@ zKXUx9ijJ6&B*=kEef#+yy~KW8_a8Lc1fbj?Ngh^q|7SKE%BCN}(ar4teY?SdOpl~SOR`>)2&|LN+uDG-s6 z5)cN1Uw_t3^1rH&P+amu{a1_-)t*x?dnuSIG8`IEYo2%vm_0OLg&Oh(${kapnTHE_&-^&JA{VwIa>iYgc zy7`xU*qB)+5OyP`O05U?{~?enNob5(7X~pxage~|zY3yKKVb9M8Zu#_e-JjsH%ITA zWa#^f@Sn6=Y%Jk^mqgkGY2Wvyt@`@EEVdCyNzgMw3&93G`uwX@Y7f*S-teA?h>b`?S@D>U`B(+jqK&@M+!84*@fOa*`wzRm zx_NU#ao6sNEi6puPHV8SS<>8AW>lsnCbhDJQC>cL!souwrG&T5#jF)&4<~)uz6f1r zJZgO+HbV8N`h?}}Gwi~1mCd8#nfUw`sRhrmijL)vEq47Y@^)jMW+VPt?z7`TV-7im zar2&;LkTiIq{J|Vn+ary;X8(sTfjA&P)KC}W42NLR(>X*9hN&tXc%Zhq7aFvo#w{M z{1wPtcazYZzo5`pNlA+pZW5>^A%=^Uj%7ZQ%Lrx*B@iLK1lae2QJN3b;Le~EAv`p}3Ug#M*q%BfYBsRUF7Du1{>X@P zG{My{7#m8B26YZb469Khf-~vzF;bAR9Zn%a;^dV4z(&|;B8iX)hLe;AT?kp9+LrAyn$wm^9WYH7na{0MG1u$w`T0$_L)!!WOMNl& z%RXjqPr15IPc;ozx(wd%Xw@j4Zq+Po5Gc!3^6vE=L_a*UMSA$&ZPaYE-24ZsTmciD zV>0z}(#yp>1W(FoYsVoj&SJss z%$&TI-L*V$)U_=Tn{NQ2w?TO5RMTU1!~`rVO&3PLmU;}eYRvhM=G94uoUD@nRL^m#&*{2OOVR$bMb93heHi|#o&QoEd>u5{SOEWgPDpjep$z%!ZI6uwG#u_)nG(rf zUJ!U$0z@sFE*AfL&NCRk97Eh^-b;$+cFxbBF7E$~V+EpdKV#2m`BXCsMJ{u@+jAeh zTfo9EoQUk43fOU`kIK+kxhJY;%*R4(zGyUm+^)m6sl7nQBuTu?JnL+-nHs{OrORf^ zc!Aq_bc1h6*YS~zdTH#-(@}0`gzn7%R$Zg{Cd3fxGSCo*js~9z%K#WS0%)AYQ47GD zC}aT4O|sU|1st9L5Ess>qzbqYc^(L)@;=fo0b#ykEF(Lx1dus7n1|v7j|>2d%u@~#L%=Kqt}X8glL5Jh zfSE|~kqQLC(ZDQ}Ku_sM1Jt!8g?2|wt5CmV|MB8&#IOR$8cLs_gbrg5=HjH{r=cZ) z>GAq3j3NU&JrB;Jw#)GxnBB+~9GiUc{8oqv^T1GbryTDGhU&R2*wUPEH7WGKFmT@O zw{O7#=97Re(UM(*g9A(gb5cvEsS4Ec6)-+oEwL<+T#^BsM0IYj5_k*|qzN>frob+< z^+TlI{(q$Y-$UvT$+2TB6fBUKeUJq{oA(?G!ww)9t~>i1gqn+Y*c@ZhoWGxDNBP8R zF|?YJ#N^OCoyPd(X;O9It^ny?04g#jTKmX@gxfNRZ|IuB83i)3<^+!iX))YEHz2s$mdOewQhoDarVl7E&-bxQ2KzH`ENgD6Q-w!IB+dNi#Le z*Rx}{RxB_GCW)=8ti;3(wShuQw?`>7SUGr^6pt~2RiFC^nyc0Z<>$rzEjMiSdZ$ud&jBRIbf&+Q2(lT zbY}|tqauIef_F^($1kGYuHhJ*xfC+@D8UGT*0IbM8VI%wwS`S4?#P;X!;x4Lc{wGBANPS@z`b9hbrybi8F|Y ztrBD;fFfH%qke8wRi@>}f~L#m4zzfcA_P$VBrp=~kLsR6vib~M$G>Z{ z9m$OKEc%pxhlradN1ItnT5Z&pwKr1ZTEX?5xI!-^ExgR|z`W_$2=F5kUU;7AXv;{fJ}915Qh1a&!?SSN z5zX)KQZ?=Ef4)&UTQG94tv-G?R#1bL!5{5#Y>0ux3RtJdpKA94U2=n{r4`JMY`<{G zldl;9APOz&SpcqI2a+#E`B3T?v>6WF@J*Ga(xej3+a?-(O_Z z?9z<=iXB#9OmMn}^>wg<8Q4iFnG`DobQIuvXRdvhWQfJ(Y5J#CJ$uKm?SMb00*gz$ z&I2|$@-k4Yw2<+qx!ToT0#;>nf3(CQL+#JM*ZSX8`uRp=IhXFICH&C}E1Iosm|4ei zJLymb3BZJ&Q*}^ydlc+4ZfhmaV+8Sn+S8q;IUg>_7ZZn+f*GC^ZgLRIc7kgz%NGT% zBse|%Zj3qJr^N#n;tZgm>`k;j2vgI*1P-dxy62o^B9}taD*WG4J1g8200%WYbDbKZ zC>gk>I4`ORVDI8$IIT-_h1#v*~qs1m<8F3Vy7r82MJj?xC$%esT zJ6HV|NNx`Sk&6#jd09&_$}xo0SU~iOG9zy?fz3M?TZ7a9!*9TSQzz}aWHrt+bXp^4 zA1TORg6wCo!X+~GcyWzOm2MQ0@CKCi84pFv z)U-=n%$;Gbj>wx^NKmMYN@4o0212m`q$fNOm_Cc zRh@$6I8fva1?No>#Qx=JMap8_=R}-IOv^9Uu^K!vqRQi%WIpj~>j&_40>O$G>whmg zB(2lh&AyjTiBW=Bp!dl;>WsIU=Q=T;cL<*(oo0l~RNqv2|0zeqFFdVC?N8P^%f-w! z6nnn5=5Vcc@I~**&yOESX25Zrl}eFaL;L1vgG8NNTE1M7|UIu_b*E3Mqh#9i@7=ImB@B5$C9 z9giL3eX2)lLEU(WQBqpA#T>gVaK+=O8~xM5qK+1fhXppY zKly%ztlK%4B`yCT6=U-m^?~xyt4m(C?ncqfRZ;TGGHzYA3z8GDq91=NbP?3Vm-$ z5Kou6;#+VTx4tAWJJ6b|+%grbRGGg;MRpgclZaF)rzJ@{LM2xay#rRG08xMc9vgk- z<6llR9z1ocJ+!NQDj(S#Rb4Y8h0)Qi#wYa%6bK%U9)NX*J#Qa0 zOSCmLZ4uD4roV@F%FHUuHBq%U-kKR%G!?3Rt#T1pnL_PE{2q+cOY4wzk4`_6Q$bT3Kd~O~IpMwis z0)ZSwD;IG$<(nu>^jPbKddCGkgM^rO#*4rpwyDG6J!cMzx+e+qqRj3#2t2}v>n(0i z_5WNeVijocR3KO;-7B4<`QYTJg~!zB>y&n3;{nN}I8XNK)ALBTB+rb<;-}jeGF|s1 za|30@U?Q*w65$0>C%VnMCk@R5hRUZF;^UGL68U$i@}E&HlD}JQ`Mn@A(?a!4DBqne zPX1xdBI*4{{uZaBko>u2$gzc|GAoZGc?mk zUrVb^h#hP0? z(^sV#o2Ajzo?|rQ$BNBPr59FhL?ar(F3xk$I^F-qy2fi|OO z4fXB!<77MOupei$uI%jO*RVKk%+u^Ov3s30in* zAXEgZZ9cm=RCgZx4)_s$)tJZJdRLD;9Y?Zj1#gQa|Lyy$gR;OkN1M{TA@)N6RLzgRf z$>XT9_3-1vwqsqtFY>nD9m>CY+(3=R3nDmlbXUCwaUtcb?8Y}UkPv818qq@LZ zalCbb6#u zs?3P|y(cu^%GBJWdTtjwN_2KlTtm8sNQkE&pn~82mn?6wGba*kyhIXl1AIuF-!5>U z9r@3W9gYd8DvF<$p^dsflKTFFUP4qs#jB;Im+2RJGh=6pK296b*E`=H8fO^DIc%9@ z!W#eEY)8h7QHlPR8@xjk$4-?sQNC_=S@yc6bJc{k+4)A_#h0E=PI_AxzKnAQh=`x| zD0O{QaMi|8dSXmhCL9<-U80|Dp4+nMGHQFb`zxN?dDjy|Wxd2eL<6lk@gxK3p5hdgG(U=!^>7+Ddjq(6Q*=eiZfP0*k~e9s#A9=@(vK>7968OA;?U z^Te4E?qFm}*M-M!v8%m8dNsBZ5%8j-JuS9r8(P%HI&m(Rfqwkd6tm_McePz=-{gf_ znNUZu)P3(2;<<~$oOYD*^|Fz_;7HGBG_n}|;%w`n?V|m}+T7ONShd~DW`Q*4SnB=A zOhHr@=c9qzOp`Bx1FsJ4U2G*`s-k;iqq)7le%AiPyJu{`Stn=2y^)HFWj1d-@u^ce zJOFPL#i15J;wz5L?kK0UPTq@e5M?x{i^4@F%HHz~`b5*mg)zORaBZ&<56W!ot7RAQ z{Eu&hGujHn+xMj9ELi8_@P6k0P0uKvZ8Ne<*^8f_!m!kWx`9k{F*&O^5+UhE=||=$ zbuYz_dX6YvE(EQ4@^=b+X~v$%|h0u<9+CK(-+cnv<6mdYjFSNb|jB zPrhQz5e<^<%A^XS>cWi<3Qw>aO!egqQ`3(he(_kRk7B~;gMTRdBsH8#gN*g0COz4$w0&gl{@rcrdQjw%*o&|Wh8JRIYUqkg zWCWDhVu}GGTMjJVoE^d=}!CN zrV0sb!nBh{iv5eNW=d?FAV7hmtutE4KJ!gWNz;Bg7aO(zD(Svwcb<~W_Nf<1Gv8b& zrVOEiotm^gs$j_v7HbS;14}6iS);avG+_9(SBzTSV2U8OW?Ifc!TI=}c5n;QDb(XI zC`934TwMh!)nubRLk72;@HZ`Bp`6uEWH_B1XRZ;YgvqJ#u=mkmX}7osE0rKy4`>+f zcfnO5j>@HQD-so+JdsLOUq; zxmSR7Qj1bAGzf<}nojQPve&9!&PvM&ACO!|T5bc+(xTe*tO*T`BF%X^@T?VeY%HM{ z;MZsD*TXCux2E81f&<|+SAj{Xt`_bvAvwLrk14TupHhA8?v~W3TC!1ojGU}k-6TDU z9z@ZTnThSajZttX*D`# z+ZU2h{+_GvOM6k}%-d6Y^2AO6CyJI_{{3?%daRd>Rny+2s(mz9wfiLk-$_j4iYm0# z_PLVX1L+DPGDKH>7Rt{t|2ji@X3* zFj_A@p3a2fo0Wuikkeq_op%>h^X;?>ALfl+C1WV2WWa+kx4D$psqIGUvQaEF( zQ^Q#f@Cr)4k5wW9r4}+!+Myz1q+2c25IFpvR`PTI*+QSmw;I00|yk3Y{@>dJYzg@guV2jEOZBHZ<$=ywKy|JEl_!YRR7$Dx|x zP?k%8gOE_n!B6L-rHA*A<+sQ|RbjWWQUtF-=gy*5tW86Eq3n41lt&%2_lMGv?3cK1 zXBl7l@j^?|M>JnEDWzol`R{?m#CDJo-1A8JHUd`uJHN||$vV~?iK;J6P9E}lY0W#a z+*+(Y{lrjxxfIkRJ*Qu&IsE?Y3f&~Ad+s?vSqSBmNsg6X{|>W0!4`*emLJ6P8QnU& zLwY~MO-ACK-nnvh6|{4r9L{m9nh6u;f^L0GwK08>rBRU z7gKc3RnAoy7uX*WqEQJO)i*Q~pL}X_BKhpE@A(`;&La6VP{6cUh~d01vVC6(sFd?0 ziDeoWo_w2dMgI7;hXYA2I%vgQb*p<+;6aFct%JKrF7FW%KLc=U>%+*ngCtd-c&l#d z>B{Q6_`OUzLwtZ8)x>CcqF*Gx!`y%DJzQ7>`w$tHx(8%~Oo9(3fUuG@8L-GJBItFk zc6HzfCDvAA@_jUv%17WM``qwG-31Q~q;lJ~WtR->HQyDzhS0D*CI;B5Q)mkDC1I(`@IwAB*>=VWvZE?qa6>W^M-q;I^qgD_;?*O z-F{DIa%5vTqp$@Wf7^4(I|sm8`fk?^p|y4i?3K{ypUDYYN*kE=%<(t7)YD22l7wL( zV!cnhn*SXYPD0j4OU*OK^pK5ip*IyO(Qg5jhXSaxM9!Ko6XeQmLzMOBKA8+ zeu4Jn`eb*PLrw(|=t3fBEofv>I7||?9q)w04=luhMu~PswGd&TiX=2wH7%2za9?uN zSOca@+?iUT-k8H2CMj^)U2M;bW3SY_=O?-`m?r-f}a&gqYVS*lF3PwJezP_@J%Spj5POVnF?sG!>9RDXvzB zg_thaCBcLGmn*#H9pc9GT^%}8^$yC1N5UEydUVfad*31*EPU9Y)$!wEokMX>9$mbEa5c|bZ5yU?TW zX^SmdpM8F)~~41a%DO#%}#y(Mw*>wmul-r$LMO)5QPjf8v3la zcidx$+@ppFB=;eUPVk81o7i?+iL1~(V5ztcs z&@(ufLo^JkjV_;By&ul>H}6NGICgw^sRZ%}?2Q!+obFllR_FUDLLC={ogG49cwGJL zO$!mMEDR|lz$Vc3=1>mPPRndz-Zd53cZW9A@v@bf%>Gcvf`=-m%1m9oRGGu3`BRc# z8%t~fgE(&NgyHSan&_JWEULlH3>SsL+|J z4M!=_QQPJ`D25HNox24;?3oR6Dc4BGsL243zq`s07K|2v2yd{P{soDZWftu{=?>5r z6UJE?O^cm;BKH0~4Hk|j$A!gGQ69Wr^58A|_3+~nVG3;}z}>dlO2$BrL=e3{uMHO3 z@qY{bLo{krf|r$~X>yuz3`HwQHe)7_awy()6o*=aVt%Y__*fY$L)lOaC^+jD?zg`u^v1A7rKCrIP zuooolc1J&yIvdMuS|1^EkO=O;?rtP~E1xTw=eHzcevG*1;l<_ID+T#!4lgBQ;-{H4 zZ0-CtEHKmZoXo1KxX;&b{r&-nr5gRG2~ySib9OA3R6-rKUNlDD8AP_1dlt=%4Z3rg zCGU7xb;aUXJqs6FF`7Z{AuoS!WxS@eX=?>0VpYyH-m(^?Hy4$mU9L zXr@JqF&BqS#%#MFztEeLRY@NT{R~4LYo=0C#XIwX&Ebt zEex;FIy_&rJQk990O{2|Z6&~~T`#8$ip$H7&0zQ&Emp5bt^;3ail$~97@cK?A}M63 zW0Hr=M}Hz@JMAaY2h==*^LMszd(9>3)fsbhT#Oy_F+ULqS@E;mI)su{>UW4b2TbmT zcPFS9^sBXmWy+ra{iLz>`FU}ygt{^NP_{>jz->{73w-{4A~{~g)pN$=}Gd=fqH_~f=+=G5Quo~U{x^$&{{VlJJbF$xCUP)`< z8Z%O;FU`yxX#x3#2Kv_zwxCeFja)j6{GcXkuf*!y55u3zv@QsZjS_w^bk%P^isLS` zhrRw2mBT#3d$xo;aF6mt-G&8SRRk6FQ_*ePkcjsBLlIi_#*Ed^etYBQ@Z8{nE#lJ1 zoE4*0(J{j-mEF?m4~p#@Sm&b>*0kMQM@&v6)bX9VTAS4=xc_*?+;G|@oz^=E<`2xg z^2lFx$T!Q3A50Fw4PgrFo?YQBY>~Tb#p&M?o!{*Cdn{(gyIE@R1LU{iy1O2aIK&Ww zg*}4iVzCpS?|TKXQN zS@2~bNmqIJO*m`z?+ppMHT#h`(;AM3`go?(ud^~DE*9SxDn-Cn1s!pV7M%jatCKR> zAFrUr3Y;zN3tSkwcYD+*r7&F3JOhT8oqMg9U=dhikY#)ac#K}HMKk%956^gdWtTaR ziK_a8=2*_Mg$ITehgd&XlNZ#n_h3(W9cjgMCi%hJ6EN$?b%AU6x)foZQ=wQtD}AuSJ6i(Tt}c~Y?1;zC zJR|?4oaOIij(+G}IhCwYMJ>NLQHlY{%tVLmYpB4nGaK^606Q%~sc2li{{_Ja5YWY9Wn+e=cpX@Dy?)bI5m z;$naFiBl6~51Pe8NBe=C0>1*1(^oR^5vAsMrem}~CCvjhLYB%`mKPdCa9&q^nr*!U zgy$d8SDyMb(FsDr!e$j7tQmjK6~TQ$i<3;RKHFMQi^plz%Prtr0*CLX-{_LO+(hE# zd}(@~WbEAYn%Yn2cI?YKARv8e_a#yuAV(_vs2=a-42z{<&%U`mcHT|%AR8g}n+H5$*M*p5}#7J9!zjv(1)Sl{m8_4_B6e8kic|T2kNo68Oc6cfl_S&co5o z-J{W`FZjumdE}Y1S(Q|f51>flhp^17%KRoox7No2sZ?|aC9l3e2)=oErzGJH9ehRe z(ehhfi`$yZ!|*3ruRpj{lqlXj9HHP6nn_%5Yif2a#73Xr`s7>prx>mgmTI@RP%_~4 z&AaUtc1y-l4(9manUbky8JAc^*_l^*JhO{?@k}n|uF0_hpedVsyqo@|RX8)Q_mc&l zyzVvD@}uWTR9WJ1R_EBTKbE&FOCjy0IUVo^ZqZ{uKI|WqU->d3E4lbwiF&BPV)@hi z(!<1SASsZ)_BD z!H_P?tMlw*12;?WnbYtQ7IUxshg^tJoz%jl4r(N>Yw+Ii`z+h2{8DzIL-3JpGiDSa zXJcZ=PVU{&?rhk1$qdizc=J@b2v97iUC4Hk9Gp&x|0&5bjP{GxGrmh~sEnpQ0u!tE zhdCPNDs=->AU&B~$y0{ymOe~59SyJ+u@~;&B0HzWvd_H2Zw93~ZRXwM*@KO;2_4N0 z1Wi_Q^!hw5;tto_c7u@9@I7g#N_lFLi#XQ6Sm-aWb7VWdR|Va_BM<(lnzS=-0fvtzeSX&$GPOJbh86W4 zo|(L5o=XFZZ`OeE@kLKN77mn*5^I=MsN*iHMpiN;Zl>Sh&u1#vd+n-yK>wxmqnAxl zcHedRgCzQcdy!r~c^@0CLmllt+!l(Ajbe`kJ9u<_hTWp0CwsJgCTS{M4Y<%s^*aRH zlYJv&$0!4KoukDb33bgydL`7jckdij)`&r=x?WCO;!Fm8kT=fVA6BXSc&Zd@(&5s~ z%Cd%`<;T4TgpoMW=_3rP^{TY0p^j=+nSOCOBhH3iBlAsP9z!gFqr&M&nh&bhd!3Wp z_85lW|ETj`Y>#Ox7v>|z<4l??Co}(0>8l8vBQEL|7VxJc>G9e=jsCp&J!`V%sqZIw&QSx@f%iIqfExP1!KkX7`XK=WlqQCb1 zN=-Us0L`Wc%n<1#?V5&M#smDFUgzZD&uAZ*zaMEX{j*2- zmnDRWAMr~`lcCcL)Xtzd!sDiW-dH9fHCcaUc;9UIXrir0@+nWoULz#J;qlyHFHve1 zL?Poprcgv|Vde-kx<#ixkcY#7pTp1SfU|bJF*=0q1}JQYTnjIYfEhWwyJ*)3M7zd4 zDRm2o?WxZBm7fDi-lzaN4z+rOVqSW{vDY*Y+v-arGgthtMLHUw29B_Em^ghrwwt~! z)3yC7EK9bXKY{Fg_ArI_LZD=f2opkY?MC2^7M#ItcWXVDcyDVeN zk%wKbp=lZ0vL*XFUYF``&y0D;RdKAfRcfRjds1=YTG&HckgJW}-)Tm*8&XfnQFhe3 z^VT2tpWJ3trHX^yVHeL*nP)tj1j)Mf=r>~`E`r^xJ<8OfnHf2SqbFx`3r|odh>fIX zmJSv%_dquXdj6rJL~X;LzaS=808Ned_`|7xQK#}Su}gPQDra;L&2QJBSBXq*O4SF7 zJ#+sLA%KqyHTGMO$=;E}8oGCq7#3}67`pZuw_QAKmhy*6Sc^o?KEVX4wdSEm><(ec zv&~tA&)~uhAce{KLuq!+j$JyF7KXVIi{d5joV*I!#RA0fq5X_c6Z4qTS6;W+thfv& z$ntbo>ab2V7bZXJeSWGq187OwAkd-m`6fLM1)ZDZfwRS z=}vx5r-8!7`)Ns>0W!ade;zMrtUg5bxfS24EJvH46TuK754iT;$fxT=zPcnJQjJ7cjmj#_)rwOaGgBdP z`sFXYqhq5aYxEGxKAQ8n39{2Od>Y{z^QJWnub)3KkEO+OT-`_MdLZOM3R5WGr3XU5 z)L0!8YXlj~C?DfSJbpw$gEawVgnvS74aAkLm@-csBvaa-x8^~~VS!g*VwO_Q;Gn_l zTe!j74@S+~wu><0pVdnVlaT1kOMqkvEbty2%2-Cf+<`kHPy@aN?@ zD4hgWpFL_?AjZbgu+RPs2-hegWXDM1AQl^XRg?7wq>y*;7@VEC964&K)Umye7Fz*R zlF?y9(PGCM`TUq^L1c9POi$ZkTC7=I%wv$Ah?X3PCIRJh9rMtsX&P z!vL58pCiF*S|DN#OdT1P|PKD%4e4+*;B)l{LJ zy4uaC?QTo~d*IKn^sraH;1(chEF5_2TbZWE6>zNeT9YS}nl8v2j zEwjbxbirE_hgx%a3y(RO7Oso&`n!Hw5gqnsRipmH z{Tm40h>r^3{EZisfb}#$?_n&b$<7yKW4Kq(vbRLWW=Xt|WCBM?Aspqxx1+ROOt(3a zaOYZwu8-!ONl{X3FY)fAO_Z=0g?E(I4Z61ivLeIC)lyGJ8$Nr3KWF|w}W;DQ%+alt?( z|8K_s(c^!ZeDLO`a}s(1{x?eXbZ~Vo#+)0isjraFWYnB zkjGpV3ay4*Abv<1YRQT9h)84g9JSCI=w5{s+5u>XCeu#Nm0t$jkvrVpMM;=Xz0%Wl zLLrt??7j%)B>VR*SDkwE$lY%G2{=UOw?oi&YPDX1UX>%onC~CL9;rc=w(jjjDhz&Gw$L+8)k9_r;fU53&`TEn*b(=ur*jfrl}&_v~)92^@TQg2} z!rYE;LA^`<{!=+YjuZSZPZ#i@v@fTm^fC)g%8e-0>!eQA(CL17#+&mBl>cw`cy(tz zpFTA>TDkDCD=28YzCSqQbH`Tm{G;(M*JeT%o=mzb))6=TcN! z*`s1%V_wgi6zZnXk)XRa@QEC-NJ5* zb+6M3dTeZlX{TZp=Mrfn*?ng2sfsHO@V+j7^xe9jI zUC()Sq0^r_bXWvc$Sn=&jzC=u@8_VeO2EW<2E6uoseP$Ku=4YXicuRu6Tz2delsWe z!M7G%q!%>ru!vJU!eJ76l*6fXx!E2?{?=2i0hV`L4$+xzJ_kj{Se`*!F4%X^L`lIZIU&&%A7Xi;oYTx}_WX>nN= zC5#bg^S17W@rh1n9m}oUpLL<|VpiK@x$E0rQ>PbcJnRC__FI=k!|adzD5p{BrMSk_ zr*2wY)O3N{MP~B!Lr2Ak(Tqk3ORpbKIrZ&>k6=rE$80H#EEJMhvrQi+=d(9SC-r-h zboDxnD&|Ww8qwY1HqZ`D^a+@FNX|pjX5I%9jqPnUrG0Z<4uWP-vk1b#Iw`9}+{(ep zV(~5g$W`m;7k87KjZYo|?_a%n&|Tax9$8vh6ex$pdDbvM-(!N?nrUO?qGJgEe90sK ztT(4_M3q3r%*lq6M)yNx`B2o`Tnlt>qTvpVdoGU2kha&h@5VaWfe!lTVB?0YBO-Tg zM6gEiB%VgIpo)fiC3$X&ypU*%{W+$!Bq@7l6GT1hU7Xze9s@d+jQQM;;aRSgLr&G_Se*6v&)P@KH4wLi(Hr@K>hWh3Q0ph}oOXEQneM=v`dAPR55AnMf>_>eu=cR*n z=~QxN1m@y`7*qIQJ>5)j9A9h=>hMST#%pO zer+I|%h8>EFSgK2hpfBBz@UHFZp@qMQV(-pN7Idz)U1OR-89&2WlQs@ObUaH6f-R9 z0^bq&*VZOB%vpE3OQ+o=D9|9e&>PVFJXZC;MuSlruS{wy16cl-m=KFyA- zMQaW3yHnLzY`P|P#(GTgG8)v_-%^7hxw4-fRVdaIjbFZ6C9)*YxXn1!@w8r5AuSwb zqNG`;0*gFWzc;Z1*m~^KhZc9(+gYUZ((lM~4&8XaJurOw4ZVLS%DDZ}ykh;HYxbm0 zpy+GgZ(HnyMAY0v^!mIL*9B#QSGxs2_2zu)x}|c_Hp;H+Y#44hq6dv_vOqM`7JxR2 zOPo8IKrM|#>XlXG@%pZ_rrf65xyA!CA5orX!Y~2{O7O%;uX~q*qWk7vyT|mdEYF$n z`ah_8`Z(Uhp|pj2>2{6}Oe@I&*EDOwQUZX{;4$WmCe|g%z)PEl%UY%RvycI|{9ImZBM#4ddZNW^N3}K8{ zWCE@>IOjWSXJ>$Y{LR7^Wpjury zviuu=-aOJz02z-yw*I9bI7LfkWc$fB9j&6|C3lVZ`yiO@owgD*fi1uCAWvq8)PIB4|dkmVR0jmcrJ~Xv1-hNFGf&zBWcGg)*EoiJ(>cq+EV(ZoIA)4 zU$~{5TglT@YdjQuW#_^DPsv6XjtZM_i2>1kwbgA0^o==>n$TpQLNlFIiuK$&hDfDI z_P`rV4`_pG_+CaHF%7V>S-Y3JDID=x-sVZ zMitGV#uUR30JmpbVaRnLQ0g~N!S*&X=2=FXd>kvQ(7LyFv3X|Dg!4 zE1(OQ_x8IQZkY0Zl#^j%g2wy`rZw4}Ye`q5L(}iT?tC6j8J{I5Ox)5@y2Z|0I5@~j zZH0HgtnN2B0zl?gn!VvQkg5`q)^R+e0LjFOzU$68J{N#@>?Aluhgp6`m#=L(wZO*F zE%t(Crb7>2rfH1G7c-M<9xm_6%i;9Tb!F99(8TIX4={Ig2Q8W<;0oQ-nbq!;$?YC; zztJQz4w4j+F#%2>59WYk|Fj*>bVMlp|EufF!=Y^d{@$=X*`}2OkPMt^hqw$|MV*;Mej;0{84i0{LH$8rs1M9dw_(oU(5v%i4V08%i zN`h~{Xu>`X(Sap>Szl~=Z+hY9ZTorGXZ(h1!(sJW;$)IZJWg3hX6N8;ZrXQG2WUEV z%kRr*NaBZq17{Pa(*jQz3r?OM9f0$Jd)SVbp%cVdBdmR)meP4nJL`)?A>=-*^Zn1{ z;^cBtdXkph9SkEZwV+uMbEFj+)@9B7UP026Gd{QQwy&6Q)IIm|)F^g@)GYns39?eP z*MkrA=VFDQN37k)N!{8KI};Xdgw1@6Q34Jwu7PS)dKVoAvllBSH?^2~dne@9b?ma7 z@-j6$67r4TKF!q>T7)Wros0;7Fv_!3jwQ)^jsN1%$=&s~P?;HXWA^rw*bp_Po!_<@ zVQoJhEF|&K-99KEECDxR>vqSu2&bc)&)GRqLn7CnH&X<4W3S#1tT7<|xE;pX)-B%#3JaK@05V|%+i zLNB|C1;X*Til)`K0gfjlqSTA_Hto+3DHOU13w^DMs679^Ou03ckhIj*Ma~j`1k(aS zc zoUk!Gqx$J*$P4HfbqzHI+%E~Zy4C%1bq#6nwpShZX6)&2S+dK zJTcrbZBgE=!SHPRJ<&3#FK|zV-v*-tFC>hVbhIWB?I6-#e5X5A<}ao(<-?)jocKL* z%#_pd{Rvya5WNH|xlpNyflT=J?Cwl^^_Vk`XnmS%=3C8>pOZ5N@zr@DYoQptNN%ck zpvW;2$sxr~^XD71c`WZ?)Jd7NVkeZfOpW%lmTA`00O^bo{ z-XJd1D;h6WDzivaBrD_6(+^#|e8aA1cL!)%AO-(%xwp%9m*Iw$MV`r6YrsdXv{g%E zE7KrT4F(oHzGk{dojj*LoNK?Hs?wl^%5Lla3EXcG>2Bxah)T2ZAIByjhsZo>QbNy} zkn|-!Ie6LuR*@($E>Qk?zGEN$`iJj#9G+mT3n+Ynt%~WEVcfn$VE<*TS1_l!f(~$h z+B)HMB2stiL}f&L0D!ekOp`FmtQQaU*@I`bhy0?jbmV@0K-c5K|H|EC^!ai}KZFmj zlA0^sJaopN_y^FD=~g484L02?cZqQocnNA|>(?M9D~97MUZE$hR{8Z@XJRmWeqs{^ zWALn=iqOmm{j)t?7PoDC))YC}1s=UUk*bG-- zDji&aWp-=`4$f7r&C~|A9V@J+Nx#U(X0k`aH}@QL4(BZ01{}ksnV<%E*7cf+ub~5* z4)yb?OAMDgKi^lg3s?LB9B;CTSLVsD6;PBp?7!+4A*jFDy|k{j2HXqHU$vGOfWlIw zRPyG6_HaP&&JF2+?lV&>j!Hf|Y^-CZT_8ccBTqJNeCxb(9OmisC33iX_qHenHQGV? zo2eW27Y74Zemr}a^R90|G)my+S;2?S6kUW+)Ch<(r8M zBtOYhnKTvi_e;c8R5*?*PJD)-gF~;JY?>{|?`NYb8`RUz6Jx8<4)R40IZ9^B7DQ&X z7i6=t0lo3e&G7F4ufMy=?>SA6KGcCcj;!w=8GzwaL|6oxlV$WLpb}_{q|T__2>z0g z_BBn=;Fl|?Q>{~S7ouN@<+D#x{~lL2!h#3`Y&@ObCPu6ugVs7+y%96Akh6?mC^_Gl ziT;8_5FoVgk^ShDB#fwfXoVSo1e(>*r`EnaG&C@K$*TI2D3&mmY(Jh8QVhINP|j!7 zjeHPl$y{1AH%p1~HMkAf6n&7y+~9UGLU2hnKN)16mUynQm-63|Ufw;?Gs?vZ?te43 zL(FZAX9c)7`LERa<>plTX)i_ST}@`qhS_B%RlqCBuOg7n4e1CM0+vQgtT=cDewtHU zu0np$a!tl!gM8a$vS=ksyd2o|paauFMr)^Z+$P_7vjfH6%=l&WdK=N4E7>klIJ&mIQ@5~gtbxBE zyWb`3?Ot?)cVrTby$k!H(9+Dawab`_`zjjD^5NGU30~>}rkhYE-HXQ0=-)SB+k!tx z2WRfig7LGs3k&q<=lvfTA@<`)M+JHUAz<+JbxguYZG0=h=pz>XC#(_E=Kv z>#*SAbeVNyJEg1{#+L| zWK`C&C@Byr0I}roHd!t*K5-qyqEC*Fgsri@wMnhVmqm>{i>)g}B8tLzfT86zTc=9_ z*Qb?3`e-6a7Y&axq~T%yGe8mO%=in(HH}UI=`VcHNf93UBU;S*F&_+G=Q`2zTo;&N zX(7U)b16mdwwS0Q7IJ`S z26Q8Hz0B81q0WwQA6R?1nasSp-8Bv~vkc_sTVI@bUB|lHaTu?xU2eQR_hiVesp@2dY&J6E zN^Jw?^U@?DPL<@X7oyL&OMuj>m0`d@w%NN5R^dw1Eg{j8mNcFl9IiyCBPCQC)^CbC znbMX%MZa1bb_s&oP->ESs9#s7C>I>nf+iVKq9MP!H@1{FU-wpigm~b`^pPc>&FQaV z)==5i#8Fag|0Niqm$9R)))4)1cCDvYliWU{mG+EMg*0GZ2tD#5a5A;dxy=224&nF+ddii|}UHhXK>P1HPLO9vD ziWRi>gx(xS9%SE`Pzk1Y*}KF{GjvJo+vT#FcgQjOOo?|4i%rtLRSFZoc?o%Gn#+!L zI+OSG&%Vf#UH8|$@9>;nAn>McN>a+@ZfB%QgShLd$8&s(mXuD>7iq65me9(*KZvFE z-GR^4n`+fL@1gQ#czoPDRPO*W!-VjorX|1h5l@qsdo)WZ;}?+uIm7Bd3!( zD2z3BCd=xHvfP{ok-jiAGGaXj9xddEIDXfn7nu-5N8xCtYB5H_(9mO=*~(=_eA_dT z7;Ya{j_sPy;e+`ft`#KKrB%+yx^#MM8%)dA`x38lkWLVkW73Y~hEajelJ?Y?`GKEj zFR^nu`{Egto+mxZWt09Z?=AK|ZVy%OWkn7@{mt$oYNR8r4;sE~JX5}V2H&%7Ifsxk z?d7mQBm|eu#r!OuIIb8ByEGaLAXK5uT}NiFP7Q3<&7ZnfYeI8rZN>&I2K8r=iRb&9 zY#nV=4~_p5b3JaAw_Og-XvxV1SfSv%lT`x>a(XuBYnFYN-=Rh1rUcw#+sp-3Y}U%! z@krNkdeHbP>`LtyccB{@RXLt5t6gB9c}q6^96XH3aXpd1>PYBwqpDXoOWzv0Jw*t7 zFYaK8jUZy4W$hy(5L0(*PF5ZR54ghfJvNHqzxm*LiZHQ4gk2dW%@2!ul%BNoX{Bx2so7jRYo|4;v069GZ&w+xD{~2sFcS%kUa{o zE&Jj32*BV5)D6z9PFsRA`)8Pr-ve z%Idb>G&;%P#CCXv35{NH+Y$csUFyzuVoG{aU5lhm2?{|nqA7=ur{z5}!Me)a9#Z~~ zMwcfihx!aUkqye;8fM`szpmNXFgso8&F7{gS}%6n8!q!Eua-wShyw+dEBje@MWdn3 zlkbWM3Mf;u3D$Av0Ac4?y6_blr5@hD_CMd&w;E8i?~bOEmaK2W09rHKg+}Y2Uaj|J z-SKPFHF>X4wq=V@EO(9o;>Iok`|W56XJ%3n?Lw#(5;5Gi1E7ys7lPW3kuT&TnEK35 zWEZxB@~wf|5iOYZFio}cLR1aN5Z0~db?Ioe~2+_r}wMlG&~(67@}u;hx}lml5r5hmxwFt(S8D>H$xAtn@gP>rdWmw)*NEI66}*#hZ`Oswh~FY9VsFs*R|aLt*0kqwXTaRL@~Q z>&d6Mr64vjL1;cPST96;&)v}C^xy={gmO^UsCogt*(HknGGUBmvZ_Yy^V1vScXMr0Nc=9v)7 zO=BRbJh08TLh<-O$o6CYLMs1OPxQKMaQEW|Br0<=lM+6Ro z!D2^&rFiXtCTpt^S=dgU7^C))!qsMYvqfLZA_zNaM0}TpRQQ=17M|k+?`8-Zq(yMR zuV?R5KVu43*P|K8Kli>RRD9sK1bM3?y&(N6RCopWAEf`jrFV|sq9=wjb3j|kaEF{lM8CjS7FG58L-kgGL>>G2Dv>`mt2$%3f??!?^#+9r29WWeS4 z`7Q`{3C`%;g90D#{HOK35vgJHw097n>^x&iqDPpfx_LBO;lM<}@rYeOJ@vp0w=A0x zheM`IPq3y^bm_TPE}LDiH+IjR;(~|l`;gISy9?!0$07jkbMW1`f?K{W~SgSFaE+=5A1T_t8Ses9PSW8NuXg51BftU^w5b2l zX(jWONQ_wP72UozUv7!VI0Z)*G?;I45PrgwCxJ7srDVWM0TCjVW8O&sc_Htc%saH} zS5jA5p9{XOt#JnxjAehIT1tRBz31qsjkC_hGScix`Mm8FaopaM`;Cx9T&VrLVr5K$ zz9K6-?32D>N6*NZ{s@X-t~jY;q1k_@b*JCy+&*r+_!(Ao~>24HatrMt!v%DA6#1kcF>KN)v&pd@X74~ zsTO~rmA3VbnDq#HN4@lDIGP`M`MO%KVfeU;M2z$$t4 z?PJ6HK<5rUoFPiQY&7(VCx>wO=B?wJtOXRxKs8$q5Q5L{C6YF9CKLmGZBPAat*I0X z5TYDKSqT9}Qqyi#$ygS&6=m63;P*GWq^{B++e$RVN=_P@2cF9L06HZe!y0m^NG;V~ zpSPHYi@8XI(+5pe|EYXr$ zJV#>Pxsk1{)LyvcB@{oB0sSR5JCnE);=(9NXiZxqHPg#i?<^>&D(GQONlvR>A)Byg zYG>1s7Xewpjs;*PDeY5$VzDRtX4^5xQr8IfkiQL3vpiA;SXJ|FN`bvr{5O6xk?Si-0pd=wVoBwmwd0+!X$=Ic;UaTYm4q70vsm zz~F^u;Crh2xhUXNSyH(3Wc=}}90^^n9qk7MjXWSF{XnXQ(9hu*ZjnnGxhw5o$GM)5 zB8L)M%zkH`mEg)@Y}S1@2S-;!80R@~YrE^|2K~06A?!@OkSLAbsp-nREOjiLa-2UBY&C! zZ8rg(l(3z>cURxix^gR3EK=B1A|re7oe}@x8L}B~Z6G#>s*UgJ44A zdEMWbDZKQ1RLJx7)kw3G3fChNRtw|+B$jZewZDATh^BwX^X+Yrcj+L!`KbxC87~Bf z;n2V}kyy=u+F-gxyjd;GJ@4LFw$T!O`ME!-)gWq>z z02%rot&zdDq*#M8_~mzgI`DlAR$~Q5)$`e|<4q$zTiG?K2L}mvj@%j+bqTTZ)}DIW z{RX~aeJN{?*fVU^0Qy_BcbTD&?^;r*G*`>x0=?!gnwoi6d+CTVu2Z*Y2&VBt}p|l`!=6Ah92ICo~yhTF{U%Ln~ zX7xa@0toSl<$;0Xc^fLx^O>!u6#c$J)u-;ZU37!yGZgko-7h~uW;N%^^34K1I>YS@ zg=R81D)=2J5Ve7UG2;5KRW8h)?r1A_%z|YABS9^)F5ZGYXTi%@bh|#vox%gZb&5+u z;_~p3(g6VK50^AFB17M9VAYH%GdU`DLH7$n4s$NFiu8#S6+1o-fzgAqri?Im_{9f6 zEI+uhaV+1TVj~`>)dZZ4E*8>{Zkx<6*!03Vo3=N3_~^+%Z4Cq3J$$%e@$nrqLaS9XA*T&z8CoXl(*5z9o1aboLo?Xa8rvF37E!o5?KlOha0U zcAMG7C3mjvm<0;Wu0kE;*Z+ysQjS<>d{X#*?!SO@Uy&q_Kq*Z7^1i}VbetjEkV-r0 zG6j008MdX(oYA^m&af}Zd!A=Q>|!T%s;Co1TAypurWd!?A6UC5^HANNHJ&2nzxn*_ z)wLKc)co7Q(XQh;fu^p)Mr6HHR|LqC=#nW1 z=?c@ZSWE5T+#{P>VnDhXuOMB2P=1V&Sf3+!No1cfV==pqd7wGr&5x^`+hq@T5@bu$ z?ponrPi%Vc&YF36h0B~jpcmm{jY5oO{tbh}gJ%(}{*pAF=4F2~SIrX3yVdp*Qb*Fb za?aTYWG*qhM$t8r-R#|gM;1Ff_ei}n{y)}RJu`MW8Te6w=Tuh3eA}~NBuH6sM_Ic; zuMAwVVAcd#HT1Uo58PUO&yQ#f+}lgoy7o6t%5Tn3ii_|z11}{vUUSX>xd71FKfy%} zfEyr}_q{u7%V+n&pOVST?GSpw7b(CIYhM>6utTgo7?E3_DF-D;@X=j>MB=08Rkff%@jEi8ar4j8f9@s!ok@pFZPNrr zD|d`R<1KJil=4&V4dVZeCMBKd0<)_dSP6T3>fPES?#|J zpnos30tOVQ)uRnA9qsq0fgSsYr}Xb-*T6(-Wbgb%Q-E6IekphV|CvZ67Vu|gY<;fS$Tjl+0R^3k AQ2+n{ literal 0 HcmV?d00001 diff --git a/docs/04_cv32a65x/design/source/cv32a6_execute.rst b/docs/04_cv32a65x/design/source/cv32a6_execute.rst index c411d44eda..57d4899342 100644 --- a/docs/04_cv32a65x/design/source/cv32a6_execute.rst +++ b/docs/04_cv32a65x/design/source/cv32a6_execute.rst @@ -139,16 +139,27 @@ Furthermore, the store_unit module provides information to the load_unit to know load_unit --------- -The load_unit module manages the data load operations. +The load unit module manages the data load operations. Before issuing a load, the load unit needs to check the store buffer for potential aliasing. -It inserts stalls until it can satisfy the current request. This means: +It stalls until it can satisfy the current request. This means: * Two loads to the same address are allowed. * Two stores to the same address are allowed. -* A store followed by a load to the same address can only be satisfied if the store has already been committed (marked as committed in the store buffer). +* A store after a load to the same address is allowed. +* A load after a store to the same address can only be processed if the store has already been sent to the cache i.e there is no fowarding. -.. TO_BE_COMPLETED, But once the store is committed, do we do forwarding without waiting for the store to actually be finished? Or do we authorize the outcome of the load, which will be carried out in memory/cache? +After the check of the store buffer, a read request is sent to the D$ with the index field of the address (1). +The load unit stalls until the D$ acknowledges this request (2). +In the next cycle, the tag field of the address is sent to the D$ (3). +If the load request address is non-idempotent, it stalls until the write buffer of the D$ is empty of non-idempotent requests and the store buffer is empty. +It also stalls until the incoming load instruction is the next instruction to be committed. +When the D$ allows the read of the data, the data is sent to the load unit and the load instruction can be committed (4). + +.. figure:: ../images/schema_fsm_load_control.png + :align: center + + Load unit's interactions .. include:: port_load_unit.rst @@ -157,7 +168,7 @@ It inserts stalls until it can satisfy the current request. This means: lsu_bypass ---------- -TO BE COMPLETED +The LSU bypass is a FIFO which keeps instructions from the issue stage when the store unit or the load unit are not available immediately. .. include:: port_lsu_bypass.rst diff --git a/docs/04_cv32a65x/design/source/port_load_unit.rst b/docs/04_cv32a65x/design/source/port_load_unit.rst index 9461f65e5d..99a2ff7d13 100644 --- a/docs/04_cv32a65x/design/source/port_load_unit.rst +++ b/docs/04_cv32a65x/design/source/port_load_unit.rst @@ -32,98 +32,98 @@ * - ``flush_i`` - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED + - Flush signal + - CONTROLLER - logic * - ``valid_i`` - in - - Load unit input port - - TO_BE_COMPLETED + - Load request is valid + - LSU_BYPASS - logic * - ``lsu_ctrl_i`` - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED + - Load request input + - LSU_BYPASS - lsu_ctrl_t * - ``pop_ld_o`` - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED + - Pop the load request from the LSU bypass FIFO + - LSU_BYPASS - logic * - ``valid_o`` - out - Load unit result is valid - - TO_BE_COMPLETED + - ISSUE_STAGE - logic * - ``trans_id_o`` - out - Load transaction ID - - TO_BE_COMPLETED + - ISSUE_STAGE - logic[CVA6Cfg.TRANS_ID_BITS-1:0] * - ``result_o`` - out - Load result - - TO_BE_COMPLETED + - ISSUE_STAGE - logic[CVA6Cfg.XLEN-1:0] * - ``ex_o`` - out - Load exception - - TO_BE_COMPLETED + - ISSUE_STAGE - exception_t * - ``translation_req_o`` - out - Request address translation - - TO_BE_COMPLETED + - MMU - logic * - ``vaddr_o`` - out - Virtual address - - TO_BE_COMPLETED + - MMU - logic[CVA6Cfg.VLEN-1:0] * - ``paddr_i`` - in - Physical address - - TO_BE_COMPLETED + - MMU - logic[CVA6Cfg.PLEN-1:0] * - ``ex_i`` - in - Excepted which appears before load - - TO_BE_COMPLETED + - MMU - exception_t * - ``page_offset_o`` - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED + - Page offset for address checking + - STORE_UNIT - logic[11:0] * - ``page_offset_matches_i`` - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED + - Indicates if the page offset matches a store unit entry + - STORE_UNIT - logic * - ``store_buffer_empty_i`` - in - Store buffer is empty - - TO_BE_COMPLETED + - STORE_UNIT - logic * - ``commit_tran_id_i`` - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED + - Transaction ID of the committing instruction + - COMMIT_STAGE - logic[CVA6Cfg.TRANS_ID_BITS-1:0] * - ``req_port_i`` @@ -140,8 +140,8 @@ * - ``dcache_wbuffer_not_ni_i`` - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED + - Presence of non-idempotent operations in the D$ write buffer + - CACHES - logic Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below From 0cbd894a7a03677e005813ab1b831a7a88e03743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me?= <124148386+cathales@users.noreply.github.com> Date: Fri, 12 Jul 2024 17:00:36 +0200 Subject: [PATCH 010/183] update port and config docs (#2363) --- core/include/config_pkg.sv | 4 +- .../01_cva6_user/Parameters_Configuration.rst | 61 +--- docs/01_cva6_user/user_cfg_doc.rst | 321 ++++++++++++++++++ .../design/source/parameters_cv32a65x.rst | 36 +- .../design/source/port_branch_unit.rst | 6 - .../design/source/port_commit_stage.rst | 6 + .../design/source/port_ex_stage.rst | 30 +- .../design/source/port_frontend.rst | 6 +- .../design/source/port_id_stage.rst | 16 +- .../design/source/port_instr_queue.rst | 6 +- .../source/port_issue_read_operands.rst | 50 +-- .../design/source/port_issue_stage.rst | 40 ++- .../design/source/port_load_store_unit.rst | 4 +- .../design/source/port_scoreboard.rst | 38 ++- docs/scripts/spec_builder.py | 52 ++- 15 files changed, 514 insertions(+), 162 deletions(-) create mode 100644 docs/01_cva6_user/user_cfg_doc.rst diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index 4186f91210..927078d622 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -170,7 +170,7 @@ package config_pkg; bit FpgaEn; // Is Techno Cut instanciated bit TechnoCut; - // Enable superscalar with 2 issue ports and 2 commit ports + // Enable superscalar* with 2 issue ports and 2 commit ports. bit SuperscalarEn; // Number of commit ports. Forced to 2 if SuperscalarEn. int unsigned NrCommitPorts; @@ -366,6 +366,8 @@ package config_pkg; assert (Cfg.NrExecuteRegionRules <= NrMaxRules); assert (Cfg.NrCachedRegionRules <= NrMaxRules); assert (Cfg.NrPMPEntries <= 64); + assert (!(Cfg.SuperscalarEn && Cfg.RVF)); + assert (!(Cfg.SuperscalarEn && Cfg.RVZCMP)); `endif // pragma translate_on endfunction diff --git a/docs/01_cva6_user/Parameters_Configuration.rst b/docs/01_cva6_user/Parameters_Configuration.rst index fc8a001127..b3117a6b8a 100644 --- a/docs/01_cva6_user/Parameters_Configuration.rst +++ b/docs/01_cva6_user/Parameters_Configuration.rst @@ -27,58 +27,15 @@ Main contributor: Jean-Roch Coulon - Thales Parameters ---------- -.. csv-table:: - :widths: auto - :align: left - :header: "Parameter", "Category", "Description" - - "``Cva6MArchID``", "Archi", "Cva6 architecture ID" - "``Xlen``", "Variant", "Data length" - "``CExtEn``", "Variant", "C extension enable" - "``AExtEn``", "Variant", "A extension enable" - "``BMExtEn``", "Variant", "Bit Manipulation extension enable" - "``FpuEn``", "Variant", "FPU enable" - "``F16En``", "Variant", "FPU 16bits enable" - "``F16AltEn``", "Variant", "FPU Alt 16bits enable" - "``F8En``", "Variant", "FPU 8bits enable" - "``FVecEn``", "Variant", "Vector FPU enable" - "``MMUEn``", "Memory", "MMU Present" - "``InstrTlbEntries``", "Memory", "Instruction TLB entry number" - "``DataTlbEntries``", "Memory", "Data TLB entry number" - "``RASDepth``", "Memory", "Depth of Return Address Stack" - "``BTBEntries``", "Memory", "BTB entry number" - "``BHTEntries``", "Memory", "BHT entry number" - "``NrNonIdempotentRules``", "Memory", "Number of non idempotent region" - "``NonIdempotentAddrBase``", "Memory", "Base address of non idempotent region" - "``NonIdempotentLength``", "Memory", "Length of non idempotent region" - "``NrExecuteRegionRules``", "Memory", "Number of excution regions" - "``ExecuteRegionAddrBase``", "Memory", "Execution region of base address (DRAM, Boot ROM and Debug Module)" - "``ExecuteRegionLength``", "Memory", "Length of execution region" - "``NrCachedRegionRules``", "Memory", "Number of cached region" - "``CachedRegionAddrBase``", "Memory", "Base address of cached region" - "``CachedRegionLength``", "Memory", "Length of cached regions" - "``NrPMPEntries``", "Memory", "Number of PMP entries" - "``DmBaseAddress``", "Debug", "Base address of debug" - "``CvxifEn``", "Ports", "CV-X-IF interface enable" - "``RVFI_TRACE (define)``", "Ports", "RVFI interface enable" - "``FIRESIM_TRACE (define)``", "Ports", "FIRESIM interface enable" - "``PITON_ARIANE (define)``", "Ports", "Piton interface enable, and AXI interface disable" - "``WT_CACHE (define)``", "Caches", "Write through cache enable, write back cache disable" - "``DepthStoreBuffer``", "Caches", "Depth of store buffer" - "``IcacheSetAssoc``", "Caches", "Instruction cache way number" - "``DcacheSetAssoc``", "Caches", "Data cache way number" - "``NrLoadPipeRegs``", "Caches", "Number of stall on load operation" - "``NrStorePipeRegs``", "Caches", "Number of stall on store operation" - "``AxiCompliant``", "Caches", "Cache configuration: AXI or XXXX" - "``SwapEndianess``", "Caches", "Endianess of cache: XXXX" - "``FetchUserEn``", "Users", "Fetch AXI user bit enable" - "``FetchUserWidth``", "Users", "Fetch user bit number when enabled" - "``DataUserEn``", "Users", "Data AXI user bit enable" - "``DataUserWidth``", "Users", "Data user bit number when enabled" - "``RenameEn``", "Pipeline", "Register renaming feature enable" - "``NrCommitPorts``", "Pipeline", "Commit port number" - "``NrScoreboardEntries``", "Pipeline", "Scoreboard entry number" - "``FpgaEn``", "Technology", "FPGA optimization enable" +.. include:: user_cfg_doc.rst + +\*: Some parameters are incompatible with others: + +- ``SuperscalarEn``: + + - Not compatible with floating point (``RVF``, ``RVD``, ``XF16``, ``XF16ALT``, ``XF8``, ``XFVec``) yet. + - Not compatible with macro instructions (``RVZCMP``) yet. + - Recommended to set ``NrScoreboardEntries`` to at least 8 for performance. Configurations diff --git a/docs/01_cva6_user/user_cfg_doc.rst b/docs/01_cva6_user/user_cfg_doc.rst new file mode 100644 index 0000000000..d0e52b1a1b --- /dev/null +++ b/docs/01_cva6_user/user_cfg_doc.rst @@ -0,0 +1,321 @@ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +.. _cva6_user_cfg_doc: + +.. list-table:: ``cva6_user_cfg_t`` parameters + :header-rows: 1 + + * - Name + - Type + - Description + + * - ``XLEN`` + - ``int unsigned`` + - General Purpose Register Size (in bits) + + * - ``RVA`` + - ``bit`` + - Atomic RISC-V extension + + * - ``RVB`` + - ``bit`` + - Bit manipulation RISC-V extension + + * - ``RVV`` + - ``bit`` + - Vector RISC-V extension + + * - ``RVC`` + - ``bit`` + - Compress RISC-V extension + + * - ``RVH`` + - ``bit`` + - Hypervisor RISC-V extension + + * - ``RVZCB`` + - ``bit`` + - Zcb RISC-V extension + + * - ``RVZCMP`` + - ``bit`` + - Zcmp RISC-V extension + + * - ``RVZiCond`` + - ``bit`` + - Zicond RISC-V extension + + * - ``RVZicntr`` + - ``bit`` + - Zicntr RISC-V extension + + * - ``RVZihpm`` + - ``bit`` + - Zihpm RISC-V extension + + * - ``RVF`` + - ``bit`` + - Floating Point + + * - ``RVD`` + - ``bit`` + - Floating Point + + * - ``XF16`` + - ``bit`` + - Non standard 16bits Floating Point extension + + * - ``XF16ALT`` + - ``bit`` + - Non standard 16bits Floating Point Alt extension + + * - ``XF8`` + - ``bit`` + - Non standard 8bits Floating Point extension + + * - ``XFVec`` + - ``bit`` + - Non standard Vector Floating Point extension + + * - ``PerfCounterEn`` + - ``bit`` + - Perf counters + + * - ``MmuPresent`` + - ``bit`` + - MMU + + * - ``RVS`` + - ``bit`` + - Supervisor mode + + * - ``RVU`` + - ``bit`` + - User mode + + * - ``DebugEn`` + - ``bit`` + - Debug support + + * - ``DmBaseAddress`` + - ``logic [63:0]`` + - Base address of the debug module + + * - ``HaltAddress`` + - ``logic [63:0]`` + - Address to jump when halt request + + * - ``ExceptionAddress`` + - ``logic [63:0]`` + - Address to jump when exception + + * - ``TvalEn`` + - ``bit`` + - Tval Support Enable + + * - ``DirectVecOnly`` + - ``bit`` + - MTVEC CSR supports only direct mode + + * - ``NrPMPEntries`` + - ``int unsigned`` + - PMP entries number + + * - ``PMPCfgRstVal`` + - ``logic [63:0][63:0]`` + - PMP CSR configuration reset values + + * - ``PMPAddrRstVal`` + - ``logic [63:0][63:0]`` + - PMP CSR address reset values + + * - ``PMPEntryReadOnly`` + - ``bit [63:0]`` + - PMP CSR read-only bits + + * - ``NrNonIdempotentRules`` + - ``int unsigned`` + - PMA non idempotent rules number + + * - ``NonIdempotentAddrBase`` + - ``logic [NrMaxRules-1:0][63:0]`` + - PMA NonIdempotent region base address + + * - ``NonIdempotentLength`` + - ``logic [NrMaxRules-1:0][63:0]`` + - PMA NonIdempotent region length + + * - ``NrExecuteRegionRules`` + - ``int unsigned`` + - PMA regions with execute rules number + + * - ``ExecuteRegionAddrBase`` + - ``logic [NrMaxRules-1:0][63:0]`` + - PMA Execute region base address + + * - ``ExecuteRegionLength`` + - ``logic [NrMaxRules-1:0][63:0]`` + - PMA Execute region address base + + * - ``NrCachedRegionRules`` + - ``int unsigned`` + - PMA regions with cache rules number + + * - ``CachedRegionAddrBase`` + - ``logic [NrMaxRules-1:0][63:0]`` + - PMA cache region base address + + * - ``CachedRegionLength`` + - ``logic [NrMaxRules-1:0][63:0]`` + - PMA cache region rules + + * - ``CvxifEn`` + - ``bit`` + - CV-X-IF coprocessor interface enable + + * - ``NOCType`` + - ``noc_type_e`` + - NOC bus type + + * - ``AxiAddrWidth`` + - ``int unsigned`` + - AXI address width + + * - ``AxiDataWidth`` + - ``int unsigned`` + - AXI data width + + * - ``AxiIdWidth`` + - ``int unsigned`` + - AXI ID width + + * - ``AxiUserWidth`` + - ``int unsigned`` + - AXI User width + + * - ``AxiBurstWriteEn`` + - ``bit`` + - AXI burst in write + + * - ``MemTidWidth`` + - ``int unsigned`` + - TODO + + * - ``IcacheByteSize`` + - ``int unsigned`` + - Instruction cache size (in bytes) + + * - ``IcacheSetAssoc`` + - ``int unsigned`` + - Instruction cache associativity (number of ways) + + * - ``IcacheLineWidth`` + - ``int unsigned`` + - Instruction cache line width + + * - ``DCacheType`` + - ``cache_type_t`` + - Cache Type + + * - ``DcacheIdWidth`` + - ``int unsigned`` + - Data cache ID + + * - ``DcacheByteSize`` + - ``int unsigned`` + - Data cache size (in bytes) + + * - ``DcacheSetAssoc`` + - ``int unsigned`` + - Data cache associativity (number of ways) + + * - ``DcacheLineWidth`` + - ``int unsigned`` + - Data cache line width + + * - ``DataUserEn`` + - ``int unsigned`` + - User field on data bus enable + + * - ``WtDcacheWbufDepth`` + - ``int unsigned`` + - Write-through data cache write buffer depth + + * - ``FetchUserEn`` + - ``int unsigned`` + - User field on fetch bus enable + + * - ``FetchUserWidth`` + - ``int unsigned`` + - Width of fetch user field + + * - ``FpgaEn`` + - ``bit`` + - Is FPGA optimization of CV32A6 + + * - ``TechnoCut`` + - ``bit`` + - Is Techno Cut instanciated + + * - ``SuperscalarEn`` + - ``bit`` + - Enable superscalar* with 2 issue ports and 2 commit ports. + + * - ``NrCommitPorts`` + - ``int unsigned`` + - Number of commit ports. Forced to 2 if SuperscalarEn. + + * - ``NrLoadPipeRegs`` + - ``int unsigned`` + - Load cycle latency number + + * - ``NrStorePipeRegs`` + - ``int unsigned`` + - Store cycle latency number + + * - ``NrScoreboardEntries`` + - ``int unsigned`` + - Scoreboard length + + * - ``NrLoadBufEntries`` + - ``int unsigned`` + - Load buffer entry buffer + + * - ``MaxOutstandingStores`` + - ``int unsigned`` + - Maximum number of outstanding stores + + * - ``RASDepth`` + - ``int unsigned`` + - Return address stack depth + + * - ``BTBEntries`` + - ``int unsigned`` + - Branch target buffer entries + + * - ``BHTEntries`` + - ``int unsigned`` + - Branch history entries + + * - ``InstrTlbEntries`` + - ``int unsigned`` + - MMU instruction TLB entries + + * - ``DataTlbEntries`` + - ``int unsigned`` + - MMU data TLB entries + + * - ``UseSharedTlb`` + - ``bit unsigned`` + - MMU option to use shared TLB + + * - ``SharedTlbDepth`` + - ``int unsigned`` + - MMU depth of shared TLB diff --git a/docs/04_cv32a65x/design/source/parameters_cv32a65x.rst b/docs/04_cv32a65x/design/source/parameters_cv32a65x.rst index 91c64d617b..7ca2918dd3 100644 --- a/docs/04_cv32a65x/design/source/parameters_cv32a65x.rst +++ b/docs/04_cv32a65x/design/source/parameters_cv32a65x.rst @@ -52,6 +52,14 @@ - Zicond RISC-V extension - False + * - RVZicntr + - Zicntr RISC-V extension + - False + + * - RVZihpm + - Zihpm RISC-V extension + - False + * - RVF - Floating Point - False @@ -112,17 +120,21 @@ - Tval Support Enable - False + * - DirectVecOnly + - MTVEC CSR supports only direct mode + - True + * - NrPMPEntries - PMP entries number - 8 * - PMPCfgRstVal - PMP CSR configuration reset values - - [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0] + - [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0] * - PMPAddrRstVal - PMP CSR address reset values - - [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0] + - [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0] * - PMPEntryReadOnly - PMP CSR read-only bits @@ -218,11 +230,11 @@ * - DcacheByteSize - Data cache size (in bytes) - - 32768 + - 2028 * - DcacheSetAssoc - Data cache associativity (number of ways) - - 8 + - 2 * - DcacheLineWidth - Data cache line width @@ -230,7 +242,7 @@ * - DataUserEn - User field on data bus enable - - 0 + - 1 * - WtDcacheWbufDepth - Write-through data cache write buffer depth @@ -238,7 +250,7 @@ * - FetchUserEn - User field on fetch bus enable - - 0 + - 1 * - FetchUserWidth - Width of fetch user field @@ -248,8 +260,16 @@ - Is FPGA optimization of CV32A6 - False + * - TechnoCut + - Is Techno Cut instanciated + - True + + * - SuperscalarEn + - Enable superscalar* with 2 issue ports and 2 commit ports. + - True + * - NrCommitPorts - - Number of commit ports + - Number of commit ports. Forced to 2 if SuperscalarEn. - 1 * - NrLoadPipeRegs @@ -262,7 +282,7 @@ * - NrScoreboardEntries - Scoreboard length - - 4 + - 8 * - NrLoadBufEntries - Load buffer entry buffer diff --git a/docs/04_cv32a65x/design/source/port_branch_unit.rst b/docs/04_cv32a65x/design/source/port_branch_unit.rst index f8ba461865..e9eb72fb75 100644 --- a/docs/04_cv32a65x/design/source/port_branch_unit.rst +++ b/docs/04_cv32a65x/design/source/port_branch_unit.rst @@ -48,12 +48,6 @@ - ISSUE_STAGE - logic - * - ``fu_valid_i`` - - in - - any functional unit is valid, check that there is no accidental mis-predict - - TO_BE_COMPLETED - - logic - * - ``branch_valid_i`` - in - Branch unit instruction is valid diff --git a/docs/04_cv32a65x/design/source/port_commit_stage.rst b/docs/04_cv32a65x/design/source/port_commit_stage.rst index d710b605ec..8625513436 100644 --- a/docs/04_cv32a65x/design/source/port_commit_stage.rst +++ b/docs/04_cv32a65x/design/source/port_commit_stage.rst @@ -54,6 +54,12 @@ - ISSUE_STAGE - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] + * - ``commit_drop_i`` + - in + - The instruction is cancelled + - ISSUE_STAGE + - logic[CVA6Cfg.NrCommitPorts-1:0] + * - ``commit_ack_o`` - out - Acknowledge that we are indeed committing diff --git a/docs/04_cv32a65x/design/source/port_ex_stage.rst b/docs/04_cv32a65x/design/source/port_ex_stage.rst index 91d59791a9..18a84056f5 100644 --- a/docs/04_cv32a65x/design/source/port_ex_stage.rst +++ b/docs/04_cv32a65x/design/source/port_ex_stage.rst @@ -40,19 +40,19 @@ - in - rs1 forwarding - ISSUE_STAGE - - logic[CVA6Cfg.VLEN-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] * - ``rs2_forwarding_i`` - in - rs2 forwarding - ISSUE_STAGE - - logic[CVA6Cfg.VLEN-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] * - ``fu_data_i`` - in - FU data useful to execute instruction - ISSUE_STAGE - - fu_data_t + - fu_data_t[CVA6Cfg.NrIssuePorts-1:0] * - ``pc_i`` - in @@ -62,7 +62,7 @@ * - ``is_compressed_instr_i`` - in - - Report whether isntruction is compressed + - Report whether instruction is compressed - ISSUE_STAGE - logic @@ -100,13 +100,13 @@ - in - ALU instruction is valid - ISSUE_STAGE - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``branch_valid_i`` - in - Branch unit instruction is valid - ISSUE_STAGE - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``branch_predict_i`` - in @@ -130,7 +130,7 @@ - in - CSR instruction is valid - ISSUE_STAGE - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``csr_addr_o`` - out @@ -148,7 +148,7 @@ - in - MULT instruction is valid - ISSUE_STAGE - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``lsu_ready_o`` - out @@ -160,7 +160,7 @@ - in - LSU instruction is valid - ISSUE_STAGE - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``load_valid_o`` - out @@ -234,11 +234,17 @@ - COMMIT_STAGE - logic + * - ``alu2_valid_i`` + - in + - ALU2 instruction is valid + - ISSUE_STAGE + - logic[CVA6Cfg.NrIssuePorts-1:0] + * - ``x_valid_i`` - in - CVXIF instruction is valid - ISSUE_STAGE - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``x_ready_o`` - out @@ -334,13 +340,13 @@ - in - Report the PMP configuration - CSR_REGFILE - - riscv::pmpcfg_t[15:0] + - riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries:0] * - ``pmpaddr_i`` - in - Report the PMP addresses - CSR_REGFILE - - logic[15:0][CVA6Cfg.PLEN-3:0] + - logic[CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below diff --git a/docs/04_cv32a65x/design/source/port_frontend.rst b/docs/04_cv32a65x/design/source/port_frontend.rst index f92b71fdb9..2f715e294d 100644 --- a/docs/04_cv32a65x/design/source/port_frontend.rst +++ b/docs/04_cv32a65x/design/source/port_frontend.rst @@ -106,19 +106,19 @@ - out - Handshake's data between fetch and decode - ID_STAGE - - fetch_entry_t[ariane_pkg::SUPERSCALAR:0] + - fetch_entry_t[CVA6Cfg.NrIssuePorts-1:0] * - ``fetch_entry_valid_o`` - out - Handshake's valid between fetch and decode - ID_STAGE - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``fetch_entry_ready_i`` - in - Handshake's ready between fetch and decode - ID_STAGE - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below diff --git a/docs/04_cv32a65x/design/source/port_id_stage.rst b/docs/04_cv32a65x/design/source/port_id_stage.rst index 687850512a..f7a4b0c799 100644 --- a/docs/04_cv32a65x/design/source/port_id_stage.rst +++ b/docs/04_cv32a65x/design/source/port_id_stage.rst @@ -40,49 +40,49 @@ - in - Handshake's data between fetch and decode - FRONTEND - - fetch_entry_t[ariane_pkg::SUPERSCALAR:0] + - fetch_entry_t[CVA6Cfg.NrIssuePorts-1:0] * - ``fetch_entry_valid_i`` - in - Handshake's valid between fetch and decode - FRONTEND - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``fetch_entry_ready_o`` - out - Handshake's ready between fetch and decode - FRONTEND - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``issue_entry_o`` - out - Handshake's data between decode and issue - ISSUE - - scoreboard_entry_t[ariane_pkg::SUPERSCALAR:0] + - scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0] * - ``orig_instr_o`` - out - Instruction value - ISSUE - - logic[ariane_pkg::SUPERSCALAR:0][31:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][31:0] * - ``issue_entry_valid_o`` - out - Handshake's valid between decode and issue - ISSUE - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``is_ctrl_flow_o`` - out - Report if instruction is a control flow instruction - ISSUE - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``issue_instr_ack_i`` - in - Handshake's acknowlege between decode and issue - ISSUE - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``irq_i`` - in diff --git a/docs/04_cv32a65x/design/source/port_instr_queue.rst b/docs/04_cv32a65x/design/source/port_instr_queue.rst index b5a73da1a3..5217fcd227 100644 --- a/docs/04_cv32a65x/design/source/port_instr_queue.rst +++ b/docs/04_cv32a65x/design/source/port_instr_queue.rst @@ -106,19 +106,19 @@ - out - Handshake’s data with ID_STAGE - ID_STAGE - - fetch_entry_t[ariane_pkg::SUPERSCALAR:0] + - fetch_entry_t[CVA6Cfg.NrIssuePorts-1:0] * - ``fetch_entry_valid_o`` - out - Handshake’s valid with ID_STAGE - ID_STAGE - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``fetch_entry_ready_i`` - in - Handshake’s ready with ID_STAGE - ID_STAGE - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below diff --git a/docs/04_cv32a65x/design/source/port_issue_read_operands.rst b/docs/04_cv32a65x/design/source/port_issue_read_operands.rst index d8f742ff93..946bdf1b8d 100644 --- a/docs/04_cv32a65x/design/source/port_issue_read_operands.rst +++ b/docs/04_cv32a65x/design/source/port_issue_read_operands.rst @@ -40,79 +40,79 @@ - in - TO_BE_COMPLETED - TO_BE_COMPLETED - - scoreboard_entry_t + - scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0] * - ``orig_instr_i`` - in - TO_BE_COMPLETED - TO_BE_COMPLETED - - logic[31:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][31:0] * - ``issue_instr_valid_i`` - in - TO_BE_COMPLETED - TO_BE_COMPLETED - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``issue_ack_o`` - out - Issue stage acknowledge - TO_BE_COMPLETED - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``rs1_o`` - out - rs1 operand address - scoreboard - - logic[REG_ADDR_SIZE-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][REG_ADDR_SIZE-1:0] * - ``rs1_i`` - in - rs1 operand - scoreboard - - logic[CVA6Cfg.XLEN-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] * - ``rs1_valid_i`` - in - rs1 operand is valid - scoreboard - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``rs2_o`` - out - rs2 operand address - scoreboard - - logic[REG_ADDR_SIZE-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][REG_ADDR_SIZE-1:0] * - ``rs2_i`` - in - rs2 operand - scoreboard - - logic[CVA6Cfg.XLEN-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] * - ``rs2_valid_i`` - in - rs2 operand is valid - scoreboard - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``rs3_o`` - out - rs3 operand address - scoreboard - - logic[REG_ADDR_SIZE-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][REG_ADDR_SIZE-1:0] * - ``rs3_i`` - in - rs3 operand - scoreboard - - rs3_len_t + - rs3_len_t[CVA6Cfg.NrIssuePorts-1:0] * - ``rs3_valid_i`` - in - rs3 operand is valid - scoreboard - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``rd_clobber_gpr_i`` - in @@ -130,19 +130,19 @@ - out - TO_BE_COMPLETED - TO_BE_COMPLETED - - fu_data_t + - fu_data_t[CVA6Cfg.NrIssuePorts-1:0] * - ``rs1_forwarding_o`` - out - Unregistered version of fu_data_o.operanda - TO_BE_COMPLETED - - logic[CVA6Cfg.XLEN-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] * - ``rs2_forwarding_o`` - out - Unregistered version of fu_data_o.operandb - TO_BE_COMPLETED - - logic[CVA6Cfg.XLEN-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] * - ``pc_o`` - out @@ -166,13 +166,13 @@ - out - ALU output is valid - TO_BE_COMPLETED - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``branch_valid_o`` - out - Branch instruction is valid - TO_BE_COMPLETED - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``branch_predict_o`` - out @@ -190,25 +190,31 @@ - out - Load Store Unit result is valid - TO_BE_COMPLETED - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``mult_valid_o`` - out - Mult result is valid - TO_BE_COMPLETED - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] + + * - ``alu2_valid_o`` + - out + - ALU output is valid + - TO_BE_COMPLETED + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``csr_valid_o`` - out - CSR result is valid - TO_BE_COMPLETED - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``cvxif_valid_o`` - out - CVXIF result is valid - TO_BE_COMPLETED - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``cvxif_ready_i`` - in diff --git a/docs/04_cv32a65x/design/source/port_issue_stage.rst b/docs/04_cv32a65x/design/source/port_issue_stage.rst index 0fa740fd3c..7e5b9b27e2 100644 --- a/docs/04_cv32a65x/design/source/port_issue_stage.rst +++ b/docs/04_cv32a65x/design/source/port_issue_stage.rst @@ -46,49 +46,49 @@ - in - Handshake's data with decode stage - ID_STAGE - - scoreboard_entry_t[SUPERSCALAR:0] + - scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0] * - ``orig_instr_i`` - in - instruction value - ID_STAGE - - logic[SUPERSCALAR:0][31:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][31:0] * - ``decoded_instr_valid_i`` - in - Handshake's valid with decode stage - ID_STAGE - - logic[SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``is_ctrl_flow_i`` - in - Is instruction a control flow instruction - ID_STAGE - - logic[SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``decoded_instr_ack_o`` - out - Handshake's acknowlege with decode stage - ID_STAGE - - logic[SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``rs1_forwarding_o`` - out - rs1 forwarding - EX_STAGE - - [CVA6Cfg.VLEN-1:0] + - [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] * - ``rs2_forwarding_o`` - out - rs2 forwarding - EX_STAGE - - [CVA6Cfg.VLEN-1:0] + - [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] * - ``fu_data_o`` - out - FU data useful to execute instruction - EX_STAGE - - fu_data_t + - fu_data_t[CVA6Cfg.NrIssuePorts-1:0] * - ``pc_o`` - out @@ -112,7 +112,7 @@ - out - ALU FU is valid - EX_STAGE - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``resolve_branch_i`` - in @@ -130,13 +130,13 @@ - out - Load store unit FU is valid - EX_STAGE - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``branch_valid_o`` - out - Branch unit is valid - EX_STAGE - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``branch_predict_o`` - out @@ -148,19 +148,25 @@ - out - Mult FU is valid - EX_STAGE - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] + + * - ``alu2_valid_o`` + - out + - ALU2 FU is valid + - EX_STAGE + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``csr_valid_o`` - out - CSR is valid - EX_STAGE - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``x_issue_valid_o`` - out - CVXIF FU is valid - EX_STAGE - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``x_issue_ready_i`` - in @@ -234,6 +240,12 @@ - COMMIT_STAGE - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] + * - ``commit_drop_o`` + - out + - Instruction is cancelled + - COMMIT_STAGE + - logic[CVA6Cfg.NrCommitPorts-1:0] + * - ``commit_ack_i`` - in - Commit acknowledge diff --git a/docs/04_cv32a65x/design/source/port_load_store_unit.rst b/docs/04_cv32a65x/design/source/port_load_store_unit.rst index ea49497f4c..8f3c1fe798 100644 --- a/docs/04_cv32a65x/design/source/port_load_store_unit.rst +++ b/docs/04_cv32a65x/design/source/port_load_store_unit.rst @@ -172,13 +172,13 @@ - in - PMP configuration - CSR_REGFILE - - riscv::pmpcfg_t[15:0] + - riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries:0] * - ``pmpaddr_i`` - in - PMP address - CSR_REGFILE - - logic[15:0][CVA6Cfg.PLEN-3:0] + - logic[CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below diff --git a/docs/04_cv32a65x/design/source/port_scoreboard.rst b/docs/04_cv32a65x/design/source/port_scoreboard.rst index aa3b2bf472..ad5afa9757 100644 --- a/docs/04_cv32a65x/design/source/port_scoreboard.rst +++ b/docs/04_cv32a65x/design/source/port_scoreboard.rst @@ -64,55 +64,55 @@ - in - rs1 operand address - issue_read_operands - - logic[ariane_pkg::REG_ADDR_SIZE-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] * - ``rs1_o`` - out - rs1 operand - issue_read_operands - - logic[CVA6Cfg.XLEN-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] * - ``rs1_valid_o`` - out - rs1 operand is valid - issue_read_operands - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``rs2_i`` - in - rs2 operand address - issue_read_operands - - logic[ariane_pkg::REG_ADDR_SIZE-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] * - ``rs2_o`` - out - rs2 operand - issue_read_operands - - logic[CVA6Cfg.XLEN-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] * - ``rs2_valid_o`` - out - rs2 operand is valid - issue_read_operands - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``rs3_i`` - in - rs3 operand address - issue_read_operands - - logic[ariane_pkg::REG_ADDR_SIZE-1:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] * - ``rs3_o`` - out - rs3 operand - issue_read_operands - - rs3_len_t + - rs3_len_t[CVA6Cfg.NrIssuePorts-1:0] * - ``rs3_valid_o`` - out - rs3 operand is valid - issue_read_operands - - logic + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``commit_instr_o`` - out @@ -120,6 +120,12 @@ - TO_BE_COMPLETED - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] + * - ``commit_drop_o`` + - out + - TO_BE_COMPLETED + - TO_BE_COMPLETED + - logic[CVA6Cfg.NrCommitPorts-1:0] + * - ``commit_ack_i`` - in - TO_BE_COMPLETED @@ -130,43 +136,43 @@ - in - TO_BE_COMPLETED - TO_BE_COMPLETED - - scoreboard_entry_t[ariane_pkg::SUPERSCALAR:0] + - scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0] * - ``orig_instr_i`` - in - TO_BE_COMPLETED - TO_BE_COMPLETED - - logic[ariane_pkg::SUPERSCALAR:0][31:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][31:0] * - ``decoded_instr_valid_i`` - in - TO_BE_COMPLETED - TO_BE_COMPLETED - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``decoded_instr_ack_o`` - out - TO_BE_COMPLETED - TO_BE_COMPLETED - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``orig_instr_o`` - out - TO_BE_COMPLETED - TO_BE_COMPLETED - - logic[ariane_pkg::SUPERSCALAR:0][31:0] + - logic[CVA6Cfg.NrIssuePorts-1:0][31:0] * - ``issue_instr_valid_o`` - out - TO_BE_COMPLETED - TO_BE_COMPLETED - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``issue_ack_i`` - in - TO_BE_COMPLETED - TO_BE_COMPLETED - - logic[ariane_pkg::SUPERSCALAR:0] + - logic[CVA6Cfg.NrIssuePorts-1:0] * - ``resolved_branch_i`` - in diff --git a/docs/scripts/spec_builder.py b/docs/scripts/spec_builder.py index 64c7348e7f..edf103582c 100755 --- a/docs/scripts/spec_builder.py +++ b/docs/scripts/spec_builder.py @@ -18,8 +18,7 @@ from parameters_extractor import writeout_parameter_table -if __name__ == "__main__": - +def main(): PATH = "04_cv32a65x" [spec_number, target] = PATH.split("_") @@ -29,6 +28,7 @@ pathout = f"./{spec_number}_{target}/design/source" fileout = f"{pathout}/parameters_{target}.rst" writeout_parameter_table(fileout, parameters, target) + export_user_cfg_doc("01_cva6_user/user_cfg_doc.rst", parameters) file = [] file.append("../core/cva6.sv") @@ -127,19 +127,7 @@ connexion = "none" with open(fileout, "w", encoding="utf-8") as fout: - fout.write("..\n") - fout.write(" Copyright 2024 Thales DIS France SAS\n") - fout.write( - ' Licensed under the Solderpad Hardware License, Version 2.1 (the "License");\n' - ) - fout.write( - " you may not use this file except in compliance with the License.\n" - ) - fout.write(" SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1\n") - fout.write( - " You may obtain a copy of the License at https://solderpad.org/licenses/\n\n" - ) - fout.write(" Original Author: Jean-Roch COULON - Thales\n\n") + fout.write(HEADER) fout.write(f".. _CVA6_{module}_ports:\n\n") fout.write(f".. list-table:: **{module} module** IO ports\n") fout.write(" :header-rows: 1\n") @@ -165,3 +153,37 @@ for comment in comments: fout.write(f"| {comment[0]},\n| {comment[1]}\n") fout.write("\n") + +HEADER = """\ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +""" + +def export_user_cfg_doc(out_path, params): + with open(out_path, "w", encoding="utf-8") as f: + f.write(HEADER) + f.write("""\ +.. _cva6_user_cfg_doc: + +.. list-table:: ``cva6_user_cfg_t`` parameters + :header-rows: 1 + + * - Name + - Type + - Description +""") + for name, param in params.items(): + f.write("\n") + f.write(f" * - ``{name}``\n") + f.write(f" - ``{param.datatype.strip()}``\n") + f.write(f" - {param.description}\n") + +if __name__ == "__main__": + main() From c4b421698106bf796025c7608fe283046db53981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Qu=C3=A9vremont?= Date: Fri, 12 Jul 2024 18:14:26 +0200 Subject: [PATCH 011/183] Update cva6_requirements_specification.rst (#2364) Specify CV-X-IF version supported: 1.0.0. Mention of B extension (with includes the Zb* extensions, already in the specification). Make FENCE.T as a "should" instead of "shall" as we do not have plans to integrate it yet. --- .../cva6_requirements_specification.rst | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/docs/02_cva6_requirements/cva6_requirements_specification.rst b/docs/02_cva6_requirements/cva6_requirements_specification.rst index d0170bb583..da5605efbb 100644 --- a/docs/02_cva6_requirements/cva6_requirements_specification.rst +++ b/docs/02_cva6_requirements/cva6_requirements_specification.rst @@ -204,8 +204,7 @@ https://github.com/riscv-non-isa/riscv-arch-test. [AXI] AXI Specification, https://developer.arm.com/documentation/ihi0022/hc. -[CV-X-IF] Placeholder for the CV-X-IF coprocessor interface currently -prepared at OpenHW Group; current version in +[CV-X-IF] “OpenHW Group Specification: Core-V eXtension interface (CV-X-IF)”, version 1.0.0, https://docs.openhwgroup.org/projects/openhw-group-core-v-xif/. [OpenPiton] “OpenPiton Microarchitecture Specification”, Princeton @@ -304,9 +303,11 @@ independent requirements. | | 2.0. | +-----------------------------------+-----------------------------------+ | ISA-120 | CVA6 should support as an | -| | **option** the **Zba**, **Zbb**, | -| | **Zbc** and **Zbs** extensions | +| | **option** the **B** extension | | | (bit manipulation), version 1.0. | +| | The **B** extension comprises the | +| | **Zba**, **Zbb**, **Zbc** | +| | and **Zbs** extensions. | +-----------------------------------+-----------------------------------+ | ISA-130 | CVA6 should support as an | | | **option** the **Zicond** | @@ -614,15 +615,15 @@ work. If a RISC-V specification is ratified, the CVA6 specification will likely switch to it. +-----------------------------------+-----------------------------------+ -| FET‑10 | CVA6 shall support the | +| FET‑10 | CVA6 should support the | | | ``FENCE.T`` instruction that | | | ensures that the execution time | | | of subsequent instructions is | | | unrelated with predecessor | | | instructions. | +-----------------------------------+-----------------------------------+ -| FET‑20 | ``FENCE.T`` shall be available in | -| | all privilege modes (machine, | +| FET‑20 | ``FENCE.T`` should be available | +| | in all privilege modes (machine, | | | supervisor, user and hypervisor | | | if present). | +-----------------------------------+-----------------------------------+ @@ -637,11 +638,6 @@ used to select a subset of microarchitecture features that will be cleared. The list of arguments, if any, will be detailed in the user’s guide. -Anticipation of verification: It can be cumbersome to prove the timing -decorrelation as expressed in the requirement with digital simulations. -We can simulate the microarchitecture features and explain how they -satisfy the requirement as Nils Wistoff’s work demonstrated. - .. _ppa_targets: PPA targets @@ -752,13 +748,6 @@ Coprocessor interface | | [CV-X-IF] specification. | +-----------------------------------+-----------------------------------+ -The goal is to have a compatible interface between CORE-V cores (CVA6, -CV32E40X…). The feasibility still needs to be confirmed; including the -speculative execution. - -CVA6 can interface with several coprocessors simultaneously through a -specific external feature implemented on the CV-X-IF interface. - .. _multi_core_interface: Multi-core interface From 8aa0f634f6bf5f388a78ac8a2b1d72a8b4600d0a Mon Sep 17 00:00:00 2001 From: Asmaa Kassimi <163407779+Asmaa-Kassimi@users.noreply.github.com> Date: Sat, 13 Jul 2024 08:32:51 +0100 Subject: [PATCH 012/183] condition load and store modules (#2349) --- core/load_unit.sv | 2 +- core/store_unit.sv | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/core/load_unit.sv b/core/load_unit.sv index cea27c6b27..2109b08ded 100644 --- a/core/load_unit.sv +++ b/core/load_unit.sv @@ -505,7 +505,7 @@ module load_unit // select correct sign bit in parallel to result shifter above // pull to 0 if unsigned - assign rdata_sign_bit = rdata_is_signed & rdata_sign_bits[rdata_offset] | rdata_is_fp_signed; + assign rdata_sign_bit = rdata_is_signed & rdata_sign_bits[rdata_offset] | (CVA6Cfg.FpPresent && rdata_is_fp_signed); // result mux always_comb begin diff --git a/core/store_unit.sv b/core/store_unit.sv index f6c373bc1b..9b85180f68 100644 --- a/core/store_unit.sv +++ b/core/store_unit.sv @@ -89,7 +89,7 @@ module store_unit // align data to address e.g.: shift data to be naturally 64 function automatic [CVA6Cfg.XLEN-1:0] data_align(logic [2:0] addr, logic [63:0] data); // Set addr[2] to 1'b0 when 32bits - logic [ 2:0] addr_tmp = {(addr[2] && CVA6Cfg.IS_XLEN64), addr[1:0]}; + logic [2:0] addr_tmp = {(addr[2] && CVA6Cfg.IS_XLEN64), addr[1:0]}; logic [63:0] data_tmp = {64{1'b0}}; case (addr_tmp) 3'b000: data_tmp[CVA6Cfg.XLEN-1:0] = {data[CVA6Cfg.XLEN-1:0]}; @@ -99,10 +99,16 @@ module store_unit data_tmp[CVA6Cfg.XLEN-1:0] = {data[CVA6Cfg.XLEN-17:0], data[CVA6Cfg.XLEN-1:CVA6Cfg.XLEN-16]}; 3'b011: data_tmp[CVA6Cfg.XLEN-1:0] = {data[CVA6Cfg.XLEN-25:0], data[CVA6Cfg.XLEN-1:CVA6Cfg.XLEN-24]}; - 3'b100: data_tmp = {data[31:0], data[63:32]}; - 3'b101: data_tmp = {data[23:0], data[63:24]}; - 3'b110: data_tmp = {data[15:0], data[63:16]}; - 3'b111: data_tmp = {data[7:0], data[63:8]}; + default: + if (CVA6Cfg.IS_XLEN64) begin + case (addr_tmp) + 3'b100: data_tmp = {data[31:0], data[63:32]}; + 3'b101: data_tmp = {data[23:0], data[63:24]}; + 3'b110: data_tmp = {data[15:0], data[63:16]}; + 3'b111: data_tmp = {data[7:0], data[63:8]}; + default: data_tmp = {data[63:0]}; + endcase + end endcase return data_tmp[CVA6Cfg.XLEN-1:0]; endfunction @@ -273,8 +279,8 @@ module store_unit logic store_buffer_ready, amo_buffer_ready; // multiplex between store unit and amo buffer - assign store_buffer_valid = st_valid & (amo_op_q == AMO_NONE); - assign amo_buffer_valid = st_valid & (amo_op_q != AMO_NONE); + assign store_buffer_valid = st_valid & (!CVA6Cfg.RVA || (amo_op_q == AMO_NONE)); + assign amo_buffer_valid = st_valid & (CVA6Cfg.RVA && (amo_op_q != AMO_NONE)); assign st_ready = store_buffer_ready & amo_buffer_ready; From 6c0e3f82c52d4852879d96a7e275ba5d2bef9991 Mon Sep 17 00:00:00 2001 From: Jalali <110232072+AyoubJalali@users.noreply.github.com> Date: Mon, 15 Jul 2024 12:39:52 +0000 Subject: [PATCH 013/183] Verif: Add load hazard instructions (#2354) --- verif/tests/custom/isacov/load_reg_hazard.S | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/verif/tests/custom/isacov/load_reg_hazard.S b/verif/tests/custom/isacov/load_reg_hazard.S index 15c1c3eece..2b63b4d9b5 100644 --- a/verif/tests/custom/isacov/load_reg_hazard.S +++ b/verif/tests/custom/isacov/load_reg_hazard.S @@ -384,6 +384,27 @@ main: c.lhu a4, 0(a4) c.lhu a5, 0(a5) + li s0, 0x80000000 + li s1, 0x80000000 + li a0, 0x80000000 + li a1, 0x80000000 + li a2, 0x80000000 + li a3, 0x80000000 + li a4, 0x80000000 + li a5, 0x80000000 + + c.lw s0, 0(s0) + c.lw s1, 0(s1) + c.lw a0, 0(a0) + c.lw a1, 0(a1) + c.lw a2, 0(a2) + c.lw a3, 0(a3) + c.lw a4, 0(a4) + c.lw a5, 0(a5) + + li sp, 0x80000000 + c.lwsp sp, 0(sp) + #End of test j test_pass From 8c709767599a12acd7c02976a42cc3dcc9f4604e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Sintzoff?= <61976467+ASintzoff@users.noreply.github.com> Date: Mon, 15 Jul 2024 14:42:07 +0200 Subject: [PATCH 014/183] docs: use correct commit for riscv-isa-manual submodule (#2368) fix after 8fa590b5c --- docs/riscv-isa/riscv-isa-manual | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/riscv-isa/riscv-isa-manual b/docs/riscv-isa/riscv-isa-manual index c8c8075a6a..ebf2e3a0b4 160000 --- a/docs/riscv-isa/riscv-isa-manual +++ b/docs/riscv-isa/riscv-isa-manual @@ -1 +1 @@ -Subproject commit c8c8075a6a71be67ac723528070e3e50ff7586b2 +Subproject commit ebf2e3a0b402cd56fd4b571b705b31f3be62c2cc From 5f8605838ec0c465a4d9724878754521aeea4bf8 Mon Sep 17 00:00:00 2001 From: AbdessamiiOukalrazqou <163409352+AbdessamiiOukalrazqou@users.noreply.github.com> Date: Sun, 21 Jul 2024 22:39:50 +0200 Subject: [PATCH 015/183] [gen_from_riscv_config] fix access issues for PMP registers, improve Factorization algorithm , improve csr_updater.yaml, add spike support (#2372) --- .../cv32a65x/csr/csr.rst | 110 +- .../cv32a65x/spike/spike.yaml | 45 +- .../scripts/libs/csr_factorizer.py | 28 +- .../scripts/libs/csr_updater.py | 20 +- .../scripts/libs/utils.py | 298 +++- .../updaters/cv32a65x/csr_updater.yaml | 1229 ++++++++++++++++- 6 files changed, 1593 insertions(+), 137 deletions(-) diff --git a/config/gen_from_riscv_config/cv32a65x/csr/csr.rst b/config/gen_from_riscv_config/cv32a65x/csr/csr.rst index ad95398249..6083081e1c 100644 --- a/config/gen_from_riscv_config/cv32a65x/csr/csr.rst +++ b/config/gen_from_riscv_config/cv32a65x/csr/csr.rst @@ -65,9 +65,13 @@ Register Summary +-------------+---------------------------------------------+-------------+----------------------------------------------------------------------------------------------------+ | 0x344 | `MIP <#MIP>`_ | MRW | The mip register is an MXLEN-bit read/write register containing information on pending interrupts. | +-------------+---------------------------------------------+-------------+----------------------------------------------------------------------------------------------------+ -| 0x3a0-0x3a3 | `PMPCFG[0-3] <#PMPCFG[0-3]>`_ | MRW | PMP configuration register | +| 0x3a0-0x3a1 | `PMPCFG[0-1] <#PMPCFG[0-1]>`_ | MRW | PMP configuration register | +-------------+---------------------------------------------+-------------+----------------------------------------------------------------------------------------------------+ -| 0x3b0-0x3bf | `PMPADDR[0-15] <#PMPADDR[0-15]>`_ | MRW | Physical memory protection address register | +| 0x3a2-0x3af | `PMPCFG[2-15] <#PMPCFG[2-15]>`_ | MRW | PMP configuration register | ++-------------+---------------------------------------------+-------------+----------------------------------------------------------------------------------------------------+ +| 0x3b0-0x3b7 | `PMPADDR[0-7] <#PMPADDR[0-7]>`_ | MRW | Physical memory protection address register | ++-------------+---------------------------------------------+-------------+----------------------------------------------------------------------------------------------------+ +| 0x3b8-0x3ef | `PMPADDR[8-63] <#PMPADDR[8-63]>`_ | MRW | Physical memory protection address register | +-------------+---------------------------------------------+-------------+----------------------------------------------------------------------------------------------------+ | 0x7c0 | `ICACHE <#ICACHE>`_ | MRW | the register controls the operation of the i-cache unit. | +-------------+---------------------------------------------+-------------+----------------------------------------------------------------------------------------------------+ @@ -206,7 +210,7 @@ MIE +---------+--------------+---------------+--------+----------------+---------------------------------------+ | 6 | VSTIE | 0x0 | ROCST | 0x0 | VS-level Timer Interrupt enable. | +---------+--------------+---------------+--------+----------------+---------------------------------------+ -| 7 | MTIE | 0x0 | ROVAR | 0x0 - 0x1 | Machine Timer Interrupt enable. | +| 7 | MTIE | 0x0 | WLRL | 0x0 - 0x1 | Machine Timer Interrupt enable. | +---------+--------------+---------------+--------+----------------+---------------------------------------+ | 8 | UEIE | 0x0 | ROCST | 0x0 | User External Interrupt enable. | +---------+--------------+---------------+--------+----------------+---------------------------------------+ @@ -214,7 +218,7 @@ MIE +---------+--------------+---------------+--------+----------------+---------------------------------------+ | 10 | VSEIE | 0x0 | ROCST | 0x0 | VS-level External Interrupt enable. | +---------+--------------+---------------+--------+----------------+---------------------------------------+ -| 11 | MEIE | 0x0 | ROVAR | 0x0 - 0x1 | Machine External Interrupt enable. | +| 11 | MEIE | 0x0 | WLRL | 0x0 - 0x1 | Machine External Interrupt enable. | +---------+--------------+---------------+--------+----------------+---------------------------------------+ | 12 | SGEIE | 0x0 | ROCST | 0x0 | HS-level External Interrupt enable. | +---------+--------------+---------------+--------+----------------+---------------------------------------+ @@ -285,7 +289,7 @@ MHPMEVENT[3-31] +--------+--------------+---------------+--------+----------------+--------------------------------------------------------------------------+ | Bits | Field Name | Reset Value | Type | Legal Values | Description | +========+==============+===============+========+================+==========================================================================+ -| [31:0] | MHPMEVENT[I] | 0x00000000 | ROCST | 0x00000000 | The mhpmevent is a MXLEN-bit event register which controls mhpmcounter3. | +| [31:0] | MHPMEVENT[I] | 0x00000000 | ROCST | 0x0 | The mhpmevent is a MXLEN-bit event register which controls mhpmcounter3. | +--------+--------------+---------------+--------+----------------+--------------------------------------------------------------------------+ @@ -336,7 +340,7 @@ MCAUSE +--------+----------------+---------------+--------+----------------+-----------------------------------------------------+ | Bits | Field Name | Reset Value | Type | Legal Values | Description | +========+================+===============+========+================+=====================================================+ -| [30:0] | EXCEPTION_CODE | 0x0 | WLRL | 0 - 15 | Encodes the exception code. | +| [30:0] | EXCEPTION_CODE | 0x0 | WLRL | 0x0 - 0x8, 0xb | Encodes the exception code. | +--------+----------------+---------------+--------+----------------+-----------------------------------------------------+ | 31 | INTERRUPT | 0x0 | WLRL | 0x0 - 0x1 | Indicates whether the trap was due to an interrupt. | +--------+----------------+---------------+--------+----------------+-----------------------------------------------------+ @@ -355,7 +359,7 @@ MTVAL +--------+--------------+---------------+--------+----------------+----------------------------------------------------------------------------------------------------+ | Bits | Field Name | Reset Value | Type | Legal Values | Description | +========+==============+===============+========+================+====================================================================================================+ -| [31:0] | MTVAL | 0x00000000 | ROCST | 0x00000000 | The mtval is a warl register that holds the address of the instruction which caused the exception. | +| [31:0] | MTVAL | 0x00000000 | ROCST | 0x0 | The mtval is a warl register that holds the address of the instruction which caused the exception. | +--------+--------------+---------------+--------+----------------+----------------------------------------------------------------------------------------------------+ @@ -402,33 +406,55 @@ MIP +---------+--------------+---------------+--------+----------------+----------------------------------------+ -.. .. _PMPCFG[0-3]::: -PMPCFG[0-3] +.. .. _PMPCFG[0-1]::: +PMPCFG[0-1] ~~~~~~~~~~~ -:Address: 0x3a0-0x3af +:Address: 0x3a0-0x3a1 :Reset Value: 0x00000000 :Privilege: MRW :Description: PMP configuration register -+---------+-----------------+---------------+--------+----------------+------------------------+ -| Bits | Field Name | Reset Value | Type | Legal Values | Description | -+=========+=================+===============+========+================+========================+ -| [7:0] | PMP[I*4 + 0]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits | -+---------+-----------------+---------------+--------+----------------+------------------------+ -| [15:8] | PMP[I*4 + 1]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits | -+---------+-----------------+---------------+--------+----------------+------------------------+ -| [23:16] | PMP[I*4 + 2]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits | -+---------+-----------------+---------------+--------+----------------+------------------------+ -| [31:24] | PMP[I*4 + 3]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits | -+---------+-----------------+---------------+--------+----------------+------------------------+ - - -.. .. _PMPADDR[0-15]::: -PMPADDR[0-15] -~~~~~~~~~~~~~ ++---------+----------------+---------------+--------+----------------+------------------------+ +| Bits | Field Name | Reset Value | Type | Legal Values | Description | ++=========+================+===============+========+================+========================+ +| [7:0] | PMP[I*4 +0]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits | ++---------+----------------+---------------+--------+----------------+------------------------+ +| [15:8] | PMP[I*4 +1]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits | ++---------+----------------+---------------+--------+----------------+------------------------+ +| [23:16] | PMP[I*4 +2]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits | ++---------+----------------+---------------+--------+----------------+------------------------+ +| [31:24] | PMP[I*4 +3]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits | ++---------+----------------+---------------+--------+----------------+------------------------+ + + +.. .. _PMPCFG[2-15]::: +PMPCFG[2-15] +~~~~~~~~~~~~ + +:Address: 0x3a2-0x3af +:Reset Value: 0x00000000 +:Privilege: MRW +:Description: PMP configuration register + ++---------+----------------+---------------+--------+----------------+------------------------+ +| Bits | Field Name | Reset Value | Type | Legal Values | Description | ++=========+================+===============+========+================+========================+ +| [7:0] | PMP[I*4 +0]CFG | 0x0 | ROCST | 0x0 | pmp configuration bits | ++---------+----------------+---------------+--------+----------------+------------------------+ +| [15:8] | PMP[I*4 +1]CFG | 0x0 | ROCST | 0x0 | pmp configuration bits | ++---------+----------------+---------------+--------+----------------+------------------------+ +| [23:16] | PMP[I*4 +2]CFG | 0x0 | ROCST | 0x0 | pmp configuration bits | ++---------+----------------+---------------+--------+----------------+------------------------+ +| [31:24] | PMP[I*4 +3]CFG | 0x0 | ROCST | 0x0 | pmp configuration bits | ++---------+----------------+---------------+--------+----------------+------------------------+ -:Address: 0x3b0-0x3ef + +.. .. _PMPADDR[0-7]::: +PMPADDR[0-7] +~~~~~~~~~~~~ + +:Address: 0x3b0-0x3b7 :Reset Value: 0x00000000 :Privilege: MRW :Description: Physical memory protection address register @@ -440,6 +466,22 @@ PMPADDR[0-15] +--------+--------------+---------------+--------+-------------------------+---------------------------------------------+ +.. .. _PMPADDR[8-63]::: +PMPADDR[8-63] +~~~~~~~~~~~~~ + +:Address: 0x3b8-0x3ef +:Reset Value: 0x00000000 +:Privilege: MRW +:Description: Physical memory protection address register + ++--------+--------------+---------------+--------+----------------+---------------------------------------------+ +| Bits | Field Name | Reset Value | Type | Legal Values | Description | ++========+==============+===============+========+================+=============================================+ +| [31:0] | PMPADDR[I] | 0x00000000 | ROCST | 0x0 | Physical memory protection address register | ++--------+--------------+---------------+--------+----------------+---------------------------------------------+ + + .. .. _ICACHE::: ICACHE ~~~~~~ @@ -523,7 +565,7 @@ MHPMCOUNTER[3-31] +--------+----------------+---------------+--------+----------------+---------------------------------------------------------------------------+ | Bits | Field Name | Reset Value | Type | Legal Values | Description | +========+================+===============+========+================+===========================================================================+ -| [31:0] | MHPMCOUNTER[I] | 0x00000000 | ROCST | 0x00000000 | The mhpmcounter is a 64-bit counter. Returns lower 32 bits in RV32I mode. | +| [31:0] | MHPMCOUNTER[I] | 0x00000000 | ROCST | 0x0 | The mhpmcounter is a 64-bit counter. Returns lower 32 bits in RV32I mode. | +--------+----------------+---------------+--------+----------------+---------------------------------------------------------------------------+ @@ -572,7 +614,7 @@ MHPMCOUNTER[3-31]H +--------+-----------------+---------------+--------+----------------+----------------------------------------------------------------+ | Bits | Field Name | Reset Value | Type | Legal Values | Description | +========+=================+===============+========+================+================================================================+ -| [31:0] | MHPMCOUNTER[I]H | 0x00000000 | ROCST | 0x00000000 | The mhpmcounterh returns the upper half word in RV32I systems. | +| [31:0] | MHPMCOUNTER[I]H | 0x00000000 | ROCST | 0x0 | The mhpmcounterh returns the upper half word in RV32I systems. | +--------+-----------------+---------------+--------+----------------+----------------------------------------------------------------+ @@ -589,7 +631,7 @@ MVENDORID +--------+--------------+---------------+--------+----------------+--------------------------------------------------------------------------------------------+ | Bits | Field Name | Reset Value | Type | Legal Values | Description | +========+==============+===============+========+================+============================================================================================+ -| [31:0] | MVENDORID | 0x00000602 | ROCST | 0x00000602 | 32-bit read-only register providing the JEDEC manufacturer ID of the provider of the core. | +| [31:0] | MVENDORID | 0x00000602 | ROCST | 0x602 | 32-bit read-only register providing the JEDEC manufacturer ID of the provider of the core. | +--------+--------------+---------------+--------+----------------+--------------------------------------------------------------------------------------------+ @@ -606,7 +648,7 @@ MARCHID +--------+--------------+---------------+--------+----------------+-------------------------------------------------------------------------------+ | Bits | Field Name | Reset Value | Type | Legal Values | Description | +========+==============+===============+========+================+===============================================================================+ -| [31:0] | MARCHID | 0x00000003 | ROCST | 0x00000003 | MXLEN-bit read-only register encoding the base microarchitecture of the hart. | +| [31:0] | MARCHID | 0x00000003 | ROCST | 0x3 | MXLEN-bit read-only register encoding the base microarchitecture of the hart. | +--------+--------------+---------------+--------+----------------+-------------------------------------------------------------------------------+ @@ -623,7 +665,7 @@ MIMPID +--------+--------------+---------------+--------+----------------+----------------------------------------------------------------------------+ | Bits | Field Name | Reset Value | Type | Legal Values | Description | +========+==============+===============+========+================+============================================================================+ -| [31:0] | MIMPID | 0x00000000 | ROCST | 0x00000000 | Provides a unique encoding of the version of the processor implementation. | +| [31:0] | MIMPID | 0x00000000 | ROCST | 0x0 | Provides a unique encoding of the version of the processor implementation. | +--------+--------------+---------------+--------+----------------+----------------------------------------------------------------------------+ @@ -640,7 +682,7 @@ MHARTID +--------+--------------+---------------+--------+----------------+-------------------------------------------------------------------------------------------------+ | Bits | Field Name | Reset Value | Type | Legal Values | Description | +========+==============+===============+========+================+=================================================================================================+ -| [31:0] | MHARTID | 0x00000000 | ROCST | 0x00000000 | MXLEN-bit read-only register containing the integer ID of the hardware thread running the code. | +| [31:0] | MHARTID | 0x00000000 | ROCST | 0x0 | MXLEN-bit read-only register containing the integer ID of the hardware thread running the code. | +--------+--------------+---------------+--------+----------------+-------------------------------------------------------------------------------------------------+ @@ -657,6 +699,6 @@ MCONFIGPTR +--------+--------------+---------------+--------+----------------+-------------------------------------------------------------------------------------------------+ | Bits | Field Name | Reset Value | Type | Legal Values | Description | +========+==============+===============+========+================+=================================================================================================+ -| [31:0] | MCONFIGPTR | 0x00000000 | ROCST | 0x00000000 | MXLEN-bit read-only register that holds the physical address of a configuration data structure. | +| [31:0] | MCONFIGPTR | 0x00000000 | ROCST | 0x0 | MXLEN-bit read-only register that holds the physical address of a configuration data structure. | +--------+--------------+---------------+--------+----------------+-------------------------------------------------------------------------------------------------+ diff --git a/config/gen_from_riscv_config/cv32a65x/spike/spike.yaml b/config/gen_from_riscv_config/cv32a65x/spike/spike.yaml index 08fb6f2af2..1185689fec 100644 --- a/config/gen_from_riscv_config/cv32a65x/spike/spike.yaml +++ b/config/gen_from_riscv_config/cv32a65x/spike/spike.yaml @@ -1,30 +1,31 @@ spike_param_tree: bootrom: true - bootrom_base: 0x10000 - bootrom_size: 0x1000 + bootrom_base: 65536 + bootrom_size: 4096 dram: true - dram_base: 0x80000000 - dram_size: 0x40000000 + dram_base: 2147483648 + dram_size: 1073741824 generic_core_config: false max_steps: 200000 max_steps_enabled: false - isa: rv32imc_zba_zbb_zbs_zbc_zicsr_zifencei + isa: rv32imczicsr_zicntr_zifencei_zcb_zba_zbb_zbc_zbs priv: M cores: - - isa: rv32imc_zba_zbb_zbs_zbc_zicsr_zifencei - boot_addr: 0x80000000 - marchid: 0x3 - misa_we: false - misa_we_enable: true - misaligned: false - mmu_mode: sv39 - mvendorid: 0x00000602 - pmpaddr0: 0x0 - pmpcfg0: 0x0 - pmpregions: 0x0 - priv: M - misa_we: false - mstatus_write_mask: 0x00000088 - mstatus_override_mask: 0x00001800 - mtval_write_mask: 0x00000000 - unified_traps: true + - isa: rv32imc_zba_zbb_zbs_zbc_zicsr_zifencei + boot_addr: 2147483648 + marchid: 3 + misa_we: false + misa_we_enable: true + pmpaddr0: 0 + pmpcfg0: 0 + pmpregions: 64 + usable_pmpregions: 8 + priv: M + status_fs_field_we: false + status_fs_field_we_enable: false + status_vs_field_we: false + status_vs_field_we_enable: false + mstatus_write_mask: 136 + mstatus_override_mask: 6144 + mtval_write_mask: 0 + unified_traps: true diff --git a/config/gen_from_riscv_config/scripts/libs/csr_factorizer.py b/config/gen_from_riscv_config/scripts/libs/csr_factorizer.py index c4a2f079eb..e291f6303e 100644 --- a/config/gen_from_riscv_config/scripts/libs/csr_factorizer.py +++ b/config/gen_from_riscv_config/scripts/libs/csr_factorizer.py @@ -24,6 +24,7 @@ def address_to_key(address): def factorizer(yaml_data): privname = None + legalname= None fieldname = [] regname = [] regdescr = [] @@ -37,9 +38,9 @@ def factorizer(yaml_data): suffix_address = [] suffix_number = [] key_to_remove = [] - for key, value in yaml_data["hart0"].items(): + for key, value in yaml_data.items(): if isinstance(value, dict): - regelement = yaml_data["hart0"].get(key, {}) + regelement = yaml_data.get(key, {}) if regelement.get("address", None): regaddress = hex(regelement.get("address", None)) else: @@ -49,11 +50,16 @@ def factorizer(yaml_data): else: desc = "" if regelement.get("rv32", "")["accessible"]: + fields = regelement.get("rv32", "").get("fields", []) + if not fields : + legal = regelement.get("rv32", "").get("type", None).keys() if regelement.get("rv32", "").get("type", None) is not None else None + else : + legal = [regelement.get("rv32", "").get(item, {}).get("type").keys()for item in fields if not isinstance(item, list) and regelement.get("rv32", "").get(item, {}).get("type") is not None] pattern = r"(\D+)(\d+)(.*)" match = re.search(pattern, key) if match: key_to_remove.append(key) - if privname and match.group(1) == privname.group(1): + if privname and match.group(1) == privname.group(1) and legalname == legal: if len(match.group(3)) > 0: suffix_name.append(match.group(0)) field_suffix.append(match.group(1)) @@ -75,7 +81,7 @@ def factorizer(yaml_data): start_address = hex(int(regadress[0], 16)) desc = str(regdescr[0]) desc = re.sub(str(regname[0]), fieldname[0], desc) - modified_data = yaml_data["hart0"][regname[0]].copy() + modified_data = yaml_data[regname[0]].copy() modified_data["address"] = ( f"{str(start_address)}-{str(regadress[-1])}" ) @@ -98,13 +104,14 @@ def factorizer(yaml_data): suffix_address = sorted(suffix_address, key=address_to_key) desc = str(suffix_descr[0]) desc = re.sub(str(suffix_name[0]), field_suffix[0], desc) - modified_data = yaml_data["hart0"][suffix_name[0]].copy() + modified_data = yaml_data[suffix_name[0]].copy() modified_data["address"] = ( f"{str(suffix_address[0])}-{str(suffix_address[-1])}" ) new_regname.append( f"{field_suffix[0]}[{suffix_number[0]}-{suffix_number[-1]}]h" ) + print(new_regname) data.append(modified_data) suffix_name = [] field_suffix = [] @@ -112,12 +119,13 @@ def factorizer(yaml_data): suffix_number = [match.group(2)] suffix_address = [] privname = match + legalname = legal if regname: start_address = hex(int(regadress[0], 16)) end_address = str(regadress[-1]) desc = str(regdescr[0]) desc = re.sub(str(regname[0]), fieldname[0], desc) - modified_data = yaml_data["hart0"][regname[0]].copy() + modified_data = yaml_data[regname[0]].copy() modified_data["description"] = desc modified_data["address"] = f"{str(start_address)}-{str(end_address)}" new_regname.append(f"{fieldname[0]}[{reg_number[0]}-{reg_number[-1]}]") @@ -129,7 +137,7 @@ def factorizer(yaml_data): if suffix_name: desc = str(suffix_descr[0]) desc = re.sub(str(suffix_name[0]), field_suffix[0], desc) - modified_data = yaml_data["hart0"][suffix_name[0]].copy() + modified_data = yaml_data[suffix_name[0]].copy() modified_data["description"] = desc modified_data["address"] = ( f"{str(hex(int(suffix_address[0],16)))}-{str(suffix_address[-1])}" @@ -143,7 +151,7 @@ def factorizer(yaml_data): regdescr = [] regadress = [] for index, reg in enumerate(new_regname): - yaml_data["hart0"][reg] = data[index] + yaml_data[reg] = data[index] for key in key_to_remove: - del yaml_data["hart0"][key] - return yaml_data["hart0"] + del yaml_data[key] + return yaml_data diff --git a/config/gen_from_riscv_config/scripts/libs/csr_updater.py b/config/gen_from_riscv_config/scripts/libs/csr_updater.py index 5a0b212996..af76b67b28 100644 --- a/config/gen_from_riscv_config/scripts/libs/csr_updater.py +++ b/config/gen_from_riscv_config/scripts/libs/csr_updater.py @@ -5,23 +5,20 @@ def csr_recursive_update(original_dict, csr_update): """ Gets the data of the RISC-V Config Yaml file and - updates the value of sub key in the RISC-V Config Yaml file - (ex: reset-val, shadow_type) - :param original_dict: parsed data of the RISC-V Config Yaml file - :param csr_update: parsed data of the CSR updater + update the value of sub key in RISC-V Config Yaml file + (ex: reset-val , address) + :param original_dict : parsed data of RISC-V Config Yaml file + csr_update : parsed data of CSR updater :return: data of RISC-V Config Yaml file updated """ for key, value in csr_update.items(): if key in original_dict: if isinstance(value, dict) and isinstance(original_dict[key], dict): - # If both are dicts, recurse - if key == "type": - # Replace the entire type dictionary + if key == "rv32": original_dict[key] = value else: csr_recursive_update(original_dict[key], value) else: - # Replace the original value with the update value original_dict[key] = value @@ -31,9 +28,9 @@ def csr_formatter(srcfile, customfile, modifile): original_dict = yaml.safe_load(file) with open(customfile, "r", encoding="utf-8") as file: custom_dict = yaml.safe_load(file) - + isa_data = original_dict.copy() - isa_data['hart0'].update(custom_dict["hart0"]) + isa_data["hart0"].update(custom_dict["hart0"]) updated_values = {} if modifile is not None: with open(modifile, "r", encoding="utf-8") as file: @@ -41,7 +38,6 @@ def csr_formatter(srcfile, customfile, modifile): # Update original_dict with values from updated_values recursively csr_recursive_update(isa_data["hart0"], updated_values) - # Identify and remove keys within the range specified for each register keys_to_remove = [] for key, value in updated_values.items(): @@ -83,4 +79,4 @@ def remove_keys_recursive(dictionary): # Remove keys from original_dict for k in keys_to_remove: isa_data.pop(k, None) - return isa_data + return isa_data["hart0"] diff --git a/config/gen_from_riscv_config/scripts/libs/utils.py b/config/gen_from_riscv_config/scripts/libs/utils.py index 8348cd2777..6bfbc2c99c 100644 --- a/config/gen_from_riscv_config/scripts/libs/utils.py +++ b/config/gen_from_riscv_config/scripts/libs/utils.py @@ -20,22 +20,25 @@ import os import re import yaml +from yaml import BaseLoader import rstcloth +import json +from mako.template import Template import libs.isa_updater import libs.csr_updater +import libs.spike_updater import libs.csr_factorizer from rstcloth import RstCloth from mdutils.mdutils import MdUtils from libs.isa_updater import isa_filter from libs.csr_updater import csr_formatter +from libs.spike_updater import spike_formatter from libs.csr_factorizer import factorizer -pattern_warl = ( - r"\b(?:warl|wlrl|ro_constant|ro_variable|rw|ro)\b" # pattern to detect warl in field -) +pattern_warl = r"\b(?:warl|wlrl|ro_constant|ro_variable|rw|ro)\b" # pattern to detect warl in field pattern_legal_dict = r"\[(0x[0-9A-Fa-f]+)(.*?(0x[0-9A-Fa-f]+))?\]" # pattern to detect if warl field is dict pattern_legal_list = r"\[(0x[0-9A-Fa-f]+)(.*?(0x[0-9A-Fa-f]+))?\]" # pattern to detect if warl field is a list -Factorizer_pattern = r".*(\d).*" # pattern to detect factorized fields +Factorizer_pattern = r"\d+" # pattern to detect factorized fields class DocumentClass: @@ -131,16 +134,32 @@ class Render: """Collection of general rendering methods which can be overridden if needed for a specific output format.""" + @staticmethod + def is_decimal(value): + """return a bool checking if value is decimal""" + try: + int( + value + ) # Alternatively, use float(value) if you want to check for floating point numbers + return True + except ValueError: + return False + @staticmethod def range(start, end): """Return a string representing the range START..END, inclusive. START and END are strings representing numerical values.""" + if Render.is_decimal(start): + start = hex(int(start)) + if Render.is_decimal(end): + end = hex(int(end)) return f"{start} - {end}" @staticmethod def value_set(values): """Return a string representing the set of values in VALUES. VALUES is a list of strings.""" + # values = [hex(int(value, 16)) if '0x' in value and '-' not in value else value for value in values] return ", ".join(values) @staticmethod @@ -162,6 +181,72 @@ def fieldtype(typ): return upcased +class CoreConfig: + def __init__( + self, + isa, + marchid, + misa_we, + misa_we_enable, + misaligned, + mmu_mode, + mvendorid, + pmpaddr0, + pmpcfg0, + pmpregions, + priv, + status_fs_field_we, + status_fs_field_we_enable, + status_vs_field_we, + status_vs_field_we_enable, + ): + self.isa = isa + self.marchid = marchid + self.misa_we = misa_we + self.misa_we_enable = misa_we_enable + self.misaligned = misaligned + self.mmu_mode = mmu_mode + self.mvendorid = mvendorid + self.pmpaddr0 = pmpaddr0 + self.pmpcfg0 = pmpcfg0 + self.pmpregions = pmpregions + self.priv = priv + self.status_fs_field_we = status_fs_field_we + self.status_fs_field_we_enable = status_fs_field_we_enable + self.status_vs_field_we = status_vs_field_we + self.status_vs_field_we_enable = status_vs_field_we_enable + + +class Spike: + def __init__( + self, + bootrom, + bootrom_base, + bootrom_size, + dram, + dram_base, + dram_size, + generic_core_config, + max_steps, + max_steps_enabled, + isa, + priv, + core_configs, + ): + self.bootrom = bootrom + self.bootrom_base = bootrom_base + self.bootrom_size = bootrom_size + self.dram = dram + self.dram_base = dram_base + self.dram_size = dram_size + self.generic_core_config = generic_core_config + self.max_steps = max_steps + self.max_steps_enabled = max_steps_enabled + self.isa = isa + self.priv = priv + self.core_configs = core_configs + + # --------------------------------------------------------------# class ISAdocumentClass: """ISA document class""" @@ -175,7 +260,7 @@ def addInstructionMapBlock(self, InstructionMap): class InstructionMapClass: - """ISA instruction map class""" + """ISA instruction map c.2n lass""" def __init__(self, name): self.name = name @@ -672,7 +757,7 @@ def returnMdRegDesc(self, name, address, resetValue, desc, access): class CsrParser: """parse CSR RISC-V config yaml file""" - def __init__(self, srcFile,customFile, target, modiFile=None): + def __init__(self, srcFile, customFile, target, modiFile=None): self.srcFile = srcFile self.customFile = customFile self.modiFile = modiFile @@ -772,16 +857,30 @@ def returnRegister( legal_value = matches.group(3) bitlegal = legal_value elif isinstance(legal_2, list): - pattern = r"\s*((?:0x)?[0-9A-Fa-f]+)\s*(.)\s*((?:0x)?[0-9A-Fa-f]+)\s*" - matches = re.search(pattern, legal_2[0]) - if matches: - legal_value = ( - Render.range( - matches.group(1), matches.group(3) - ) - if matches.group(2) == ":" - else Render.value_set(legal_2[0].split(",")) - ) + pattern = r"\s*((?:0x)?[0-9A-Fa-f]+)\s*(:|,?)\s*((?:0x)?[0-9A-Fa-f]+)?" + for value in legal_2: + value_list = value.split(",") + processed_values = [] + for val in value_list: + matches = re.search(pattern, val) + if matches: + first_value = matches.group(1) + separator = matches.group(2) + second_value = ( + matches.group(3) + if matches.group(3) + else first_value + ) + if separator == ":": + processed_value = Render.range( + first_value, second_value + ) + else: + processed_value = hex( + int(first_value) + ) + processed_values.append(processed_value) + legal_value = Render.value_set(processed_values) bitlegal = legal_value else: legal_value = hex(legal_2) @@ -791,9 +890,13 @@ def returnRegister( if match: match_field = re.search(Factorizer_pattern, str(item)) if match_field: + if match_field.group(0) not in {"0", "1", "2", "3"}: + field_number = int(match_field.group(0)) - 8 + else: + field_number = match_field.group(0) fieldName = re.sub( - match_field.group(1), - f"[i*4 + {match_field.group(1)}]", + Factorizer_pattern, + f"[i*4 +{field_number}]", item, ) else: @@ -910,18 +1013,32 @@ def returnRegister( legal_value = matches.group(3) bitlegal = legal_value elif isinstance(legal_2, list): - pattern = r"\s*((?:0x)?[0-9A-Fa-f]+)\s*(.)\s*((?:0x)?[0-9A-Fa-f]+)\s*" - matches = re.search(pattern, legal_2[0]) - if matches: - legal_value = ( - Render.range(matches.group(1), matches.group(3)) - if matches.group(2) == ":" - else Render.value_set(legal_2[0].split(",")) - ) + pattern = r"\s*((?:0x)?[0-9A-Fa-f]+)\s*(:|,?)\s*((?:0x)?[0-9A-Fa-f]+)?" + for value in legal_2: + value_list = value.split(",") + processed_values = [] + for val in value_list: + matches = re.search(pattern, val) + if matches: + first_value = matches.group(1) + separator = matches.group(2) + second_value = ( + matches.group(3) + if matches.group(3) + else first_value + ) + if separator == ":": + processed_value = Render.range( + first_value, second_value + ) + else: + processed_value = hex(int(first_value)) + processed_values.append(processed_value) + legal_value = Render.value_set(processed_values) bitlegal = legal_value else: - bitmask = 0 - bitlegal = "0x" + hex(legal_2)[2:].zfill(int(size / 4)) + legal_value = hex(legal_2) + bitlegal = legal_value fieldDesc = regDesc fieldreset = "0x" + hex(int(resetValue, 16))[2:].zfill(int(size / 4)) if bitlsb is None: @@ -950,9 +1067,12 @@ def returnRegister( def returnDocument(self): with open(self.srcFile, "r", encoding="utf-8") as f: data = yaml.safe_load(f) - data = csr_formatter(self.srcFile,self.customFile, self.modiFile) - Registers = factorizer(data) docName = data["hart0"] + size = int( + data["hart0"].get("supported_xlen", "")[0] + ) # depends on architecture + data = csr_formatter(self.srcFile, self.customFile, self.modiFile) + Registers = factorizer(data) d = DocumentClass(docName) m = MemoryMapClass(docName) a = AddressBlockClass("csr") @@ -966,7 +1086,7 @@ def returnDocument(self): else hex(RegElement.get("address", None)) ) reset = hex(RegElement.get("reset-val", "")) - size = int(data["hart0"].get("supported_xlen", "")[0]) + access = RegElement.get("priv_mode", "") if Registers.get(register, {}).get("description", "") is not None: desc = Registers.get(register, {}).get("description", "") @@ -1082,6 +1202,96 @@ def returnRegister(self, key, Extension_Name, Descr, instructions_data): return Inst +class SpikeParser: + """A class to parse data related to Spike.""" + + def __init__(self, srcFile, target): + self.srcFile = srcFile + self.target = target + + def returnDocument(self): + with open(self.srcFile, "r", encoding="utf-8") as f: + data = yaml.safe_load(f) + core_configs = [] + pattern = r"pmpaddr(\d+)" + index = 0 + bitWidth = 32 + isa = "" + for entry in data["hart_ids"]: + M = ( + "M" + if data[f"hart{entry}"] + .get("mstatus", {}) + .get("rv32", "") + .get("accessible", []) + else "" + ) + S = ( + "S" + if data[f"hart{entry}"] + .get("sstatus", {}) + .get("rv32", "") + .get("accessible", []) + else "" + ) + U = ( + "U" + if data[f"hart{entry}"] + .get("ustatus", {}) + .get("rv32", "") + .get("accessible", []) + else "" + ) + for k in data[f"hart{entry}"].keys(): + match = re.search(pattern, str(k)) + if match: + index += int(match.group(1)) + isa = data[f"hart{entry}"]["ISA"].lower() + core_config = CoreConfig( + isa=data[f"hart{entry}"]["ISA"].lower(), + marchid=data[f"hart{entry}"].get("marchid", {}).get("reset-val", ""), + misa_we=False, + misa_we_enable=True, + misaligned=data[f"hart{entry}"].get("hw_data_misaligned_support", ""), + mmu_mode=( + "bare" + if not ( + (int(data[f"hart{entry}"].get("satp", {}).get("reset-val", ""))) + >> 31 + ) + else "sv32" + ), + mvendorid=data[f"hart{entry}"] + .get("mvendorid", {}) + .get("reset-val", ""), + pmpaddr0=data[f"hart{entry}"].get("pmpaddr0", {}).get("reset-val", ""), + pmpcfg0=data[f"hart{entry}"].get("pmpcfg0", {}).get("reset-val", ""), + pmpregions=index, + priv=f"{M}{S}{U}".format(M, S, U), + status_fs_field_we=False, + status_fs_field_we_enable=False, + status_vs_field_we=False, + status_vs_field_we_enable=False, + ) + core_configs.append(core_config) + S = Spike( + bootrom=True, + bootrom_base=0x10000, + bootrom_size=0x1000, + dram=True, + dram_base=0x80000000, + dram_size=0x40000000, + generic_core_config=False, + max_steps=200000, + max_steps_enabled=False, + isa=isa, + priv=f"{M}{S}{U}".format(M, S, U), + core_configs=core_configs, + ) + + return S + + class IsaGenerator: """generate isa folder with isa docs""" @@ -1121,7 +1331,6 @@ def __init__(self, target): def write(self, file_name, string): path = f"./{self.target}/csr/" - print(path) if not os.path.exists(path): os.makedirs(path) _dest = os.path.join(path, file_name) @@ -1141,3 +1350,28 @@ def generateCSR(self, generatorClass, document): s = block.returnAsString() file_name = blockName + block.suffix self.write(file_name, s) + + +class SpikeGenerator: + """Generate spike folder with spike docs""" + + def __init__(self, target, temp, modiFile=None): + self.target = target + self.temp = temp + self.modiFile = modiFile + + def write(self, file_name, string): + path = f"./{self.target}/spike/" + if not os.path.exists(path): + os.makedirs(path) + _dest = os.path.join(path, file_name) + print("writing file " + _dest) + with open(_dest, "w", encoding="utf-8") as f: + yaml.dump(string, f, default_flow_style=False, sort_keys=False) + + def generateSpike(self, document): + template = Template(filename=self.temp) + s = template.render(spike=document) + data = spike_formatter(yaml.load(s, Loader=BaseLoader), self.modiFile) + file_name = "spike.yaml" + self.write(file_name, data) diff --git a/config/gen_from_riscv_config/updaters/cv32a65x/csr_updater.yaml b/config/gen_from_riscv_config/updaters/cv32a65x/csr_updater.yaml index 129ab53171..7070c4d87e 100644 --- a/config/gen_from_riscv_config/updaters/cv32a65x/csr_updater.yaml +++ b/config/gen_from_riscv_config/updaters/cv32a65x/csr_updater.yaml @@ -3,36 +3,1209 @@ # SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 # Author: Abdessamii Oukalrazqou -mip: - rv32: - meip: - type: - ro_variable: - - 0x0:0x1 - mtip: - type: - ro_variable: - - 0x0:0x1 -mie: - rv32: - meie: - type: - ro_variable: - - 0x0:0x1 - mtie: - type: - ro_variable: - - 0x0:0x1 -mstatus : - rv32 : - mie : - type : +mcause: + rv32: + accessible: true + interrupt: + implemented: true + description: Indicates whether the trap was due to an interrupt. + shadow: + shadow_type: rw + msb: 31 + lsb: 31 + type: wlrl: - 0x0:0x1 - mpie : - type: + exception_code: + implemented: true + description: Encodes the exception code. + shadow: + shadow_type: rw + msb: 30 + lsb: 0 + type: wlrl: - - 0x0:0x1 + - 0:8 , 11 + fields: + - exception_code + - interrupt +mip: + rv32: + accessible: true + usip: + implemented: false + description: User Software Interrupt Pending. + shadow: + shadow_type: rw + msb: 0 + lsb: 0 + ssip: + implemented: false + description: Supervisor Software Interrupt Pending. + shadow: + shadow_type: rw + msb: 1 + lsb: 1 + msip: + implemented: false + description: Machine Software Interrupt Pending. + shadow: + shadow_type: rw + msb: 3 + lsb: 3 + utip: + implemented: false + description: User Timer Interrupt Pending. + shadow: + shadow_type: rw + msb: 4 + lsb: 4 + stip: + implemented: false + description: Supervisor Timer Interrupt Pending. + shadow: + shadow_type: rw + msb: 5 + lsb: 5 + mtip: + implemented: true + description: Machine Timer Interrupt Pending. + shadow: + shadow_type: rw + msb: 7 + lsb: 7 + type: + ro_variable: [0:1] + ueip: + implemented: false + description: User External Interrupt Pending. + shadow: + shadow_type: rw + msb: 8 + lsb: 8 + seip: + implemented: false + description: Supervisor External Interrupt Pending. + shadow: + shadow_type: rw + msb: 9 + lsb: 9 + meip: + implemented: true + description: Machine External Interrupt Pending. + shadow: + shadow_type: rw + msb: 11 + lsb: 11 + type: + ro_variable: [0:1] + fields: + - usip + - ssip + - vssip + - msip + - utip + - stip + - vstip + - mtip + - ueip + - seip + - vseip + - meip + - sgeip + - + - + - 13 + - 31 + vssip: + implemented: false + description: VS-level Software Interrupt Pending. + shadow: + shadow_type: rw + msb: 2 + lsb: 2 + vstip: + implemented: false + description: VS-level Timer Interrupt Pending. + shadow: + shadow_type: rw + msb: 6 + lsb: 6 + vseip: + implemented: false + description: VS-level External Interrupt Pending. + shadow: + shadow_type: rw + msb: 10 + lsb: 10 + sgeip: + implemented: false + description: HS-level External Interrupt Pending. + shadow: + shadow_type: rw + msb: 12 + lsb: 12 +pmpcfg2: + rv32: + accessible: true + pmp8cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp9cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp10cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp11cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp8cfg + - pmp9cfg + - pmp10cfg + - pmp11cfg +pmpcfg3: + rv32: + accessible: true + pmp12cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp13cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp14cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp15cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp12cfg + - pmp13cfg + - pmp14cfg + - pmp15cfg + +pmpcfg5: + rv32: + accessible: true + pmp20cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp21cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp22cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp23cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp20cfg + - pmp21cfg + - pmp22cfg + - pmp23cfg + +pmpcfg6: + rv32: + accessible: true + pmp24cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp25cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp26cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp27cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp24cfg + - pmp25cfg + - pmp26cfg + - pmp27cfg + +pmpcfg7: + rv32: + accessible: true + pmp28cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp29cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp30cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp31cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp28cfg + - pmp29cfg + - pmp30cfg + - pmp31cfg +pmpcfg8: + rv32: + accessible: true + pmp32cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp33cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp34cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp35cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp32cfg + - pmp33cfg + - pmp34cfg + - pmp35cfg +pmpcfg9: + rv32: + accessible: true + pmp36cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp37cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp38cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp39cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp36cfg + - pmp37cfg + - pmp38cfg + - pmp39cfg +pmpcfg10: + rv32: + accessible: true + pmp40cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp41cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp42cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp43cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp40cfg + - pmp41cfg + - pmp42cfg + - pmp43cfg +pmpcfg11: + rv32: + accessible: true + pmp44cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp45cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp46cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp47cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp44cfg + - pmp45cfg + - pmp46cfg + - pmp47cfg +pmpcfg12: + rv32: + accessible: true + pmp48cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp49cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp50cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp51cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp48cfg + - pmp49cfg + - pmp50cfg + - pmp51cfg +pmpcfg13: + rv32: + accessible: true + pmp52cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp53cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp54cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp55cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp52cfg + - pmp53cfg + - pmp54cfg + - pmp55cfg +pmpcfg14: + rv32: + accessible: true + pmp56cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp57cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp58cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp59cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp56cfg + - pmp57cfg + - pmp58cfg + - pmp59cfg +pmpcfg15: + rv32: + accessible: true + pmp60cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp61cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp62cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp63cfg: + implemented: true + type: + ro_constant : 0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp60cfg + - pmp61cfg + - pmp62cfg + - pmp63cfg + +#Adjust PMPADDR NUMBER FROM 15 TO 64 +pmpaddr16: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr17: + rv32: + accessible: true + type: + ro_constant: 0 +pmpaddr18: + rv32: + accessible: true + type: + ro_constant: 0 + +pmpaddr19: + rv32: + accessible: true + type: + ro_constant: 0 + +pmpaddr20: + rv32: + accessible: true + type: + ro_constant: 0 + +pmpaddr21: + rv32: + accessible: true + type: + + ro_constant: 0 + +pmpaddr22: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr23: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr24: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr25: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr26: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + + +pmpaddr27: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr28: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr29: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr30: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + + + +pmpaddr31: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr32: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr33: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr34: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr35: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + rv64: + accessible: false + reset-val: 0 + description: Physical memory protection address register + address: 0x3D3 + priv_mode: M +pmpaddr36: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr37: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr38: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr39: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr40: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr41: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr42: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr43: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr44: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr45: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr46: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr47: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr48: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr49: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 + +pmpaddr50: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr51: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr52: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr53: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr54: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr55: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr56: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr57: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr58: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr59: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr60: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr61: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr62: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 +pmpaddr63: + rv32: + accessible: true + type: + ro_constant: 0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 # Exclude mode exclude : key : priv_mode @@ -40,3 +1213,5 @@ exclude : exclude : key : priv_mode cond : U + + From 95049c4a3d3394da47f1fd8bc7fa64ea5ae33b77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:23:52 +0200 Subject: [PATCH 016/183] Bump verif/core-v-verif from `66cd091` to `20c2d30` (#2367) --- verif/core-v-verif | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verif/core-v-verif b/verif/core-v-verif index 66cd091b84..20c2d30a33 160000 --- a/verif/core-v-verif +++ b/verif/core-v-verif @@ -1 +1 @@ -Subproject commit 66cd091b84489d855dc0542b0d7f8337e82e2ef3 +Subproject commit 20c2d30a333afa8ee54b51b0d9c13785ec6f51e1 From 8d413b7c549f66a002d507243f276248b6aa4ec9 Mon Sep 17 00:00:00 2001 From: JeanRochCoulon Date: Mon, 22 Jul 2024 13:15:06 +0200 Subject: [PATCH 017/183] doc PMA: cv32a65x is always idempotent and without caches (#2377) --- docs/04_cv32a65x/riscv/priv-isa-cv32a65x.html | 69 +++---------------- .../riscv/priv-isa-cv64a6_mmu.html | 69 +++---------------- docs/riscv-isa/src/machine.adoc | 45 +++++------- 3 files changed, 34 insertions(+), 149 deletions(-) diff --git a/docs/04_cv32a65x/riscv/priv-isa-cv32a65x.html b/docs/04_cv32a65x/riscv/priv-isa-cv32a65x.html index 13d9d4fc3a..e7861f8092 100644 --- a/docs/04_cv32a65x/riscv/priv-isa-cv32a65x.html +++ b/docs/04_cv32a65x/riscv/priv-isa-cv32a65x.html @@ -4256,34 +4256,13 @@

3.6. Physical Memory Attributes

systems implement and check PMAs.

-

[CV32A65X] PMAs are inherent properties of the underlying hardware. The PMAs of -some memory regions are fixed at chip design time.

-
-
-

[CV32A65X] Some PMAs are dynamically -checked in hardware later in the execution pipeline after the physical -address is known, as some operations will not be supported at all -physical memory addresses, and some operations require knowing the -setting of a PMA attribute.

-
-
-

[CV32A65X] For RISC-V, we separate out specification and checking of PMAs into a -separate hardware structure, the PMA checker. In CV32A65X, the -attributes are known at system design time for each physical address -region, and are hardwired into the PMA checker. -PMAs are checked for any access to physical memory, including accesses -that have undergone virtual to physical memory translation. To aid in -system debugging, we strongly recommend that, where possible, RISC-V -processors precisely trap physical memory accesses that fail PMA checks. -Precisely trapped PMA violations manifest as instruction, load, or store -access-fault exceptions, distinct from virtual-memory page-fault -exceptions. Precise PMA traps might not always be possible, for example, -when probing a legacy bus architecture that uses access failures as part -of the discovery mechanism. In this case, error responses from -peripheral devices will be reported as imprecise bus-error interrupts.

-
-
-

[CV32A65X] PMAs are not readable by software.

+

[CV32A65X] PMA is not implemented by CV32A65X but information +is sent outside the processor to be able to check PMA outside processor. +These checkers are based on the following information contained in the +memory accesses requested by the processor. +- The information which indicates whether memory access is read, write or +execution, +- The access length information to check the subword and subblock access rights.

3.6.1. Main Memory versus I/O Regions

@@ -4367,44 +4346,14 @@

3.6.5. Memory-Ordering PMAs

3.6.6. Coherence and Cacheability PMAs

-

[CV32A65X] Write accesses are not cached. No cache-coherence scheme +

[CV32A65X] Caches are not implemented. No cache-coherence scheme is implemented.

-
-

If a PMA indicates non-cacheability, then accesses to that region must -be satisfied by the memory itself, not by any caches.

-

3.6.7. Idempotency PMAs

-

Idempotency PMAs describe whether reads and writes to an address region -are idempotent. Main memory regions are assumed to be idempotent. For -I/O regions, idempotency on reads and writes can be specified separately -(e.g., reads are idempotent but writes are not). If accesses are -non-idempotent, i.e., there is potentially a side effect on any read or -write access, then speculative or redundant accesses must be avoided.

-
-
-

For the purposes of defining the idempotency PMAs, changes in observed -memory ordering created by redundant accesses are not considered a side -effect.

-
-
-

For non-idempotent regions, implicit reads and writes must not be -performed early or speculatively, with the following exceptions. When a -non-speculative implicit read is performed, an implementation is -permitted to additionally read any of the bytes within a naturally -aligned power-of-2 region containing the address of the non-speculative -implicit read. Furthermore, when a non-speculative instruction fetch is -performed, an implementation is permitted to additionally read any of -the bytes within the next naturally aligned power-of-2 region of the -same size (with the address of the region taken modulo -2XLEN. The results of these additional reads -may be used to satisfy subsequent early or speculative implicit reads. -The size of these naturally aligned power-of-2 regions is -implementation-defined, but, for systems with page-based virtual memory, -must not exceed the smallest supported page size.

+

[CV32A65X] All memory accesses are idempotent.

diff --git a/docs/06_cv64a6_mmu/riscv/priv-isa-cv64a6_mmu.html b/docs/06_cv64a6_mmu/riscv/priv-isa-cv64a6_mmu.html index ee255cc89d..b6d4553df3 100644 --- a/docs/06_cv64a6_mmu/riscv/priv-isa-cv64a6_mmu.html +++ b/docs/06_cv64a6_mmu/riscv/priv-isa-cv64a6_mmu.html @@ -4498,34 +4498,13 @@

3.6. Physical Memory Attributes

systems implement and check PMAs.

-

[CV64A6_MMU] PMAs are inherent properties of the underlying hardware. The PMAs of -some memory regions are fixed at chip design time.

-
-
-

[CV64A6_MMU] Some PMAs are dynamically -checked in hardware later in the execution pipeline after the physical -address is known, as some operations will not be supported at all -physical memory addresses, and some operations require knowing the -setting of a PMA attribute.

-
-
-

[CV64A6_MMU] For RISC-V, we separate out specification and checking of PMAs into a -separate hardware structure, the PMA checker. In CV64A6_MMU, the -attributes are known at system design time for each physical address -region, and are hardwired into the PMA checker. -PMAs are checked for any access to physical memory, including accesses -that have undergone virtual to physical memory translation. To aid in -system debugging, we strongly recommend that, where possible, RISC-V -processors precisely trap physical memory accesses that fail PMA checks. -Precisely trapped PMA violations manifest as instruction, load, or store -access-fault exceptions, distinct from virtual-memory page-fault -exceptions. Precise PMA traps might not always be possible, for example, -when probing a legacy bus architecture that uses access failures as part -of the discovery mechanism. In this case, error responses from -peripheral devices will be reported as imprecise bus-error interrupts.

-
-
-

[CV64A6_MMU] PMAs are not readable by software.

+

[CV64A6_MMU] PMA is not implemented by CV64A6_MMU but information +is sent outside the processor to be able to check PMA outside processor. +These checkers are based on the following information contained in the +memory accesses requested by the processor. +- The information which indicates whether memory access is read, write or +execution, +- The access length information to check the subword and subblock access rights.

3.6.1. Main Memory versus I/O Regions

@@ -4609,44 +4588,14 @@

3.6.5. Memory-Ordering PMAs

3.6.6. Coherence and Cacheability PMAs

-

[CV64A6_MMU] Write accesses are not cached. No cache-coherence scheme +

[CV64A6_MMU] Caches are not implemented. No cache-coherence scheme is implemented.

-
-

If a PMA indicates non-cacheability, then accesses to that region must -be satisfied by the memory itself, not by any caches.

-

3.6.7. Idempotency PMAs

-

Idempotency PMAs describe whether reads and writes to an address region -are idempotent. Main memory regions are assumed to be idempotent. For -I/O regions, idempotency on reads and writes can be specified separately -(e.g., reads are idempotent but writes are not). If accesses are -non-idempotent, i.e., there is potentially a side effect on any read or -write access, then speculative or redundant accesses must be avoided.

-
-
-

For the purposes of defining the idempotency PMAs, changes in observed -memory ordering created by redundant accesses are not considered a side -effect.

-
-
-

For non-idempotent regions, implicit reads and writes must not be -performed early or speculatively, with the following exceptions. When a -non-speculative implicit read is performed, an implementation is -permitted to additionally read any of the bytes within a naturally -aligned power-of-2 region containing the address of the non-speculative -implicit read. Furthermore, when a non-speculative instruction fetch is -performed, an implementation is permitted to additionally read any of -the bytes within the next naturally aligned power-of-2 region of the -same size (with the address of the region taken modulo -2XLEN. The results of these additional reads -may be used to satisfy subsequent early or speculative implicit reads. -The size of these naturally aligned power-of-2 regions is -implementation-defined, but, for systems with page-based virtual memory, -must not exceed the smallest supported page size.

+

[CV64A6_MMU] All memory accesses are idempotent.

diff --git a/docs/riscv-isa/src/machine.adoc b/docs/riscv-isa/src/machine.adoc index 41f8e1468a..efd4489898 100644 --- a/docs/riscv-isa/src/machine.adoc +++ b/docs/riscv-isa/src/machine.adoc @@ -3621,31 +3621,13 @@ endif::[] ifdef::archi-CVA6[] -[{ohg-config}] PMAs are inherent properties of the underlying hardware. The PMAs of -some memory regions are fixed at chip design time. - -[{ohg-config}] Some PMAs are dynamically -checked in hardware later in the execution pipeline after the physical -address is known, as some operations will not be supported at all -physical memory addresses, and some operations require knowing the -setting of a PMA attribute. - -[{ohg-config}] For RISC-V, we separate out specification and checking of PMAs into a -separate hardware structure, the _PMA checker_. In {ohg-config}, the -attributes are known at system design time for each physical address -region, and are hardwired into the PMA checker. -PMAs are checked for any access to physical memory, including accesses -that have undergone virtual to physical memory translation. To aid in -system debugging, we strongly recommend that, where possible, RISC-V -processors precisely trap physical memory accesses that fail PMA checks. -Precisely trapped PMA violations manifest as instruction, load, or store -access-fault exceptions, distinct from virtual-memory page-fault -exceptions. Precise PMA traps might not always be possible, for example, -when probing a legacy bus architecture that uses access failures as part -of the discovery mechanism. In this case, error responses from -peripheral devices will be reported as imprecise bus-error interrupts. - -[{ohg-config}] PMAs are not readable by software. +[{ohg-config}] PMA is not implemented by {ohg-config} but information +is sent outside the processor to be able to check PMA outside processor. +These checkers are based on the following information contained in the +memory accesses requested by the processor. +- The information which indicates whether memory access is read, write or +execution, +- The access length information to check the subword and subblock access rights. endif::[] ==== Main Memory versus I/O Regions @@ -4003,15 +3985,13 @@ modes’ uncacheable accesses. endif::[] ifndef::archi-default,DCacheEn-true[] -[{ohg-config}] Write accesses are not cached. No cache-coherence scheme +[{ohg-config}] Caches are not implemented. No cache-coherence scheme is implemented. - -If a PMA indicates non-cacheability, then accesses to that region must -be satisfied by the memory itself, not by any caches. endif::[] ==== Idempotency PMAs +ifdef::archi-default[] Idempotency PMAs describe whether reads and writes to an address region are idempotent. Main memory regions are assumed to be idempotent. For I/O regions, idempotency on reads and writes can be specified separately @@ -4022,6 +4002,7 @@ write access, then speculative or redundant accesses must be avoided. For the purposes of defining the idempotency PMAs, changes in observed memory ordering created by redundant accesses are not considered a side effect. +endif::[] ifeval::[{note} == true] [NOTE] @@ -4039,6 +4020,7 @@ could cause unexpected side effects. ==== endif::[] +ifdef::archi-default[] For non-idempotent regions, implicit reads and writes must not be performed early or speculatively, with the following exceptions. When a non-speculative implicit read is performed, an implementation is @@ -4053,6 +4035,11 @@ may be used to satisfy subsequent early or speculative implicit reads. The size of these naturally aligned power-of-2 regions is implementation-defined, but, for systems with page-based virtual memory, must not exceed the smallest supported page size. +endif::[] + +ifdef::archi-CVA6[] +[{ohg-config}] All memory accesses are idempotent. +endif::[] [[pmp]] === Physical Memory Protection From 4a223bee46ae98b46cd3243da45316ebb3823716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me?= <124148386+cathales@users.noreply.github.com> Date: Mon, 22 Jul 2024 14:22:56 +0200 Subject: [PATCH 018/183] decorrelate instr and addr depths in IQ (#2375) --- .gitlab-ci/expected_synth.yml | 2 +- .gitlab-ci/scripts/report_benchmark.py | 2 +- core/frontend/instr_queue.sv | 38 ++++++++++---------------- core/include/ariane_pkg.sv | 1 + 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/.gitlab-ci/expected_synth.yml b/.gitlab-ci/expected_synth.yml index 431cbfff27..b0ef7a0b93 100644 --- a/.gitlab-ci/expected_synth.yml +++ b/.gitlab-ci/expected_synth.yml @@ -1,2 +1,2 @@ cv32a65x: - gates: 163431 + gates: 162469 diff --git a/.gitlab-ci/scripts/report_benchmark.py b/.gitlab-ci/scripts/report_benchmark.py index 04097ed341..55578af5ce 100644 --- a/.gitlab-ci/scripts/report_benchmark.py +++ b/.gitlab-ci/scripts/report_benchmark.py @@ -18,7 +18,7 @@ # Will fail if the number of cycles is different from this one valid_cycles = { 'dhrystone': 217900, - 'coremark': 549055, + 'coremark': 549045, } for arg in sys.argv[1:]: diff --git a/core/frontend/instr_queue.sv b/core/frontend/instr_queue.sv index 4827a9364f..56558f3668 100644 --- a/core/frontend/instr_queue.sv +++ b/core/frontend/instr_queue.sv @@ -103,23 +103,18 @@ module instr_queue logic [CVA6Cfg.LOG2_INSTR_PER_FETCH-1:0] branch_index; // instruction queues - logic [CVA6Cfg.INSTR_PER_FETCH-1:0][$clog2( -ariane_pkg::FETCH_FIFO_DEPTH -)-1:0] instr_queue_usage; instr_data_t [CVA6Cfg.INSTR_PER_FETCH-1:0] instr_data_in, instr_data_out; logic [CVA6Cfg.INSTR_PER_FETCH-1:0] push_instr, push_instr_fifo; - logic [ CVA6Cfg.INSTR_PER_FETCH-1:0] pop_instr; - logic [ CVA6Cfg.INSTR_PER_FETCH-1:0] instr_queue_full; - logic [ CVA6Cfg.INSTR_PER_FETCH-1:0] instr_queue_empty; - logic instr_overflow; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] pop_instr; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] instr_queue_full; + logic [CVA6Cfg.INSTR_PER_FETCH-1:0] instr_queue_empty; + logic instr_overflow; // address queue - logic [$clog2(ariane_pkg::FETCH_FIFO_DEPTH)-1:0] address_queue_usage; - logic [ CVA6Cfg.VLEN-1:0] address_out; - logic pop_address; - logic push_address; - logic full_address; - logic empty_address; - logic address_overflow; + logic [ CVA6Cfg.VLEN-1:0] address_out; + logic pop_address; + logic push_address; + logic full_address; + logic address_overflow; // input stream counter logic [CVA6Cfg.LOG2_INSTR_PER_FETCH-1:0] idx_is_d, idx_is_q; @@ -137,7 +132,6 @@ ariane_pkg::FETCH_FIFO_DEPTH logic [CVA6Cfg.INSTR_PER_FETCH*2-2:0] branch_mask_extended; logic [CVA6Cfg.INSTR_PER_FETCH-1:0] branch_mask; - logic branch_empty; logic [CVA6Cfg.INSTR_PER_FETCH-1:0] taken; // shift amount, e.g.: instructions we want to retire logic [CVA6Cfg.LOG2_INSTR_PER_FETCH:0] popcount; @@ -167,7 +161,7 @@ ariane_pkg::FETCH_FIFO_DEPTH ) i_lzc_branch_index ( .in_i (taken), // we want to count trailing zeros .cnt_o (branch_index), // first branch on branch_index - .empty_o(branch_empty) + .empty_o() ); @@ -237,7 +231,6 @@ ariane_pkg::FETCH_FIFO_DEPTH end else begin : gen_multiple_instr_per_fetch_without_C assign taken = '0; - assign branch_empty = '0; assign branch_index = '0; assign branch_mask_extended = '0; assign branch_mask = '0; @@ -478,7 +471,7 @@ ariane_pkg::FETCH_FIFO_DEPTH .testmode_i(1'b0), .full_o (instr_queue_full[i]), .empty_o (instr_queue_empty[i]), - .usage_o (instr_queue_usage[i]), + .usage_o (), .data_i (instr_data_in[i]), .push_i (push_instr_fifo[i]), .data_o (instr_data_out[i]), @@ -496,7 +489,7 @@ ariane_pkg::FETCH_FIFO_DEPTH end cva6_fifo_v3 #( - .DEPTH (ariane_pkg::FETCH_FIFO_DEPTH), // TODO(zarubaf): Fork out to separate param + .DEPTH (ariane_pkg::FETCH_ADDR_FIFO_DEPTH), .DATA_WIDTH(CVA6Cfg.VLEN), .FPGA_EN (CVA6Cfg.FpgaEn) ) i_fifo_address ( @@ -505,19 +498,16 @@ ariane_pkg::FETCH_FIFO_DEPTH .flush_i (flush_i), .testmode_i(1'b0), .full_o (full_address), - .empty_o (empty_address), - .usage_o (address_queue_usage), + .empty_o (), + .usage_o (), .data_i (predict_address_i), .push_i (push_address & ~full_address), .data_o (address_out), .pop_i (pop_address) ); - unread i_unread_address_fifo (.d_i(|{empty_address, address_queue_usage})); unread i_unread_branch_mask (.d_i(|branch_mask_extended)); - unread i_unread_lzc (.d_i(|{branch_empty})); unread i_unread_fifo_pos (.d_i(|fifo_pos_extended)); // we don't care about the lower signals - unread i_unread_instr_fifo (.d_i(|instr_queue_usage)); if (CVA6Cfg.RVC) begin : gen_pc_q_with_c always_ff @(posedge clk_i or negedge rst_ni) begin diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv index 1e2666f239..e729929d3e 100644 --- a/core/include/ariane_pkg.sv +++ b/core/include/ariane_pkg.sv @@ -167,6 +167,7 @@ package ariane_pkg; // leave as is (fails with >8 entries and wider fetch width) localparam int unsigned FETCH_FIFO_DEPTH = 4; + localparam int unsigned FETCH_ADDR_FIFO_DEPTH = 2; typedef enum logic [2:0] { NoCF, // No control flow prediction From 77c6cc328dfa5bfbefd7a3d764a49d19380f7243 Mon Sep 17 00:00:00 2001 From: valentinThomazic Date: Mon, 22 Jul 2024 15:29:25 +0000 Subject: [PATCH 019/183] fix CI regression testlists (#2378) --- .../testlist_riscv-compliance-cv32a65x.yaml | 24 +++++++++---------- ...-mmu-sv32-arch-test-cv32a6_imac_sv32.yaml} | 0 .../testlist_riscv-tests-cv32a65x-p.yaml | 14 +++++------ 3 files changed, 19 insertions(+), 19 deletions(-) rename verif/tests/{testlist_riscv-mmu-sv32-arch-test-cv32a60x.yaml => testlist_riscv-mmu-sv32-arch-test-cv32a6_imac_sv32.yaml} (100%) diff --git a/verif/tests/testlist_riscv-compliance-cv32a65x.yaml b/verif/tests/testlist_riscv-compliance-cv32a65x.yaml index 76292f112b..ee4a47217a 100644 --- a/verif/tests/testlist_riscv-compliance-cv32a65x.yaml +++ b/verif/tests/testlist_riscv-compliance-cv32a65x.yaml @@ -354,7 +354,7 @@ testlist: asm_tests: /riscv-compliance/riscv-test-suite/rv32mi/src/scall.S - test: rv32mi-ma_addr - iterations: 1 + iterations: 0 # spike needs to be configured with tval_en=1 <<: *common_test_config asm_tests: /riscv-compliance/riscv-test-suite/rv32mi/src/ma_addr.S @@ -409,7 +409,7 @@ testlist: asm_tests: /riscv-compliance/riscv-test-suite/rv32i/src/I-SB-01.S - test: rv32i-I-MISALIGN_LDST-01 - iterations: 1 + iterations: 0 # spike needs to be configured with tval_en=1 <<: *common_test_config asm_tests: /riscv-compliance/riscv-test-suite/rv32i/src/I-MISALIGN_LDST-01.S @@ -468,8 +468,8 @@ testlist: <<: *common_test_config asm_tests: /riscv-compliance/riscv-test-suite/rv32i/src/I-DELAY_SLOTS-01.S - - test: rv32i-I-EBREAK-01 # infinite loop with spike - iterations: 0 + - test: rv32i-I-EBREAK-01 + iterations: 0 # infinite loop with spike <<: *common_test_config asm_tests: /riscv-compliance/riscv-test-suite/rv32i/src/I-EBREAK-01.S @@ -488,8 +488,8 @@ testlist: <<: *common_test_config asm_tests: /riscv-compliance/riscv-test-suite/rv32i/src/I-OR-01.S - - test: rv32i-I-MISALIGN_JMP-01 # infinite loop with spike - iterations: 0 + - test: rv32i-I-MISALIGN_JMP-01 + iterations: 0 # infinite loop with spike <<: *common_test_config asm_tests: /riscv-compliance/riscv-test-suite/rv32i/src/I-MISALIGN_JMP-01.S @@ -624,32 +624,32 @@ testlist: asm_tests: /riscv-compliance/riscv-test-suite/rv32i/src/I-ADD-01.S - test: rv32si-sbreak - iterations: 1 + iterations: 0 # needs supervisor mode <<: *common_test_config asm_tests: /riscv-compliance/riscv-test-suite/rv32si/src/sbreak.S - test: rv32si-scall - iterations: 1 + iterations: 0 # needs supervisor mode <<: *common_test_config asm_tests: /riscv-compliance/riscv-test-suite/rv32si/src/scall.S - test: rv32si-ma_fetch - iterations: 1 + iterations: 0 # needs supervisor mode <<: *common_test_config asm_tests: /riscv-compliance/riscv-test-suite/rv32si/src/ma_fetch.S - test: rv32si-wfi - iterations: 1 + iterations: 0 # needs supervisor mode <<: *common_test_config asm_tests: /riscv-compliance/riscv-test-suite/rv32si/src/wfi.S - test: rv32si-dirty - iterations: 0 # exception on spike + iterations: 0 # exception on spike # needs supervisor mode <<: *common_test_config asm_tests: /riscv-compliance/riscv-test-suite/rv32si/src/dirty.S - test: rv32si-csr - iterations: 1 + iterations: 0 # needs supervisor mode <<: *common_test_config asm_tests: /riscv-compliance/riscv-test-suite/rv32si/src/csr.S diff --git a/verif/tests/testlist_riscv-mmu-sv32-arch-test-cv32a60x.yaml b/verif/tests/testlist_riscv-mmu-sv32-arch-test-cv32a6_imac_sv32.yaml similarity index 100% rename from verif/tests/testlist_riscv-mmu-sv32-arch-test-cv32a60x.yaml rename to verif/tests/testlist_riscv-mmu-sv32-arch-test-cv32a6_imac_sv32.yaml diff --git a/verif/tests/testlist_riscv-tests-cv32a65x-p.yaml b/verif/tests/testlist_riscv-tests-cv32a65x-p.yaml index bdafab5f59..15db4a51dc 100644 --- a/verif/tests/testlist_riscv-tests-cv32a65x-p.yaml +++ b/verif/tests/testlist_riscv-tests-cv32a65x-p.yaml @@ -255,7 +255,7 @@ testlist: asm_tests: /riscv-tests/isa/rv32mi/illegal.S - test: rv32mi-p-ma_addr - iterations: 1 + iterations: 0 # spike needs to be configured with tval_en = 1 <<: *common_test_config asm_tests: /riscv-tests/isa/rv32mi/ma_addr.S @@ -280,32 +280,32 @@ testlist: asm_tests: /riscv-tests/isa/rv32mi/shamt.S - test: rv32si-p-csr - iterations: 1 + iterations: 0 # needs supervisor mode <<: *common_test_config asm_tests: /riscv-tests/isa/rv32si/csr.S - test: rv32si-p-ma_fetch - iterations: 1 + iterations: 0 # needs supervisor mode <<: *common_test_config asm_tests: /riscv-tests/isa/rv32si/ma_fetch.S - test: rv32si-p-scall - iterations: 1 + iterations: 0 # needs supervisor mode <<: *common_test_config asm_tests: /riscv-tests/isa/rv32si/scall.S - test: rv32si-p-wfi - iterations: 1 + iterations: 0 # needs supervisor mode <<: *common_test_config asm_tests: /riscv-tests/isa/rv32si/wfi.S - test: rv32si-p-sbreak - iterations: 1 + iterations: 0 # needs supervisor mode <<: *common_test_config asm_tests: /riscv-tests/isa/rv32si/sbreak.S - test: rv32si-p-dirty - iterations: 0 # to be explained + iterations: 0 # needs supervisor mode <<: *common_test_config asm_tests: /riscv-tests/isa/rv32si/dirty.S From aa4ced4a8a953df679a445e6c872454271c3f86f Mon Sep 17 00:00:00 2001 From: AbdessamiiOukalrazqou <163409352+AbdessamiiOukalrazqou@users.noreply.github.com> Date: Mon, 22 Jul 2024 18:04:53 +0200 Subject: [PATCH 020/183] [gen_from_riscv_config] improve readme file and requirements file to support spike (#2380) --- config/gen_from_riscv_config/README.md | 76 +++++++++++++++++-- config/gen_from_riscv_config/requirements.txt | 3 +- .../scripts/libs/spike_updater.py | 74 ++++++++++++++++++ .../templates/spike.mako | 53 +++++++++++++ .../updaters/cv32a65x/spike_updater.yaml | 31 ++++++++ 5 files changed, 228 insertions(+), 9 deletions(-) create mode 100644 config/gen_from_riscv_config/scripts/libs/spike_updater.py create mode 100644 config/gen_from_riscv_config/templates/spike.mako create mode 100644 config/gen_from_riscv_config/updaters/cv32a65x/spike_updater.yaml diff --git a/config/gen_from_riscv_config/README.md b/config/gen_from_riscv_config/README.md index 4de91244fc..d13a2b6a57 100644 --- a/config/gen_from_riscv_config/README.md +++ b/config/gen_from_riscv_config/README.md @@ -34,11 +34,14 @@ pip3 install -r requirements.txt ```bash #Generate Restructred-text documentation for Control and Status Registers (CSR) -python3 .py -s <../riscv-config/Config_Name/generated/isa_gen>.yaml -c <../riscv-config/Config_Name/generated/custom_gen>.yaml-m .yaml -t < Config_Name> +python3 .py -s <../riscv-config/Config_Name/generated/isa_gen>.yaml -c <../riscv-config/Config_Name/generated/custom_gen>.yaml -m .yaml -t < Config_Name> #Generate Restructred-text documentation for ISA extensions python3 .py -s <../riscv-config/Config_Name/generated/isa_gen>.yaml -i .yaml -m .yaml -t < Config_Name> +#Generate the Yaml spike configuration file +python3 .py -s <../riscv-config/Config_Name/generated/isa_gen>.yaml -c <../riscv-config/Config_Name/generated/custom_gen>.yaml -i .mako -m .yaml -t < Config_Name> + ``` ## Usage with cv32a65x @@ -50,6 +53,9 @@ python3 scripts/riscv_config_gen.py -s ../riscv-config/cv32a65x/generated/isa_ge #Generate the Restructred-text documentation for ISA extensions python3 scripts/riscv_config_gen.py -s ../riscv-config/cv32a65x/generated/isa_gen.yaml -i templates/isa_template.yaml -m updaters/cv32a65x/isa_updater.yaml -t cv32a65x +#Generate the Yaml spike configuration file +python3 scripts/riscv_config_gen.py -s ../riscv-config/cv32a65x/generated/isa_gen.yaml -c ../riscv-config/cv32a65x/generated/custom_gen.yaml -i templates/spike.mako -m updaters/cv32a65x/spike_updater.yaml -t cv32a65x + ``` You could find your output files in this directory : @@ -59,12 +65,18 @@ if the output is ISA Documentation: if the output is CSR Documentation : `/csr/` + +if the output is Spike yaml : + `/spike/` + -for more details about How to write CSR or ISA Updater,see [UPDATERS](##Updaters) section +for more details about How to write CSR or ISA Updater,see [Updaters](#updaters) section + +for more details about How to write ISA template ,see [Annexes2](#annexes2) section -for more details about How to write ISA template ,see [Annexes2](##Annexes2) section +for more details about How to write spike template , see [mako](https://www.makotemplates.org/) section @@ -130,7 +142,7 @@ Example : ISA_Updater.yaml -If you want to modify any parameter for registers in RISC CONFIG YAML : - Format : +- Format : Register name : sub_feature : @@ -146,7 +158,7 @@ Example : ISA_Updater.yaml -If you want to exclude any registers base on condition : - Format : +- Format : exclude : @@ -155,7 +167,7 @@ Example : ISA_Updater.yaml sub_key : sub_value (if exist if not dont include it ) cond: value - Exemple : +- Exemple : exclude : @@ -168,12 +180,12 @@ Example : ISA_Updater.yaml Example : (PMPADDR , MHPMCOUNTER, ...) -Format : +- Format : Register Name : range : number -Exemple : +- Exemple : pmpaddr : @@ -184,6 +196,54 @@ CSR/ISA Updater read RISC-CONFIG.yaml and update the registers so if you want to +### SPIKE Updater + + +-If you want to modify any parameter Spike yaml: + +- Format : + + : + +- Example : + + + bootrom: false + +-If you want to to modify any parameter in core config in Spike yaml : + +- Format : + + cores: + + : +- Exemple : +- Exemple : + + cores: + isa: rv32imc_zba_zbb_zbs_zbc_zicsr_zifencei + boot_addr: 0x80000000 + marchid: 0x3 + misa_we: false + misa_we_enable: true + pmpaddr0: 0x0 + pmpcfg0: 0x0 + pmpregions: 0x40 + usable_pmpregions : 0x8 + priv: M + status_fs_field_we: false + status_fs_field_we_enable: false + status_vs_field_we: false + status_vs_field_we_enable: false + misa_we: false + mstatus_write_mask: 0x00000088 + mstatus_override_mask: 0x00001800 + mtval_write_mask: 0x00000000 + unified_traps: true + + +Spike Updater read spike.yaml and update the parameters so if you want to add parameter in spike.yaml you need to respect it architecture. + ## Annexes diff --git a/config/gen_from_riscv_config/requirements.txt b/config/gen_from_riscv_config/requirements.txt index f97f9c9699..50404b7d41 100644 --- a/config/gen_from_riscv_config/requirements.txt +++ b/config/gen_from_riscv_config/requirements.txt @@ -3,4 +3,5 @@ pyyaml mdutils restructuredtext-lint rstcloth -regex \ No newline at end of file +regex +Mako \ No newline at end of file diff --git a/config/gen_from_riscv_config/scripts/libs/spike_updater.py b/config/gen_from_riscv_config/scripts/libs/spike_updater.py new file mode 100644 index 0000000000..79a48b7e7a --- /dev/null +++ b/config/gen_from_riscv_config/scripts/libs/spike_updater.py @@ -0,0 +1,74 @@ +# Copyright 2024 Thales DIS France SAS +# +# 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. +# +# Original Author: Oukalrazqou Abdessamii + + +""" Module is used to update Spike based on yaml file called spike updater """ +import re +import yaml +from yaml import BaseLoader + + +def spike_recursive_update(original_dict, spike_update): + """ + Gets the data of the RISC-V Config Yaml file and + update the value of sub key in RISC-V Config Yaml file + (ex: priv , pmpaddr) + :param original_dict : parsed data of Spike Yaml file + spike_update : parsed data of Spike updaters + :return: data of Spike Yaml file updated + """ + for key, value in spike_update.items(): + if key in original_dict: + if isinstance(value, dict) and isinstance(original_dict[key], dict): + if key == "cores": + original_dict[key] = value + else: + csr_recursive_update(original_dict[key], value) + else: + original_dict[key] = value + + +def is_hex_string(s): + return bool(re.match(r"'?(0x[0-9a-fA-F]+)'?", s)) + + +def custom_convert(data): + if isinstance(data, dict): + return {k: custom_convert(v) for k, v in data.items()} + elif isinstance(data, list): + return [custom_convert(item) for item in data] + elif isinstance(data, str): + if data.lower() == "true": + return True + elif data.lower() == "false": + return False + elif data.isdigit(): + return int(data) + elif is_hex_string(data.strip()): + return int(data, 16) + return data + + +def spike_formatter(original_dict, modifile): + # Read original dictionary from YAML Source file + updated_values = {} + if modifile is not None: + with open(modifile, "r", encoding="utf-8") as file: + updated_values = yaml.load(file, Loader=BaseLoader) + # Update original_dict with values from updated_values recursively + spike_recursive_update(original_dict["spike_param_tree"], updated_values) + original_dict = custom_convert(original_dict) + return original_dict diff --git a/config/gen_from_riscv_config/templates/spike.mako b/config/gen_from_riscv_config/templates/spike.mako new file mode 100644 index 0000000000..e6aadd8cde --- /dev/null +++ b/config/gen_from_riscv_config/templates/spike.mako @@ -0,0 +1,53 @@ +# Copyright 2024 Thales DIS France SAS +# +# 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. +# +# Original Author: Oukalrazqou Abdessamii + +<%! +def format_hex(value): + return f"0x{value:X}" + +def format_bool(value): + return "true" if value else "false" +%> +spike_param_tree: + bootrom: ${format_bool(spike.bootrom)} + bootrom_base: ${format_hex(spike.bootrom_base)} + bootrom_size: ${format_hex(spike.bootrom_size)} + dram: ${format_bool(spike.dram)} + dram_base: ${format_hex(spike.dram_base)} + dram_size: ${format_hex(spike.dram_size)} + generic_core_config: ${format_bool(spike.generic_core_config)} + max_steps: ${spike.max_steps} + max_steps_enabled: ${format_bool(spike.max_steps_enabled)} + isa: ${spike.isa} + priv: ${spike.priv} + core_configs: +% for core in spike.core_configs: + - isa: ${core.isa} + marchid: ${format_hex(core.marchid)} + misa_we: ${format_bool(core.misa_we)} + misa_we_enable: ${format_bool(core.misa_we_enable)} + misaligned: ${format_bool(core.misaligned)} + mmu_mode: ${core.mmu_mode} + mvendorid: ${format_hex(core.mvendorid)} + pmpaddr0: ${format_hex(core.pmpaddr0)} + pmpcfg0: ${format_hex(core.pmpcfg0)} + pmpregions: ${format_hex(core.pmpregions)} + priv: ${core.priv} + status_fs_field_we: ${format_bool(core.status_fs_field_we)} + status_fs_field_we_enable: ${format_bool(core.status_fs_field_we_enable)} + status_vs_field_we: ${format_bool(core.status_vs_field_we)} + status_vs_field_we_enable: ${format_bool(core.status_vs_field_we_enable)} +% endfor diff --git a/config/gen_from_riscv_config/updaters/cv32a65x/spike_updater.yaml b/config/gen_from_riscv_config/updaters/cv32a65x/spike_updater.yaml new file mode 100644 index 0000000000..9f81849ccf --- /dev/null +++ b/config/gen_from_riscv_config/updaters/cv32a65x/spike_updater.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2024 OpenHW Group +# Copyright (c) 2024 Thales +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +# Author: Abdessamii Oukalrazqou + + + + + +cores: + - isa: rv32imc_zba_zbb_zbs_zbc_zicsr_zifencei + boot_addr: 0x80000000 + marchid: 0x3 + misa_we: false + misa_we_enable: true + pmpaddr0: 0x0 + pmpcfg0: 0x0 + pmpregions: 0x40 + usable_pmpregions : 0x8 + priv: M + status_fs_field_we: false + status_fs_field_we_enable: false + status_vs_field_we: false + status_vs_field_we_enable: false + priv: M + misa_we: false + mstatus_write_mask: 0x00000088 + mstatus_override_mask: 0x00001800 + mtval_write_mask: 0x00000000 + unified_traps: true + From 4b2b6e2983631902668598a791e77d794881641c Mon Sep 17 00:00:00 2001 From: AEzzejjari <110914586+AEzzejjari@users.noreply.github.com> Date: Mon, 22 Jul 2024 21:53:15 +0100 Subject: [PATCH 021/183] Enable HPDcache in the UVM config (#2379) --- verif/env/uvme/uvme_cva6_cfg.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verif/env/uvme/uvme_cva6_cfg.sv b/verif/env/uvme/uvme_cva6_cfg.sv index 3b12bad585..a43fc4f585 100644 --- a/verif/env/uvme/uvme_cva6_cfg.sv +++ b/verif/env/uvme/uvme_cva6_cfg.sv @@ -142,7 +142,7 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c; dm_halt_addr_valid == 1; dm_exception_addr_valid == 1; nmi_addr_valid == 1; - HPDCache_supported == (CVA6Cfg.DCacheType == 2); + HPDCache_supported == 1; DirectVecOnly == CVA6Cfg.DirectVecOnly; TvalEn == CVA6Cfg.TvalEn; From 2acf5ba407ef78721000b1a2f57ddfce3daf69c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me?= <124148386+cathales@users.noreply.github.com> Date: Tue, 23 Jul 2024 14:09:01 +0200 Subject: [PATCH 022/183] fix ex_stage synthesis (#2384) --- core/ex_stage.sv | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 5f11ebe3c0..69af0e763a 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -274,13 +274,19 @@ module ex_stage assign one_cycle_select = alu_valid_i | branch_valid_i | csr_valid_i; fu_data_t one_cycle_data; + logic [CVA6Cfg.VLEN-1:0] rs1_forwarding; + logic [CVA6Cfg.VLEN-1:0] rs2_forwarding; always_comb begin // data silence operation one_cycle_data = one_cycle_select[0] ? fu_data_i[0] : '0; + rs1_forwarding = rs1_forwarding_i[0]; + rs2_forwarding = rs2_forwarding_i[0]; if (CVA6Cfg.SuperscalarEn) begin if (one_cycle_select[1]) begin one_cycle_data = fu_data_i[1]; + rs1_forwarding = rs1_forwarding_i[1]; + rs2_forwarding = rs2_forwarding_i[1]; end end end @@ -671,10 +677,10 @@ module ex_stage gpaddr_to_be_flushed <= '0; // if the current instruction in EX_STAGE is a sfence.vma, in the next cycle no writes will happen end else if ((~(current_instruction_is_sfence_vma || current_instruction_is_hfence_vvma || current_instruction_is_hfence_gvma)) && (~((fu_data_i[0].operation == SFENCE_VMA || fu_data_i[0].operation == HFENCE_VVMA || fu_data_i[0].operation == HFENCE_GVMA ) && |csr_valid_i))) begin - vaddr_to_be_flushed <= rs1_forwarding_i; - gpaddr_to_be_flushed <= {2'b00, rs1_forwarding_i[CVA6Cfg.GPLEN-1:2]}; - asid_to_be_flushed <= rs2_forwarding_i[CVA6Cfg.ASID_WIDTH-1:0]; - vmid_to_be_flushed <= rs2_forwarding_i[CVA6Cfg.VMID_WIDTH-1:0]; + vaddr_to_be_flushed <= rs1_forwarding; + gpaddr_to_be_flushed <= {2'b00, rs1_forwarding[CVA6Cfg.GPLEN-1:2]}; + asid_to_be_flushed <= rs2_forwarding[CVA6Cfg.ASID_WIDTH-1:0]; + vmid_to_be_flushed <= rs2_forwarding[CVA6Cfg.VMID_WIDTH-1:0]; end end end else begin @@ -687,8 +693,8 @@ module ex_stage vaddr_to_be_flushed <= '0; // if the current instruction in EX_STAGE is a sfence.vma, in the next cycle no writes will happen end else if ((~current_instruction_is_sfence_vma) && (~((fu_data_i[0].operation == SFENCE_VMA) && |csr_valid_i))) begin - vaddr_to_be_flushed <= rs1_forwarding_i; - asid_to_be_flushed <= rs2_forwarding_i[CVA6Cfg.ASID_WIDTH-1:0]; + vaddr_to_be_flushed <= rs1_forwarding; + asid_to_be_flushed <= rs2_forwarding[CVA6Cfg.ASID_WIDTH-1:0]; end end end From d4809a7e2b9b29561ac5ca2f89ae369219ba8815 Mon Sep 17 00:00:00 2001 From: valentinThomazic Date: Tue, 23 Jul 2024 15:55:43 +0000 Subject: [PATCH 023/183] change required dhrystone cycles count value (#2386) --- .gitlab-ci/scripts/report_benchmark.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci/scripts/report_benchmark.py b/.gitlab-ci/scripts/report_benchmark.py index 55578af5ce..f7ffeb6155 100644 --- a/.gitlab-ci/scripts/report_benchmark.py +++ b/.gitlab-ci/scripts/report_benchmark.py @@ -17,7 +17,7 @@ # Keep it up-to-date with compiler version and core performance improvements # Will fail if the number of cycles is different from this one valid_cycles = { - 'dhrystone': 217900, + 'dhrystone': 220885, 'coremark': 549045, } From 04ebfbd713b4ff90b93538727efae66e2d2a4422 Mon Sep 17 00:00:00 2001 From: JeanRochCoulon Date: Tue, 23 Jul 2024 17:57:22 +0200 Subject: [PATCH 024/183] Disable PMA execute and nonidempotent features (#2385) --- core/include/config_pkg.sv | 12 ++++++++---- core/include/cv32a65x_config_pkg.sv | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index 927078d622..7e82dadaac 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -391,11 +391,15 @@ package config_pkg; function automatic logic is_inside_execute_regions(cva6_cfg_t Cfg, logic [63:0] address); // if we don't specify any region we assume everything is accessible logic [NrMaxRules-1:0] pass; - pass = '0; - for (int unsigned k = 0; k < Cfg.NrExecuteRegionRules; k++) begin - pass[k] = range_check(Cfg.ExecuteRegionAddrBase[k], Cfg.ExecuteRegionLength[k], address); + if (Cfg.NrExecuteRegionRules == 0) begin + pass = '0; + for (int unsigned k = 0; k < Cfg.NrExecuteRegionRules; k++) begin + pass[k] = range_check(Cfg.ExecuteRegionAddrBase[k], Cfg.ExecuteRegionLength[k], address); + end + return |pass; + end else begin + return 1; end - return |pass; endfunction : is_inside_execute_regions function automatic logic is_inside_cacheable_regions(cva6_cfg_t Cfg, logic [63:0] address); diff --git a/core/include/cv32a65x_config_pkg.sv b/core/include/cv32a65x_config_pkg.sv index c5056aa3a6..318b7a6607 100644 --- a/core/include/cv32a65x_config_pkg.sv +++ b/core/include/cv32a65x_config_pkg.sv @@ -65,10 +65,10 @@ package cva6_config_pkg; PMPAddrRstVal: {64{64'h0}}, PMPEntryReadOnly: 64'd0, NOCType: config_pkg::NOC_TYPE_AXI4_ATOP, - NrNonIdempotentRules: unsigned'(2), + NrNonIdempotentRules: unsigned'(0), NonIdempotentAddrBase: 1024'({64'b0, 64'b0}), NonIdempotentLength: 1024'({64'b0, 64'b0}), - NrExecuteRegionRules: unsigned'(3), + NrExecuteRegionRules: unsigned'(0), ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}), ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}), NrCachedRegionRules: unsigned'(1), From 118f353f546406f221e025baeb1f6b1a8c13ae4d Mon Sep 17 00:00:00 2001 From: Jalali <110232072+AyoubJalali@users.noreply.github.com> Date: Tue, 23 Jul 2024 17:40:49 +0000 Subject: [PATCH 025/183] Exclude page fault exceptions if mmu isn't supported (#2387) --- verif/env/uvme/cov/uvme_exception_covg.sv | 3 +++ verif/env/uvme/uvme_cva6_cfg.sv | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/verif/env/uvme/cov/uvme_exception_covg.sv b/verif/env/uvme/cov/uvme_exception_covg.sv index d56e868ae6..a91e730ef6 100644 --- a/verif/env/uvme/cov/uvme_exception_covg.sv +++ b/verif/env/uvme/cov/uvme_exception_covg.sv @@ -21,6 +21,7 @@ covergroup cg_exception( string name, bit pmp_supported, + bit MmuPresent, bit unaligned_access_supported, bit ext_c_supported, bit mode_u_supported, @@ -63,6 +64,7 @@ covergroup cg_exception( bins ENV_CALL_MMODE = {11} iff (instr.trap); + ignore_bins IGN_PAGE_FAULT_EXC = {12, 13, 15} iff (!MmuPresent); bins INSTR_PAGE_FAULT = {12} iff (instr.trap); bins LOAD_PAGE_FAULT = {13} iff (instr.trap); @@ -199,6 +201,7 @@ function void uvme_exception_cov_model_c::build_phase(uvm_phase phase); exception_cg = new("exception_cg", .pmp_supported(cfg.pmp_supported), + .MmuPresent(cfg.MmuPresent), .unaligned_access_supported(cfg.unaligned_access_supported), .ext_c_supported(cfg.ext_c_supported), .mode_u_supported(cfg.mode_u_supported), diff --git a/verif/env/uvme/uvme_cva6_cfg.sv b/verif/env/uvme/uvme_cva6_cfg.sv index a43fc4f585..95094c21e5 100644 --- a/verif/env/uvme/uvme_cva6_cfg.sv +++ b/verif/env/uvme/uvme_cva6_cfg.sv @@ -56,6 +56,9 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c; // Zihpm extension rand bit ext_zihpm_supported; + // MMU support + rand bit MmuPresent; + // Handle to RTL configuration rand cva6_cfg_t CVA6Cfg; @@ -70,6 +73,7 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c; `uvm_field_int ( HPDCache_supported , UVM_DEFAULT ) `uvm_field_int ( nr_pmp_entries , UVM_DEFAULT ) `uvm_field_int ( ext_zihpm_supported , UVM_DEFAULT ) + `uvm_field_int ( MmuPresent , UVM_DEFAULT ) `uvm_field_int ( sys_clk_period , UVM_DEFAULT + UVM_DEC) `uvm_field_object(clknrst_cfg, UVM_DEFAULT) @@ -146,6 +150,7 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c; DirectVecOnly == CVA6Cfg.DirectVecOnly; TvalEn == CVA6Cfg.TvalEn; + MmuPresent == CVA6Cfg.MmuPresent; } constraint ext_const { From 71812782239512a7e7fc71e91d3225c3cc7c3681 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 23:21:25 +0200 Subject: [PATCH 026/183] Bump verif/core-v-verif from `20c2d30` to `f42effb` (#2381) --- verif/core-v-verif | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verif/core-v-verif b/verif/core-v-verif index 20c2d30a33..f42effb5e6 160000 --- a/verif/core-v-verif +++ b/verif/core-v-verif @@ -1 +1 @@ -Subproject commit 20c2d30a333afa8ee54b51b0d9c13785ec6f51e1 +Subproject commit f42effb5e64971b268dcd6c1a8227aaeb6e4b94a From 14be0af7f017eef8fec615308c1d161584b45f07 Mon Sep 17 00:00:00 2001 From: Asmaa Kassimi <163407779+Asmaa-Kassimi@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:09:25 +0100 Subject: [PATCH 027/183] solve simple lint errors (#2388) --- core/csr_regfile.sv | 30 ++++++++++++++++++++++-------- spyglass/reference_summary.rpt | 19 ++++++++++--------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 8dbfe038f3..252c771f55 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -2415,8 +2415,10 @@ module csr_regfile epc_o = mepc_q[CVA6Cfg.VLEN-1:0]; // we are returning from supervisor or virtual supervisor mode, so take the sepc register - if (CVA6Cfg.RVS && sret) begin - epc_o = (CVA6Cfg.RVH && v_q) ? vsepc_q[CVA6Cfg.VLEN-1:0] : sepc_q[CVA6Cfg.VLEN-1:0]; + if (CVA6Cfg.RVS) begin + if (sret) begin + epc_o = (CVA6Cfg.RVH && v_q) ? vsepc_q[CVA6Cfg.VLEN-1:0] : sepc_q[CVA6Cfg.VLEN-1:0]; + end end // we are returning from debug mode, to take the dpc register if (CVA6Cfg.DebugEn) begin @@ -2457,10 +2459,14 @@ module csr_regfile assign frm_o = fcsr_q.frm; assign fprec_o = fcsr_q.fprec; // MMU outputs - assign satp_ppn_o = satp_q.ppn; + assign satp_ppn_o = CVA6Cfg.RVS ? satp_q.ppn : '0; assign vsatp_ppn_o = CVA6Cfg.RVH ? vsatp_q.ppn : '0; assign hgatp_ppn_o = CVA6Cfg.RVH ? hgatp_q.ppn : '0; - assign asid_o = satp_q.asid[CVA6Cfg.ASID_WIDTH-1:0]; + if (CVA6Cfg.RVS) begin + assign asid_o = satp_q.asid[CVA6Cfg.ASID_WIDTH-1:0]; + end else begin + assign asid_o = '0; + end assign vs_asid_o = CVA6Cfg.RVH ? vsatp_q.asid[CVA6Cfg.ASID_WIDTH-1:0] : '0; assign vmid_o = CVA6Cfg.RVH ? hgatp_q.vmid[CVA6Cfg.VMID_WIDTH-1:0] : '0; assign sum_o = mstatus_q.sum; @@ -2483,12 +2489,20 @@ module csr_regfile : 1'b0; assign en_g_translation_o = 1'b0; end - assign mxr_o = mstatus_q.mxr; + assign mxr_o = mstatus_q.mxr; assign vmxr_o = CVA6Cfg.RVH ? vsstatus_q.mxr : '0; - assign tvm_o = (CVA6Cfg.RVH && v_q) ? hstatus_q.vtvm : mstatus_q.tvm; - assign tw_o = mstatus_q.tw; + if (CVA6Cfg.RVH) begin + assign tvm_o = (v_q) ? hstatus_q.vtvm : mstatus_q.tvm; + end else begin + assign tvm_o = mstatus_q.tvm; + end + assign tw_o = mstatus_q.tw; assign vtw_o = CVA6Cfg.RVH ? hstatus_q.vtw : '0; - assign tsr_o = (CVA6Cfg.RVH && v_q) ? hstatus_q.vtsr : mstatus_q.tsr; + if (CVA6Cfg.RVH) begin + assign tsr_o = (v_q) ? hstatus_q.vtsr : mstatus_q.tsr; + end else begin + assign tsr_o = mstatus_q.tsr; + end assign halt_csr_o = wfi_q; `ifdef PITON_ARIANE assign icache_en_o = icache_q[0]; diff --git a/spyglass/reference_summary.rpt b/spyglass/reference_summary.rpt index 1287fb11db..c383d57efa 100644 --- a/spyglass/reference_summary.rpt +++ b/spyglass/reference_summary.rpt @@ -4,7 +4,8 @@ # This file has been generated by SpyGlass: # Report Name : summary # Report Created by: akassimi -# Report Created on: Tue Jul 9 11:39:13 2024 +# Report Created on: Tue Jul 16 15:53:46 2024 +# Working Directory: /home/akassimi/rhel8/cva6_synthesis/cva6/spyglass # SpyGlass Version : SpyGlass_vS-2021.09-SP2-3 # Policy Name : SpyGlass(SpyGlass_vS-2021.09-SP2-03) # clock-reset(SpyGlass_vS-2021.09-SP2-03) @@ -19,9 +20,9 @@ # starc2005(SpyGlass_vS-2021.09-SP2-03) # txv(SpyGlass_vS-2021.09-SP2-03) # -# Total Number of Generated Messages : 1490 +# Total Number of Generated Messages : 1501 # Number of Waived Messages : 2 -# Number of Reported Messages : 1488 +# Number of Reported Messages : 1499 # Number of Overlimit Messages : 0 # # @@ -56,7 +57,7 @@ INFO HdlLibDuCheck_03 1 Reports that 'hdllibdu' is not required +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Severity Rule Name Count Short Help =============================================================================== -WARNING SYNTH_12605 4 Used Priority/Unique Type case/if +WARNING SYNTH_12605 5 Used Priority/Unique Type case/if statement but all the conditions are not covered WARNING SYNTH_12608 1 The logic of the always block @@ -86,9 +87,9 @@ INFO ElabSummary 1 Generates Elaborated design units Severity Rule Name Count Short Help =============================================================================== ERROR InferLatch 2 Latch inferred -ERROR UndrivenInTerm-ML 4 Undriven but loaded input terminal of +ERROR UndrivenInTerm-ML 3 Undriven but loaded input terminal of an instance detected -ERROR W123 18 A signal or variable has been read but +ERROR W123 11 A signal or variable has been read but is not set ERROR W416 1 Width of return type and return value of a function should be same (Verilog) @@ -114,17 +115,17 @@ WARNING STARC05-2.2.3.3 14 Do not assign over the same signal in circuits WARNING W224 1 Multi-bit expression found when one-bit expression expected -WARNING W240 297 An input has been declared but is not +WARNING W240 323 An input has been declared but is not read WARNING W263 4 A case expression width does not match case select expression width WARNING W287b 32 Output port of an instance is not connected -WARNING W415a 536 Signal may be multiply assigned (beside +WARNING W415a 526 Signal may be multiply assigned (beside initialization) in the same scope. WARNING W480 3 Loop index is not of type integer WARNING W486 2 Shift overflow - some bits may be lost -WARNING W528 481 A signal or variable is set but never +WARNING W528 483 A signal or variable is set but never read INFO W240 1 An input has been declared but is not read From 4ff16f9da324f464958b870a772e8d8c6d04e3ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me?= <124148386+cathales@users.noreply.github.com> Date: Wed, 24 Jul 2024 23:54:26 +0200 Subject: [PATCH 028/183] set WtDcacheWbufDepth to 8 (#2390) --- .gitlab-ci/expected_synth.yml | 2 +- .gitlab-ci/scripts/report_benchmark.py | 2 +- core/include/cv32a65x_config_pkg.sv | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci/expected_synth.yml b/.gitlab-ci/expected_synth.yml index b0ef7a0b93..9a479c2e34 100644 --- a/.gitlab-ci/expected_synth.yml +++ b/.gitlab-ci/expected_synth.yml @@ -1,2 +1,2 @@ cv32a65x: - gates: 162469 + gates: 172629 diff --git a/.gitlab-ci/scripts/report_benchmark.py b/.gitlab-ci/scripts/report_benchmark.py index f7ffeb6155..7efef29051 100644 --- a/.gitlab-ci/scripts/report_benchmark.py +++ b/.gitlab-ci/scripts/report_benchmark.py @@ -18,7 +18,7 @@ # Will fail if the number of cycles is different from this one valid_cycles = { 'dhrystone': 220885, - 'coremark': 549045, + 'coremark': 534419, } for arg in sys.argv[1:]: diff --git a/core/include/cv32a65x_config_pkg.sv b/core/include/cv32a65x_config_pkg.sv index 318b7a6607..9047d2f134 100644 --- a/core/include/cv32a65x_config_pkg.sv +++ b/core/include/cv32a65x_config_pkg.sv @@ -85,7 +85,7 @@ package cva6_config_pkg; DcacheSetAssoc: unsigned'(2), DcacheLineWidth: unsigned'(128), DataUserEn: unsigned'(1), - WtDcacheWbufDepth: int'(2), + WtDcacheWbufDepth: int'(8), FetchUserWidth: unsigned'(32), FetchUserEn: unsigned'(1), InstrTlbEntries: int'(2), From 846e1a1269cf1e8ca3573de06b299a9e2e5b7b5d Mon Sep 17 00:00:00 2001 From: Zbigniew Chamski <107464696+zchamski@users.noreply.github.com> Date: Wed, 24 Jul 2024 23:56:04 +0200 Subject: [PATCH 029/183] [CI DEBUG] Track cause of failures in Spike version check. (#2360) --- .gitlab-ci.yml | 11 +++++++---- Makefile | 14 +++++++------- README.md | 10 ++++++---- verif/core-v-verif | 2 +- verif/regress/install-spike.sh | 2 +- verif/sim/Makefile | 6 ++++-- verif/sim/cva6.py | 32 ++++++++++++++++++++++++++++---- 7 files changed, 54 insertions(+), 23 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 74db1b28b6..c3878b8808 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -107,13 +107,17 @@ build_tools: - mkdir -p artifacts/tools/ - mv tools/spike artifacts/tools/ +.copy_spike_artifacts: ©_spike_artifacts + - mkdir -p tools + - mv artifacts/tools/spike tools + - /sbin/ldconfig -N tools/spike/lib + .fe_smoke_test: stage: light tests rules: *on_dev before_script: - git -C verif/core-v-verif fetch --unshallow - - mkdir -p tools - - mv artifacts/tools/spike tools + - !reference [.copy_spike_artifacts] - rm -rf artifacts/ - mkdir -p artifacts/{reports,logs} - python3 .gitlab-ci/scripts/report_fail.py @@ -471,8 +475,7 @@ simu-gate: TARGET: $DV_TARGET script: - git -C verif/core-v-verif fetch --unshallow - - mkdir -p tools - - mv artifacts/tools/spike tools + - !reference [.copy_spike_artifacts] - echo $PERIOD - source ./verif/sim/setup-env.sh - git clone ${SYNTH_SCRIPT} ${SYNTH_SCRIPT_PATH} diff --git a/Makefile b/Makefile index f191dff5d5..c565489ef4 100644 --- a/Makefile +++ b/Makefile @@ -334,13 +334,13 @@ vcs_build: $(dpi-library)/ariane_dpi.so vcs: vcs_build cd $(vcs-library) && \ ./simv +permissive $(if $(VERDI), -verdi -do $(root-dir)/init_testharness.do,) \ - +elf_file=$(elf_file) ++$(elf_file) $(if $(spike-tandem),-sv_lib $(SPIKE_INSTALL_DIR)/libriscv) \ + +elf_file=$(elf_file) ++$(elf_file) $(if $(spike-tandem), -sv_lib $(SPIKE_INSTALL_DIR)/libyaml-cpp) -sv_lib $(SPIKE_INSTALL_DIR)/libriscv \ -sv_lib ../work-dpi/ariane_dpi | tee vcs.log # Build the TB and module using QuestaSim build: $(library) $(library)/.build-srcs $(library)/.build-tb $(dpi-library)/ariane_dpi.so # Optimize top level - $(VOPT) -64 -work $(library) $(top_level) -o $(top_level)_optimized +acc -check_synthesis -dpilib $(SPIKE_INSTALL_DIR)/lib/libriscv -dpilib $(SPIKE_INSTALL_DIR)/lib/lifesvr $(vopt_flag) + $(VOPT) -64 -work $(library) $(top_level) -o $(top_level)_optimized +acc -check_synthesis -dpilib $(SPIKE_INSTALL_DIR)/lib/libriscv -dpilib $(SPIKE_INSTALL_DIR)/lib/libfesvr -dpilib $(SPIKE_INSTALL_DIR)/lib/libyaml-cpp $(vopt_flag) # src files $(library)/.build-srcs: $(library) @@ -368,13 +368,13 @@ $(dpi-library)/%.o: corev_apu/tb/dpi/%.cc $(dpi_hdr) $(dpi-library)/ariane_dpi.so: $(dpi) mkdir -p $(dpi-library) # Compile C-code and generate .so file - $(CXX) -shared -m64 -o $(dpi-library)/ariane_dpi.so $? -L$(RISCV)/lib -L$(SPIKE_INSTALL_DIR)/lib -Wl,-rpath,$(RISCV)/lib -Wl,-rpath,$(SPIKE_INSTALL_DIR)/lib -lfesvr -lriscv + $(CXX) -shared -m64 -o $(dpi-library)/ariane_dpi.so $? -L$(RISCV)/lib -L$(SPIKE_INSTALL_DIR)/lib -Wl,-rpath,$(RISCV)/lib -Wl,-rpath,$(SPIKE_INSTALL_DIR)/lib -lfesvr -lriscv -lyaml-cpp $(dpi-library)/xrun_ariane_dpi.so: $(dpi) # Make Dir work-dpi mkdir -p $(dpi-library) # Compile C-code and generate .so file - $(CXX) -shared -m64 -o $(dpi-library)/xrun_ariane_dpi.so $? -L$(RISCV)/lib -L$(SPIKE_INSTALL_DIR)/lib -Wl,-rpath,$(RISCV)/lib -Wl,-rpath,$(SPIKE_INSTALL_DIR)/lib -lfesvr -lriscv + $(CXX) -shared -m64 -o $(dpi-library)/xrun_ariane_dpi.so $? -L$(RISCV)/lib -L$(SPIKE_INSTALL_DIR)/lib -Wl,-rpath,$(RISCV)/lib -Wl,-rpath,$(SPIKE_INSTALL_DIR)/lib -lfesvr -lriscv -lyaml-cpp # single test runs on Questa can be started by calling make , e.g. make towers.riscv # the test names are defined in ci/riscv-asm-tests.list, and in ci/riscv-benchmarks.list @@ -386,8 +386,8 @@ generate-trace-vsim: sim: build $(VSIM) +permissive $(questa-flags) $(questa-cmd) -lib $(library) +MAX_CYCLES=$(max_cycles) +UVM_TESTNAME=$(test_case) \ - +BASEDIR=$(riscv-test-dir) $(uvm-flags) -sv_lib $(SPIKE_INSTALL_DIR)/lib/libriscv -sv_lib $(SPIKE_INSTALL_DIR)/lib/libfesvr \ - -sv_lib $(SPIKE_INSTALL_DIR)/lib/libdisasm \ + +BASEDIR=$(riscv-test-dir) $(uvm-flags) -sv_lib $(SPIKE_INSTALL_DIR)/lib/libyaml-cpp -sv_lib $(SPIKE_INSTALL_DIR)/lib/libriscv -sv_lib $(SPIKE_INSTALL_DIR)/lib/libfesvr \ + -sv_lib $(SPIKE_INSTALL_DIR)/lib/libdisasm \ ${top_level}_optimized +permissive-off +elf_file=$(elf_file) ++$(elf_file) ++$(target-options) $(riscv-asm-tests): build @@ -618,7 +618,7 @@ verilate_command := $(verilator) --no-timing verilator_config.vlt $(if $(DEBUG), --trace-structs,) \ $(if $(TRACE_COMPACT), --trace-fst $(VL_INC_DIR)/verilated_fst_c.cpp) \ $(if $(TRACE_FAST), --trace $(VL_INC_DIR)/verilated_vcd_c.cpp) \ - -LDFLAGS "-L$(RISCV)/lib -L$(SPIKE_INSTALL_DIR)/lib -Wl,-rpath,$(RISCV)/lib -Wl,-rpath,$(SPIKE_INSTALL_DIR)/lib -lfesvr -lriscv -ldisasm $(if $(PROFILE), -g -pg,) -lpthread $(if $(TRACE_COMPACT), -lz,)" \ + -LDFLAGS "-L$(RISCV)/lib -L$(SPIKE_INSTALL_DIR)/lib -Wl,-rpath,$(RISCV)/lib -Wl,-rpath,$(SPIKE_INSTALL_DIR)/lib -lfesvr -lriscv -ldisasm -lyaml-cpp $(if $(PROFILE), -g -pg,) -lpthread $(if $(TRACE_COMPACT), -lz,)" \ -CFLAGS "$(CFLAGS)$(if $(PROFILE), -g -pg,) -DVL_DEBUG -I$(SPIKE_INSTALL_DIR)" \ $(if $(SPIKE_TANDEM), +define+SPIKE_TANDEM, ) \ --cc --vpi \ diff --git a/README.md b/README.md index 20be84f1eb..397d9f9456 100644 --- a/README.md +++ b/README.md @@ -31,12 +31,14 @@ git submodule update --init --recursive :warning: It is **strongly recommended** to use the toolchain built with the provided scripts. -3. Set the RISCV environment variable. +3. Install `cmake`, version 3.14 or higher. + +4. Set the RISCV environment variable. ```sh export RISCV=/path/to/toolchain/installation/directory ``` -4. Install `help2man` and `device-tree-compiler` packages. +5. Install `help2man` and `device-tree-compiler` packages. For Debian-based Linux distributions, run : @@ -44,13 +46,13 @@ For Debian-based Linux distributions, run : sudo apt-get install help2man device-tree-compiler ``` -5. Install the riscv-dv requirements: +6. Install the riscv-dv requirements: ```sh pip3 install -r verif/sim/dv/requirements.txt ``` -6. Run these commands to install a custom Spike and Verilator (i.e. these versions must be used to simulate the CVA6) and [these](#running-regression-tests-simulations) tests suites. +7. Run these commands to install a custom Spike and Verilator (i.e. these versions must be used to simulate the CVA6) and [these](#running-regression-tests-simulations) tests suites. ```sh # DV_SIMULATORS is detailed in the next section export DV_SIMULATORS=veri-testharness,spike diff --git a/verif/core-v-verif b/verif/core-v-verif index f42effb5e6..1e7f049744 160000 --- a/verif/core-v-verif +++ b/verif/core-v-verif @@ -1 +1 @@ -Subproject commit f42effb5e64971b268dcd6c1a8227aaeb6e4b94a +Subproject commit 1e7f049744c2d839267b0e4dfe2bb1d377676987 diff --git a/verif/regress/install-spike.sh b/verif/regress/install-spike.sh index 0ace2559df..b05470878e 100755 --- a/verif/regress/install-spike.sh +++ b/verif/regress/install-spike.sh @@ -50,8 +50,8 @@ if ! [ -f "$SPIKE_INSTALL_DIR/bin/spike" ]; then fi # Build both shared and static versions of the yaml-cpp library in sequence # prior to building Spike. - make yaml-cpp make yaml-cpp-static + make yaml-cpp make -j${NUM_JOBS} echo "Installing Spike in '$SPIKE_INSTALL_DIR'..." make install diff --git a/verif/sim/Makefile b/verif/sim/Makefile index 6d8e2d1676..03fc9fb00e 100644 --- a/verif/sim/Makefile +++ b/verif/sim/Makefile @@ -201,12 +201,13 @@ ifneq ($(UVM_VERBOSITY),) COMMON_PLUS_ARGS += +UVM_VERBOSITY=$(UVM_VERBOSITY) endif +# Libraries that provide symbols for other libs must come first. COMMON_RUN_ARGS = \ $(COMMON_PLUS_ARGS) $(issrun_opts) \ -sv_lib $(SPIKE_INSTALL_DIR)/lib/libcustomext \ + -sv_lib $(SPIKE_INSTALL_DIR)/lib/libyaml-cpp \ -sv_lib $(SPIKE_INSTALL_DIR)/lib/libriscv \ -sv_lib $(SPIKE_INSTALL_DIR)/lib/libfesvr \ - -sv_lib $(SPIKE_INSTALL_DIR)/lib/libyaml-cpp \ -sv_lib $(SPIKE_INSTALL_DIR)/lib/libdisasm ALL_UVM_FLAGS = -lca -sverilog +incdir+$(VCS_HOME)/etc/uvm/src \ @@ -308,14 +309,15 @@ xrun_uvm_comp: $(cov-comp-opt) $(isscomp_opts)\ -top uvmt_cva6_tb +# Libraries that provide symbols for other libs must come first. xrun_uvm_run: @echo "[XRUN] Running" cd $(XRUN_WORK_DIR) && \ xrun \ $(XRUN_RUN) \ + +sv_lib=$(SPIKE_INSTALL_DIR)/lib/libyaml-cpp \ +sv_lib=$(SPIKE_INSTALL_DIR)/lib/libriscv \ +sv_lib=$(SPIKE_INSTALL_DIR)/lib/libfesvr \ - +sv_lib=$(SPIKE_INSTALL_DIR)/lib/libyaml-cpp \ +sv_lib=$(SPIKE_INSTALL_DIR)/lib/libdisasm \ ++$(elf) \ +elf_file=$(elf) \ diff --git a/verif/sim/cva6.py b/verif/sim/cva6.py index e8c1744541..f7a513ddd6 100644 --- a/verif/sim/cva6.py +++ b/verif/sim/cva6.py @@ -1103,15 +1103,39 @@ def check_spike_version(): # Get Spike User version get_env_var("SPIKE_PATH") user_spike_version = subprocess.run("$SPIKE_PATH/spike -v", capture_output=True, text=True, shell=True) - user_spike_version_string = user_spike_version.stderr.strip() + user_spike_stdout_string = user_spike_version.stdout.strip() + user_spike_stderr_string = user_spike_version.stderr.strip() if user_spike_version.returncode != 0: + # Re-run 'spike -v' and print contents of stdout and stderr. + logging.info("Spike version check ('$SPIKE_PATH/spike -v')") + logging.info(f"- stdout:\n\n{user_spike_stdout_string}\n") + logging.info(f"- stderr:\n\n{user_spike_stderr_string}") + # Run 'ldd' on Spike binary and print contents of stdout and stderr. + spike_ldd = subprocess.run( + "/bin/ldd $SPIKE_PATH/spike", capture_output=True, text=True, shell=True + ) + spike_ldd_stdout = spike_ldd.stdout.strip() + spike_ldd_stderr = spike_ldd.stderr.strip() + logging.info("Spike LDD check ('ldd $SPIKE_PATH/spike')") + logging.info(f"- stdout:\n\n{spike_ldd_stdout}\n") + logging.info(f"- stderr:\n\n{spike_ldd_stderr}") + # Run 'ls -l' on Spike lib directory and print contents of stdout and stderr. + spike_lib_ls = subprocess.run( + "ls -l $SPIKE_PATH/../lib", capture_output=True, text=True, shell=True + ) + spike_lib_stdout = spike_lib_ls.stdout.strip() + spike_lib_stderr = spike_lib_ls.stderr.strip() + logging.info("Stdout of Spike library check ('ls -l $SPIKE_PATH/../lib')") + logging.info(f"- stdout:\n\n{spike_lib_stdout}\n") + logging.info(f"- stderr:\n\n{spike_lib_stderr}") + incorrect_version_exit("Spike", "- unknown -", spike_version) - logging.info(f"Spike Version: {user_spike_version_string}") + logging.info(f"Spike Version: {user_spike_stderr_string}") - if user_spike_version_string != spike_version: - incorrect_version_exit("Spike", user_spike_version_string, spike_version) + if user_spike_stderr_string != spike_version: + incorrect_version_exit("Spike", user_spike_stderr_string, spike_version) def check_verilator_version(): From 4c48a6080449f72c4c085c6741d7447752203cb2 Mon Sep 17 00:00:00 2001 From: Asmaa Kassimi <163407779+Asmaa-Kassimi@users.noreply.github.com> Date: Thu, 25 Jul 2024 06:37:21 +0100 Subject: [PATCH 030/183] increase condition coverage in lsu, issue and commit stages (#2391) --- core/commit_stage.sv | 21 +++++++++++---------- core/issue_read_operands.sv | 13 ++++++++++--- core/load_store_unit.sv | 36 +++++++++++++++++++++--------------- 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/core/commit_stage.sv b/core/commit_stage.sv index 129422e62d..0403442119 100644 --- a/core/commit_stage.sv +++ b/core/commit_stage.sv @@ -314,7 +314,7 @@ module commit_stage && !halt_i && !(commit_instr_i[0].fu inside {CSR}) && !flush_dcache_i - && !instr_0_is_amo + && !(CVA6Cfg.RVA && instr_0_is_amo) && !single_step_i) begin // only if the first instruction didn't throw an exception and this instruction won't throw an exception // and the functional unit is of type ALU, LOAD, CTRL_FLOW, MULT, FPU or FPU_VEC @@ -334,15 +334,16 @@ module commit_stage // additionally check if we are retiring an FPU instruction because we need to make sure that we write all // exception flags - if (CVA6Cfg.FpPresent && commit_instr_i[1].fu inside {FPU, FPU_VEC}) begin - if (csr_write_fflags_o) - csr_wdata_o = { - {CVA6Cfg.XLEN - 5{1'b0}}, - (commit_instr_i[0].ex.cause[4:0] | commit_instr_i[1].ex.cause[4:0]) - }; - else csr_wdata_o = {{CVA6Cfg.XLEN - 5{1'b0}}, commit_instr_i[1].ex.cause[4:0]}; - - csr_write_fflags_o = 1'b1; + if (CVA6Cfg.FpPresent) begin + if (commit_instr_i[1].fu inside {FPU, FPU_VEC}) begin + if (csr_write_fflags_o) + csr_wdata_o = { + {CVA6Cfg.XLEN - 5{1'b0}}, + (commit_instr_i[0].ex.cause[4:0] | commit_instr_i[1].ex.cause[4:0]) + }; + else csr_wdata_o = {{CVA6Cfg.XLEN - 5{1'b0}}, commit_instr_i[1].ex.cause[4:0]}; + csr_write_fflags_o = 1'b1; + end end end end diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index 12cb04faa0..7a37030bf1 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -367,12 +367,19 @@ module issue_read_operands CTRL_FLOW: fu_busy[i] = fus_busy[i].ctrl_flow; CSR: fu_busy[i] = fus_busy[i].csr; MULT: fu_busy[i] = fus_busy[i].mult; - FPU: fu_busy[i] = fus_busy[i].fpu; - FPU_VEC: fu_busy[i] = fus_busy[i].fpu_vec; LOAD: fu_busy[i] = fus_busy[i].load; STORE: fu_busy[i] = fus_busy[i].store; CVXIF: fu_busy[i] = fus_busy[i].cvxif; - default: fu_busy[i] = 1'b0; + default: + if (CVA6Cfg.FpPresent) begin + unique case (issue_instr_i[i].fu) + FPU: fu_busy[i] = fus_busy[i].fpu; + FPU_VEC: fu_busy[i] = fus_busy[i].fpu_vec; + default: fu_busy[i] = 1'b0; + endcase + end else begin + fu_busy[i] = 1'b0; + end endcase end end diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 119bf1c020..514f61244c 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -541,17 +541,22 @@ module load_store_unit data_misaligned = 1'b0; if (lsu_ctrl.valid) begin - case (lsu_ctrl.operation) - // double word - LD, SD, FLD, FSD, - AMO_LRD, AMO_SCD, - AMO_SWAPD, AMO_ADDD, AMO_ANDD, AMO_ORD, - AMO_XORD, AMO_MAXD, AMO_MAXDU, AMO_MIND, - AMO_MINDU, HLV_D, HSV_D: begin - if (CVA6Cfg.IS_XLEN64 && lsu_ctrl.vaddr[2:0] != 3'b000) begin - data_misaligned = 1'b1; + if (CVA6Cfg.IS_XLEN64) begin + case (lsu_ctrl.operation) + // double word + LD, SD, FLD, FSD, + AMO_LRD, AMO_SCD, + AMO_SWAPD, AMO_ADDD, AMO_ANDD, AMO_ORD, + AMO_XORD, AMO_MAXD, AMO_MAXDU, AMO_MIND, + AMO_MINDU, HLV_D, HSV_D: begin + if (lsu_ctrl.vaddr[2:0] != 3'b000) begin + data_misaligned = 1'b1; + end end - end + default: ; + endcase + end + case (lsu_ctrl.operation) // word LW, LWU, SW, FLW, FSW, AMO_LRW, AMO_SCW, @@ -585,8 +590,8 @@ module load_store_unit misaligned_exception.tinst = lsu_ctrl.tinst; misaligned_exception.gva = ld_st_v_i; end - - end else if (lsu_ctrl.fu == STORE) begin + end + if (lsu_ctrl.fu == STORE) begin misaligned_exception.cause = riscv::ST_ADDR_MISALIGNED; misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) @@ -611,8 +616,8 @@ module load_store_unit misaligned_exception.tinst = lsu_ctrl.tinst; misaligned_exception.gva = ld_st_v_i; end - - end else if (lsu_ctrl.fu == STORE) begin + end + if (lsu_ctrl.fu == STORE) begin misaligned_exception.cause = riscv::STORE_PAGE_FAULT; misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) @@ -637,7 +642,8 @@ module load_store_unit misaligned_exception.tinst = lsu_ctrl.tinst; misaligned_exception.gva = ld_st_v_i; end - end else if (lsu_ctrl.fu == STORE) begin + end + if (lsu_ctrl.fu == STORE) begin misaligned_exception.cause = riscv::STORE_GUEST_PAGE_FAULT; misaligned_exception.valid = 1'b1; if (CVA6Cfg.TvalEn) From 335c91cc080c231deae79d07152541d9fb2d45ac Mon Sep 17 00:00:00 2001 From: CoralieAllioux <140795322+CoralieAllioux@users.noreply.github.com> Date: Thu, 25 Jul 2024 07:37:43 +0200 Subject: [PATCH 031/183] [Xcelium flow] Xrun compile fixes (#2389) --- common/local/util/instr_tracer.sv | 2 +- common/local/util/sram.sv | 2 +- core/cache_subsystem/cva6_hpdcache_wrapper.sv | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/local/util/instr_tracer.sv b/common/local/util/instr_tracer.sv index 934509b2e7..9083664069 100644 --- a/common/local/util/instr_tracer.sv +++ b/common/local/util/instr_tracer.sv @@ -20,7 +20,7 @@ module instr_tracer #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type bp_resolve_t = logic, - parameter type scoreboard_entry_t = logic, + parameter type scoreboard_entry_t = logic[303:0], // Fix for xcelium bug at runtime: does not have enough memory space reserved for scoreboard_entry parameter type interrupts_t = logic, parameter type exception_t = logic, parameter interrupts_t INTERRUPTS = '0 diff --git a/common/local/util/sram.sv b/common/local/util/sram.sv index f8dd934256..8c6c0d34d2 100644 --- a/common/local/util/sram.sv +++ b/common/local/util/sram.sv @@ -106,8 +106,8 @@ end // synthesis translate_off begin: i_tc_sram_wrapper_user begin: i_tc_sram - logic init_val; localparam type data_t = logic [63:0]; + data_t init_val [0:0]; data_t sram [NUM_WORDS-1:0] /* verilator public_flat */; end end diff --git a/core/cache_subsystem/cva6_hpdcache_wrapper.sv b/core/cache_subsystem/cva6_hpdcache_wrapper.sv index 1e532a2b5e..6b56d44bd2 100644 --- a/core/cache_subsystem/cva6_hpdcache_wrapper.sv +++ b/core/cache_subsystem/cva6_hpdcache_wrapper.sv @@ -17,7 +17,7 @@ module cva6_hpdcache_wrapper // {{{ #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, - parameter hpdcache_pkg::hpdcache_cfg_t HPDcacheCfg, + parameter hpdcache_pkg::hpdcache_cfg_t HPDcacheCfg = '0, parameter type dcache_req_i_t = logic, parameter type dcache_req_o_t = logic, parameter int NumPorts = 4, From 3deb95af21cd1dd3741f6c39caaca1b311758220 Mon Sep 17 00:00:00 2001 From: slgth <166491525+slgth@users.noreply.github.com> Date: Thu, 25 Jul 2024 08:37:27 +0200 Subject: [PATCH 032/183] cv64a6_mmu: add RISC-V ISA documentation to main page (#2393) --- docs/06_cv64a6_mmu/index.rst | 2 +- docs/index.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/06_cv64a6_mmu/index.rst b/docs/06_cv64a6_mmu/index.rst index be609f4f0d..6adf3e3315 100644 --- a/docs/06_cv64a6_mmu/index.rst +++ b/docs/06_cv64a6_mmu/index.rst @@ -1,4 +1,4 @@ -CV32A65X documentation +CV64A6_MMU documentation ====================== .. toctree:: diff --git a/docs/index.rst b/docs/index.rst index c8ba58bc72..5ab692133d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -69,5 +69,5 @@ The :doc:`CVA6 APU <05_cva6_apu/index>` describes an Application Processor Unit 01_cva6_user/index.rst 03_cva6_design/index.rst 04_cv32a65x/index.rst + 06_cv64a6_mmu/index.rst 05_cva6_apu/index.rst - From 1e48237a7a2b0cbb678f6c011fba19b51f4393a1 Mon Sep 17 00:00:00 2001 From: Somya Dashora <38585070+somyadashora@users.noreply.github.com> Date: Thu, 25 Jul 2024 13:24:13 +0530 Subject: [PATCH 033/183] Update csr_regfile.sv to fix #2373 (#2374) --- core/csr_regfile.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 252c771f55..1527fe202a 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -2247,7 +2247,7 @@ module csr_regfile // precedence over interrupts if (csr_op_i inside {CSR_WRITE, CSR_SET, CSR_CLEAR, CSR_READ}) begin if (access_priv < csr_addr.csr_decode.priv_lvl) begin - if (v_q && csr_addr.csr_decode.priv_lvl == riscv::PRIV_LVL_HS) + if (v_q && csr_addr.csr_decode.priv_lvl <= riscv::PRIV_LVL_HS) virtual_privilege_violation = 1'b1; else privilege_violation = 1'b1; end From 631513eda801a45d16bd864a07b3ffa52b1cba26 Mon Sep 17 00:00:00 2001 From: Asmaa Kassimi <163407779+Asmaa-Kassimi@users.noreply.github.com> Date: Thu, 25 Jul 2024 11:03:38 +0100 Subject: [PATCH 034/183] Add RVU condition to increase coverage (#2396) --- core/csr_regfile.sv | 2 +- spyglass/reference_summary.rpt | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 1527fe202a..e15cf24c66 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -2302,7 +2302,7 @@ module csr_regfile // if we are reading or writing, check for the correct privilege level this has // precedence over interrupts if (csr_op_i inside {CSR_WRITE, CSR_SET, CSR_CLEAR, CSR_READ}) begin - if ((riscv::priv_lvl_t'(priv_lvl_o & csr_addr.csr_decode.priv_lvl) != csr_addr.csr_decode.priv_lvl)) begin + if (CVA6Cfg.RVU && (riscv::priv_lvl_t'(priv_lvl_o & csr_addr.csr_decode.priv_lvl) != csr_addr.csr_decode.priv_lvl)) begin privilege_violation = 1'b1; end // check access to debug mode only CSRs diff --git a/spyglass/reference_summary.rpt b/spyglass/reference_summary.rpt index c383d57efa..8988519e4b 100644 --- a/spyglass/reference_summary.rpt +++ b/spyglass/reference_summary.rpt @@ -8,17 +8,14 @@ # Working Directory: /home/akassimi/rhel8/cva6_synthesis/cva6/spyglass # SpyGlass Version : SpyGlass_vS-2021.09-SP2-3 # Policy Name : SpyGlass(SpyGlass_vS-2021.09-SP2-03) -# clock-reset(SpyGlass_vS-2021.09-SP2-03) # erc(SpyGlass_vS-2021.09-SP2-03) # latch(SpyGlass_vS-2021.09-SP2-03) # lint(SpyGlass_vS-2021.09-SP2-03) # morelint(SpyGlass_vS-2021.09-SP2-03) # openmore(SpyGlass_vS-2021.09-SP2-03) -# power_est(SpyGlass_vS-2021.09-SP2-03) # simulation(SpyGlass_vS-2021.09-SP2-03) # starc(SpyGlass_vS-2021.09-SP2-03) # starc2005(SpyGlass_vS-2021.09-SP2-03) -# txv(SpyGlass_vS-2021.09-SP2-03) # # Total Number of Generated Messages : 1501 # Number of Waived Messages : 2 From fd489a16fbfbb791d598c4a61afa765267ab12ff Mon Sep 17 00:00:00 2001 From: Moritz Schneider Date: Thu, 25 Jul 2024 12:08:53 +0200 Subject: [PATCH 035/183] Fix off by one error in PMP length (#2394) --- .gitlab-ci/expected_synth.yml | 2 +- core/acc_dispatcher.sv | 4 ++-- core/csr_regfile.sv | 8 ++++---- core/cva6.sv | 4 ++-- core/cva6_mmu/cva6_mmu.sv | 4 ++-- core/cva6_mmu/cva6_ptw.sv | 4 ++-- core/ex_stage.sv | 4 ++-- core/load_store_unit.sv | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.gitlab-ci/expected_synth.yml b/.gitlab-ci/expected_synth.yml index 9a479c2e34..f0f9d8ef93 100644 --- a/.gitlab-ci/expected_synth.yml +++ b/.gitlab-ci/expected_synth.yml @@ -1,2 +1,2 @@ cv32a65x: - gates: 172629 + gates: 171002 diff --git a/core/acc_dispatcher.sv b/core/acc_dispatcher.sv index 4784564c84..57a8170b69 100644 --- a/core/acc_dispatcher.sv +++ b/core/acc_dispatcher.sv @@ -65,8 +65,8 @@ module acc_dispatcher // Interface with the CSRs input priv_lvl_t ld_st_priv_lvl_i, input logic sum_i, - input pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i, - input logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, + input pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i, + input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, input logic [2:0] fcsr_frm_i, output logic dirty_v_state_o, // Interface with the issue stage diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index e15cf24c66..7695f7740d 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -163,9 +163,9 @@ module csr_regfile // TO_BE_COMPLETED - PERF_COUNTERS output logic perf_we_o, // PMP configuration containing pmpcfg for max 64 PMPs - ACC_DISPATCHER - output riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_o, + output riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_o, // PMP addresses - ACC_DISPATCHER - output logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_o, + output logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_o, // TO_BE_COMPLETED - PERF_COUNTERS output logic [31:0] mcountinhibit_o, // RVFI @@ -293,8 +293,8 @@ module csr_regfile | (CVA6Cfg.XLEN'(CVA6Cfg.NSX) << 23) // X - Non-standard extensions present | ((CVA6Cfg.XLEN == 64 ? 2 : 1) << CVA6Cfg.XLEN - 2); // MXL - assign pmpcfg_o = pmpcfg_q[CVA6Cfg.NrPMPEntries:0]; - assign pmpaddr_o = pmpaddr_q[CVA6Cfg.NrPMPEntries:0]; + assign pmpcfg_o = pmpcfg_q[CVA6Cfg.NrPMPEntries-1:0]; + assign pmpaddr_o = pmpaddr_q[CVA6Cfg.NrPMPEntries-1:0]; riscv::fcsr_t fcsr_q, fcsr_d; // ---------------- diff --git a/core/cva6.sv b/core/cva6.sv index 0bc4a9a449..b3b1cb5618 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -554,8 +554,8 @@ module cva6 logic acc_cons_en_csr; logic debug_mode; logic single_step_csr_commit; - riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg; - logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr; + riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg; + logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr; logic [31:0] mcountinhibit_csr_perf; // ---------------------------- // Performance Counters <-> * diff --git a/core/cva6_mmu/cva6_mmu.sv b/core/cva6_mmu/cva6_mmu.sv index 39826da371..364c2ef269 100644 --- a/core/cva6_mmu/cva6_mmu.sv +++ b/core/cva6_mmu/cva6_mmu.sv @@ -99,8 +99,8 @@ module cva6_mmu output dcache_req_i_t req_port_o, // PMP - input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i, - input logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_i + input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i, + input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i ); // memory management, pte for cva6 diff --git a/core/cva6_mmu/cva6_ptw.sv b/core/cva6_mmu/cva6_ptw.sv index 34c2cf1a19..f7117d62ee 100644 --- a/core/cva6_mmu/cva6_ptw.sv +++ b/core/cva6_mmu/cva6_ptw.sv @@ -84,8 +84,8 @@ module cva6_ptw // PMP - input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i, - input logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, + input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i, + input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, output logic [CVA6Cfg.PLEN-1:0] bad_paddr_o, output logic [CVA6Cfg.GPLEN-1:0] bad_gpaddr_o diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 69af0e763a..b6776f3c58 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -222,9 +222,9 @@ module ex_stage // To count the data TLB misses - PERF_COUNTERS output logic dtlb_miss_o, // Report the PMP configuration - CSR_REGFILE - input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i, + input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i, // Report the PMP addresses - CSR_REGFILE - input logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, + input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, // Information dedicated to RVFI - RVFI output lsu_ctrl_t rvfi_lsu_ctrl_o, // Information dedicated to RVFI - RVFI diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 514f61244c..8e8acd7e81 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -148,9 +148,9 @@ module load_store_unit input amo_resp_t amo_resp_i, // PMP configuration - CSR_REGFILE - input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries:0] pmpcfg_i, + input riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg_i, // PMP address - CSR_REGFILE - input logic [CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, + input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i, // RVFI inforamtion - RVFI output lsu_ctrl_t rvfi_lsu_ctrl_o, From e9648eaf8c3178ec671e89c4605dd89a66ff2ac2 Mon Sep 17 00:00:00 2001 From: slgth <166491525+slgth@users.noreply.github.com> Date: Thu, 25 Jul 2024 17:18:27 +0200 Subject: [PATCH 036/183] Design documentation: AsciiDoc conversion (#2399) --- .../cv32a65x/csr/csr.adoc | 496 + .../cv32a65x/isa/isa.adoc | 232 + .../scripts/libs/utils.py | 185 + .../scripts/riscv_config_gen.py | 21 +- .../{riscv/src => config}/config.adoc | 2 + docs/04_cv32a65x/design/Makefile | 44 +- docs/04_cv32a65x/design/design-cv32a65x.html | 12954 ++++++++++++++++ .../design/{source/traps.rst => design.rst} | 15 +- docs/04_cv32a65x/design/make.bat | 35 - docs/04_cv32a65x/design/requirements.txt | 5 - docs/04_cv32a65x/design/source/CSRs.rst | 1 - docs/04_cv32a65x/design/source/conf.py | 214 - .../design/source/cv32a6_glossary.rst | 71 - .../design/source/cva6_commit_stage.rst | 36 - .../design/source/cva6_issue_stage.rst | 64 - .../images/CV32A65X_subsystems.png | Bin docs/04_cv32a65x/design/source/index.rst | 23 - .../design/source/instructions.rst | 31 - docs/04_cv32a65x/design/source/intro.rst | 95 - docs/04_cv32a65x/design/source/mmu.rst | 1587 -- .../04_cv32a65x/design/source/parameters.adoc | 93 + .../design/source/parameters_cv32a65x.rst | 321 - docs/04_cv32a65x/design/source/port_alu.adoc | 28 + docs/04_cv32a65x/design/source/port_alu.rst | 51 - docs/04_cv32a65x/design/source/port_bht.adoc | 34 + docs/04_cv32a65x/design/source/port_bht.rst | 57 - .../design/source/port_branch_unit.adoc | 48 + .../design/source/port_branch_unit.rst | 99 - docs/04_cv32a65x/design/source/port_btb.adoc | 34 + docs/04_cv32a65x/design/source/port_btb.rst | 57 - .../design/source/port_commit_stage.adoc | 84 + .../design/source/port_commit_stage.rst | 183 - .../source/port_compressed_decoder.adoc | 28 + .../design/source/port_compressed_decoder.rst | 51 - .../design/source/port_controller.adoc | 74 + .../design/source/port_controller.rst | 149 - .../design/source/port_csr_buffer.adoc | 36 + .../design/source/port_csr_buffer.rst | 75 - .../design/source/port_csr_regfile.adoc | 125 + .../design/source/port_csr_regfile.rst | 228 - docs/04_cv32a65x/design/source/port_cva6.adoc | 46 + docs/04_cv32a65x/design/source/port_cva6.rst | 93 - .../source/port_cva6_hpdcache_subsystem.adoc | 74 + .../source/port_cva6_hpdcache_subsystem.rst | 153 - .../design/source/port_cvxif_fu.adoc | 50 + .../design/source/port_cvxif_fu.rst | 103 - .../design/source/port_decoder.adoc | 68 + .../design/source/port_decoder.rst | 131 - .../design/source/port_ex_stage.adoc | 189 + .../design/source/port_ex_stage.rst | 406 - .../design/source/port_frontend.adoc | 59 + .../design/source/port_frontend.rst | 130 - .../design/source/port_id_stage.adoc | 76 + .../design/source/port_id_stage.rst | 121 - .../design/source/port_instr_queue.adoc | 58 + .../design/source/port_instr_queue.rst | 129 - .../design/source/port_instr_realign.adoc | 38 + .../design/source/port_instr_realign.rst | 81 - .../design/source/port_instr_scan.adoc | 46 + .../design/source/port_instr_scan.rst | 105 - .../source/port_issue_read_operands.adoc | 136 + .../source/port_issue_read_operands.rst | 267 - .../design/source/port_issue_stage.adoc | 140 + .../design/source/port_issue_stage.rst | 275 - .../design/source/port_load_store_unit.adoc | 115 + .../design/source/port_load_store_unit.rst | 226 - .../design/source/port_load_unit.adoc | 70 + .../design/source/port_load_unit.rst | 157 - .../design/source/port_lsu_bypass.adoc | 36 + .../design/source/port_lsu_bypass.rst | 75 - docs/04_cv32a65x/design/source/port_mult.adoc | 36 + docs/04_cv32a65x/design/source/port_mult.rst | 75 - .../design/source/port_multiplier.adoc | 40 + .../design/source/port_multiplier.rst | 87 - docs/04_cv32a65x/design/source/port_ras.adoc | 34 + docs/04_cv32a65x/design/source/port_ras.rst | 61 - .../design/source/port_scoreboard.adoc | 97 + .../design/source/port_scoreboard.rst | 220 - .../design/source/port_scoreboard.rst.ori | 229 - .../design/source/port_serdiv.adoc | 44 + .../04_cv32a65x/design/source/port_serdiv.rst | 99 - .../design/source/port_store_unit.adoc | 78 + .../design/source/port_store_unit.rst | 173 - docs/04_cv32a65x/index.rst | 2 +- docs/README.md | 26 + .../src => common}/config_define.adoc | 0 docs/conf.py | 2 +- docs/design/build.mk | 38 + docs/design/design-manual/Makefile | 122 + .../design-manual/source/AXI.adoc} | 6 +- .../design-manual/source/AXI_Interface.adoc | 895 ++ docs/design/design-manual/source/CSRs.adoc | 3 + .../design-manual/source/CVXIF.adoc} | 6 +- .../source/CVX_Interface_Coprocessor.adoc | 294 + .../source/Traps_Interrupts_Exceptions.adoc | 129 + .../design-manual/source/architecture.adoc} | 45 +- .../design-manual/source/cv32a6_execute.adoc} | 122 +- .../source/cv32a6_frontend.adoc} | 194 +- .../design-manual/source/cv32a6_glossary.adoc | 65 + .../design-manual/source/cva6_caches.adoc} | 31 +- .../source/cva6_commit_stage.adoc | 42 + .../source/cva6_controller.adoc} | 17 +- .../source/cva6_csr_regfile.adoc} | 16 +- .../design-manual/source/cva6_id_stage.adoc} | 82 +- .../source/cva6_issue_stage.adoc | 65 + docs/design/design-manual/source/design.adoc | 40 + .../design-manual/source/functionality.adoc} | 21 +- .../source}/images/CVA6_subsystems.png | Bin .../design-manual/source}/images/LZC.png | Bin .../design-manual/source}/images/RR.png | Bin .../source}/images/ZoominFrontend.png | Bin .../source}/images/ariane_overview.drawio.png | Bin .../source}/images/ariane_overview.png | Bin .../design-manual/source}/images/bht.png | Bin .../design-manual/source}/images/caches.png | Bin .../source}/images/cva6_tlb_entry.png | Bin .../source}/images/cva6_tlb_hit.png | Bin .../source}/images/ex_stage_modules.png | Bin .../source}/images/frontend_modules.png | Bin .../source}/images/id_stage_modules.png | Bin .../source}/images/in_out_tlb.png | Bin .../source}/images/issue_stage_modules.png | Bin .../images/load_store_unit_modules.png | Bin .../source}/images/mmu_control_flow.png | Bin .../source}/images/mmu_in_out.png | Bin .../source}/images/mmu_major_blocks.png | Bin .../source}/images/mult_modules.png | Bin .../source}/images/openhw-landscape.svg | 0 .../source}/images/plru_tree_indexing.png | Bin .../design-manual/source}/images/ptw_dptw.png | Bin .../source}/images/ptw_dptw_s.png | Bin .../design-manual/source}/images/ptw_idle.png | Bin .../source}/images/ptw_in_out.png | Bin .../design-manual/source}/images/ptw_iptw.png | Bin .../source}/images/ptw_mis_sup.png | Bin .../design-manual/source}/images/ptw_nlvl.png | Bin .../source}/images/ptw_pte_1.png | Bin .../source}/images/ptw_pte_flowchart.png | Bin .../source}/images/ptw_state_diagram.png | Bin .../source}/images/replacement_entry.png | Bin .../images/schema_fsm_load_control.png | Bin .../source}/images/sfence_vaddr_asid.png | Bin .../source}/images/sfence_vaddr_x0.png | Bin .../source}/images/sfence_x0_asid.png | Bin .../source}/images/sfence_x0_x0.png | Bin .../source}/images/shared_tlb.png | Bin .../source}/images/shared_tlb_in_out.png | Bin .../source}/images/shared_tlb_set.png | Bin .../source}/images/subsystems.png | Bin .../source}/images/update_tree.png | Bin .../design-manual/source/instructions.adoc | 19 + docs/design/design-manual/source/intro.adoc | 120 + docs/design/design-manual/source/mmu.adoc | 1258 ++ .../design-manual/source/subsystem.adoc} | 43 +- .../design-manual/source/traps.adoc} | 8 +- docs/index.rst | 2 +- docs/riscv-isa/build.mk | 3 +- docs/scripts/parameters_extractor.py | 26 + docs/scripts/spec_builder.py | 155 +- 159 files changed, 19552 insertions(+), 7237 deletions(-) create mode 100644 config/gen_from_riscv_config/cv32a65x/csr/csr.adoc create mode 100644 config/gen_from_riscv_config/cv32a65x/isa/isa.adoc rename docs/04_cv32a65x/{riscv/src => config}/config.adoc (95%) create mode 100644 docs/04_cv32a65x/design/design-cv32a65x.html rename docs/04_cv32a65x/design/{source/traps.rst => design.rst} (60%) delete mode 100644 docs/04_cv32a65x/design/make.bat delete mode 100644 docs/04_cv32a65x/design/requirements.txt delete mode 100644 docs/04_cv32a65x/design/source/CSRs.rst delete mode 100644 docs/04_cv32a65x/design/source/conf.py delete mode 100644 docs/04_cv32a65x/design/source/cv32a6_glossary.rst delete mode 100644 docs/04_cv32a65x/design/source/cva6_commit_stage.rst delete mode 100644 docs/04_cv32a65x/design/source/cva6_issue_stage.rst rename docs/04_cv32a65x/design/{ => source}/images/CV32A65X_subsystems.png (100%) delete mode 100644 docs/04_cv32a65x/design/source/index.rst delete mode 100644 docs/04_cv32a65x/design/source/instructions.rst delete mode 100644 docs/04_cv32a65x/design/source/intro.rst delete mode 100644 docs/04_cv32a65x/design/source/mmu.rst create mode 100644 docs/04_cv32a65x/design/source/parameters.adoc delete mode 100644 docs/04_cv32a65x/design/source/parameters_cv32a65x.rst create mode 100644 docs/04_cv32a65x/design/source/port_alu.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_alu.rst create mode 100644 docs/04_cv32a65x/design/source/port_bht.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_bht.rst create mode 100644 docs/04_cv32a65x/design/source/port_branch_unit.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_branch_unit.rst create mode 100644 docs/04_cv32a65x/design/source/port_btb.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_btb.rst create mode 100644 docs/04_cv32a65x/design/source/port_commit_stage.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_commit_stage.rst create mode 100644 docs/04_cv32a65x/design/source/port_compressed_decoder.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_compressed_decoder.rst create mode 100644 docs/04_cv32a65x/design/source/port_controller.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_controller.rst create mode 100644 docs/04_cv32a65x/design/source/port_csr_buffer.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_csr_buffer.rst create mode 100644 docs/04_cv32a65x/design/source/port_csr_regfile.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_csr_regfile.rst create mode 100644 docs/04_cv32a65x/design/source/port_cva6.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_cva6.rst create mode 100644 docs/04_cv32a65x/design/source/port_cva6_hpdcache_subsystem.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_cva6_hpdcache_subsystem.rst create mode 100644 docs/04_cv32a65x/design/source/port_cvxif_fu.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_cvxif_fu.rst create mode 100644 docs/04_cv32a65x/design/source/port_decoder.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_decoder.rst create mode 100644 docs/04_cv32a65x/design/source/port_ex_stage.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_ex_stage.rst create mode 100644 docs/04_cv32a65x/design/source/port_frontend.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_frontend.rst create mode 100644 docs/04_cv32a65x/design/source/port_id_stage.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_id_stage.rst create mode 100644 docs/04_cv32a65x/design/source/port_instr_queue.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_instr_queue.rst create mode 100644 docs/04_cv32a65x/design/source/port_instr_realign.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_instr_realign.rst create mode 100644 docs/04_cv32a65x/design/source/port_instr_scan.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_instr_scan.rst create mode 100644 docs/04_cv32a65x/design/source/port_issue_read_operands.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_issue_read_operands.rst create mode 100644 docs/04_cv32a65x/design/source/port_issue_stage.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_issue_stage.rst create mode 100644 docs/04_cv32a65x/design/source/port_load_store_unit.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_load_store_unit.rst create mode 100644 docs/04_cv32a65x/design/source/port_load_unit.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_load_unit.rst create mode 100644 docs/04_cv32a65x/design/source/port_lsu_bypass.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_lsu_bypass.rst create mode 100644 docs/04_cv32a65x/design/source/port_mult.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_mult.rst create mode 100644 docs/04_cv32a65x/design/source/port_multiplier.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_multiplier.rst create mode 100644 docs/04_cv32a65x/design/source/port_ras.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_ras.rst create mode 100644 docs/04_cv32a65x/design/source/port_scoreboard.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_scoreboard.rst delete mode 100644 docs/04_cv32a65x/design/source/port_scoreboard.rst.ori create mode 100644 docs/04_cv32a65x/design/source/port_serdiv.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_serdiv.rst create mode 100644 docs/04_cv32a65x/design/source/port_store_unit.adoc delete mode 100644 docs/04_cv32a65x/design/source/port_store_unit.rst create mode 100644 docs/README.md rename docs/{riscv-isa/src => common}/config_define.adoc (100%) create mode 100644 docs/design/build.mk create mode 100644 docs/design/design-manual/Makefile rename docs/{04_cv32a65x/design/source/AXI.rst => design/design-manual/source/AXI.adoc} (86%) create mode 100644 docs/design/design-manual/source/AXI_Interface.adoc create mode 100644 docs/design/design-manual/source/CSRs.adoc rename docs/{04_cv32a65x/design/source/csr_list.rst => design/design-manual/source/CVXIF.adoc} (85%) create mode 100644 docs/design/design-manual/source/CVX_Interface_Coprocessor.adoc create mode 100644 docs/design/design-manual/source/Traps_Interrupts_Exceptions.adoc rename docs/{04_cv32a65x/design/source/architecture.rst => design/design-manual/source/architecture.adoc} (57%) rename docs/{04_cv32a65x/design/source/cv32a6_execute.rst => design/design-manual/source/cv32a6_execute.adoc} (75%) rename docs/{04_cv32a65x/design/source/cv32a6_frontend.rst => design/design-manual/source/cv32a6_frontend.adoc} (55%) create mode 100644 docs/design/design-manual/source/cv32a6_glossary.adoc rename docs/{04_cv32a65x/design/source/cva6_caches.rst => design/design-manual/source/cva6_caches.adoc} (68%) create mode 100644 docs/design/design-manual/source/cva6_commit_stage.adoc rename docs/{04_cv32a65x/design/source/cva6_controller.rst => design/design-manual/source/cva6_controller.adoc} (76%) rename docs/{04_cv32a65x/design/source/cva6_csr_regfile.rst => design/design-manual/source/cva6_csr_regfile.adoc} (76%) rename docs/{04_cv32a65x/design/source/cva6_id_stage.rst => design/design-manual/source/cva6_id_stage.adoc} (52%) create mode 100644 docs/design/design-manual/source/cva6_issue_stage.adoc create mode 100644 docs/design/design-manual/source/design.adoc rename docs/{04_cv32a65x/design/source/functionality.rst => design/design-manual/source/functionality.adoc} (70%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/CVA6_subsystems.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/LZC.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/RR.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ZoominFrontend.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ariane_overview.drawio.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ariane_overview.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/bht.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/caches.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/cva6_tlb_entry.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/cva6_tlb_hit.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ex_stage_modules.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/frontend_modules.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/id_stage_modules.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/in_out_tlb.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/issue_stage_modules.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/load_store_unit_modules.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/mmu_control_flow.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/mmu_in_out.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/mmu_major_blocks.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/mult_modules.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/openhw-landscape.svg (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/plru_tree_indexing.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ptw_dptw.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ptw_dptw_s.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ptw_idle.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ptw_in_out.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ptw_iptw.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ptw_mis_sup.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ptw_nlvl.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ptw_pte_1.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ptw_pte_flowchart.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/ptw_state_diagram.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/replacement_entry.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/schema_fsm_load_control.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/sfence_vaddr_asid.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/sfence_vaddr_x0.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/sfence_x0_asid.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/sfence_x0_x0.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/shared_tlb.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/shared_tlb_in_out.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/shared_tlb_set.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/subsystems.png (100%) rename docs/{04_cv32a65x/design => design/design-manual/source}/images/update_tree.png (100%) create mode 100644 docs/design/design-manual/source/instructions.adoc create mode 100644 docs/design/design-manual/source/intro.adoc create mode 100644 docs/design/design-manual/source/mmu.adoc rename docs/{04_cv32a65x/design/source/subsystem.rst => design/design-manual/source/subsystem.adoc} (57%) rename docs/{04_cv32a65x/design/source/CVXIF.rst => design/design-manual/source/traps.adoc} (84%) diff --git a/config/gen_from_riscv_config/cv32a65x/csr/csr.adoc b/config/gen_from_riscv_config/cv32a65x/csr/csr.adoc new file mode 100644 index 0000000000..e390932111 --- /dev/null +++ b/config/gen_from_riscv_config/cv32a65x/csr/csr.adoc @@ -0,0 +1,496 @@ +//// + Copyright (c) 2024 OpenHW Group + Copyright (c) 2024 Thales + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + Author: Abdessamii Oukalrazqou +//// + +=== csr + +==== Conventions + +In the subsequent sections, register fields are labeled with one of the following abbreviations: + +* WPRI (Writes Preserve Values, Reads Ignore Values): read/write field reserved +for future use. For forward compatibility, implementations that do not +furnish these fields must make them read-only zero. +* WLRL (Write/Read Only Legal Values): read/write CSR field that specifies +behavior for only a subset of possible bit encodings, with other bit encodings +reserved. +* WARL (Write Any Values, Reads Legal Values): read/write CSR fields which are +only defined for a subset of bit encodings, but allow any value to be written +while guaranteeing to return a legal value whenever read. +* ROCST (Read-Only Constant): A special case of WARL field which admits only one +legal value, and therefore, behaves as a constant field that silently ignores +writes. +* ROVAR (Read-Only Variable): A special case of WARL field which can take +multiple legal values but cannot be modified by software and depends only on +the architectural state of the hart. + +In particular, a register that is not internally divided +into multiple fields can be considered as containing a single field of XLEN bits. +This allows to clearly represent read-write registers holding a single legal value +(typically zero). + +==== Register Summary + +|=== +|Address | Register Name | Privilege | Description + +|0x300| `<<_MSTATUS,MSTATUS>>`|MRW|The mstatus register keeps track of and controls the hart's current operating state. +|0x301| `<<_MISA,MISA>>`|MRW|misa is a read-write register reporting the ISA supported by the hart. +|0x304| `<<_MIE,MIE>>`|MRW|The mie register is an MXLEN-bit read/write register containing interrupt enable bits. +|0x305| `<<_MTVEC,MTVEC>>`|MRW|MXLEN-bit read/write register that holds trap vector configuration. +|0x310| `<<_MSTATUSH,MSTATUSH>>`|MRW|The mstatush register keeps track of and controls the hart’s current operating state. +|0x323-0x33f| `<<_MHPMEVENT3-31,MHPMEVENT[3-31]>>`|MRW|The mhpmevent is a MXLEN-bit event register which controls mhpmcounter3. +|0x340| `<<_MSCRATCH,MSCRATCH>>`|MRW|The mscratch register is an MXLEN-bit read/write register dedicated for use by machine mode. +|0x341| `<<_MEPC,MEPC>>`|MRW|The mepc is a warl register that must be able to hold all valid physical and virtual addresses. +|0x342| `<<_MCAUSE,MCAUSE>>`|MRW|The mcause register stores the information regarding the trap. +|0x343| `<<_MTVAL,MTVAL>>`|MRW|The mtval is a warl register that holds the address of the instruction which caused the exception. +|0x344| `<<_MIP,MIP>>`|MRW|The mip register is an MXLEN-bit read/write register containing information on pending interrupts. +|0x3a0-0x3a3| `<<_PMPCFG0-3,PMPCFG[0-3]>>`|MRW|PMP configuration register +|0x3b0-0x3bf| `<<_PMPADDR0-15,PMPADDR[0-15]>>`|MRW|Physical memory protection address register +|0x7c0| `<<_ICACHE,ICACHE>>`|MRW|the register controls the operation of the i-cache unit. +|0x7c1| `<<_DCACHE,DCACHE>>`|MRW|the register controls the operation of the d-cache unit. +|0xb00| `<<_MCYCLE,MCYCLE>>`|MRW|Counts the number of clock cycles executed from an arbitrary point in time. +|0xb02| `<<_MINSTRET,MINSTRET>>`|MRW|Counts the number of instructions completed from an arbitrary point in time. +|0xb03-0xb1f| `<<_MHPMCOUNTER3-31,MHPMCOUNTER[3-31]>>`|MRW|The mhpmcounter is a 64-bit counter. Returns lower 32 bits in RV32I mode. +|0xb80| `<<_MCYCLEH,MCYCLEH>>`|MRW|upper 32 bits of mcycle +|0xb82| `<<_MINSTRETH,MINSTRETH>>`|MRW|Upper 32 bits of minstret. +|0xb83-0xb9f| `<<_MHPMCOUNTER3-31H,MHPMCOUNTER[3-31]H>>`|MRW|The mhpmcounterh returns the upper half word in RV32I systems. +|0xf11| `<<_MVENDORID,MVENDORID>>`|MRO|32-bit read-only register providing the JEDEC manufacturer ID of the provider of the core. +|0xf12| `<<_MARCHID,MARCHID>>`|MRO|MXLEN-bit read-only register encoding the base microarchitecture of the hart. +|0xf13| `<<_MIMPID,MIMPID>>`|MRO|Provides a unique encoding of the version of the processor implementation. +|0xf14| `<<_MHARTID,MHARTID>>`|MRO|MXLEN-bit read-only register containing the integer ID of the hardware thread running the code. +|0xf15| `<<_MCONFIGPTR,MCONFIGPTR>>`|MRO|MXLEN-bit read-only register that holds the physical address of a configuration data structure. +|=== + +==== Register Description + +[[_MSTATUS]] +===== MSTATUS + +Address:: 0x300 +Reset Value:: 0x00001800 +Privilege:: MRW +Description:: The mstatus register keeps track of and controls the hart's current operating state. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| 0 | UIE | 0x0 | ROCST | 0x0 | Stores the state of the user mode interrupts. +| 1 | SIE | 0x0 | ROCST | 0x0 | Stores the state of the supervisor mode interrupts. +| 2 | RESERVED_2 | 0x0 | WPRI | | *Reserved* +| 3 | MIE | 0x0 | WLRL | 0 - 1 | Stores the state of the machine mode interrupts. +| 4 | UPIE | 0x0 | ROCST | 0x0 | Stores the state of the user mode interrupts prior to the trap. +| 5 | SPIE | 0x0 | ROCST | 0x0 | Stores the state of the supervisor mode interrupts prior to the trap. +| 6 | UBE | 0x0 | ROCST | 0x0 | control the endianness of memory accesses other than instruction fetches for user mode +| 7 | MPIE | 0x0 | WLRL | 0 - 1 | Stores the state of the machine mode interrupts prior to the trap. +| 8 | SPP | 0x0 | ROCST | 0x0 | Stores the previous priority mode for supervisor. +| [10:9] | RESERVED_9 | 0x0 | WPRI | | *Reserved* +| [12:11] | MPP | 0x3 | WARL | 0x3 | Stores the previous priority mode for machine. +| [14:13] | FS | 0x0 | ROCST | 0x0 | Encodes the status of the floating-point unit, including the CSR fcsr and floating-point data registers. +| [16:15] | XS | 0x0 | ROCST | 0x0 | Encodes the status of additional user-mode extensions and associated state. +| 17 | MPRV | 0x0 | ROCST | 0x0 | Modifies the privilege level at which loads and stores execute in all privilege modes. +| 18 | SUM | 0x0 | ROCST | 0x0 | Modifies the privilege with which S-mode loads and stores access virtual memory. +| 19 | MXR | 0x0 | ROCST | 0x0 | Modifies the privilege with which loads access virtual memory. +| 20 | TVM | 0x0 | ROCST | 0x0 | Supports intercepting supervisor virtual-memory management operations. +| 21 | TW | 0x0 | ROCST | 0x0 | Supports intercepting the WFI instruction. +| 22 | TSR | 0x0 | ROCST | 0x0 | Supports intercepting the supervisor exception return instruction. +| 23 | SPELP | 0x0 | ROCST | 0x0 | Supervisor mode previous expected-landing-pad (ELP) state. +| [30:24] | RESERVED_24 | 0x0 | WPRI | | *Reserved* +| 31 | SD | 0x0 | ROCST | 0x0 | Read-only bit that summarizes whether either the FS field or XS field signals the presence of some dirty state. +|=== + +[[_MISA]] +===== MISA + +Address:: 0x301 +Reset Value:: 0x40001106 +Privilege:: MRW +Description:: misa is a read-write register reporting the ISA supported by the hart. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [25:0] | EXTENSIONS | 0x1106 | ROCST | 0x1106 | Encodes the presence of the standard extensions, with a single bit per letter of the alphabet. +| [29:26] | RESERVED_26 | 0x0 | WPRI | | *Reserved* +| [31:30] | MXL | 0x1 | WARL | 0x1 | Encodes the native base integer ISA width. +|=== + +[[_MIE]] +===== MIE + +Address:: 0x304 +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: The mie register is an MXLEN-bit read/write register containing interrupt enable bits. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| 0 | USIE | 0x0 | ROCST | 0x0 | User Software Interrupt enable. +| 1 | SSIE | 0x0 | ROCST | 0x0 | Supervisor Software Interrupt enable. +| 2 | VSSIE | 0x0 | ROCST | 0x0 | VS-level Software Interrupt enable. +| 3 | MSIE | 0x0 | ROCST | 0x0 | Machine Software Interrupt enable. +| 4 | UTIE | 0x0 | ROCST | 0x0 | User Timer Interrupt enable. +| 5 | STIE | 0x0 | ROCST | 0x0 | Supervisor Timer Interrupt enable. +| 6 | VSTIE | 0x0 | ROCST | 0x0 | VS-level Timer Interrupt enable. +| 7 | MTIE | 0x0 | WLRL | 0 - 1 | Machine Timer Interrupt enable. +| 8 | UEIE | 0x0 | ROCST | 0x0 | User External Interrupt enable. +| 9 | SEIE | 0x0 | ROCST | 0x0 | Supervisor External Interrupt enable. +| 10 | VSEIE | 0x0 | ROCST | 0x0 | VS-level External Interrupt enable. +| 11 | MEIE | 0x0 | WLRL | 0 - 1 | Machine External Interrupt enable. +| 12 | SGEIE | 0x0 | ROCST | 0x0 | HS-level External Interrupt enable. +| [31:13] | RESERVED_13 | 0x0 | WPRI | | *Reserved* +|=== + +[[_MTVEC]] +===== MTVEC + +Address:: 0x305 +Reset Value:: 0x80010000 +Privilege:: MRW +Description:: MXLEN-bit read/write register that holds trap vector configuration. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [1:0] | MODE | 0x0 | WARL | 0x0 | Vector mode. +| [31:2] | BASE | 0x20004000 | WARL | 0x00000000 - 0x3FFFFFFF | Vector base address. +|=== + +[[_MSTATUSH]] +===== MSTATUSH + +Address:: 0x310 +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: The mstatush register keeps track of and controls the hart’s current operating state. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [3:0] | RESERVED_0 | 0x0 | WPRI | | *Reserved* +| 4 | SBE | 0x0 | ROCST | 0x0 | control the endianness of memory accesses other than instruction fetches for supervisor mode +| 5 | MBE | 0x0 | ROCST | 0x0 | control the endianness of memory accesses other than instruction fetches for machine mode +| 6 | GVA | 0x0 | ROCST | 0x0 | Stores the state of the supervisor mode interrupts. +| 7 | MPV | 0x0 | ROCST | 0x0 | Stores the state of the user mode interrupts. +| 8 | RESERVED_8 | 0x0 | WPRI | | *Reserved* +| 9 | MPELP | 0x0 | ROCST | 0x0 | Machine mode previous expected-landing-pad (ELP) state. +| [31:10] | RESERVED_10 | 0x0 | WPRI | | *Reserved* +|=== + +[[_MHPMEVENT3-31]] +===== MHPMEVENT[3-31] + +Address:: 0x323-0x33f +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: The mhpmevent is a MXLEN-bit event register which controls mhpmcounter3. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MHPMEVENT[I] | 0x00000000 | ROCST | 0x00000000 | The mhpmevent is a MXLEN-bit event register which controls mhpmcounter3. +|=== + +[[_MSCRATCH]] +===== MSCRATCH + +Address:: 0x340 +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: The mscratch register is an MXLEN-bit read/write register dedicated for use by machine mode. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MSCRATCH | 0x00000000 | WARL | 0x00000000 - 0xFFFFFFFF | The mscratch register is an MXLEN-bit read/write register dedicated for use by machine mode. +|=== + +[[_MEPC]] +===== MEPC + +Address:: 0x341 +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: The mepc is a warl register that must be able to hold all valid physical and virtual addresses. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MEPC | 0x00000000 | WARL | 0x00000000 - 0xFFFFFFFF | The mepc is a warl register that must be able to hold all valid physical and virtual addresses. +|=== + +[[_MCAUSE]] +===== MCAUSE + +Address:: 0x342 +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: The mcause register stores the information regarding the trap. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [30:0] | EXCEPTION_CODE | 0x0 | WLRL | 0 - 15 | Encodes the exception code. +| 31 | INTERRUPT | 0x0 | WLRL | 0x0 - 0x1 | Indicates whether the trap was due to an interrupt. +|=== + +[[_MTVAL]] +===== MTVAL + +Address:: 0x343 +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: The mtval is a warl register that holds the address of the instruction which caused the exception. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MTVAL | 0x00000000 | ROCST | 0x00000000 | The mtval is a warl register that holds the address of the instruction which caused the exception. +|=== + +[[_MIP]] +===== MIP + +Address:: 0x344 +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: The mip register is an MXLEN-bit read/write register containing information on pending interrupts. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| 0 | USIP | 0x0 | ROCST | 0x0 | User Software Interrupt Pending. +| 1 | SSIP | 0x0 | ROCST | 0x0 | Supervisor Software Interrupt Pending. +| 2 | VSSIP | 0x0 | ROCST | 0x0 | VS-level Software Interrupt Pending. +| 3 | MSIP | 0x0 | ROCST | 0x0 | Machine Software Interrupt Pending. +| 4 | UTIP | 0x0 | ROCST | 0x0 | User Timer Interrupt Pending. +| 5 | STIP | 0x0 | ROCST | 0x0 | Supervisor Timer Interrupt Pending. +| 6 | VSTIP | 0x0 | ROCST | 0x0 | VS-level Timer Interrupt Pending. +| 7 | MTIP | 0x0 | ROVAR | 0x1 | Machine Timer Interrupt Pending. +| 8 | UEIP | 0x0 | ROCST | 0x0 | User External Interrupt Pending. +| 9 | SEIP | 0x0 | ROCST | 0x0 | Supervisor External Interrupt Pending. +| 10 | VSEIP | 0x0 | ROCST | 0x0 | VS-level External Interrupt Pending. +| 11 | MEIP | 0x0 | ROVAR | 0x1 | Machine External Interrupt Pending. +| 12 | SGEIP | 0x0 | ROCST | 0x0 | HS-level External Interrupt Pending. +| [31:13] | RESERVED_13 | 0x0 | WPRI | | *Reserved* +|=== + +[[_PMPCFG0-3]] +===== PMPCFG[0-3] + +Address:: 0x3a0-0x3a3 +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: PMP configuration register + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [7:0] | PMP[I*4 + 0]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits +| [15:8] | PMP[I*4 + 1]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits +| [23:16] | PMP[I*4 + 2]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits +| [31:24] | PMP[I*4 + 3]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits +|=== + +[[_PMPADDR0-15]] +===== PMPADDR[0-15] + +Address:: 0x3b0-0x3bf +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: Physical memory protection address register + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | PMPADDR[I] | 0x00000000 | WARL | 0x00000000 - 0xFFFFFFFF | Physical memory protection address register +|=== + +[[_ICACHE]] +===== ICACHE + +Address:: 0x7c0 +Reset Value:: 0x00000001 +Privilege:: MRW +Description:: the register controls the operation of the i-cache unit. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| 0 | ICACHE | 0x1 | RW | 0x1 | bit for cache-enable of instruction cache +| [31:1] | RESERVED_1 | 0x0 | WPRI | | *Reserved* +|=== + +[[_DCACHE]] +===== DCACHE + +Address:: 0x7c1 +Reset Value:: 0x00000001 +Privilege:: MRW +Description:: the register controls the operation of the d-cache unit. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| 0 | DCACHE | 0x1 | RW | 0x1 | bit for cache-enable of data cache +| [31:1] | RESERVED_1 | 0x0 | WPRI | | *Reserved* +|=== + +[[_MCYCLE]] +===== MCYCLE + +Address:: 0xb00 +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: Counts the number of clock cycles executed from an arbitrary point in time. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MCYCLE | 0x00000000 | WARL | 0x00000000 - 0xFFFFFFFF | Counts the number of clock cycles executed from an arbitrary point in time. +|=== + +[[_MINSTRET]] +===== MINSTRET + +Address:: 0xb02 +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: Counts the number of instructions completed from an arbitrary point in time. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MINSTRET | 0x00000000 | WARL | 0x00000000 - 0xFFFFFFFF | Counts the number of instructions completed from an arbitrary point in time. +|=== + +[[_MHPMCOUNTER3-31]] +===== MHPMCOUNTER[3-31] + +Address:: 0xb03-0xb1f +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: The mhpmcounter is a 64-bit counter. Returns lower 32 bits in RV32I mode. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MHPMCOUNTER[I] | 0x00000000 | ROCST | 0x00000000 | The mhpmcounter is a 64-bit counter. Returns lower 32 bits in RV32I mode. +|=== + +[[_MCYCLEH]] +===== MCYCLEH + +Address:: 0xb80 +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: upper 32 bits of mcycle + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MCYCLEH | 0x00000000 | WARL | 0x00000000 - 0xFFFFFFFF | upper 32 bits of mcycle +|=== + +[[_MINSTRETH]] +===== MINSTRETH + +Address:: 0xb82 +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: Upper 32 bits of minstret. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MINSTRETH | 0x00000000 | WARL | 0x00000000 - 0xFFFFFFFF | Upper 32 bits of minstret. +|=== + +[[_MHPMCOUNTER3-31H]] +===== MHPMCOUNTER[3-31]H + +Address:: 0xb83-0xb9f +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: The mhpmcounterh returns the upper half word in RV32I systems. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MHPMCOUNTER[I]H | 0x00000000 | ROCST | 0x00000000 | The mhpmcounterh returns the upper half word in RV32I systems. +|=== + +[[_MVENDORID]] +===== MVENDORID + +Address:: 0xf11 +Reset Value:: 0x00000602 +Privilege:: MRO +Description:: 32-bit read-only register providing the JEDEC manufacturer ID of the provider of the core. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MVENDORID | 0x00000602 | ROCST | 0x00000602 | 32-bit read-only register providing the JEDEC manufacturer ID of the provider of the core. +|=== + +[[_MARCHID]] +===== MARCHID + +Address:: 0xf12 +Reset Value:: 0x00000003 +Privilege:: MRO +Description:: MXLEN-bit read-only register encoding the base microarchitecture of the hart. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MARCHID | 0x00000003 | ROCST | 0x00000003 | MXLEN-bit read-only register encoding the base microarchitecture of the hart. +|=== + +[[_MIMPID]] +===== MIMPID + +Address:: 0xf13 +Reset Value:: 0x00000000 +Privilege:: MRO +Description:: Provides a unique encoding of the version of the processor implementation. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MIMPID | 0x00000000 | ROCST | 0x00000000 | Provides a unique encoding of the version of the processor implementation. +|=== + +[[_MHARTID]] +===== MHARTID + +Address:: 0xf14 +Reset Value:: 0x00000000 +Privilege:: MRO +Description:: MXLEN-bit read-only register containing the integer ID of the hardware thread running the code. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MHARTID | 0x00000000 | ROCST | 0x00000000 | MXLEN-bit read-only register containing the integer ID of the hardware thread running the code. +|=== + +[[_MCONFIGPTR]] +===== MCONFIGPTR + +Address:: 0xf15 +Reset Value:: 0x00000000 +Privilege:: MRO +Description:: MXLEN-bit read-only register that holds the physical address of a configuration data structure. + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | MCONFIGPTR | 0x00000000 | ROCST | 0x00000000 | MXLEN-bit read-only register that holds the physical address of a configuration data structure. +|=== + diff --git a/config/gen_from_riscv_config/cv32a65x/isa/isa.adoc b/config/gen_from_riscv_config/cv32a65x/isa/isa.adoc new file mode 100644 index 0000000000..68d0bd2712 --- /dev/null +++ b/config/gen_from_riscv_config/cv32a65x/isa/isa.adoc @@ -0,0 +1,232 @@ +//// + Copyright (c) 2024 OpenHW Group + Copyright (c) 2024 Thales + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + Author: Abdessamii Oukalrazqou +//// + +=== isa + +==== Instructions + +|=== +|Subset Name | Name | Description + +|I | RV32I Base Integer Instructions | the base integer instruction set, also known as the 'RV32I' or 'RV64I' instruction set , depending on the address space size, provides the core functionality required for general-purpose computing .it includes instructions for arithmetic, logical, and control operations, as well as memory accessand manipulation +|M | RV32M Multiplication and Division Instructions | the standard integer multiplication and division instruction extension, which is named “M” and contains instructions that multiply or divide values held in two integer registers. +|C | RV32C Compressed Instructions | RVC uses a simple compression scheme that offers shorter 16-bit versions of common 32-bit RISC-V instructions when: the immediate or address offset is small; one of the registers is the zero register (x0), the ABI link register (x1), or the ABI stack pointer (x2); the destination register and the first source register are identical; the registers used are the 8 most popular ones.The C extension is compatible with all other standard instruction extensions. The C extension allows 16-bit instructions to be freely intermixed with 32-bit instructions, with the latter now able to start on any 16-bit boundary. With the addition of the C extension, JAL and JALR instructions will no longer raise an instruction misaligned exception +|Zicsr | RV32Zicsr Control and Status Register Instructions | All CSR instructions atomically read-modify-write a single CSR, whose CSR specifier is encoded in the 12-bit csr field of the instruction held in bits 31–20. The immediate forms use a 5-bit zero-extended immediate encoded in the rs1 field. +|Zifencei | RVZifencei Instruction Fetch Fence | FENCE.I instruction that provides explicit synchronization between writes to instruction memory and instruction fetches on the same hart.Currently, this instruction is the only standard mechanism to ensure that stores visible to a hart will also be visible to it instruction fetches. +|Zcb | RV32Zcb Code Size Reduction Instructions | Zcb belongs to the group of extensions called RISC-V Code Size Reduction Extension (Zc*). Zc* has become the superset of the Standard C extension adding more 16-bit instructions to the ISA. Zcb includes the 16-bit version of additional Integer (I), Multiply (M), and Bit-Manipulation (Zbb) Instructions. All the Zcb instructions require at least standard C extension support as a prerequisite, along with M and Zbb extensions for the 16-bit version of the respective instructions. +|Zba | RVZba Address generation instructions | The Zba instructions can be used to accelerate the generation of addresses that index into arrays of basic types (halfword, word, doubleword) using both unsigned word-sized and XLEN-sized indices: a shifted index is added to a base address. The shift and add instructions do a left shift of 1, 2, or 3 because these are commonly found in real-world code and because they can be implemented with a minimal amount of additional hardware beyond that of the simple adder. This avoids lengthening the critical path in implementations. While the shift and add instructions are limited to a maximum left shift of 3, the slli instruction (from the base ISA) can be used to perform similar shifts for indexing into arrays of wider elements. The slli.uw added in this extension can be used when the index is to be interpreted as an unsigned word. +|Zbb | RVZbb Basic bit-manipulation | The bit-manipulation (bitmanip) extension collection is comprised of several component extensions to the base RISC-V architecture that are intended to provide some combination of code size reduction, performance improvement, and energy reduction. While the instructions are intended to have general use, some instructions are more useful in some domains than others. Hence, several smaller bitmanip extensions are provided. Each of these smaller extensions is grouped by common function and use case, and each has its own Zb*-extension name. +|Zbc | RVZbc Carry-less multiplication | Carry-less multiplication is the multiplication in the polynomial ring over GF(2).clmul produces the lower half of the carry-less product and clmulh produces the upper half of the 2✕XLEN carry-less product.clmulr produces bits 2✕XLEN−2:XLEN-1 of the 2✕XLEN carry-less product. +|Zbs | RVZbs Single bit Instructions | The single-bit instructions provide a mechanism to set, clear, invert, or extract a single bit in a register. The bit is specified by its index. +|Zicntr | Zicntr | No info found yet for extension Zicntr +|=== + +==== RV32I Base Integer Instructions + +|=== +| Name | Format | Pseudocode|Invalid_values | Exception_raised | Description| Op Name + +| ADDI | addi rd, rs1, imm[11:0] | x[rd] = x[rs1] + sext(imm[11:0]) | NONE | NONE | add sign-extended 12-bit immediate to register rs1, and store the result in register rd. | Integer_Register_Immediate_Operations +| ANDI | andi rd, rs1, imm[11:0] | x[rd] = x[rs1] & sext(imm[11:0]) | NONE | NONE | perform bitwise AND on register rs1 and the sign-extended 12-bit immediate and place the result in rd. | Integer_Register_Immediate_Operations +| ORI | ori rd, rs1, imm[11:0] | x[rd] = x[rs1] \| sext(imm[11:0]) | NONE | NONE | perform bitwise OR on register rs1 and the sign-extended 12-bit immediate and place the result in rd. | Integer_Register_Immediate_Operations +| XORI | xori rd, rs1, imm[11:0] | x[rd] = x[rs1] ^ sext(imm[11:0]) | NONE | NONE | perform bitwise XOR on register rs1 and the sign-extended 12-bit immediate and place the result in rd. | Integer_Register_Immediate_Operations +| SLTI | slti rd, rs1, imm[11:0] | if (x[rs1] < sext(imm[11:0])) x[rd] = 1 else x[rd] = 0 | NONE | NONE | set register rd to 1 if register rs1 is less than the sign extended immediate when both are treated as signed numbers, else 0 is written to rd. | Integer_Register_Immediate_Operations +| SLTIU | sltiu rd, rs1, imm[11:0] | if (x[rs1] > imm[4:0] | NONE | NONE | logical right shift (zeros are shifted into the upper bits). | Integer_Register_Immediate_Operations +| SRAI | srai rd, rs1, imm[4:0] | x[rd] = x[rs1] >>s imm[4:0] | NONE | NONE | arithmetic right shift (the original sign bit is copied into the vacated upper bits). | Integer_Register_Immediate_Operations +| LUI | lui rd, imm[19:0] | x[rd] = sext(imm[31:12] << 12) | NONE | NONE | place the immediate value in the top 20 bits of the destination register rd, filling in the lowest 12 bits with zeros. | Integer_Register_Immediate_Operations +| AUIPC | auipc rd, imm[19:0] | x[rd] = pc + sext(immediate[31:12] << 12) | NONE | NONE | form a 32-bit offset from the 20-bit immediate, filling in the lowest 12 bits with zeros, adds this offset to the pc, then place the result in register rd. | Integer_Register_Immediate_Operations +| ADD | add rd, rs1, rs2 | x[rd] = x[rs1] + x[rs2] | NONE | NONE | add rs2 to register rs1, and store the result in register rd. | Integer_Register_Register_Operations +| SUB | sub rd, rs1, rs2 | x[rd] = x[rs1] - x[rs2] | NONE | NONE | subtract rs2 from register rs1, and store the result in register rd. | Integer_Register_Register_Operations +| AND | and rd, rs1, rs2 | x[rd] = x[rs1] & x[rs2] | NONE | NONE | perform bitwise AND on register rs1 and rs2 and place the result in rd. | Integer_Register_Register_Operations +| OR | or rd, rs1, rs2 | x[rd] = x[rs1] \| x[rs2] | NONE | NONE | perform bitwise OR on register rs1 and rs2 and place the result in rd. | Integer_Register_Register_Operations +| XOR | xor rd, rs1, rs2 | x[rd] = x[rs1] ^ x[rs2] | NONE | NONE | perform bitwise XOR on register rs1 and rs2 and place the result in rd. | Integer_Register_Register_Operations +| SLT | slt rd, rs1, rs2 | if (x[rs1] < x[rs2]) x[rd] = 1 else x[rd] = 0 | NONE | NONE | set register rd to 1 if register rs1 is less than rs2 when both are treated as signed numbers, else 0 is written to rd. | Integer_Register_Register_Operations +| SLTU | sltu rd, rs1, rs2 | if (x[rs1] > x[rs2] | NONE | NONE | logical right shift (zeros are shifted into the upper bits). | Integer_Register_Register_Operations +| SRA | sra rd, rs1, rs2 | x[rd] = x[rs1] >>s x[rs2] | NONE | NONE | arithmetic right shift (the original sign bit is copied into the vacated upper bits). | Integer_Register_Register_Operations +| JAL | jal rd, imm[20:1] | x[rd] = pc+4; pc += sext(imm[20:1]) | NONE | jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception. | offset is sign-extended and added to the pc to form the jump target address (pc is calculated using signed arithmetic), then setting the least-significant bit of the result to zero, and store the address of instruction following the jump (pc+4) into register rd. | Control_Transfer_Operations-Unconditional_Jumps +| JALR | jalr rd, rs1, imm[11:0] | t = pc+4; pc = (x[rs1]+sext(imm[11:0]))&∼1 ; x[rd] = t | NONE | jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception. | target address is obtained by adding the 12-bit signed immediate to the register rs1 (pc is calculated using signed arithmetic), then setting the least-significant bit of the result to zero, and store the address of instruction following the jump (pc+4) into register rd. | Control_Transfer_Operations-Unconditional_Jumps +| BEQ | beq rs1, rs2, imm[12:1] | if (x[rs1] == x[rs2]) pc += sext({imm[12:1], 1’b0}) else pc += 4 | NONE | no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions. | takes the branch (pc is calculated using signed arithmetic) if registers rs1 and rs2 are equal. | Control_Transfer_Operations-Conditional_Branches +| BNE | bne rs1, rs2, imm[12:1] | if (x[rs1] != x[rs2]) pc += sext({imm[12:1], 1’b0}) else pc += 4 | NONE | no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions. | takes the branch (pc is calculated using signed arithmetic) if registers rs1 and rs2 are not equal. | Control_Transfer_Operations-Conditional_Branches +| BLT | blt rs1, rs2, imm[12:1] | if (x[rs1] < x[rs2]) pc += sext({imm[12:1], 1’b0}) else pc += 4 | NONE | no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions. | takes the branch (pc is calculated using signed arithmetic) if registers rs1 less than rs2 (using signed comparison). | Control_Transfer_Operations-Conditional_Branches +| BLTU | bltu rs1, rs2, imm[12:1] | if (x[rs1] = x[rs2]) pc += sext({imm[12:1], 1’b0}) else pc += 4 | NONE | no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions. | takes the branch (pc is calculated using signed arithmetic) if registers rs1 is greater than or equal rs2 (using signed comparison). | Control_Transfer_Operations-Conditional_Branches +| BGEU | bgeu rs1, rs2, imm[12:1] | if (x[rs1] >=u x[rs2]) pc += sext({imm[12:1], 1’b0}) else pc += 4 | NONE | no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions. | takes the branch (pc is calculated using signed arithmetic) if registers rs1 is greater than or equal rs2 (using unsigned comparison). | Control_Transfer_Operations-Conditional_Branches +| LB | lb rd, imm(rs1) | x[rd] = sext(M[x[rs1] + sext(imm[11:0])][7:0]) | NONE | loads with a destination of x0 must still raise any exceptions and action any other side effects even though the load value is discarded. | loads a 8-bit value from memory, then sign-extends to 32-bit before storing in rd (rd is calculated using signed arithmetic), the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset. | Load_and_Store_Instructions +| LH | lh rd, imm(rs1) | x[rd] = sext(M[x[rs1] + sext(imm[11:0])][15:0]) | NONE | loads with a destination of x0 must still raise any exceptions and action any other side effects even though the load value is discarded, also an exception is raised if the memory address isn't aligned (2-byte boundary). | loads a 16-bit value from memory, then sign-extends to 32-bit before storing in rd (rd is calculated using signed arithmetic), the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset. | Load_and_Store_Instructions +| LW | lw rd, imm(rs1) | x[rd] = sext(M[x[rs1] + sext(imm[11:0])][31:0]) | NONE | loads with a destination of x0 must still raise any exceptions and action any other side effects even though the load value is discarded, also an exception is raised if the memory address isn't aligned (4-byte boundary). | loads a 32-bit value from memory, then storing in rd (rd is calculated using signed arithmetic). The effective address is obtained by adding register rs1 to the sign-extended 12-bit offset. | Load_and_Store_Instructions +| LBU | lbu rd, imm(rs1) | x[rd] = zext(M[x[rs1] + sext(imm[11:0])][7:0]) | NONE | loads with a destination of x0 must still raise any exceptions and action any other side effects even though the load value is discarded. | loads a 8-bit value from memory, then zero-extends to 32-bit before storing in rd (rd is calculated using unsigned arithmetic), the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset. | Load_and_Store_Instructions +| LHU | lhu rd, imm(rs1) | x[rd] = zext(M[x[rs1] + sext(imm[11:0])][15:0]) | NONE | loads with a destination of x0 must still raise any exceptions and action any other side effects even though the load value is discarded, also an exception is raised if the memory address isn't aligned (2-byte boundary). | loads a 16-bit value from memory, then zero-extends to 32-bit before storing in rd (rd is calculated using unsigned arithmetic), the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset. | Load_and_Store_Instructions +| SB | sb rs2, imm(rs1) | M[x[rs1] + sext(imm[11:0])][7:0] = x[rs2][7:0] | NONE | NONE | stores a 8-bit value from the low bits of register rs2 to memory, the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset. | Load_and_Store_Instructions +| SH | sh rs2, imm(rs1) | M[x[rs1] + sext(imm[11:0])][15:0] = x[rs2][15:0] | NONE | an exception is raised if the memory address isn't aligned (2-byte boundary). | stores a 16-bit value from the low bits of register rs2 to memory, the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset. | Load_and_Store_Instructions +| SW | sw rs2, imm(rs1) | M[x[rs1] + sext(imm[11:0])][31:0] = x[rs2][31:0] | NONE | an exception is raised if the memory address isn't aligned (4-byte boundary). | stores a 32-bit value from register rs2 to memory, the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset. | Load_and_Store_Instructions +| FENCE | fence pre, succ | No operation (nop) | NONE | NONE | order device I/O and memory accesses as viewed by other RISC-V harts and external devices or coprocessors. Any combination of device input (I), device output (O), memory reads (R), and memory writes (W) may be ordered with respect to any combination of the same. Informally, no other RISC-V hart or external device can observe any operation in the successor set following a FENCE before any operation in the predecessor set preceding the FENCE, as the core support 1 hart, the fence instruction has no effect so we can considerate it as a nop instruction. | Memory_Ordering +| ECALL | ecall | RaiseException(EnvironmentCall) | NONE | Raise an Environment Call exception. | make a request to the supporting execution environment, which is usually an operating system. The ABI for the system will define how parameters for the environment request are passed, but usually these will be in defined locations in the integer register file. | Environment_Call_and_Breakpoints +| EBREAK | ebreak | x[8 + rd'] = sext(x[8 + rd'][7:0]) | NONE | NONE | This instruction takes a single source/destination operand. It sign-extends the least-significant byte in the operand by copying the most-significant bit in the byte (i.e., bit 7) to all of the more-significant bits. It also requires Bit-Manipulation (Zbb) extension support. | Environment_Call_and_Breakpoints +|=== + +==== RV32M Multiplication and Division Instructions + +|=== +| Name | Format | Pseudocode|Invalid_values | Exception_raised | Description| Op Name + +| MUL | mul rd, rs1, rs2 | x[rd] = x[rs1] * x[rs2] | NONE | NONE | performs a 32-bit × 32-bit multiplication and places the lower 32 bits in the destination register (Both rs1 and rs2 treated as signed numbers). | Multiplication Operations +| MULH | mulh rd, rs1, rs2 | x[rd] = (x[rs1] s*s x[rs2]) >>s 32 | NONE | NONE | performs a 32-bit × 32-bit multiplication and places the upper 32 bits in the destination register of the 64-bit product (Both rs1 and rs2 treated as signed numbers). | Multiplication Operations +| MULHU | mulhu rd, rs1, rs2 | x[rd] = (x[rs1] u*u x[rs2]) >>u 32 | NONE | NONE | performs a 32-bit × 32-bit multiplication and places the upper 32 bits in the destination register of the 64-bit product (Both rs1 and rs2 treated as unsigned numbers). | Multiplication Operations +| MULHSU | mulhsu rd, rs1, rs2 | x[rd] = (x[rs1] s*u x[rs2]) >>s 32 | NONE | NONE | performs a 32-bit × 32-bit multiplication and places the upper 32 bits in the destination register of the 64-bit product (rs1 treated as signed number, rs2 treated as unsigned number). | Multiplication Operations +| DIV | div rd, rs1, rs2 | x[rd] = x[rs1] /s x[rs2] | NONE | NONE | perform signed integer division of 32 bits by 32 bits (rounding towards zero). | Division Operations +| DIVU | divu rd, rs1, rs2 | x[rd] = x[rs1] /u x[rs2] | NONE | NONE | perform unsigned integer division of 32 bits by 32 bits (rounding towards zero). | Division Operations +| REM | rem rd, rs1, rs2 | x[rd] = x[rs1] %s x[rs2] | NONE | NONE | provide the remainder of the corresponding division operation DIV (the sign of rd equals the sign of rs1). | Division Operations +| REMU | rem rd, rs1, rs2 | x[rd] = x[rs1] %u x[rs2] | NONE | NONE | provide the remainder of the corresponding division operation DIVU. | Division Operations +|=== + +==== RV32C Compressed Instructions + +|=== +| Name | Format | Pseudocode|Invalid_values | Exception_raised | Description| Op Name + +| C.LI | c.li rd, imm[5:0] | x[rd] = sext(imm[5:0]) | rd = x0 | NONE | loads the sign-extended 6-bit immediate, imm, into register rd. | Integer Computational Instructions +| C.LUI | c.lui rd, nzimm[17:12] | x[rd] = sext(nzimm[17:12] << 12) | rd = x0 & rd = x2 & nzimm = 0 | NONE | loads the non-zero 6-bit immediate field into bits 17–12 of the destination register, clears the bottom 12 bits, and sign-extends bit 17 into all higher bits of the destination. | Integer Computational Instructions +| C.ADDI | c.addi rd, nzimm[5:0] | x[rd] = x[rd] + sext(nzimm[5:0]) | rd = x0 & nzimm = 0 | NONE | adds the non-zero sign-extended 6-bit immediate to the value in register rd then writes the result to rd. | Integer Computational Instructions +| C.ADDI16SP | c.addi16sp nzimm[9:4] | x[2] = x[2] + sext(nzimm[9:4]) | rd != x2 & nzimm = 0 | NONE | adds the non-zero sign-extended 6-bit immediate to the value in the stack pointer (sp=x2), where the immediate is scaled to represent multiples of 16 in the range (-512,496). C.ADDI16SP is used to adjust the stack pointer in procedure prologues and epilogues. C.ADDI16SP shares the opcode with C.LUI, but has a destination field of x2. | Integer Computational Instructions +| C.ADDI4SPN | c.addi4spn rd', nzimm[9:2] | x[8 + rd'] = x[2] + zext(nzimm[9:2]) | nzimm = 0 | NONE | adds a zero-extended non-zero immediate, scaled by 4, to the stack pointer, x2, and writes the result to rd'. This instruction is used to generate pointers to stack-allocated variables. | Integer Computational Instructions +| C.SLLI | c.slli rd, uimm[5:0] | x[rd] = x[rd] << uimm[5:0] | rd = x0 & uimm[5] = 0 | NONE | performs a logical left shift (zeros are shifted into the lower bits). | Integer Computational Instructions +| C.SRLI | c.srli rd', uimm[5:0] | x[8 + rd'] = x[8 + rd'] >> uimm[5:0] | uimm[5] = 0 | NONE | performs a logical right shift (zeros are shifted into the upper bits). | Integer Computational Instructions +| C.SRAI | c.srai rd', uimm[5:0] | x[8 + rd'] = x[8 + rd'] >>s uimm[5:0] | uimm[5] = 0 | NONE | performs an arithmetic right shift (sign bits are shifted into the upper bits). | Integer Computational Instructions +| C.ANDI | c.andi rd', imm[5:0] | x[8 + rd'] = x[8 + rd'] & sext(imm[5:0]) | NONE | NONE | computes the bitwise AND of the value in register rd', and the sign-extended 6-bit immediate, then writes the result to rd'. | Integer Computational Instructions +| C.ADD | c.add rd, rs2 | x[rd] = x[rd] + x[rs2] | rd = x0 & rs2 = x0 | NONE | adds the values in registers rd and rs2 and writes the result to register rd. | Integer Computational Instructions +| C.MV | c.mv rd, rs2 | x[rd] = x[rs2] | rd = x0 & rs2 = x0 | NONE | copies the value in register rs2 into register rd. | Integer Computational Instructions +| C.AND | c.and rd', rs2' | x[8 + rd'] = x[8 + rd'] & x[8 + rs2'] | NONE | NONE | computes the bitwise AND of of the value in register rd', and register rs2', then writes the result to rd'. | Integer Computational Instructions +| C.OR | c.or rd', rs2' | x[8 + rd'] = x[8 + rd'] \| x[8 + rs2'] | NONE | NONE | computes the bitwise OR of of the value in register rd', and register rs2', then writes the result to rd'. | Integer Computational Instructions +| C.XOR | c.and rd', rs2' | x[8 + rd'] = x[8 + rd'] ^ x[8 + rs2'] | NONE | NONE | computes the bitwise XOR of of the value in register rd', and register rs2', then writes the result to rd'. | Integer Computational Instructions +| C.SUB | c.sub rd', rs2' | x[8 + rd'] = x[8 + rd'] - x[8 + rs2'] | NONE | NONE | subtracts the value in registers rs2' from value in rd' and writes the result to register rd'. | Integer Computational Instructions +| C.EBREAK | c.ebreak | RaiseException(Breakpoint) | NONE | Raise a Breakpoint exception. | cause control to be transferred back to the debugging environment. | Integer Computational Instructions +| C.J | c.j imm[11:1] | pc += sext(imm[11:1]) | NONE | jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception. | performs an unconditional control transfer. The offset is sign-extended and added to the pc to form the jump target address. | Control Transfer Instructions +| C.JAL | c.jal imm[11:1] | x[1] = pc+2; pc += sext(imm[11:1]) | NONE | jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception. | performs the same operation as C.J, but additionally writes the address of the instruction following the jump (pc+2) to the link register, x1. | Control Transfer Instructions +| C.JR | c.jr rs1 | pc = x[rs1] | rs1 = x0 | jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception. | performs an unconditional control transfer to the address in register rs1. | Control Transfer Instructions +| C.JALR | c.jalr rs1 | t = pc+2; pc = x[rs1]; x[1] = t | rs1 = x0 | jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception. | performs the same operation as C.JR, but additionally writes the address of the instruction following the jump (pc+2) to the link register, x1. | Control Transfer Instructions +| C.BEQZ | c.beqz rs1', imm[8:1] | if (x[8+rs1'] == 0) pc += sext(imm[8:1]) | NONE | no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions. | performs conditional control transfers. The offset is sign-extended and added to the pc to form the branch target address. C.BEQZ takes the branch if the value in register rs1' is zero. | Control Transfer Instructions +| C.BNEZ | c.bnez rs1', imm[8:1] | if (x[8+rs1'] != 0) pc += sext(imm[8:1]) | NONE | no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions. | performs conditional control transfers. The offset is sign-extended and added to the pc to form the branch target address. C.BEQZ takes the branch if the value in register rs1' isn't zero. | Control Transfer Instructions +| C.LWSP | c.lwsp rd, uimm(x2) | x[rd] = M[x[2] + zext(uimm[7:2])][31:0] | rd = x0 | loads with a destination of x0 must still raise any exceptions, also an exception if the memory address isn't aligned (4-byte boundary). | loads a 32-bit value from memory into register rd. It computes an effective address by adding the zero-extended offset, scaled by 4, to the stack pointer, x2. | Load and Store Instructions +| C.SWSP | c.swsp rd, uimm(x2) | M[x[2] + zext(uimm[7:2])][31:0] = x[rs2] | NONE | an exception raised if the memory address isn't aligned (4-byte boundary). | stores a 32-bit value in register rs2 to memory. It computes an effective address by adding the zero-extended offset, scaled by 4, to the stack pointer, x2. | Load and Store Instructions +| C.LW | c.lw rd', uimm(rs1') | x[8+rd'] = M[x[8+rs1'] + zext(uimm[6:2])][31:0]) | NONE | an exception raised if the memory address isn't aligned (4-byte boundary). | loads a 32-bit value from memory into register rd'. It computes an effective address by adding the zero-extended offset, scaled by 4, to the base address in register rs1'. | Load and Store Instructions +| C.SW | c.sw rs2', uimm(rs1') | M[x[8+rs1'] + zext(uimm[6:2])][31:0] = x[8+rs2'] | NONE | an exception raised if the memory address isn't aligned (4-byte boundary). | stores a 32-bit value from memory into register rd'. It computes an effective address by adding the zero-extended offset, scaled by 4, to the base address in register rs1'. | Load and Store Instructions +|=== + +==== RV32Zicsr Control and Status Register Instructions + +|=== +| Name | Format | Pseudocode|Invalid_values | Exception_raised | Description| Op Name + +| CSRRW | csrrw rd, csr, rs1 | t = CSRs[csr]; CSRs[csr] = x[rs1]; x[rd] = t | NONE | Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions. | Reads the old value of the CSR, zero-extends the value to 32 bits, then writes it to integer register rd. The initial value in rs1 is written to the CSR. If rd=x0, then the instruction shall not read the CSR and shall not cause any of the side-effects that might occur on a CSR read. | Control and Status Register Operations +| CSRRS | csrrs rd, csr, rs1 | t = CSRs[csr]; CSRs[csr] = t \| x[rs1]; x[rd] = t | NONE | Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions. | Reads the value of the CSR, zero-extends the value to 32 bits, and writes it to integer register rd. The initial value in integer register rs1 is treated as a bit mask that specifies bit positions to be set in the CSR. Any bit that is high in rs1 will cause the corresponding bit to be set in the CSR, if that CSR bit is writable. Other bits in the CSR are unaffected (though CSRs might have side effects when written). If rs1=x0, then the instruction will not write to the CSR at all, and so shall not cause any of the side effects that might otherwise occur on a CSR write, such as raising illegal instruction exceptions on accesses to read-only CSRs. | Control and Status Register Operations +| CSRRC | csrrc rd, csr, rs1 | t = CSRs[csr]; CSRs[csr] = t & ∼x[rs1]; x[rd] = t | NONE | Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions. | Reads the value of the CSR, zero-extends the value to 32 bits, and writes it to integer register rd. The initial value in integer register rs1 is treated as a bit mask that specifies bit positions to be cleared in the CSR. Any bit that is high in rs1 will cause the corresponding bit to be set in the CSR, if that CSR bit is writable. Other bits in the CSR are unaffected (though CSRs might have side effects when written). If rs1=x0, then the instruction will not write to the CSR at all, and so shall not cause any of the side effects that might otherwise occur on a CSR write, such as raising illegal instruction exceptions on accesses to read-only CSRs. | Control and Status Register Operations +| CSRRWI | csrrwi rd, csr, uimm[4:0] | x[rd] = CSRs[csr]; CSRs[csr] = zext(uimm[4:0]) | NONE | Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions. | Reads the old value of the CSR, zero-extends the value to 32 bits, then writes it to integer register rd. The zero-extends immediate is written to the CSR. If rd=x0, then the instruction shall not read the CSR and shall not cause any of the side-effects that might occur on a CSR read. | Control and Status Register Operations +| CSRRSI | csrrsi rd, csr, uimm[4:0] | t = CSRs[csr]; CSRs[csr] = t \| zext(uimm[4:0]); x[rd] = t | NONE | Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions. | Reads the value of the CSR, zero-extends the value to 32 bits, and writes it to integer register rd. The zero-extends immediate value is treated as a bit mask that specifies bit positions to be set in the CSR. Any bit that is high in zero-extends immediate will cause the corresponding bit to be set in the CSR, if that CSR bit is writable. Other bits in the CSR are unaffected (though CSRs might have side effects when written). If the uimm[4:0] field is zero, then these instructions will not write to the CSR, and shall not cause any of the side effects that might otherwise occur on a CSR write. | Control and Status Register Operations +| CSRRCI | csrrci rd, csr, uimm[4:0] | t = CSRs[csr]; CSRs[csr] = t & ∼zext(uimm[4:0]); x[rd] = t | NONE | Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions. | Reads the value of the CSR, zero-extends the value to 32 bits, and writes it to integer register rd. The zero-extends immediate value is treated as a bit mask that specifies bit positions to be cleared in the CSR. Any bit that is high in zero-extends immediate will cause the corresponding bit to be set in the CSR, if that CSR bit is writable. Other bits in the CSR are unaffected (though CSRs might have side effects when written). If the uimm[4:0] field is zero, then these instructions will not write to the CSR, and shall not cause any of the side effects that might otherwise occur on a CSR write. | Control and Status Register Operations +|=== + +==== RVZifencei Instruction Fetch Fence + +|=== +| Name | Format | Pseudocode|Invalid_values | Exception_raised | Description| Op Name + +| FENCE.I | fence.i | Fence(Store, Fetch) | NONE | NONE | The FENCE.I instruction is used to synchronize the instruction and data streams. RISC-V does not guarantee that stores to instruction memory will be made visible to instruction fetches on the same RISC-V hart until a FENCE.I instruction is executed. A FENCE.I instruction only ensures that a subsequent instruction fetch on a RISC-V hart will see any previous data stores already visible to the same RISC-V hart. | Fetch Fence Operations +|=== + +==== RV32Zcb Code Size Reduction Instructions + +|=== +| Name | Format | Pseudocode|Invalid_values | Exception_raised | Description| Op Name + +| C.ZEXT.B | c.zext.b rd' | x[8 + rd'] = zext(x[8 + rd'][7:0]) | NONE | NONE | This instruction takes a single source/destination operand. It zero-extends the least-significant byte of the operand by inserting zeros into all of the bits more significant than 7. | Code Size Reduction Operations +| C.SEXT.B | c.sext.b rd' | x[8 + rd'] = sext(x[8 + rd'][7:0]) | NONE | NONE | This instruction takes a single source/destination operand. It sign-extends the least-significant byte in the operand by copying the most-significant bit in the byte (i.e., bit 7) to all of the more-significant bits. It also requires Bit-Manipulation (Zbb) extension support. | Code Size Reduction Operations +| C.ZEXT.H | c.zext.h rd' | x[8 + rd'] = zext(x[8 + rd'][15:0]) | NONE | NONE | This instruction takes a single source/destination operand. It zero-extends the least-significant halfword of the operand by inserting zeros into all of the bits more significant than 15. It also requires Bit-Manipulation (Zbb) extension support. | Code Size Reduction Operations +| C.SEXT.H | c.sext.h rd' | x[8 + rd'] = sext(x[8 + rd'][15:0]) | NONE | NONE | This instruction takes a single source/destination operand. It sign-extends the least-significant halfword in the operand by copying the most-significant bit in the halfword (i.e., bit 15) to all of the more-significant bits. It also requires Bit-Manipulation (Zbb) extension support. | Code Size Reduction Operations +| C.NOT | c.not rd' | x[8 + rd'] = x[8 + rd'] ^ -1 | NONE | NONE | This instruction takes the one’s complement of rd'/rs1' and writes the result to the same register. | Code Size Reduction Operations +| C.MUL | c.mul rd', rs2' | x[8 + rd'] = (x[8 + rd'] * x[8 + rs2'])[31:0] | NONE | NONE | performs a 32-bit × 32-bit multiplication and places the lower 32 bits in the destination register (Both rd' and rs2' treated as signed numbers). It also requires M extension support. | Code Size Reduction Operations +| C.LHU | c.lhu rd', uimm(rs1') | x[8+rd'] = zext(M[x[8+rs1'] + zext(uimm[1])][15:0]) | NONE | an exception raised if the memory address isn't aligned (2-byte boundary). | This instruction loads a halfword from the memory address formed by adding rs1' to the zero extended immediate uimm. The resulting halfword is zero extended and is written to rd'. | Code Size Reduction Operations +| C.LH | c.lh rd', uimm(rs1') | x[8+rd'] = sext(M[x[8+rs1'] + zext(uimm[1])][15:0]) | NONE | an exception raised if the memory address isn't aligned (2-byte boundary). | This instruction loads a halfword from the memory address formed by adding rs1' to the zero extended immediate uimm. The resulting halfword is sign extended and is written to rd'. | Code Size Reduction Operations +| C.LBU | c.lbu rd', uimm(rs1') | x[8+rd'] = zext(M[x[8+rs1'] + zext(uimm[1:0])][7:0]) | NONE | NONE | This instruction loads a byte from the memory address formed by adding rs1' to the zero extended immediate uimm. The resulting byte is zero extended and is written to rd'. | Code Size Reduction Operations +| C.SH | c.sh rs2', uimm(rs1') | M[x[8+rs1'] + zext(uimm[1])][15:0] = x[8+rs2'] | NONE | an exception raised if the memory address isn't aligned (2-byte boundary). | This instruction stores the least significant halfword of rs2' to the memory address formed by adding rs1' to the zero extended immediate uimm. | Code Size Reduction Operations +| C.SB | c.sb rs2', uimm(rs1') | M[x[8+rs1'] + zext(uimm[1:0])][7:0] = x[8+rs2'] | NONE | NONE | This instruction stores the least significant byte of rs2' to the memory address formed by adding rs1' to the zero extended immediate uimm. | Code Size Reduction Operations +|=== + +==== RVZba Address generation instructions + +|=== +| Name | Format | Pseudocode|Invalid_values | Exception_raised | Description| Op Name + +| ADD.UW | add.uw rd, rs1, rs2 | X(rd) = rs2 + EXTZ(X(rs1)[31..0]) | NONE | NONE | This instruction performs an XLEN-wide addition between rs2 and the zero-extended least-significant word of rs1. | Address generation instructions +| SH1ADD | sh1add rd, rs1, rs2 | X(rd) = X(rs2) + (X(rs1) << 1) | NONE | NONE | This instruction shifts rs1 to the left by 1 bit and adds it to rs2. | Address generation instructions +| SH1ADD.UW | sh1add.uw rd, rs1, rs2 | X(rd) = rs2 + (EXTZ(X(rs1)[31..0]) << 1) | NONE | NONE | This instruction performs an XLEN-wide addition of two addends. The first addend is rs2. The second addend is the unsigned value formed by extracting the least-significant word of rs1 and shifting it left by 1 place. | Address generation instructions +| SH2ADD | sh2add rd, rs1, rs2 | X(rd) = X(rs2) + (X(rs1) << 2) | NONE | NONE | This instruction shifts rs1 to the left by 2 bit and adds it to rs2. | Address generation instructions +| SH2ADD.UW | sh2add.uw rd, rs1, rs2 | X(rd) = rs2 + (EXTZ(X(rs1)[31..0]) << 2) | NONE | NONE | This instruction performs an XLEN-wide addition of two addends. The first addend is rs2. The second addend is the unsigned value formed by extracting the least-significant word of rs1 and shifting it left by 2 places. | Address generation instructions +| SH3ADD | sh3add rd, rs1, rs2 | X(rd) = X(rs2) + (X(rs1) << 3) | NONE | NONE | This instruction shifts rs1 to the left by 3 bit and adds it to rs2. | Address generation instructions +| SH3ADD.UW | sh3add.uw rd, rs1, rs2 | X(rd) = rs2 + (EXTZ(X(rs1)[31..0]) << 3) | NONE | NONE | This instruction performs an XLEN-wide addition of two addends. The first addend is rs2. The second addend is the unsigned value formed by extracting the least-significant word of rs1 and shifting it left by 3 places. | Address generation instructions +| SLLI.UW | slli.uw rd, rs1, imm | X(rd) = (EXTZ(X(rs)[31..0]) << imm) | NONE | NONE | This instruction takes the least-significant word of rs1, zero-extends it, and shifts it left by the immediate. | Address generation instructions +|=== + +==== RVZbb Basic bit-manipulation + +|=== +| Name | Format | Pseudocode|Invalid_values | Exception_raised | Description| Op Name + +| ANDN | andn rd, rs1, rs2 | X(rd) = X(rs1) & ~X(rs2) | NONE | NONE | Performs bitwise AND operation between rs1 and bitwise inversion of rs2. | Logical_with_negate +| ORN | orn rd, rs1, rs2 | X(rd) = X(rs1) \| ~X(rs2) | NONE | NONE | Performs bitwise OR operation between rs1 and bitwise inversion of rs2. | Logical_with_negate +| XNOR | xnor rd, rs1, rs2 | X(rd) = ~(X(rs1) ^ X(rs2)) | NONE | NONE | Performs bitwise XOR operation between rs1 and rs2, then complements the result. | Logical_with_negate +| CLZ | clz rd, rs | if [x[i]] == 1 then return(i) else return -1 | NONE | NONE | Counts leading zero bits in rs. | Count_leading_trailing_zero_bits +| CTZ | ctz rd, rs | if [x[i]] == 1 then return(i) else return xlen; | NONE | NONE | Counts trailing zero bits in rs. | Count_leading_trailing_zero_bits +| CLZW | clzw rd, rs | if [x[i]] == 1 then return(i) else return -1 | NONE | NONE | Counts leading zero bits in the least-significant word of rs. | Count_leading_trailing_zero_bits +| CTZW | ctzw rd, rs | if [x[i]] == 1 then return(i) else return 32; | NONE | NONE | Counts trailing zero bits in the least-significant word of rs. | Count_leading_trailing_zero_bits +| CPOP | cpop rd, rs | if rs[i] == 1 then bitcount = bitcount + 1 else () | NONE | NONE | Counts set bits in rs. | Count_population +| CPOPW | cpopw rd, rs | if rs[i] == 0b1 then bitcount = bitcount + 1 else () | NONE | NONE | Counts set bits in the least-significant word of rs. | Count_population +| MAX | max rd, rs1, rs2 | if rs1_val <_s rs2_val then rs2_val else rs1_val | NONE | NONE | Returns the larger of two signed integers. | Integer_minimum_maximum +| MAXU | maxu rd, rs1, rs2 | if rs1_val <_u rs2_val then rs2_val else rs1_val | NONE | NONE | Returns the larger of two unsigned integers. | Integer_minimum_maximum +| MIN | min rd, rs1, rs2 | if rs1_val <_s rs2_val then rs1_val else rs2_val | NONE | NONE | Returns the smaller of two signed integers. | Integer_minimum_maximum +| MINU | minu rd, rs1, rs2 | if rs1_val <_u rs2_val then rs1_val else rs2_val | NONE | NONE | Returns the smaller of two unsigned integers. | Integer_minimum_maximum +| SEXT.B | sext.b rd, rs | X(rd) = EXTS(X(rs)[7..0]) | NONE | NONE | Sign-extends the least-significant byte in the source to XLEN. | Sign_and_zero_extension +| SEXT.H | sext.h rd, rs | X(rd) = EXTS(X(rs)[15..0]) | NONE | NONE | Sign-extends the least-significant halfword in rs to XLEN. | Sign_and_zero_extension +| ZEXT.H | zext.h rd, rs | X(rd) = EXTZ(X(rs)[15..0]) | NONE | NONE | Zero-extends the least-significant halfword of the source to XLEN. | Sign_and_zero_extension +| ROL | rol rd, rs1, rs2 | (X(rs1) << log2(XLEN)) \| (X(rs1) >> (xlen - log2(XLEN))) | NONE | NONE | Performs a rotate left of rs1 by the amount in least-significant log2(XLEN) bits of rs2. | Bitwise_rotation +| ROR | ror rd, rs1, rs2 | (X(rs1) >> log2(XLEN)) \| (X(rs1) << (xlen - log2(XLEN))) | NONE | NONE | Performs a rotate right of rs1 by the amount in least-significant log2(XLEN) bits of rs2. | Bitwise_rotation +| RORI | rori rd, rs1, shamt | (X(rs1) >> log2(XLEN)) \| (X(rs1) << (xlen - log2(XLEN))) | NONE | NONE | Performs a rotate right of rs1 by the amount in least-significant log2(XLEN) bits of shamt. | Bitwise_rotation +| ROLW | rolw rd, rs1, rs2 | EXTS((rs1 << X(rs2)[4..0]) \| (rs1 >> (32 - X(rs2)[4..0]))) | NONE | NONE | Performs a rotate left on the least-significant word of rs1 by the amount in least-significant 5 bits of rs2. | Bitwise_rotation +| RORIW | roriw rd, rs1, shamt | (rs1_data >> shamt[4..0]) \| (rs1_data << (32 - shamt[4..0])) | NONE | NONE | Performs a rotate right on the least-significant word of rs1 by the amount in least-significant log2(XLEN) bits of shamt. | Bitwise_rotation +| RORW | rorw rd, rs1, rs2 | (rs1 >> X(rs2)[4..0]) \| (rs1 << (32 - X(rs2)[4..0])) | NONE | NONE | Performs a rotate right on the least-significant word of rs1 by the amount in least-significant 5 bits of rs2. | Bitwise_rotation +| ORC.b | orc.b rd, rs | if { input[(i + 7)..i] == 0 then 0b00000000 else 0b11111111 | NONE | NONE | Sets the bits of each byte in rd to all zeros if no bit within the respective byte of rs is set, or to all ones if any bit within the respective byte of rs is set. | OR_Combine +| REV8 | rev8 rd, rs | output[i..(i + 7)] = input[(j - 7)..j] | NONE | NONE | Reverses the order of the bytes in rs. | Byte_reverse +|=== + +==== RVZbc Carry-less multiplication + +|=== +| Name | Format | Pseudocode|Invalid_values | Exception_raised | Description| Op Name + +| CLMUL | clmul rd, rs1, rs2 | foreach (i from 1 to xlen by 1) { output = if ((rs2 >> i) & 1) then output ^ (rs1 << i); else output;} | NONE | NONE | clmul produces the lower half of the 2.XLEN carry-less product. | Carry-less multiplication Operations +| CLMULH | clmulh rd, rs1, rs2 | foreach (i from 1 to xlen by 1) { output = if ((rs2_val >> i) & 1) then output ^ (rs1_val >> (xlen - i)) else output} | NONE | NONE | clmulh produces the upper half of the 2.XLEN carry-less product. | Carry-less multiplication Operations +| CLMULR | clmulr rd, rs1, rs2 | foreach (i from 0 to (xlen - 1) by 1) { output = if ((rs2_val >> i) & 1) then output ^ (rs1_val >> (xlen - i - 1)) else output} | NONE | NONE | clmulr produces bits 2.XLEN-2:XLEN-1 of the 2.XLEN carry-less product. | Carry-less multiplication Operations +|=== + +==== RVZbs Single bit Instructions + +|=== +| Name | Format | Pseudocode|Invalid_values | Exception_raised | Description| Op Name + +| BCLR | bclr rd, rs1, rs2 | X(rd) = X(rs1) & ~(1 << (X(rs2) & (XLEN - 1))) | NONE | NONE | This instruction returns rs1 with a single bit cleared at the index specified in rs2. The index is read from the lower log2(XLEN) bits of rs2. | Single_bit_Operations +| BCLRI | bclri rd, rs1, shamt | X(rd) = X(rs1) & ~(1 << (shamt & (XLEN - 1))) | NONE | NONE | This instruction returns rs1 with a single bit cleared at the index specified in shamt. The index is read from the lower log2(XLEN) bits of shamt. For RV32, the encodings corresponding to shamt[5]=1 are reserved. | Single_bit_Operations +| BEXT | bext rd, rs1, rs2 | X(rd) = (X(rs1) >> (X(rs2) & (XLEN - 1))) & 1 | NONE | NONE | This instruction returns a single bit extracted from rs1 at the index specified in rs2. The index is read from the lower log2(XLEN) bits of rs2. | Single_bit_Operations +| BEXTI | bexti rd, rs1, shamt | X(rd) = (X(rs1) >> (shamt & (XLEN - 1))) & 1 | NONE | NONE | This instruction returns a single bit extracted from rs1 at the index specified in rs2. The index is read from the lower log2(XLEN) bits of shamt. For RV32, the encodings corresponding to shamt[5]=1 are reserved. | Single_bit_Operations +| BINV | binv rd, rs1, rs2 | X(rd) = X(rs1) ^ (1 << (X(rs2) & (XLEN - 1))) | NONE | NONE | This instruction returns rs1 with a single bit inverted at the index specified in rs2. The index is read from the lower log2(XLEN) bits of rs2. | Single_bit_Operations +| BINVI | binvi rd, rs1, shamt | X(rd) = X(rs1) ^ (1 << (shamt & (XLEN - 1))) | NONE | NONE | This instruction returns rs1 with a single bit inverted at the index specified in shamt. The index is read from the lower log2(XLEN) bits of shamt. For RV32, the encodings corresponding to shamt[5]=1 are reserved. | Single_bit_Operations +| BSET | bset rd, rs1, rs2 | X(rd) = X(rs1) \| (1 << (X(rs2) & (XLEN - 1))) | NONE | NONE | This instruction returns rs1 with a single bit set at the index specified in rs2. The index is read from the lower log2(XLEN) bits of rs2. | Single_bit_Operations +| BSETI | bseti rd, rs1, shamt | X(rd) = X(rs1) \| (1 << (shamt & (XLEN - 1))) | NONE | NONE | This instruction returns rs1 with a single bit set at the index specified in shamt. The index is read from the lower log2(XLEN) bits of shamt. For RV32, the encodings corresponding to shamt[5]=1 are reserved. | Single_bit_Operations +|=== + diff --git a/config/gen_from_riscv_config/scripts/libs/utils.py b/config/gen_from_riscv_config/scripts/libs/utils.py index 6bfbc2c99c..0a620462b2 100644 --- a/config/gen_from_riscv_config/scripts/libs/utils.py +++ b/config/gen_from_riscv_config/scripts/libs/utils.py @@ -539,6 +539,191 @@ def returnAsString(self): r.table(header=_headers, data=reg_table) return r.data +class AdocAddressBlock(AddressBlockClass): + """Generates an AsciiDoc file from a IP-XACT register description""" + + def __init__(self, name): + super().__init__("csr") + self.name = name + self.registerList = [] + self.suffix = ".adoc" + + def get_access_privilege(self, reg): + """Registers with address bits [11:10] == 2'b11 are Read-Only + as per privileged ISA spec.""" + # Handle register address ranges separated by dashes. + if (int(reg.address.split("-")[0], 0) & 0xC00) == 0xC00: + return "RO" + else: + return "RW" + + def generate_label(self, name): + return "_" + name.replace('[','').replace(']','').upper() + + def returnAsString(self): + registerlist = sorted(self.registerList, key=lambda reg: reg.address) + r = "" + regNameList = [reg.name.upper() for reg in registerlist] + regAddressList = [reg.address for reg in registerlist] + regPrivModeList = [reg.access for reg in registerlist] + regPrivAccessList = [self.get_access_privilege(reg) for reg in registerlist] + regDescrList = [reg.desc for reg in registerlist] + regRV32List = [reg.RV32 for reg in registerlist] + regRV64List = [reg.RV64 for reg in registerlist] + + r += "////\n" + r += " Copyright (c) 2024 OpenHW Group\n" + r += " Copyright (c) 2024 Thales\n" + r += " SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1\n" + r += " Author: Abdessamii Oukalrazqou\n" + r += "////\n\n" + + r += "=== %s\n\n"%self.name + r += "==== Conventions\n\n" + + r += "In the subsequent sections, register fields are labeled with one of the following abbreviations:\n\n" + + r += "* WPRI (Writes Preserve Values, Reads Ignore Values): read/write field reserved\n" + r += "for future use. For forward compatibility, implementations that do not\n" + r += "furnish these fields must make them read-only zero.\n" + + r += "* WLRL (Write/Read Only Legal Values): read/write CSR field that specifies\n" + r += "behavior for only a subset of possible bit encodings, with other bit encodings\n" + r += "reserved.\n" + + r += "* WARL (Write Any Values, Reads Legal Values): read/write CSR fields which are\n" + r += "only defined for a subset of bit encodings, but allow any value to be written\n" + r += "while guaranteeing to return a legal value whenever read.\n" + + r += "* ROCST (Read-Only Constant): A special case of WARL field which admits only one\n" + r += "legal value, and therefore, behaves as a constant field that silently ignores\n" + r += "writes.\n" + + r += "* ROVAR (Read-Only Variable): A special case of WARL field which can take\n" + r += "multiple legal values but cannot be modified by software and depends only on\n" + r += "the architectural state of the hart.\n\n" + + r += "In particular, a register that is not internally divided\n" + r += "into multiple fields can be considered as containing a single field of XLEN bits.\n" + r += "This allows to clearly represent read-write registers holding a single legal value\n" + r += "(typically zero).\n\n" + + r += "==== Register Summary\n\n" + + r += "|===\n" + r += "|Address | Register Name | Privilege | Description\n\n" + for i, _ in enumerate(regNameList): + if regRV32List[i] | regRV64List[i]: + r += "|" + regAddressList[i] + \ + f"| `<<{self.generate_label(regNameList[i])},{regNameList[i].upper()}>>`" + \ + "|" + regPrivModeList[i] + regPrivAccessList[i] + \ + "|" + str(regDescrList[i]) + "\n" + r += "|===\n\n" + + r += "==== Register Description\n\n" + for reg in registerlist: + if reg.RV32 | reg.RV64: + r += "[[%s]]\n"%self.generate_label(reg.name) + r += "===== %s\n\n"%reg.name.upper() + + r += "Address:: %s\n"%reg.address + if reg.resetValue: + # display the resetvalue in hex notation in the full length of the register + r += "Reset Value:: 0x%s\n"%f"{reg.resetValue[2:].zfill(int(reg.size/4))}" + # RO/RW privileges are encoded in register address. + r += "Privilege:: %s\n"%(reg.access + self.get_access_privilege(reg)) + r += "Description:: %s\n\n"%(reg.desc) + + reg_table = [] + for field in reg.field: + if field.bitWidth == 1: # only one bit -> no range needed + bits = f"{field.bitlsb}" + else: + bits = f"[{field.bitmsb}:{field.bitlsb}]" + _line = [ + bits, + field.name.upper(), + field.fieldreset, + field.fieldaccess, + ( + Render.bitmask(field.andMask, field.orMask) + if field.andMask and field.orMask + else field.bitlegal + ), + ] + _line.append(field.fieldDesc) + reg_table.append(_line) + + reg_table = sorted( + reg_table, key=lambda x: int(x[0].strip("[]").split(":")[0]) + ) + # table of the register + r += "|===\n" + r += "| Bits | Field Name | Reset Value | Type | Legal Values | Description\n\n" + for reg in reg_table: + for col in reg: + r +="| %s "%col.replace('\n','') + r += "\n" + r += "|===\n\n" + + return r + +class InstadocBlock(InstructionBlockClass): + """Generates a ISA AsciiDoc file from RISC-V Config Yaml register description""" + + def __init__(self, name): + super().__init__("isa") + self.name = name + self.Instructionlist = [] + self.suffix = ".adoc" + + def returnAsString(self): + r = "" + InstrNameList = [reg.key for reg in self.Instructionlist] + InstrDescrList = [reg.descr for reg in self.Instructionlist] + InstrExtList = [reg.Extension_Name for reg in self.Instructionlist] + + r += "////\n" + r += " Copyright (c) 2024 OpenHW Group\n" + r += " Copyright (c) 2024 Thales\n" + r += " SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1\n" + r += " Author: Abdessamii Oukalrazqou\n" + r += "////\n\n" + + r += "=== %s\n\n"%self.name + r += "==== Instructions\n\n" + + r += "|===\n" + r += "|Subset Name | Name | Description\n\n" + for i, _ in enumerate(InstrNameList): + r += "|%s | %s | %s\n"%(str(InstrExtList[i]), + str(InstrNameList[i]), + str(InstrDescrList[i]).replace('\n','')) + r += "|===\n\n" + + for reg in self.Instructionlist: + reg_table = [] + if len(reg.Name) > 0: + r += "==== %s\n\n"%reg.key + r += "|===\n" + r += "| Name | Format | Pseudocode|Invalid_values | Exception_raised | Description| Op Name\n\n" + + for fieldIndex in list(range(len(reg.Name))): + _line = [ + reg.Name[fieldIndex], + reg.Format[fieldIndex], + reg.pseudocode[fieldIndex].replace('|','\|'), + reg.invalid_values[fieldIndex], + reg.exception_raised[fieldIndex], + reg.Description[fieldIndex], + ] + _line.append(reg.OperationName[fieldIndex]) + + for col in _line: + r +="| %s "%col.replace('\n','') + r += "\n" + r += "|===\n\n" + return r class InstmdBlock(InstructionBlockClass): """Generates an ISA Markdown file from a RISC Config Yaml register description""" diff --git a/config/gen_from_riscv_config/scripts/riscv_config_gen.py b/config/gen_from_riscv_config/scripts/riscv_config_gen.py index 78cd82263c..fd18c2afaf 100644 --- a/config/gen_from_riscv_config/scripts/riscv_config_gen.py +++ b/config/gen_from_riscv_config/scripts/riscv_config_gen.py @@ -23,8 +23,10 @@ from libs.utils import IsaGenerator from libs.utils import CsrGenerator from libs.utils import RstAddressBlock +from libs.utils import AdocAddressBlock from libs.utils import MdAddressBlock from libs.utils import InstrstBlock +from libs.utils import InstadocBlock from libs.utils import InstmdBlock if __name__ == "__main__": @@ -35,13 +37,28 @@ parser.add_argument("-m", "--modif", help="ISA /CSR Formatter if exist") parser.add_argument("-i", "--temp", help="Full ISA /SPIKETemplate") parser.add_argument("-t", "--target", help="Specifiy Config Name") + parser.add_argument("-f", "--format", help="Specifiy format output") args, unknown_args = parser.parse_known_args() + + if args.format in ['rst']: + C_instrBlock = InstrstBlock + C_AddressBlock = RstAddressBlock + elif args.format in ['adoc']: + C_instrBlock = InstadocBlock + C_AddressBlock = AdocAddressBlock + elif args.format in ['md']: + C_instrBlock = InstmdBlock + C_AddressBlock = MdAddressBlock + else: + C_instrBlock = InstrstBlock + C_AddressBlock = RstAddressBlock + if args.temp: if "isa" in args.temp: e = IsaParser(args.srcFile, args.temp, args.target, args.modif) document = e.returnDocument() generator = IsaGenerator(args.target) - generator.generateISA(InstrstBlock, document) + generator.generateISA(C_instrBlock, document) elif "spike" in args.temp: e = SpikeParser(args.srcFile, args.target) document = e.returnDocument() @@ -51,4 +68,4 @@ e = CsrParser(args.srcFile, args.customFile, args.target, args.modif) document = e.returnDocument() generator = CsrGenerator(args.target) - generator.generateCSR(RstAddressBlock, document) + generator.generateCSR(C_AddressBlock, document) diff --git a/docs/04_cv32a65x/riscv/src/config.adoc b/docs/04_cv32a65x/config/config.adoc similarity index 95% rename from docs/04_cv32a65x/riscv/src/config.adoc rename to docs/04_cv32a65x/config/config.adoc index c41149b11e..1983cd1300 100644 --- a/docs/04_cv32a65x/riscv/src/config.adoc +++ b/docs/04_cv32a65x/config/config.adoc @@ -47,3 +47,5 @@ :MTvalEn: false :MTvecDirectEn: true :note: false +:DebugEn: false +:MmuPresent: false diff --git a/docs/04_cv32a65x/design/Makefile b/docs/04_cv32a65x/design/Makefile index 974e00577e..b48cea0b29 100644 --- a/docs/04_cv32a65x/design/Makefile +++ b/docs/04_cv32a65x/design/Makefile @@ -1,38 +1,10 @@ +# Copyright 2024 Thales DIS France SAS +# Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); +# you may not use this file except in compliance with the License. +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +# You may obtain a copy of the License at https://solderpad.org/licenses/ # -# Copyright (c) 2020 OpenHW Group -# -# Licensed under the Solderpad Hardware Licence, 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 -# -# https://solderpad.org/licenses/ -# -# 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 WITH SHL-2.0 -# -############################################################################### -# -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -SOURCEDIR = source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile +# Original Author: Thales DIS -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) +CONFIG := cv32a65x +include ../../design/build.mk diff --git a/docs/04_cv32a65x/design/design-cv32a65x.html b/docs/04_cv32a65x/design/design-cv32a65x.html new file mode 100644 index 0000000000..a191b6a607 --- /dev/null +++ b/docs/04_cv32a65x/design/design-cv32a65x.html @@ -0,0 +1,12954 @@ + + + + + + + + +Design Documentation for CV32A65X architecture + + + + + +
+
+
+
+

Editor: Jean Roch Coulon

+
+
+
+
+

1. Introduction

+
+
+

The OpenHW Group uses semantic versioning to +describe the release status of its IP. This document describes the +CV32A65X configuration version of CVA6. This intends to be the first +formal release of CVA6.

+
+
+

CVA6 is a 6-stage in-order and single issue processor core which +implements the RISC-V instruction set. CVA6 can be configured as a 32- +or 64-bit core (RV32 or RV64), called CV32A6 or CV64A6.

+
+
+

The objective of this document is to provide enough information to allow +the RTL modification (by designers) and the RTL verification (by +verificators). This document is not dedicated to CVA6 users looking for +information to develop software like instructions or registers.

+
+
+

The CVA6 architecture is illustrated in the following figure.

+
+
+

CVA6 Architecture

+
+
+

1.1. License

+
+
Copyright 2022 Thales
+Copyright 2018 ETH Zürich and University of Bologna
+SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
+Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file except in compliance with the License, or, at your option, the Apache License version 2.0. You may obtain a copy of the License at https://solderpad.org/licenses/SHL-2.1/.
+Unless required by applicable law or agreed to in writing, any work 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.
+
+
+
+

1.2. Standards Compliance

+
+

To ease the reading, the reference to these specifications can be +implicit in the requirements below. For the sake of precision, the +requirements identify the versions of RISC-V extensions from these +specifications.

+
+
+ +
+
+

CV32A6 is a standards-compliant 32-bit processor fully compliant with +RISC-V specifications: [RVunpriv], [RVpriv] and [RVdbg] and passes +[RVcompat] compatibility tests, as requested by [GEN-10] in [CVA6req].

+
+
+
+

1.3. Documentation framework

+
+

The framework of this document is inspired by the Common Criteria. The +Common Criteria for Information Technology Security Evaluation (referred +to as Common Criteria or CC) is an international standard (ISO/IEC +15408) for computer security certification.

+
+
+

Description of the framework:

+
+
+
    +
  • +

    Processor is split into module corresponding to the main modules of +the design

    +
  • +
  • +

    Modules can contain several modules

    +
  • +
  • +

    Each module is described in a chapter, which contains the following +subchapters: Description, Functionalities, Architecture and +Modules and Registers (if any)

    +
  • +
  • +

    The subchapter Description describes the main features of the +submodule, the interconnections between the current module and the +others and the inputs/outputs interface.

    +
  • +
  • +

    The subchapter Functionality lists in details the module +functionalities. Please avoid using the RTL signal names to explain the +functionalities.

    +
  • +
  • +

    The subchapter Architecture and Modules provides a drawing to +present the module hierarchy, then the functionalities covered by the +module

    +
  • +
  • +

    The subchapter Registers specifies the module registers if any

    +
  • +
+
+
+
+

1.4. Contributors

+
+
Jean-Roch Coulon - Thales
+Ayoub Jalali (ayoub.jalali@external.thalesgroup.com)
+Alae Eddine Ezzejjari (alae-eddine.ez-zejjari@external.thalesgroup.com)
+
+
+

[TO BE COMPLETED]

+
+
+
+
+
+

2. Subsystem

+
+
+

2.1. Global functionality

+
+

The CVA6 is a subsystem composed of the modules and protocol interfaces +as illustrated The processor is a Harvard-based modern architecture. +Instructions are issued in-order through the DECODE stage and executed +out-of-order but committed in-order. The processor is Single issue, that +means that at maximum one instruction per cycle can be issued to the +EXECUTE stage.

+
+
+

The CVA6 implements a 6-stage pipeline composed of PC Generation, +Instruction Fetch, Instruction Decode, Issue stage, Execute stage and +Commit stage. At least 6 cycles are needed to execute one instruction.

+
+
+
+

2.2. Connection with other sub-systems

+
+

The submodule is connected to :

+
+
+
    +
  • +

    NOC interconnect provides memory content

    +
  • +
  • +

    COPROCESSOR connects through CV-X-IF coprocessor interface protocol

    +
  • +
  • +

    TRACER provides support for verification

    +
  • +
  • +

    TRAP provides traps inputs

    +
  • +
+
+
+
+

2.3. Parameter configuration

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1. cv32a65x parameter configuration
Namedescriptiondescription

XLEN

General Purpose Register Size (in bits)

32

RVA

Atomic RISC-V extension

False

RVB

Bit manipulation RISC-V extension

True

RVV

Vector RISC-V extension

False

RVC

Compress RISC-V extension

True

RVH

Hypervisor RISC-V extension

False

RVZCB

Zcb RISC-V extension

True

RVZCMP

Zcmp RISC-V extension

False

RVZiCond

Zicond RISC-V extension

False

RVZicntr

Zicntr RISC-V extension

False

RVZihpm

Zihpm RISC-V extension

False

RVF

Floating Point

False

RVD

Floating Point

False

XF16

Non standard 16bits Floating Point extension

False

XF16ALT

Non standard 16bits Floating Point Alt extension

False

XF8

Non standard 8bits Floating Point extension

False

XFVec

Non standard Vector Floating Point extension

False

PerfCounterEn

Perf counters

False

MmuPresent

MMU

False

RVS

Supervisor mode

False

RVU

User mode

False

DebugEn

Debug support

False

DmBaseAddress

Base address of the debug module

0x0

HaltAddress

Address to jump when halt request

0x800

ExceptionAddress

Address to jump when exception

0x808

TvalEn

Tval Support Enable

False

DirectVecOnly

MTVEC CSR supports only direct mode

True

NrPMPEntries

PMP entries number

8

PMPCfgRstVal

PMP CSR configuration reset values

[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]

PMPAddrRstVal

PMP CSR address reset values

[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]

PMPEntryReadOnly

PMP CSR read-only bits

0

NrNonIdempotentRules

PMA non idempotent rules number

0

NonIdempotentAddrBase

PMA NonIdempotent region base address

[0b0, 0b0]

NonIdempotentLength

PMA NonIdempotent region length

[0b0, 0b0]

NrExecuteRegionRules

PMA regions with execute rules number

0

ExecuteRegionAddrBase

PMA Execute region base address

[0x80000000, 0x10000, 0x0]

ExecuteRegionLength

PMA Execute region address base

[0x40000000, 0x10000, 0x1000]

NrCachedRegionRules

PMA regions with cache rules number

1

CachedRegionAddrBase

PMA cache region base address

[0x80000000]

CachedRegionLength

PMA cache region rules

[0x40000000]

CvxifEn

CV-X-IF coprocessor interface enable

True

NOCType

NOC bus type

config_pkg::NOC_TYPE_AXI4_ATOP

AxiAddrWidth

AXI address width

64

AxiDataWidth

AXI data width

64

AxiIdWidth

AXI ID width

4

AxiUserWidth

AXI User width

32

AxiBurstWriteEn

AXI burst in write

False

MemTidWidth

TODO

4

IcacheByteSize

Instruction cache size (in bytes)

2048

IcacheSetAssoc

Instruction cache associativity (number of ways)

2

IcacheLineWidth

Instruction cache line width

128

DCacheType

Cache Type

config_pkg::HPDCACHE

DcacheIdWidth

Data cache ID

1

DcacheByteSize

Data cache size (in bytes)

2028

DcacheSetAssoc

Data cache associativity (number of ways)

2

DcacheLineWidth

Data cache line width

128

DataUserEn

User field on data bus enable

1

WtDcacheWbufDepth

Write-through data cache write buffer depth

2

FetchUserEn

User field on fetch bus enable

1

FetchUserWidth

Width of fetch user field

32

FpgaEn

Is FPGA optimization of CV32A6

False

TechnoCut

Is Techno Cut instanciated

True

SuperscalarEn

Enable superscalar* with 2 issue ports and 2 commit ports.

True

NrCommitPorts

Number of commit ports. Forced to 2 if SuperscalarEn.

1

NrLoadPipeRegs

Load cycle latency number

0

NrStorePipeRegs

Store cycle latency number

0

NrScoreboardEntries

Scoreboard length

8

NrLoadBufEntries

Load buffer entry buffer

2

MaxOutstandingStores

Maximum number of outstanding stores

7

RASDepth

Return address stack depth

2

BTBEntries

Branch target buffer entries

0

BHTEntries

Branch history entries

32

InstrTlbEntries

MMU instruction TLB entries

2

DataTlbEntries

MMU data TLB entries

2

UseSharedTlb

MMU option to use shared TLB

True

SharedTlbDepth

MMU depth of shared TLB

64

+
+
+

2.4. IO ports

+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2. cva6 module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

boot_addr_i

in

Reset boot address

SUBSYSTEM

logic[CVA6Cfg.VLEN-1:0]

hart_id_i

in

Hard ID reflected as CSR

SUBSYSTEM

logic[CVA6Cfg.XLEN-1:0]

irq_i

in

Level sensitive (async) interrupts

SUBSYSTEM

logic[1:0]

ipi_i

in

Inter-processor (async) interrupt

SUBSYSTEM

logic

time_irq_i

in

Timer (async) interrupt

SUBSYSTEM

logic

cvxif_req_o

out

CVXIF request

SUBSYSTEM

cvxif_req_t

cvxif_resp_i

in

CVXIF response

SUBSYSTEM

cvxif_resp_t

noc_req_o

out

noc request, can be AXI or OpenPiton

SUBSYSTEM

noc_req_t

noc_resp_i

in

noc response, can be AXI or OpenPiton

SUBSYSTEM

noc_resp_t

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As DebugEn = False,
+
+
+
    +
  • +

    debug_req_i input is tied to 0

    +
  • +
+
+
+
As IsRVFI = 0,
+
+
+
    +
  • +

    rvfi_probes_o output is tied to 0

    +
  • +
+
+
+
+
+
+
+
+
+

3. Functionality

+
+
+

3.1. Instructions

+
+

The next subchapter lists the extensions implemented in CV32A65X. By +configuration, we can enable/disable the extensions. CV32A65X supports +the extensions described in the next subchapters.

+
+
+
+

3.2. isa

+
+

3.2.1. Instructions

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Subset NameNameDescription

I

RV32I Base Integer Instructions

the base integer instruction set, also known as the 'RV32I' or 'RV64I' instruction set , depending on the address space size, provides the core functionality required for general-purpose computing .it includes instructions for arithmetic, logical, and control operations, as well as memory accessand manipulation

M

RV32M Multiplication and Division Instructions

the standard integer multiplication and division instruction extension, which is named “M” and contains instructions that multiply or divide values held in two integer registers.

C

RV32C Compressed Instructions

RVC uses a simple compression scheme that offers shorter 16-bit versions of common 32-bit RISC-V instructions when: the immediate or address offset is small; one of the registers is the zero register (x0), the ABI link register (x1), or the ABI stack pointer (x2); the destination register and the first source register are identical; the registers used are the 8 most popular ones.The C extension is compatible with all other standard instruction extensions. The C extension allows 16-bit instructions to be freely intermixed with 32-bit instructions, with the latter now able to start on any 16-bit boundary. With the addition of the C extension, JAL and JALR instructions will no longer raise an instruction misaligned exception

Zicsr

RV32Zicsr Control and Status Register Instructions

All CSR instructions atomically read-modify-write a single CSR, whose CSR specifier is encoded in the 12-bit csr field of the instruction held in bits 31–20. The immediate forms use a 5-bit zero-extended immediate encoded in the rs1 field.

Zifencei

RVZifencei Instruction Fetch Fence

FENCE.I instruction that provides explicit synchronization between writes to instruction memory and instruction fetches on the same hart.Currently, this instruction is the only standard mechanism to ensure that stores visible to a hart will also be visible to it instruction fetches.

Zcb

RV32Zcb Code Size Reduction Instructions

Zcb belongs to the group of extensions called RISC-V Code Size Reduction Extension (Zc*). Zc* has become the superset of the Standard C extension adding more 16-bit instructions to the ISA. Zcb includes the 16-bit version of additional Integer (I), Multiply (M), and Bit-Manipulation (Zbb) Instructions. All the Zcb instructions require at least standard C extension support as a prerequisite, along with M and Zbb extensions for the 16-bit version of the respective instructions.

Zba

RVZba Address generation instructions

The Zba instructions can be used to accelerate the generation of addresses that index into arrays of basic types (halfword, word, doubleword) using both unsigned word-sized and XLEN-sized indices: a shifted index is added to a base address. The shift and add instructions do a left shift of 1, 2, or 3 because these are commonly found in real-world code and because they can be implemented with a minimal amount of additional hardware beyond that of the simple adder. This avoids lengthening the critical path in implementations. While the shift and add instructions are limited to a maximum left shift of 3, the slli instruction (from the base ISA) can be used to perform similar shifts for indexing into arrays of wider elements. The slli.uw added in this extension can be used when the index is to be interpreted as an unsigned word.

Zbb

RVZbb Basic bit-manipulation

The bit-manipulation (bitmanip) extension collection is comprised of several component extensions to the base RISC-V architecture that are intended to provide some combination of code size reduction, performance improvement, and energy reduction. While the instructions are intended to have general use, some instructions are more useful in some domains than others. Hence, several smaller bitmanip extensions are provided. Each of these smaller extensions is grouped by common function and use case, and each has its own Zb*-extension name.

Zbc

RVZbc Carry-less multiplication

Carry-less multiplication is the multiplication in the polynomial ring over GF(2).clmul produces the lower half of the carry-less product and clmulh produces the upper half of the 2✕XLEN carry-less product.clmulr produces bits 2✕XLEN−2:XLEN-1 of the 2✕XLEN carry-less product.

Zbs

RVZbs Single bit Instructions

The single-bit instructions provide a mechanism to set, clear, invert, or extract a single bit in a register. The bit is specified by its index.

Zicntr

Zicntr

No info found yet for extension Zicntr

+
+
+

3.2.2. RV32I Base Integer Instructions

+ +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameFormatPseudocodeInvalid_valuesException_raisedDescriptionOp Name

ADDI

addi rd, rs1, imm[11:0]

x[rd] = x[rs1] + sext(imm[11:0])

NONE

NONE

add sign-extended 12-bit immediate to register rs1, and store the result in register rd.

Integer_Register_Immediate_Operations

ANDI

andi rd, rs1, imm[11:0]

x[rd] = x[rs1] & sext(imm[11:0])

NONE

NONE

perform bitwise AND on register rs1 and the sign-extended 12-bit immediate and place the result in rd.

Integer_Register_Immediate_Operations

ORI

ori rd, rs1, imm[11:0]

x[rd] = x[rs1] | sext(imm[11:0])

NONE

NONE

perform bitwise OR on register rs1 and the sign-extended 12-bit immediate and place the result in rd.

Integer_Register_Immediate_Operations

XORI

xori rd, rs1, imm[11:0]

x[rd] = x[rs1] ^ sext(imm[11:0])

NONE

NONE

perform bitwise XOR on register rs1 and the sign-extended 12-bit immediate and place the result in rd.

Integer_Register_Immediate_Operations

SLTI

slti rd, rs1, imm[11:0]

if (x[rs1] < sext(imm[11:0])) x[rd] = 1 else x[rd] = 0

NONE

NONE

set register rd to 1 if register rs1 is less than the sign extended immediate when both are treated as signed numbers, else 0 is written to rd.

Integer_Register_Immediate_Operations

SLTIU

sltiu rd, rs1, imm[11:0]

if (x[rs1] <u sext(imm[11:0])) x[rd] = 1 else x[rd] = 0

NONE

NONE

set register rd to 1 if register rs1 is less than the sign extended immediate when both are treated as unsigned numbers, else 0 is written to rd."

Integer_Register_Immediate_Operations

SLLI

slli rd, rs1, imm[4:0]

x[rd] = x[rs1] << imm[4:0]

NONE

NONE

logical left shift (zeros are shifted into the lower bits).

Integer_Register_Immediate_Operations

SRLI

srli rd, rs1, imm[4:0]

x[rd] = x[rs1] >> imm[4:0]

NONE

NONE

logical right shift (zeros are shifted into the upper bits).

Integer_Register_Immediate_Operations

SRAI

srai rd, rs1, imm[4:0]

x[rd] = x[rs1] >>s imm[4:0]

NONE

NONE

arithmetic right shift (the original sign bit is copied into the vacated upper bits).

Integer_Register_Immediate_Operations

LUI

lui rd, imm[19:0]

x[rd] = sext(imm[31:12] << 12)

NONE

NONE

place the immediate value in the top 20 bits of the destination register rd, filling in the lowest 12 bits with zeros.

Integer_Register_Immediate_Operations

AUIPC

auipc rd, imm[19:0]

x[rd] = pc + sext(immediate[31:12] << 12)

NONE

NONE

form a 32-bit offset from the 20-bit immediate, filling in the lowest 12 bits with zeros, adds this offset to the pc, then place the result in register rd.

Integer_Register_Immediate_Operations

ADD

add rd, rs1, rs2

x[rd] = x[rs1] + x[rs2]

NONE

NONE

add rs2 to register rs1, and store the result in register rd.

Integer_Register_Register_Operations

SUB

sub rd, rs1, rs2

x[rd] = x[rs1] - x[rs2]

NONE

NONE

subtract rs2 from register rs1, and store the result in register rd.

Integer_Register_Register_Operations

AND

and rd, rs1, rs2

x[rd] = x[rs1] & x[rs2]

NONE

NONE

perform bitwise AND on register rs1 and rs2 and place the result in rd.

Integer_Register_Register_Operations

OR

or rd, rs1, rs2

x[rd] = x[rs1] | x[rs2]

NONE

NONE

perform bitwise OR on register rs1 and rs2 and place the result in rd.

Integer_Register_Register_Operations

XOR

xor rd, rs1, rs2

x[rd] = x[rs1] ^ x[rs2]

NONE

NONE

perform bitwise XOR on register rs1 and rs2 and place the result in rd.

Integer_Register_Register_Operations

SLT

slt rd, rs1, rs2

if (x[rs1] < x[rs2]) x[rd] = 1 else x[rd] = 0

NONE

NONE

set register rd to 1 if register rs1 is less than rs2 when both are treated as signed numbers, else 0 is written to rd.

Integer_Register_Register_Operations

SLTU

sltu rd, rs1, rs2

if (x[rs1] <u x[rs2]) x[rd] = 1 else x[rd] = 0

NONE

NONE

set register rd to 1 if register rs1 is less than rs2 when both are treated as unsigned numbers, else 0 is written to rd.

Integer_Register_Register_Operations

SLL

sll rd, rs1, rs2

x[rd] = x[rs1] << x[rs2]

NONE

NONE

logical left shift (zeros are shifted into the lower bits).

Integer_Register_Register_Operations

SRL

srl rd, rs1, rs2

x[rd] = x[rs1] >> x[rs2]

NONE

NONE

logical right shift (zeros are shifted into the upper bits).

Integer_Register_Register_Operations

SRA

sra rd, rs1, rs2

x[rd] = x[rs1] >>s x[rs2]

NONE

NONE

arithmetic right shift (the original sign bit is copied into the vacated upper bits).

Integer_Register_Register_Operations

JAL

jal rd, imm[20:1]

x[rd] = pc+4; pc += sext(imm[20:1])

NONE

jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception.

offset is sign-extended and added to the pc to form the jump target address (pc is calculated using signed arithmetic), then setting the least-significant bit of the result to zero, and store the address of instruction following the jump (pc+4) into register rd.

Control_Transfer_Operations-Unconditional_Jumps

JALR

jalr rd, rs1, imm[11:0]

t = pc+4; pc = (x[rs1]+sext(imm[11:0]))&∼1 ; x[rd] = t

NONE

jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception.

target address is obtained by adding the 12-bit signed immediate to the register rs1 (pc is calculated using signed arithmetic), then setting the least-significant bit of the result to zero, and store the address of instruction following the jump (pc+4) into register rd.

Control_Transfer_Operations-Unconditional_Jumps

BEQ

beq rs1, rs2, imm[12:1]

if (x[rs1] == x[rs2]) pc += sext({imm[12:1], 1’b0}) else pc += 4

NONE

no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.

takes the branch (pc is calculated using signed arithmetic) if registers rs1 and rs2 are equal.

Control_Transfer_Operations-Conditional_Branches

BNE

bne rs1, rs2, imm[12:1]

if (x[rs1] != x[rs2]) pc += sext({imm[12:1], 1’b0}) else pc += 4

NONE

no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.

takes the branch (pc is calculated using signed arithmetic) if registers rs1 and rs2 are not equal.

Control_Transfer_Operations-Conditional_Branches

BLT

blt rs1, rs2, imm[12:1]

if (x[rs1] < x[rs2]) pc += sext({imm[12:1], 1’b0}) else pc += 4

NONE

no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.

takes the branch (pc is calculated using signed arithmetic) if registers rs1 less than rs2 (using signed comparison).

Control_Transfer_Operations-Conditional_Branches

BLTU

bltu rs1, rs2, imm[12:1]

if (x[rs1] <u x[rs2]) pc += sext({imm[12:1], 1’b0}) else pc += 4

NONE

no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.

takes the branch (pc is calculated using signed arithmetic) if registers rs1 less than rs2 (using unsigned comparison).

Control_Transfer_Operations-Conditional_Branches

BGE

bge rs1, rs2, imm[12:1]

if (x[rs1] >= x[rs2]) pc += sext({imm[12:1], 1’b0}) else pc += 4

NONE

no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.

takes the branch (pc is calculated using signed arithmetic) if registers rs1 is greater than or equal rs2 (using signed comparison).

Control_Transfer_Operations-Conditional_Branches

BGEU

bgeu rs1, rs2, imm[12:1]

if (x[rs1] >=u x[rs2]) pc += sext({imm[12:1], 1’b0}) else pc += 4

NONE

no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.

takes the branch (pc is calculated using signed arithmetic) if registers rs1 is greater than or equal rs2 (using unsigned comparison).

Control_Transfer_Operations-Conditional_Branches

LB

lb rd, imm(rs1)

x[rd] = sext(M[x[rs1] + sext(imm[11:0])][7:0])

NONE

loads with a destination of x0 must still raise any exceptions and action any other side effects even though the load value is discarded.

loads a 8-bit value from memory, then sign-extends to 32-bit before storing in rd (rd is calculated using signed arithmetic), the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.

Load_and_Store_Instructions

LH

lh rd, imm(rs1)

x[rd] = sext(M[x[rs1] + sext(imm[11:0])][15:0])

NONE

loads with a destination of x0 must still raise any exceptions and action any other side effects even though the load value is discarded, also an exception is raised if the memory address isn’t aligned (2-byte boundary).

loads a 16-bit value from memory, then sign-extends to 32-bit before storing in rd (rd is calculated using signed arithmetic), the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.

Load_and_Store_Instructions

LW

lw rd, imm(rs1)

x[rd] = sext(M[x[rs1] + sext(imm[11:0])][31:0])

NONE

loads with a destination of x0 must still raise any exceptions and action any other side effects even though the load value is discarded, also an exception is raised if the memory address isn’t aligned (4-byte boundary).

loads a 32-bit value from memory, then storing in rd (rd is calculated using signed arithmetic). The effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.

Load_and_Store_Instructions

LBU

lbu rd, imm(rs1)

x[rd] = zext(M[x[rs1] + sext(imm[11:0])][7:0])

NONE

loads with a destination of x0 must still raise any exceptions and action any other side effects even though the load value is discarded.

loads a 8-bit value from memory, then zero-extends to 32-bit before storing in rd (rd is calculated using unsigned arithmetic), the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.

Load_and_Store_Instructions

LHU

lhu rd, imm(rs1)

x[rd] = zext(M[x[rs1] + sext(imm[11:0])][15:0])

NONE

loads with a destination of x0 must still raise any exceptions and action any other side effects even though the load value is discarded, also an exception is raised if the memory address isn’t aligned (2-byte boundary).

loads a 16-bit value from memory, then zero-extends to 32-bit before storing in rd (rd is calculated using unsigned arithmetic), the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.

Load_and_Store_Instructions

SB

sb rs2, imm(rs1)

M[x[rs1] + sext(imm[11:0])][7:0] = x[rs2][7:0]

NONE

NONE

stores a 8-bit value from the low bits of register rs2 to memory, the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.

Load_and_Store_Instructions

SH

sh rs2, imm(rs1)

M[x[rs1] + sext(imm[11:0])][15:0] = x[rs2][15:0]

NONE

an exception is raised if the memory address isn’t aligned (2-byte boundary).

stores a 16-bit value from the low bits of register rs2 to memory, the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.

Load_and_Store_Instructions

SW

sw rs2, imm(rs1)

M[x[rs1] + sext(imm[11:0])][31:0] = x[rs2][31:0]

NONE

an exception is raised if the memory address isn’t aligned (4-byte boundary).

stores a 32-bit value from register rs2 to memory, the effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.

Load_and_Store_Instructions

FENCE

fence pre, succ

No operation (nop)

NONE

NONE

order device I/O and memory accesses as viewed by other RISC-V harts and external devices or coprocessors. Any combination of device input (I), device output (O), memory reads ®, and memory writes (W) may be ordered with respect to any combination of the same. Informally, no other RISC-V hart or external device can observe any operation in the successor set following a FENCE before any operation in the predecessor set preceding the FENCE, as the core support 1 hart, the fence instruction has no effect so we can considerate it as a nop instruction.

Memory_Ordering

ECALL

ecall

RaiseException(EnvironmentCall)

NONE

Raise an Environment Call exception.

make a request to the supporting execution environment, which is usually an operating system. The ABI for the system will define how parameters for the environment request are passed, but usually these will be in defined locations in the integer register file.

Environment_Call_and_Breakpoints

EBREAK

ebreak

x[8 + rd'] = sext(x[8 + rd'][7:0])

NONE

NONE

This instruction takes a single source/destination operand. It sign-extends the least-significant byte in the operand by copying the most-significant bit in the byte (i.e., bit 7) to all of the more-significant bits. It also requires Bit-Manipulation (Zbb) extension support.

Environment_Call_and_Breakpoints

+
+
+

3.2.3. RV32M Multiplication and Division Instructions

+ +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameFormatPseudocodeInvalid_valuesException_raisedDescriptionOp Name

MUL

mul rd, rs1, rs2

x[rd] = x[rs1] * x[rs2]

NONE

NONE

performs a 32-bit × 32-bit multiplication and places the lower 32 bits in the destination register (Both rs1 and rs2 treated as signed numbers).

Multiplication Operations

MULH

mulh rd, rs1, rs2

x[rd] = (x[rs1] s*s x[rs2]) >>s 32

NONE

NONE

performs a 32-bit × 32-bit multiplication and places the upper 32 bits in the destination register of the 64-bit product (Both rs1 and rs2 treated as signed numbers).

Multiplication Operations

MULHU

mulhu rd, rs1, rs2

x[rd] = (x[rs1] u*u x[rs2]) >>u 32

NONE

NONE

performs a 32-bit × 32-bit multiplication and places the upper 32 bits in the destination register of the 64-bit product (Both rs1 and rs2 treated as unsigned numbers).

Multiplication Operations

MULHSU

mulhsu rd, rs1, rs2

x[rd] = (x[rs1] s*u x[rs2]) >>s 32

NONE

NONE

performs a 32-bit × 32-bit multiplication and places the upper 32 bits in the destination register of the 64-bit product (rs1 treated as signed number, rs2 treated as unsigned number).

Multiplication Operations

DIV

div rd, rs1, rs2

x[rd] = x[rs1] /s x[rs2]

NONE

NONE

perform signed integer division of 32 bits by 32 bits (rounding towards zero).

Division Operations

DIVU

divu rd, rs1, rs2

x[rd] = x[rs1] /u x[rs2]

NONE

NONE

perform unsigned integer division of 32 bits by 32 bits (rounding towards zero).

Division Operations

REM

rem rd, rs1, rs2

x[rd] = x[rs1] %s x[rs2]

NONE

NONE

provide the remainder of the corresponding division operation DIV (the sign of rd equals the sign of rs1).

Division Operations

REMU

rem rd, rs1, rs2

x[rd] = x[rs1] %u x[rs2]

NONE

NONE

provide the remainder of the corresponding division operation DIVU.

Division Operations

+
+
+

3.2.4. RV32C Compressed Instructions

+ +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameFormatPseudocodeInvalid_valuesException_raisedDescriptionOp Name

C.LI

c.li rd, imm[5:0]

x[rd] = sext(imm[5:0])

rd = x0

NONE

loads the sign-extended 6-bit immediate, imm, into register rd.

Integer Computational Instructions

C.LUI

c.lui rd, nzimm[17:12]

x[rd] = sext(nzimm[17:12] << 12)

rd = x0 & rd = x2 & nzimm = 0

NONE

loads the non-zero 6-bit immediate field into bits 17–12 of the destination register, clears the bottom 12 bits, and sign-extends bit 17 into all higher bits of the destination.

Integer Computational Instructions

C.ADDI

c.addi rd, nzimm[5:0]

x[rd] = x[rd] + sext(nzimm[5:0])

rd = x0 & nzimm = 0

NONE

adds the non-zero sign-extended 6-bit immediate to the value in register rd then writes the result to rd.

Integer Computational Instructions

C.ADDI16SP

c.addi16sp nzimm[9:4]

x[2] = x[2] + sext(nzimm[9:4])

rd != x2 & nzimm = 0

NONE

adds the non-zero sign-extended 6-bit immediate to the value in the stack pointer (sp=x2), where the immediate is scaled to represent multiples of 16 in the range (-512,496). C.ADDI16SP is used to adjust the stack pointer in procedure prologues and epilogues. C.ADDI16SP shares the opcode with C.LUI, but has a destination field of x2.

Integer Computational Instructions

C.ADDI4SPN

c.addi4spn rd', nzimm[9:2]

x[8 + rd'] = x[2] + zext(nzimm[9:2])

nzimm = 0

NONE

adds a zero-extended non-zero immediate, scaled by 4, to the stack pointer, x2, and writes the result to rd'. This instruction is used to generate pointers to stack-allocated variables.

Integer Computational Instructions

C.SLLI

c.slli rd, uimm[5:0]

x[rd] = x[rd] << uimm[5:0]

rd = x0 & uimm[5] = 0

NONE

performs a logical left shift (zeros are shifted into the lower bits).

Integer Computational Instructions

C.SRLI

c.srli rd', uimm[5:0]

x[8 + rd'] = x[8 + rd'] >> uimm[5:0]

uimm[5] = 0

NONE

performs a logical right shift (zeros are shifted into the upper bits).

Integer Computational Instructions

C.SRAI

c.srai rd', uimm[5:0]

x[8 + rd'] = x[8 + rd'] >>s uimm[5:0]

uimm[5] = 0

NONE

performs an arithmetic right shift (sign bits are shifted into the upper bits).

Integer Computational Instructions

C.ANDI

c.andi rd', imm[5:0]

x[8 + rd'] = x[8 + rd'] & sext(imm[5:0])

NONE

NONE

computes the bitwise AND of the value in register rd', and the sign-extended 6-bit immediate, then writes the result to rd'.

Integer Computational Instructions

C.ADD

c.add rd, rs2

x[rd] = x[rd] + x[rs2]

rd = x0 & rs2 = x0

NONE

adds the values in registers rd and rs2 and writes the result to register rd.

Integer Computational Instructions

C.MV

c.mv rd, rs2

x[rd] = x[rs2]

rd = x0 & rs2 = x0

NONE

copies the value in register rs2 into register rd.

Integer Computational Instructions

C.AND

c.and rd', rs2'

x[8 + rd'] = x[8 + rd'] & x[8 + rs2']

NONE

NONE

computes the bitwise AND of of the value in register rd', and register rs2', then writes the result to rd'.

Integer Computational Instructions

C.OR

c.or rd', rs2'

x[8 + rd'] = x[8 + rd'] | x[8 + rs2']

NONE

NONE

computes the bitwise OR of of the value in register rd', and register rs2', then writes the result to rd'.

Integer Computational Instructions

C.XOR

c.and rd', rs2'

x[8 + rd'] = x[8 + rd'] ^ x[8 + rs2']

NONE

NONE

computes the bitwise XOR of of the value in register rd', and register rs2', then writes the result to rd'.

Integer Computational Instructions

C.SUB

c.sub rd', rs2'

x[8 + rd'] = x[8 + rd'] - x[8 + rs2']

NONE

NONE

subtracts the value in registers rs2' from value in rd' and writes the result to register rd'.

Integer Computational Instructions

C.EBREAK

c.ebreak

RaiseException(Breakpoint)

NONE

Raise a Breakpoint exception.

cause control to be transferred back to the debugging environment.

Integer Computational Instructions

C.J

c.j imm[11:1]

pc += sext(imm[11:1])

NONE

jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception.

performs an unconditional control transfer. The offset is sign-extended and added to the pc to form the jump target address.

Control Transfer Instructions

C.JAL

c.jal imm[11:1]

x[1] = pc+2; pc += sext(imm[11:1])

NONE

jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception.

performs the same operation as C.J, but additionally writes the address of the instruction following the jump (pc+2) to the link register, x1.

Control Transfer Instructions

C.JR

c.jr rs1

pc = x[rs1]

rs1 = x0

jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception.

performs an unconditional control transfer to the address in register rs1.

Control Transfer Instructions

C.JALR

c.jalr rs1

t = pc+2; pc = x[rs1]; x[1] = t

rs1 = x0

jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception.

performs the same operation as C.JR, but additionally writes the address of the instruction following the jump (pc+2) to the link register, x1.

Control Transfer Instructions

C.BEQZ

c.beqz rs1', imm[8:1]

if (x[8+rs1'] == 0) pc += sext(imm[8:1])

NONE

no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.

performs conditional control transfers. The offset is sign-extended and added to the pc to form the branch target address. C.BEQZ takes the branch if the value in register rs1' is zero.

Control Transfer Instructions

C.BNEZ

c.bnez rs1', imm[8:1]

if (x[8+rs1'] != 0) pc += sext(imm[8:1])

NONE

no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.

performs conditional control transfers. The offset is sign-extended and added to the pc to form the branch target address. C.BEQZ takes the branch if the value in register rs1' isn’t zero.

Control Transfer Instructions

C.LWSP

c.lwsp rd, uimm(x2)

x[rd] = M[x[2] + zext(uimm[7:2])][31:0]

rd = x0

loads with a destination of x0 must still raise any exceptions, also an exception if the memory address isn’t aligned (4-byte boundary).

loads a 32-bit value from memory into register rd. It computes an effective address by adding the zero-extended offset, scaled by 4, to the stack pointer, x2.

Load and Store Instructions

C.SWSP

c.swsp rd, uimm(x2)

M[x[2] + zext(uimm[7:2])][31:0] = x[rs2]

NONE

an exception raised if the memory address isn’t aligned (4-byte boundary).

stores a 32-bit value in register rs2 to memory. It computes an effective address by adding the zero-extended offset, scaled by 4, to the stack pointer, x2.

Load and Store Instructions

C.LW

c.lw rd', uimm(rs1')

x[8+rd'] = M[x[8+rs1'] + zext(uimm[6:2])][31:0])

NONE

an exception raised if the memory address isn’t aligned (4-byte boundary).

loads a 32-bit value from memory into register rd'. It computes an effective address by adding the zero-extended offset, scaled by 4, to the base address in register rs1'.

Load and Store Instructions

C.SW

c.sw rs2', uimm(rs1')

M[x[8+rs1'] + zext(uimm[6:2])][31:0] = x[8+rs2']

NONE

an exception raised if the memory address isn’t aligned (4-byte boundary).

stores a 32-bit value from memory into register rd'. It computes an effective address by adding the zero-extended offset, scaled by 4, to the base address in register rs1'.

Load and Store Instructions

+
+
+

3.2.5. RV32Zicsr Control and Status Register Instructions

+ +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameFormatPseudocodeInvalid_valuesException_raisedDescriptionOp Name

CSRRW

csrrw rd, csr, rs1

t = CSRs[csr]; CSRs[csr] = x[rs1]; x[rd] = t

NONE

Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions.

Reads the old value of the CSR, zero-extends the value to 32 bits, then writes it to integer register rd. The initial value in rs1 is written to the CSR. If rd=x0, then the instruction shall not read the CSR and shall not cause any of the side-effects that might occur on a CSR read.

Control and Status Register Operations

CSRRS

csrrs rd, csr, rs1

t = CSRs[csr]; CSRs[csr] = t | x[rs1]; x[rd] = t

NONE

Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions.

Reads the value of the CSR, zero-extends the value to 32 bits, and writes it to integer register rd. The initial value in integer register rs1 is treated as a bit mask that specifies bit positions to be set in the CSR. Any bit that is high in rs1 will cause the corresponding bit to be set in the CSR, if that CSR bit is writable. Other bits in the CSR are unaffected (though CSRs might have side effects when written). If rs1=x0, then the instruction will not write to the CSR at all, and so shall not cause any of the side effects that might otherwise occur on a CSR write, such as raising illegal instruction exceptions on accesses to read-only CSRs.

Control and Status Register Operations

CSRRC

csrrc rd, csr, rs1

t = CSRs[csr]; CSRs[csr] = t & ∼x[rs1]; x[rd] = t

NONE

Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions.

Reads the value of the CSR, zero-extends the value to 32 bits, and writes it to integer register rd. The initial value in integer register rs1 is treated as a bit mask that specifies bit positions to be cleared in the CSR. Any bit that is high in rs1 will cause the corresponding bit to be set in the CSR, if that CSR bit is writable. Other bits in the CSR are unaffected (though CSRs might have side effects when written). If rs1=x0, then the instruction will not write to the CSR at all, and so shall not cause any of the side effects that might otherwise occur on a CSR write, such as raising illegal instruction exceptions on accesses to read-only CSRs.

Control and Status Register Operations

CSRRWI

csrrwi rd, csr, uimm[4:0]

x[rd] = CSRs[csr]; CSRs[csr] = zext(uimm[4:0])

NONE

Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions.

Reads the old value of the CSR, zero-extends the value to 32 bits, then writes it to integer register rd. The zero-extends immediate is written to the CSR. If rd=x0, then the instruction shall not read the CSR and shall not cause any of the side-effects that might occur on a CSR read.

Control and Status Register Operations

CSRRSI

csrrsi rd, csr, uimm[4:0]

t = CSRs[csr]; CSRs[csr] = t | zext(uimm[4:0]); x[rd] = t

NONE

Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions.

Reads the value of the CSR, zero-extends the value to 32 bits, and writes it to integer register rd. The zero-extends immediate value is treated as a bit mask that specifies bit positions to be set in the CSR. Any bit that is high in zero-extends immediate will cause the corresponding bit to be set in the CSR, if that CSR bit is writable. Other bits in the CSR are unaffected (though CSRs might have side effects when written). If the uimm[4:0] field is zero, then these instructions will not write to the CSR, and shall not cause any of the side effects that might otherwise occur on a CSR write.

Control and Status Register Operations

CSRRCI

csrrci rd, csr, uimm[4:0]

t = CSRs[csr]; CSRs[csr] = t & ∼zext(uimm[4:0]); x[rd] = t

NONE

Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions.

Reads the value of the CSR, zero-extends the value to 32 bits, and writes it to integer register rd. The zero-extends immediate value is treated as a bit mask that specifies bit positions to be cleared in the CSR. Any bit that is high in zero-extends immediate will cause the corresponding bit to be set in the CSR, if that CSR bit is writable. Other bits in the CSR are unaffected (though CSRs might have side effects when written). If the uimm[4:0] field is zero, then these instructions will not write to the CSR, and shall not cause any of the side effects that might otherwise occur on a CSR write.

Control and Status Register Operations

+
+
+

3.2.6. RVZifencei Instruction Fetch Fence

+ +++++++++ + + + + + + + + + + + + + + + + + + + + + + +
NameFormatPseudocodeInvalid_valuesException_raisedDescriptionOp Name

FENCE.I

fence.i

Fence(Store, Fetch)

NONE

NONE

The FENCE.I instruction is used to synchronize the instruction and data streams. RISC-V does not guarantee that stores to instruction memory will be made visible to instruction fetches on the same RISC-V hart until a FENCE.I instruction is executed. A FENCE.I instruction only ensures that a subsequent instruction fetch on a RISC-V hart will see any previous data stores already visible to the same RISC-V hart.

Fetch Fence Operations

+
+
+

3.2.7. RV32Zcb Code Size Reduction Instructions

+ +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameFormatPseudocodeInvalid_valuesException_raisedDescriptionOp Name

C.ZEXT.B

c.zext.b rd'

x[8 + rd'] = zext(x[8 + rd'][7:0])

NONE

NONE

This instruction takes a single source/destination operand. It zero-extends the least-significant byte of the operand by inserting zeros into all of the bits more significant than 7.

Code Size Reduction Operations

C.SEXT.B

c.sext.b rd'

x[8 + rd'] = sext(x[8 + rd'][7:0])

NONE

NONE

This instruction takes a single source/destination operand. It sign-extends the least-significant byte in the operand by copying the most-significant bit in the byte (i.e., bit 7) to all of the more-significant bits. It also requires Bit-Manipulation (Zbb) extension support.

Code Size Reduction Operations

C.ZEXT.H

c.zext.h rd'

x[8 + rd'] = zext(x[8 + rd'][15:0])

NONE

NONE

This instruction takes a single source/destination operand. It zero-extends the least-significant halfword of the operand by inserting zeros into all of the bits more significant than 15. It also requires Bit-Manipulation (Zbb) extension support.

Code Size Reduction Operations

C.SEXT.H

c.sext.h rd'

x[8 + rd'] = sext(x[8 + rd'][15:0])

NONE

NONE

This instruction takes a single source/destination operand. It sign-extends the least-significant halfword in the operand by copying the most-significant bit in the halfword (i.e., bit 15) to all of the more-significant bits. It also requires Bit-Manipulation (Zbb) extension support.

Code Size Reduction Operations

C.NOT

c.not rd'

x[8 + rd'] = x[8 + rd'] ^ -1

NONE

NONE

This instruction takes the one’s complement of rd'/rs1' and writes the result to the same register.

Code Size Reduction Operations

C.MUL

c.mul rd', rs2'

x[8 + rd'] = (x[8 + rd'] * x[8 + rs2'])[31:0]

NONE

NONE

performs a 32-bit × 32-bit multiplication and places the lower 32 bits in the destination register (Both rd' and rs2' treated as signed numbers). It also requires M extension support.

Code Size Reduction Operations

C.LHU

c.lhu rd', uimm(rs1')

x[8+rd'] = zext(M[x[8+rs1'] + zext(uimm[1])][15:0])

NONE

an exception raised if the memory address isn’t aligned (2-byte boundary).

This instruction loads a halfword from the memory address formed by adding rs1' to the zero extended immediate uimm. The resulting halfword is zero extended and is written to rd'.

Code Size Reduction Operations

C.LH

c.lh rd', uimm(rs1')

x[8+rd'] = sext(M[x[8+rs1'] + zext(uimm[1])][15:0])

NONE

an exception raised if the memory address isn’t aligned (2-byte boundary).

This instruction loads a halfword from the memory address formed by adding rs1' to the zero extended immediate uimm. The resulting halfword is sign extended and is written to rd'.

Code Size Reduction Operations

C.LBU

c.lbu rd', uimm(rs1')

x[8+rd'] = zext(M[x[8+rs1'] + zext(uimm[1:0])][7:0])

NONE

NONE

This instruction loads a byte from the memory address formed by adding rs1' to the zero extended immediate uimm. The resulting byte is zero extended and is written to rd'.

Code Size Reduction Operations

C.SH

c.sh rs2', uimm(rs1')

M[x[8+rs1'] + zext(uimm[1])][15:0] = x[8+rs2']

NONE

an exception raised if the memory address isn’t aligned (2-byte boundary).

This instruction stores the least significant halfword of rs2' to the memory address formed by adding rs1' to the zero extended immediate uimm.

Code Size Reduction Operations

C.SB

c.sb rs2', uimm(rs1')

M[x[8+rs1'] + zext(uimm[1:0])][7:0] = x[8+rs2']

NONE

NONE

This instruction stores the least significant byte of rs2' to the memory address formed by adding rs1' to the zero extended immediate uimm.

Code Size Reduction Operations

+
+
+

3.2.8. RVZba Address generation instructions

+ +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameFormatPseudocodeInvalid_valuesException_raisedDescriptionOp Name

ADD.UW

add.uw rd, rs1, rs2

X(rd) = rs2 + EXTZ(X(rs1)[31..0])

NONE

NONE

This instruction performs an XLEN-wide addition between rs2 and the zero-extended least-significant word of rs1.

Address generation instructions

SH1ADD

sh1add rd, rs1, rs2

X(rd) = X(rs2) + (X(rs1) << 1)

NONE

NONE

This instruction shifts rs1 to the left by 1 bit and adds it to rs2.

Address generation instructions

SH1ADD.UW

sh1add.uw rd, rs1, rs2

X(rd) = rs2 + (EXTZ(X(rs1)[31..0]) << 1)

NONE

NONE

This instruction performs an XLEN-wide addition of two addends. The first addend is rs2. The second addend is the unsigned value formed by extracting the least-significant word of rs1 and shifting it left by 1 place.

Address generation instructions

SH2ADD

sh2add rd, rs1, rs2

X(rd) = X(rs2) + (X(rs1) << 2)

NONE

NONE

This instruction shifts rs1 to the left by 2 bit and adds it to rs2.

Address generation instructions

SH2ADD.UW

sh2add.uw rd, rs1, rs2

X(rd) = rs2 + (EXTZ(X(rs1)[31..0]) << 2)

NONE

NONE

This instruction performs an XLEN-wide addition of two addends. The first addend is rs2. The second addend is the unsigned value formed by extracting the least-significant word of rs1 and shifting it left by 2 places.

Address generation instructions

SH3ADD

sh3add rd, rs1, rs2

X(rd) = X(rs2) + (X(rs1) << 3)

NONE

NONE

This instruction shifts rs1 to the left by 3 bit and adds it to rs2.

Address generation instructions

SH3ADD.UW

sh3add.uw rd, rs1, rs2

X(rd) = rs2 + (EXTZ(X(rs1)[31..0]) << 3)

NONE

NONE

This instruction performs an XLEN-wide addition of two addends. The first addend is rs2. The second addend is the unsigned value formed by extracting the least-significant word of rs1 and shifting it left by 3 places.

Address generation instructions

SLLI.UW

slli.uw rd, rs1, imm

X(rd) = (EXTZ(X(rs)[31..0]) << imm)

NONE

NONE

This instruction takes the least-significant word of rs1, zero-extends it, and shifts it left by the immediate.

Address generation instructions

+
+
+

3.2.9. RVZbb Basic bit-manipulation

+ +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameFormatPseudocodeInvalid_valuesException_raisedDescriptionOp Name

ANDN

andn rd, rs1, rs2

X(rd) = X(rs1) & ~X(rs2)

NONE

NONE

Performs bitwise AND operation between rs1 and bitwise inversion of rs2.

Logical_with_negate

ORN

orn rd, rs1, rs2

X(rd) = X(rs1) | ~X(rs2)

NONE

NONE

Performs bitwise OR operation between rs1 and bitwise inversion of rs2.

Logical_with_negate

XNOR

xnor rd, rs1, rs2

X(rd) = ~(X(rs1) ^ X(rs2))

NONE

NONE

Performs bitwise XOR operation between rs1 and rs2, then complements the result.

Logical_with_negate

CLZ

clz rd, rs

if [x[i]] == 1 then return(i) else return -1

NONE

NONE

Counts leading zero bits in rs.

Count_leading_trailing_zero_bits

CTZ

ctz rd, rs

if [x[i]] == 1 then return(i) else return xlen;

NONE

NONE

Counts trailing zero bits in rs.

Count_leading_trailing_zero_bits

CLZW

clzw rd, rs

if [x[i]] == 1 then return(i) else return -1

NONE

NONE

Counts leading zero bits in the least-significant word of rs.

Count_leading_trailing_zero_bits

CTZW

ctzw rd, rs

if [x[i]] == 1 then return(i) else return 32;

NONE

NONE

Counts trailing zero bits in the least-significant word of rs.

Count_leading_trailing_zero_bits

CPOP

cpop rd, rs

if rs[i] == 1 then bitcount = bitcount + 1 else ()

NONE

NONE

Counts set bits in rs.

Count_population

CPOPW

cpopw rd, rs

if rs[i] == 0b1 then bitcount = bitcount + 1 else ()

NONE

NONE

Counts set bits in the least-significant word of rs.

Count_population

MAX

max rd, rs1, rs2

if rs1_val <_s rs2_val then rs2_val else rs1_val

NONE

NONE

Returns the larger of two signed integers.

Integer_minimum_maximum

MAXU

maxu rd, rs1, rs2

if rs1_val <_u rs2_val then rs2_val else rs1_val

NONE

NONE

Returns the larger of two unsigned integers.

Integer_minimum_maximum

MIN

min rd, rs1, rs2

if rs1_val <_s rs2_val then rs1_val else rs2_val

NONE

NONE

Returns the smaller of two signed integers.

Integer_minimum_maximum

MINU

minu rd, rs1, rs2

if rs1_val <_u rs2_val then rs1_val else rs2_val

NONE

NONE

Returns the smaller of two unsigned integers.

Integer_minimum_maximum

SEXT.B

sext.b rd, rs

X(rd) = EXTS(X(rs)[7..0])

NONE

NONE

Sign-extends the least-significant byte in the source to XLEN.

Sign_and_zero_extension

SEXT.H

sext.h rd, rs

X(rd) = EXTS(X(rs)[15..0])

NONE

NONE

Sign-extends the least-significant halfword in rs to XLEN.

Sign_and_zero_extension

ZEXT.H

zext.h rd, rs

X(rd) = EXTZ(X(rs)[15..0])

NONE

NONE

Zero-extends the least-significant halfword of the source to XLEN.

Sign_and_zero_extension

ROL

rol rd, rs1, rs2

(X(rs1) << log2(XLEN)) | (X(rs1) >> (xlen - log2(XLEN)))

NONE

NONE

Performs a rotate left of rs1 by the amount in least-significant log2(XLEN) bits of rs2.

Bitwise_rotation

ROR

ror rd, rs1, rs2

(X(rs1) >> log2(XLEN)) | (X(rs1) << (xlen - log2(XLEN)))

NONE

NONE

Performs a rotate right of rs1 by the amount in least-significant log2(XLEN) bits of rs2.

Bitwise_rotation

RORI

rori rd, rs1, shamt

(X(rs1) >> log2(XLEN)) | (X(rs1) << (xlen - log2(XLEN)))

NONE

NONE

Performs a rotate right of rs1 by the amount in least-significant log2(XLEN) bits of shamt.

Bitwise_rotation

ROLW

rolw rd, rs1, rs2

EXTSrs1 << X(rs2)[4..0]) | (rs1)

NONE

NONE

Performs a rotate left on the least-significant word of rs1 by the amount in least-significant 5 bits of rs2.

Bitwise_rotation

RORIW

roriw rd, rs1, shamt

(rs1_data >> shamt[4..0]) | (rs1_data << (32 - shamt[4..0]))

NONE

NONE

Performs a rotate right on the least-significant word of rs1 by the amount in least-significant log2(XLEN) bits of shamt.

Bitwise_rotation

RORW

rorw rd, rs1, rs2

(rs1 >> X(rs2)[4..0]) | (rs1 << (32 - X(rs2)[4..0]))

NONE

NONE

Performs a rotate right on the least-significant word of rs1 by the amount in least-significant 5 bits of rs2.

Bitwise_rotation

ORC.b

orc.b rd, rs

if { input[(i + 7)..i] == 0 then 0b00000000 else 0b11111111

NONE

NONE

Sets the bits of each byte in rd to all zeros if no bit within the respective byte of rs is set, or to all ones if any bit within the respective byte of rs is set.

OR_Combine

REV8

rev8 rd, rs

output[i..(i + 7)] = input[(j - 7)..j]

NONE

NONE

Reverses the order of the bytes in rs.

Byte_reverse

+
+
+

3.2.10. RVZbc Carry-less multiplication

+ +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameFormatPseudocodeInvalid_valuesException_raisedDescriptionOp Name

CLMUL

clmul rd, rs1, rs2

foreach (i from 1 to xlen by 1) { output = if ((rs2 >> i) & 1) then output ^ (rs1 << i); else output;}

NONE

NONE

clmul produces the lower half of the 2.XLEN carry-less product.

Carry-less multiplication Operations

CLMULH

clmulh rd, rs1, rs2

foreach (i from 1 to xlen by 1) { output = if rs2_val else output}

NONE

NONE

clmulh produces the upper half of the 2.XLEN carry-less product.

Carry-less multiplication Operations

CLMULR

clmulr rd, rs1, rs2

foreach (i from 0 to (xlen - 1) by 1) { output = if rs2_val else output}

NONE

NONE

clmulr produces bits 2.XLEN-2:XLEN-1 of the 2.XLEN carry-less product.

Carry-less multiplication Operations

+
+
+

3.2.11. RVZbs Single bit Instructions

+ +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameFormatPseudocodeInvalid_valuesException_raisedDescriptionOp Name

BCLR

bclr rd, rs1, rs2

X(rd) = X(rs1) & ~(1 << (X(rs2) & (XLEN - 1)))

NONE

NONE

This instruction returns rs1 with a single bit cleared at the index specified in rs2. The index is read from the lower log2(XLEN) bits of rs2.

Single_bit_Operations

BCLRI

bclri rd, rs1, shamt

X(rd) = X(rs1) & ~(1 << (shamt & (XLEN - 1)))

NONE

NONE

This instruction returns rs1 with a single bit cleared at the index specified in shamt. The index is read from the lower log2(XLEN) bits of shamt. For RV32, the encodings corresponding to shamt[5]=1 are reserved.

Single_bit_Operations

BEXT

bext rd, rs1, rs2

X(rd) = (X(rs1) >> (X(rs2) & (XLEN - 1))) & 1

NONE

NONE

This instruction returns a single bit extracted from rs1 at the index specified in rs2. The index is read from the lower log2(XLEN) bits of rs2.

Single_bit_Operations

BEXTI

bexti rd, rs1, shamt

X(rd) = (X(rs1) >> (shamt & (XLEN - 1))) & 1

NONE

NONE

This instruction returns a single bit extracted from rs1 at the index specified in rs2. The index is read from the lower log2(XLEN) bits of shamt. For RV32, the encodings corresponding to shamt[5]=1 are reserved.

Single_bit_Operations

BINV

binv rd, rs1, rs2

X(rd) = X(rs1) ^ (1 << (X(rs2) & (XLEN - 1)))

NONE

NONE

This instruction returns rs1 with a single bit inverted at the index specified in rs2. The index is read from the lower log2(XLEN) bits of rs2.

Single_bit_Operations

BINVI

binvi rd, rs1, shamt

X(rd) = X(rs1) ^ (1 << (shamt & (XLEN - 1)))

NONE

NONE

This instruction returns rs1 with a single bit inverted at the index specified in shamt. The index is read from the lower log2(XLEN) bits of shamt. For RV32, the encodings corresponding to shamt[5]=1 are reserved.

Single_bit_Operations

BSET

bset rd, rs1, rs2

X(rd) = X(rs1) | (1 << (X(rs2) & (XLEN - 1)))

NONE

NONE

This instruction returns rs1 with a single bit set at the index specified in rs2. The index is read from the lower log2(XLEN) bits of rs2.

Single_bit_Operations

BSETI

bseti rd, rs1, shamt

X(rd) = X(rs1) | (1 << (shamt & (XLEN - 1)))

NONE

NONE

This instruction returns rs1 with a single bit set at the index specified in shamt. The index is read from the lower log2(XLEN) bits of shamt. For RV32, the encodings corresponding to shamt[5]=1 are reserved.

Single_bit_Operations

+
+
+
+

3.3. Traps, Interrupts, Exceptions

+
+

Traps are composed of interrupts and exceptions. +Interrupts are asynchronous events whereas exceptions are synchronous ones. +On one hand, interrupts are occuring independently of the instructions +(mainly raised by peripherals or debug module). +On the other hand, an instruction may raise exceptions synchronously.

+
+
+

3.3.1. Raising Traps

+
+

When a trap is raised, the behaviour of the CVA6 core depends on +several CSRs and some CSRs are modified.

+
+
+
3.3.1.1. Configuration CSRs
+
+

CSRs having an effect on the core behaviour when a trap occurs are:

+
+
+
    +
  • +

    mstatus and sstatus: several fields control the core behaviour like interrupt enable (MIE, SIE)

    +
  • +
  • +

    mtvec and stvec: specifies the address of trap handler.

    +
  • +
  • +

    medeleg: specifies which exceptions can be handled by a lower privileged mode (S-mode)

    +
  • +
  • +

    mideleg: specifies which interrupts can be handled by a lower privileged mode (S-mode)

    +
  • +
+
+
+
+
3.3.1.2. Modified CSRs
+
+

CSRs (or fields) updated by the core when a trap occurs are:

+
+
+
    +
  • +

    mstatus or sstatus: several fields are updated like previous privilege mode (MPP, SPP), previous interrupt enabled (MPIE, SPIE``)

    +
  • +
  • +

    mepc or sepc: updated with the virtual address of the interrupted instruction or the instruction raising the exception.

    +
  • +
  • +

    mcause or scause: updated with a code indicating the event causing the trap.

    +
  • +
  • +

    mtval or stval: updated with exception specific information like the faulting virtual address

    +
  • +
+
+
+
+
3.3.1.3. Supported exceptions
+
+

The following exceptions are supported by the CVA6:

+
+
+
    +
  • +

    instruction address misaligned

    +
    +
      +
    • +

      control flow instruction with misaligned target

      +
    • +
    +
    +
  • +
  • +

    instruction access fault

    +
    +
      +
    • +

      access to PMP region without execute permissions

      +
    • +
    +
    +
  • +
  • +

    illegal instruction:

    +
    +
      +
    • +

      unimplemented CSRs

      +
    • +
    • +

      unsupported extensions

      +
    • +
    +
    +
  • +
  • +

    breakpoint (EBREAK)

    +
  • +
  • +

    load address misaligned:

    +
    +
      +
    • +

      LH at 2n+1 address

      +
    • +
    • +

      LW at 4n+1, 4n+2, 4n+3 address

      +
    • +
    +
    +
  • +
  • +

    load access fault

    +
    +
      +
    • +

      access to PMP region without read permissions

      +
    • +
    +
    +
  • +
  • +

    store/AMO address misaligned

    +
    +
      +
    • +

      SH at 2n+1 address

      +
    • +
    • +

      SW at 4n+1, 4n+2, 4n+3 address

      +
    • +
    +
    +
  • +
  • +

    store/AMO access fault

    +
    +
      +
    • +

      access to PMP region without write permissions

      +
    • +
    +
    +
  • +
  • +

    environment call (ECALL) from U-mode

    +
  • +
  • +

    environment call (ECALL) from S-mode

    +
  • +
  • +

    environment call (ECALL) from M-mode

    +
  • +
  • +

    instruction page fault

    +
  • +
  • +

    load page fault

    +
    +
      +
    • +

      access to effective address without read permissions

      +
    • +
    +
    +
  • +
  • +

    store/AMO page fault

    +
    +
      +
    • +

      access to effective address without write permissions

      +
    • +
    +
    +
  • +
  • +

    debug request (custom) via debug interface

    +
  • +
+
+
+

Note: all exceptions are supported except the ones linked to the hypervisor extension

+
+
+
+
+

3.3.2. Trap return

+
+

Trap handler ends with trap return instruction (MRET, SRET). The behaviour of the CVA6 core depends on several CSRs.

+
+
+
3.3.2.1. Configuration CSRs
+
+

CSRs having an effect on the core behaviour when returning from a trap are:

+
+
+
    +
  • +

    mstatus: several fields control the core behaviour like previous privilege mode (MPP, SPP), previous interrupt enabled (MPIE, SPIE)

    +
  • +
+
+
+
+
3.3.2.2. Modified CSRs
+
+

CSRs (or fields) updated by the core when returning from a trap are:

+
+
+
    +
  • +

    mstatus: several fields are updated like interrupt enable (MIE, SIE), modify privilege (MPRV)

    +
  • +
+
+
+
+
+

3.3.3. Interrupts

+
+
    +
  • +

    external interrupt: irq_i signal

    +
  • +
  • +

    software interrupt (inter-processor interrupt): ipi_i signal

    +
  • +
  • +

    timer interrupt: time_irq_i signal

    +
  • +
  • +

    debug interrupt: debug_req_i signal

    +
  • +
+
+
+

These signals are level sensitive. It means the interrupt is raised until it is cleared.

+
+
+

The exception code field (mcause CSR) depends on the interrupt source.

+
+
+
+

3.3.4. Wait for Interrupt

+
+
    +
  • +

    CVA6 implementation: WFI stalls the core. The instruction is not available in U-mode (raise illegal instruction exception). Such exception is also raised when TW=1 in mstatus.

    +
  • +
+
+
+
+
+

3.4. csr

+
+

3.4.1. Conventions

+
+

In the subsequent sections, register fields are labeled with one of the following abbreviations:

+
+
+
    +
  • +

    WPRI (Writes Preserve Values, Reads Ignore Values): read/write field reserved +for future use. For forward compatibility, implementations that do not +furnish these fields must make them read-only zero.

    +
  • +
  • +

    WLRL (Write/Read Only Legal Values): read/write CSR field that specifies +behavior for only a subset of possible bit encodings, with other bit encodings +reserved.

    +
  • +
  • +

    WARL (Write Any Values, Reads Legal Values): read/write CSR fields which are +only defined for a subset of bit encodings, but allow any value to be written +while guaranteeing to return a legal value whenever read.

    +
  • +
  • +

    ROCST (Read-Only Constant): A special case of WARL field which admits only one +legal value, and therefore, behaves as a constant field that silently ignores +writes.

    +
  • +
  • +

    ROVAR (Read-Only Variable): A special case of WARL field which can take +multiple legal values but cannot be modified by software and depends only on +the architectural state of the hart.

    +
  • +
+
+
+

In particular, a register that is not internally divided +into multiple fields can be considered as containing a single field of XLEN bits. +This allows to clearly represent read-write registers holding a single legal value +(typically zero).

+
+
+
+

3.4.2. Register Summary

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AddressRegister NamePrivilegeDescription

0x300

MSTATUS

MRW

The mstatus register keeps track of and controls the hart’s current operating state.

0x301

MISA

MRW

misa is a read-write register reporting the ISA supported by the hart.

0x304

MIE

MRW

The mie register is an MXLEN-bit read/write register containing interrupt enable bits.

0x305

MTVEC

MRW

MXLEN-bit read/write register that holds trap vector configuration.

0x310

MSTATUSH

MRW

The mstatush register keeps track of and controls the hart’s current operating state.

0x323-0x33f

MHPMEVENT[3-31]

MRW

The mhpmevent is a MXLEN-bit event register which controls mhpmcounter3.

0x340

MSCRATCH

MRW

The mscratch register is an MXLEN-bit read/write register dedicated for use by machine mode.

0x341

MEPC

MRW

The mepc is a warl register that must be able to hold all valid physical and virtual addresses.

0x342

MCAUSE

MRW

The mcause register stores the information regarding the trap.

0x343

MTVAL

MRW

The mtval is a warl register that holds the address of the instruction which caused the exception.

0x344

MIP

MRW

The mip register is an MXLEN-bit read/write register containing information on pending interrupts.

0x3a0-0x3a3

PMPCFG[0-3]

MRW

PMP configuration register

0x3b0-0x3bf

PMPADDR[0-15]

MRW

Physical memory protection address register

0x7c0

ICACHE

MRW

the register controls the operation of the i-cache unit.

0x7c1

DCACHE

MRW

the register controls the operation of the d-cache unit.

0xb00

MCYCLE

MRW

Counts the number of clock cycles executed from an arbitrary point in time.

0xb02

MINSTRET

MRW

Counts the number of instructions completed from an arbitrary point in time.

0xb03-0xb1f

MHPMCOUNTER[3-31]

MRW

The mhpmcounter is a 64-bit counter. Returns lower 32 bits in RV32I mode.

0xb80

MCYCLEH

MRW

upper 32 bits of mcycle

0xb82

MINSTRETH

MRW

Upper 32 bits of minstret.

0xb83-0xb9f

MHPMCOUNTER[3-31]H

MRW

The mhpmcounterh returns the upper half word in RV32I systems.

0xf11

MVENDORID

MRO

32-bit read-only register providing the JEDEC manufacturer ID of the provider of the core.

0xf12

MARCHID

MRO

MXLEN-bit read-only register encoding the base microarchitecture of the hart.

0xf13

MIMPID

MRO

Provides a unique encoding of the version of the processor implementation.

0xf14

MHARTID

MRO

MXLEN-bit read-only register containing the integer ID of the hardware thread running the code.

0xf15

MCONFIGPTR

MRO

MXLEN-bit read-only register that holds the physical address of a configuration data structure.

+
+
+

3.4.3. Register Description

+
+
3.4.3.1. MSTATUS
+
+
+
Address
+
+

0x300

+
+
Reset Value
+
+

0x00001800

+
+
Privilege
+
+

MRW

+
+
Description
+
+

The mstatus register keeps track of and controls the hart’s current operating state.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

0

UIE

0x0

ROCST

0x0

Stores the state of the user mode interrupts.

1

SIE

0x0

ROCST

0x0

Stores the state of the supervisor mode interrupts.

2

RESERVED_2

0x0

WPRI

Reserved

3

MIE

0x0

WLRL

0 - 1

Stores the state of the machine mode interrupts.

4

UPIE

0x0

ROCST

0x0

Stores the state of the user mode interrupts prior to the trap.

5

SPIE

0x0

ROCST

0x0

Stores the state of the supervisor mode interrupts prior to the trap.

6

UBE

0x0

ROCST

0x0

control the endianness of memory accesses other than instruction fetches for user mode

7

MPIE

0x0

WLRL

0 - 1

Stores the state of the machine mode interrupts prior to the trap.

8

SPP

0x0

ROCST

0x0

Stores the previous priority mode for supervisor.

[10:9]

RESERVED_9

0x0

WPRI

Reserved

[12:11]

MPP

0x3

WARL

0x3

Stores the previous priority mode for machine.

[14:13]

FS

0x0

ROCST

0x0

Encodes the status of the floating-point unit, including the CSR fcsr and floating-point data registers.

[16:15]

XS

0x0

ROCST

0x0

Encodes the status of additional user-mode extensions and associated state.

17

MPRV

0x0

ROCST

0x0

Modifies the privilege level at which loads and stores execute in all privilege modes.

18

SUM

0x0

ROCST

0x0

Modifies the privilege with which S-mode loads and stores access virtual memory.

19

MXR

0x0

ROCST

0x0

Modifies the privilege with which loads access virtual memory.

20

TVM

0x0

ROCST

0x0

Supports intercepting supervisor virtual-memory management operations.

21

TW

0x0

ROCST

0x0

Supports intercepting the WFI instruction.

22

TSR

0x0

ROCST

0x0

Supports intercepting the supervisor exception return instruction.

23

SPELP

0x0

ROCST

0x0

Supervisor mode previous expected-landing-pad (ELP) state.

[30:24]

RESERVED_24

0x0

WPRI

Reserved

31

SD

0x0

ROCST

0x0

Read-only bit that summarizes whether either the FS field or XS field signals the presence of some dirty state.

+
+
+
3.4.3.2. MISA
+
+
+
Address
+
+

0x301

+
+
Reset Value
+
+

0x40001106

+
+
Privilege
+
+

MRW

+
+
Description
+
+

misa is a read-write register reporting the ISA supported by the hart.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[25:0]

EXTENSIONS

0x1106

ROCST

0x1106

Encodes the presence of the standard extensions, with a single bit per letter of the alphabet.

[29:26]

RESERVED_26

0x0

WPRI

Reserved

[31:30]

MXL

0x1

WARL

0x1

Encodes the native base integer ISA width.

+
+
+
3.4.3.3. MIE
+
+
+
Address
+
+

0x304

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

The mie register is an MXLEN-bit read/write register containing interrupt enable bits.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

0

USIE

0x0

ROCST

0x0

User Software Interrupt enable.

1

SSIE

0x0

ROCST

0x0

Supervisor Software Interrupt enable.

2

VSSIE

0x0

ROCST

0x0

VS-level Software Interrupt enable.

3

MSIE

0x0

ROCST

0x0

Machine Software Interrupt enable.

4

UTIE

0x0

ROCST

0x0

User Timer Interrupt enable.

5

STIE

0x0

ROCST

0x0

Supervisor Timer Interrupt enable.

6

VSTIE

0x0

ROCST

0x0

VS-level Timer Interrupt enable.

7

MTIE

0x0

WLRL

0 - 1

Machine Timer Interrupt enable.

8

UEIE

0x0

ROCST

0x0

User External Interrupt enable.

9

SEIE

0x0

ROCST

0x0

Supervisor External Interrupt enable.

10

VSEIE

0x0

ROCST

0x0

VS-level External Interrupt enable.

11

MEIE

0x0

WLRL

0 - 1

Machine External Interrupt enable.

12

SGEIE

0x0

ROCST

0x0

HS-level External Interrupt enable.

[31:13]

RESERVED_13

0x0

WPRI

Reserved

+
+
+
3.4.3.4. MTVEC
+
+
+
Address
+
+

0x305

+
+
Reset Value
+
+

0x80010000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

MXLEN-bit read/write register that holds trap vector configuration.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[1:0]

MODE

0x0

WARL

0x0

Vector mode.

[31:2]

BASE

0x20004000

WARL

0x00000000 - 0x3FFFFFFF

Vector base address.

+
+
+
3.4.3.5. MSTATUSH
+
+
+
Address
+
+

0x310

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

The mstatush register keeps track of and controls the hart’s current operating state.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[3:0]

RESERVED_0

0x0

WPRI

Reserved

4

SBE

0x0

ROCST

0x0

control the endianness of memory accesses other than instruction fetches for supervisor mode

5

MBE

0x0

ROCST

0x0

control the endianness of memory accesses other than instruction fetches for machine mode

6

GVA

0x0

ROCST

0x0

Stores the state of the supervisor mode interrupts.

7

MPV

0x0

ROCST

0x0

Stores the state of the user mode interrupts.

8

RESERVED_8

0x0

WPRI

Reserved

9

MPELP

0x0

ROCST

0x0

Machine mode previous expected-landing-pad (ELP) state.

[31:10]

RESERVED_10

0x0

WPRI

Reserved

+
+
+
3.4.3.6. MHPMEVENT[3-31]
+
+
+
Address
+
+

0x323-0x33f

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

The mhpmevent is a MXLEN-bit event register which controls mhpmcounter3.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MHPMEVENT[I]

0x00000000

ROCST

0x00000000

The mhpmevent is a MXLEN-bit event register which controls mhpmcounter3.

+
+
+
3.4.3.7. MSCRATCH
+
+
+
Address
+
+

0x340

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

The mscratch register is an MXLEN-bit read/write register dedicated for use by machine mode.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MSCRATCH

0x00000000

WARL

0x00000000 - 0xFFFFFFFF

The mscratch register is an MXLEN-bit read/write register dedicated for use by machine mode.

+
+
+
3.4.3.8. MEPC
+
+
+
Address
+
+

0x341

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

The mepc is a warl register that must be able to hold all valid physical and virtual addresses.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MEPC

0x00000000

WARL

0x00000000 - 0xFFFFFFFF

The mepc is a warl register that must be able to hold all valid physical and virtual addresses.

+
+
+
3.4.3.9. MCAUSE
+
+
+
Address
+
+

0x342

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

The mcause register stores the information regarding the trap.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[30:0]

EXCEPTION_CODE

0x0

WLRL

0 - 15

Encodes the exception code.

31

INTERRUPT

0x0

WLRL

0x0 - 0x1

Indicates whether the trap was due to an interrupt.

+
+
+
3.4.3.10. MTVAL
+
+
+
Address
+
+

0x343

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

The mtval is a warl register that holds the address of the instruction which caused the exception.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MTVAL

0x00000000

ROCST

0x00000000

The mtval is a warl register that holds the address of the instruction which caused the exception.

+
+
+
3.4.3.11. MIP
+
+
+
Address
+
+

0x344

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

The mip register is an MXLEN-bit read/write register containing information on pending interrupts.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

0

USIP

0x0

ROCST

0x0

User Software Interrupt Pending.

1

SSIP

0x0

ROCST

0x0

Supervisor Software Interrupt Pending.

2

VSSIP

0x0

ROCST

0x0

VS-level Software Interrupt Pending.

3

MSIP

0x0

ROCST

0x0

Machine Software Interrupt Pending.

4

UTIP

0x0

ROCST

0x0

User Timer Interrupt Pending.

5

STIP

0x0

ROCST

0x0

Supervisor Timer Interrupt Pending.

6

VSTIP

0x0

ROCST

0x0

VS-level Timer Interrupt Pending.

7

MTIP

0x0

ROVAR

0x1

Machine Timer Interrupt Pending.

8

UEIP

0x0

ROCST

0x0

User External Interrupt Pending.

9

SEIP

0x0

ROCST

0x0

Supervisor External Interrupt Pending.

10

VSEIP

0x0

ROCST

0x0

VS-level External Interrupt Pending.

11

MEIP

0x0

ROVAR

0x1

Machine External Interrupt Pending.

12

SGEIP

0x0

ROCST

0x0

HS-level External Interrupt Pending.

[31:13]

RESERVED_13

0x0

WPRI

Reserved

+
+
+
3.4.3.12. PMPCFG[0-3]
+
+
+
Address
+
+

0x3a0-0x3a3

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

PMP configuration register

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[7:0]

PMP[I*4 + 0]CFG

0x0

WARL

0x00 - 0xFF

pmp configuration bits

[15:8]

PMP[I*4 + 1]CFG

0x0

WARL

0x00 - 0xFF

pmp configuration bits

[23:16]

PMP[I*4 + 2]CFG

0x0

WARL

0x00 - 0xFF

pmp configuration bits

[31:24]

PMP[I*4 + 3]CFG

0x0

WARL

0x00 - 0xFF

pmp configuration bits

+
+
+
3.4.3.13. PMPADDR[0-15]
+
+
+
Address
+
+

0x3b0-0x3bf

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

Physical memory protection address register

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

PMPADDR[I]

0x00000000

WARL

0x00000000 - 0xFFFFFFFF

Physical memory protection address register

+
+
+
3.4.3.14. ICACHE
+
+
+
Address
+
+

0x7c0

+
+
Reset Value
+
+

0x00000001

+
+
Privilege
+
+

MRW

+
+
Description
+
+

the register controls the operation of the i-cache unit.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

0

ICACHE

0x1

RW

0x1

bit for cache-enable of instruction cache

[31:1]

RESERVED_1

0x0

WPRI

Reserved

+
+
+
3.4.3.15. DCACHE
+
+
+
Address
+
+

0x7c1

+
+
Reset Value
+
+

0x00000001

+
+
Privilege
+
+

MRW

+
+
Description
+
+

the register controls the operation of the d-cache unit.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

0

DCACHE

0x1

RW

0x1

bit for cache-enable of data cache

[31:1]

RESERVED_1

0x0

WPRI

Reserved

+
+
+
3.4.3.16. MCYCLE
+
+
+
Address
+
+

0xb00

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

Counts the number of clock cycles executed from an arbitrary point in time.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MCYCLE

0x00000000

WARL

0x00000000 - 0xFFFFFFFF

Counts the number of clock cycles executed from an arbitrary point in time.

+
+
+
3.4.3.17. MINSTRET
+
+
+
Address
+
+

0xb02

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

Counts the number of instructions completed from an arbitrary point in time.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MINSTRET

0x00000000

WARL

0x00000000 - 0xFFFFFFFF

Counts the number of instructions completed from an arbitrary point in time.

+
+
+
3.4.3.18. MHPMCOUNTER[3-31]
+
+
+
Address
+
+

0xb03-0xb1f

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

The mhpmcounter is a 64-bit counter. Returns lower 32 bits in RV32I mode.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MHPMCOUNTER[I]

0x00000000

ROCST

0x00000000

The mhpmcounter is a 64-bit counter. Returns lower 32 bits in RV32I mode.

+
+
+
3.4.3.19. MCYCLEH
+
+
+
Address
+
+

0xb80

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

upper 32 bits of mcycle

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MCYCLEH

0x00000000

WARL

0x00000000 - 0xFFFFFFFF

upper 32 bits of mcycle

+
+
+
3.4.3.20. MINSTRETH
+
+
+
Address
+
+

0xb82

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

Upper 32 bits of minstret.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MINSTRETH

0x00000000

WARL

0x00000000 - 0xFFFFFFFF

Upper 32 bits of minstret.

+
+
+
3.4.3.21. MHPMCOUNTER[3-31]H
+
+
+
Address
+
+

0xb83-0xb9f

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRW

+
+
Description
+
+

The mhpmcounterh returns the upper half word in RV32I systems.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MHPMCOUNTER[I]H

0x00000000

ROCST

0x00000000

The mhpmcounterh returns the upper half word in RV32I systems.

+
+
+
3.4.3.22. MVENDORID
+
+
+
Address
+
+

0xf11

+
+
Reset Value
+
+

0x00000602

+
+
Privilege
+
+

MRO

+
+
Description
+
+

32-bit read-only register providing the JEDEC manufacturer ID of the provider of the core.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MVENDORID

0x00000602

ROCST

0x00000602

32-bit read-only register providing the JEDEC manufacturer ID of the provider of the core.

+
+
+
3.4.3.23. MARCHID
+
+
+
Address
+
+

0xf12

+
+
Reset Value
+
+

0x00000003

+
+
Privilege
+
+

MRO

+
+
Description
+
+

MXLEN-bit read-only register encoding the base microarchitecture of the hart.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MARCHID

0x00000003

ROCST

0x00000003

MXLEN-bit read-only register encoding the base microarchitecture of the hart.

+
+
+
3.4.3.24. MIMPID
+
+
+
Address
+
+

0xf13

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRO

+
+
Description
+
+

Provides a unique encoding of the version of the processor implementation.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MIMPID

0x00000000

ROCST

0x00000000

Provides a unique encoding of the version of the processor implementation.

+
+
+
3.4.3.25. MHARTID
+
+
+
Address
+
+

0xf14

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRO

+
+
Description
+
+

MXLEN-bit read-only register containing the integer ID of the hardware thread running the code.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MHARTID

0x00000000

ROCST

0x00000000

MXLEN-bit read-only register containing the integer ID of the hardware thread running the code.

+
+
+
3.4.3.26. MCONFIGPTR
+
+
+
Address
+
+

0xf15

+
+
Reset Value
+
+

0x00000000

+
+
Privilege
+
+

MRO

+
+
Description
+
+

MXLEN-bit read-only register that holds the physical address of a configuration data structure.

+
+
+
+ ++++++++ + + + + + + + + + + + + + + + + + + + + +
BitsField NameReset ValueTypeLegal ValuesDescription

[31:0]

MCONFIGPTR

0x00000000

ROCST

0x00000000

MXLEN-bit read-only register that holds the physical address of a configuration data structure.

+
+
+
+
+

3.5. AXI

+
+

3.5.1. Introduction

+
+

In this chapter, we describe in detail the restriction that apply to the supported features.

+
+
+

In order to understand how the AXI memory interface behaves in CVA6, it is necessary to read the AMBA AXI and ACE Protocol Specification (https://developer.arm.com/documentation/ihi0022/hc) and this chapter.

+
+
+

Applicability of this chapter to configurations:

+
+ ++++ + + + + + + + + + + + + + + + + +
ConfigurationImplementation

CV32A60AX

AXI included

CV32A60X

AXI included

+
+
3.5.1.1. About the AXI4 protocol
+
+

The AMBA AXI protocol supports high-performance, high-frequency system designs for communication between Manager and Subordinate components.

+
+
+

The AXI protocol features are:

+
+
+
    +
  • +

    It is suitable for high-bandwidth and low-latency designs.

    +
  • +
  • +

    High-frequency operation is provided, without using complex bridges.

    +
  • +
  • +

    The protocol meets the interface requirements of a wide range of components.

    +
  • +
  • +

    It is suitable for memory controllers with high initial access latency.

    +
  • +
  • +

    Flexibility in the implementation of interconnect architectures is provided.

    +
  • +
  • +

    It is backward-compatible with AHB and APB interfaces.

    +
  • +
+
+
+

The key features of the AXI protocol are:

+
+
+
    +
  • +

    Separate address/control and data phases.

    +
  • +
  • +

    Support for unaligned data transfers, using byte strobes.

    +
  • +
  • +

    Uses burst-based transactions with only the start address issued.

    +
  • +
  • +

    Separate read and write data channels, that can provide low-cost Direct Memory Access (DMA).

    +
  • +
  • +

    Support for issuing multiple outstanding addresses.

    +
  • +
  • +

    Support for out-of-order transaction completion.

    +
  • +
  • +

    Permits easy addition of register stages to provide timing closure.

    +
  • +
+
+
+

The present specification is based on: https://developer.arm.com/documentation/ihi0022/hc

+
+
+
+
3.5.1.2. AXI4 and CVA6
+
+

The AXI bus protocol is used with the CVA6 processor as a memory interface. Since the processor is the one that initiates the connection with the memory, it will have a manager interface to send requests to the subordinate, which will be the memory.

+
+
+

Features supported by CVA6 are the ones in the AMBA AXI4 specification and the Atomic Operation feature from AXI5. With restriction that apply to some features.

+
+
+

This doesn’t mean that all the full set of signals available on an AXI interface are supported by the CVA6. Nevertheless, all required AXI signals are implemented.

+
+
+

Supported AXI4 features are defined in AXI Protocol Specification sections: A3, A4, A5, A6 and A7.

+
+
+

Supported AXI5 feature are defined in AXI Protocol Specification section: E1.1.

+
+
+
+
+

3.5.2. Signal Description (Section A2)

+
+

This section introduces the AXI memory interface signals of CVA6. Most of the signals are supported by CVA6, the tables summarizing the signals identify the exceptions.

+
+
+

In the following tables, the Src column tells whether the signal is driven by Manager ou Subordinate.

+
+
+

The AXI required and optional signals, and the default signals values that apply when an optional signal is not implemented are defined in AXI Protocol Specification section A9.3.

+
+
+
3.5.2.1. Global signals (Section A2.1)
+
+

Table 2.1 shows the global AXI memory interface signals.

+
+ +++++ + + + + + + + + + + + + + + + + + + + +
SignalSrcDescription

ACLK

Clock source

+
Global clock signal. Synchronous signals are sampled on the
+rising edge of the global clock.
+

WDATA

Reset source

+
Global reset signal. This signal is active-LOW.
+
+
+
+
3.5.2.2. Write address channel signals (Section A2.2)
+
+

Table 2.2 shows the AXI memory interface write address channel signals. Unless the description indicates otherwise, a signal can take any parameter if is supported.

+
+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SignalSrcSupportDescription

AWID

M

+
Yes
+(optional)
+
+
Identification tag for a write transaction.
+CVA6 gives the id depending on the type of transaction.
+See transaction_identifiers_label.
+

AWADDR

M

Yes

+
The address of the first transfer in a write transaction.
+

AWLEN

M

+
Yes
+(optional)
+
+
Length, the exact number of data transfers in a write
+transaction. This information determines the number of
+data transfers associated with the address.
+All write transactions performed by CVA6 are of length 1.
+(AWLEN = 0b00000000)
+

AWSIZE

M

+
Yes
+(optional)
+
+
Size, the number of bytes in each data transfer in a write
+transaction
+See address_structure_label.
+

AWBURST

M

+
Yes
+(optional)
+
+
Burst type, indicates how address changes between each
+transfer in a write transaction.
+All write transactions performed by CVA6 are of burst type
+INCR. (AWBURST = 0b01)
+

AWLOCK

M

+
Yes
+(optional)
+
+
Provides information about the atomic characteristics of a
+write transaction.
+

AWCACHE

M

+
Yes
+(optional)
+
+
Indicates how a write transaction is required to progress
+through a system.
+The subordinate is always of type Normal Non-cacheable Non-bufferable.
+(AWCACHE = 0b0010)
+

AWPROT

M

Yes

+
Protection attributes of a write transaction:
+privilege, security level, and access type.
+The value of AWPROT is always 0b000.
+

AWQOS

M

+
No
+(optional)
+
+
Quality of Service identifier for a write transaction.
+AWQOS = 0b0000
+

AWREGION

M

+
No
+(optional)
+
+
Region indicator for a write transaction.
+AWREGION = 0b0000
+

AWUSER

M

+
No
+(optional)
+
+
User-defined extension for the write address channel.
+AWUSER = 0b00
+

AWATOP

M

+
Yes
+(optional)
+
+
AWATOP indicates the Properties of the Atomic Operation
+used for a write transaction.
+See atomic_transactions_label.
+

AWVALID

M

Yes

+
Indicates that the write address channel signals are valid.
+

AWREADY

S

Yes

+
Indicates that a transfer on the write address channel
+can be accepted.
+
+
+
+
3.5.2.3. Write data channel signals (Section A2.3)
+
+

Table 2.3 shows the AXI write data channel signals. Unless the description indicates otherwise, a signal can take any parameter if is supported.

+
+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SignalSrcSupportDescription

WDATA

M

Yes

+
Write data.
+

WSTRB

M

+
Yes
+(optional)
+
+
Write strobes, indicate which byte lanes hold valid data
+See data_read_and_write_structure_label.
+

WLAST

M

Yes

+
Indicates whether this is the last data transfer in a write
+transaction.
+

WUSER

M

+
Yes
+(optional)
+
+
User-defined extension for the write data channel.
+

WVALID

M

Yes

+
Indicates that the write data channel signals are valid.
+

WREADY

S

Yes

+
Indicates that a transfer on the write data channel can be
+accepted.
+
+
+
+
3.5.2.4. Write Response Channel signals (Section A2.4)
+
+

Table 2.4 shows the AXI write response channel signals. Unless the description indicates otherwise, a signal can take any parameter if is supported.

+
+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SignalSrcSupportDescription

BID

S

+
Yes
+(optional)
+
+
Identification tag for a write response.
+CVA6 gives the id depending on the type of transaction.
+See transaction_identifiers_label.
+

BRESP

S

Yes

+
Write response, indicates the status of a write transaction.
+See read_and_write_response_structure_label.
+

BUSER

S

+
No
+(optional)
+
+
User-defined extension for the write response channel.
+Not supported.
+

BVALID

S

Yes

+
Indicates that the write response channel signals are valid.
+

BREADY

M

Yes

+
Indicates that a transfer on the write response channel can be
+accepted.
+
+
+
+
3.5.2.5. Read address channel signals (Section A2.5)
+
+

Table 2.5 shows the AXI read address channel signals. Unless the description indicates otherwise, a signal can take any parameter if is supported.

+
+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SignalSrcSupportDescription

ARID

M

+
Yes
+(optional)
+
+
Identification tag for a read transaction.
+CVA6 gives the id depending on the type of transaction.
+See transaction_identifiers_label.
+

ARADDR

M

+
Yes
+
+
The address of the first transfer in a read transaction.
+

ARLEN

M

+
Yes
+(optional)
+
+
Length, the exact number of data transfers in a read
+transaction. This information determines the number of data
+transfers associated with the address.
+All read transactions performed by CVA6 have a length equal to 0,
+ICACHE_LINE_WIDTH/64 or DCACHE_LINE_WIDTH/64.
+

ARSIZE

M

+
Yes
+(optional)
+
+
Size, the number of bytes in each data transfer in a read
+transaction
+See address_structure_label.
+

ARBURST

M

+
Yes
+(optional)
+
+
Burst type, indicates how address changes between each
+transfer in a read transaction.
+All Read transactions performed by CVA6 are of burst type INCR.
+(ARBURST = 0b01)
+

ARLOCK

M

+
Yes
+(optional)
+
+
Provides information about the atomic characteristics of
+a read transaction.
+

ARCACHE

M

+
Yes
+(optional)
+
+
Indicates how a read transaction is required to progress
+through a system.
+The memory is always of type Normal Non-cacheable Non-bufferable.
+(ARCACHE = 0b0010)
+

ARPROT

M

+
Yes
+
+
Protection attributes of a read transaction:
+privilege, security level, and access type.
+The value of ARPROT is always 0b000.
+

ARQOS

M

+
No
+(optional)
+
+
Quality of Service identifier for a read transaction.
+ARQOS= 0b00
+

ARREGION

M

+
No
+(optional)
+
+
Region indicator for a read transaction.
+ARREGION= 0b00
+

ARUSER

M

+
No
+(optional)
+
+
User-defined extension for the read address channel.
+ARUSER= 0b00
+

ARVALID

M

+
Yes
+(optional)
+
+
Indicates that the read address channel signals are valid.
+

ARREADY

S

+
Yes
+(optional)
+
+
Indicates that a transfer on the read address channel can be
+accepted.
+
+
+
+
3.5.2.6. Read data channel signals (Section A2.6)
+
+

Table 2.6 shows the AXI read data channel signals. Unless the description indicates otherwise, a signal can take any parameter if is supported.

+
+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SignalSrcSupportDescription

RID

S

+
Yes
+(optional)
+
+
The ID tag of the read data transfer.
+CVA6 gives the id depending on the type of transaction.
+See transaction_identifiers_label.
+

RDATA

S

Yes

+
Read data.
+

RLAST

S

Yes

+
Indicates whether this is the last data transfer in a read
+transaction.
+

RUSER

S

+
Yes
+(optional)
+
+
User-defined extension for the read data channel.
+Not supported.
+

RVALID

S

Yes

+
Indicates that the read data channel signals are valid.
+

RREADY

M

Yes

+
Indicates that a transfer on the read data channel can be accepted.
+
+
+
+
+

3.5.3. Single Interface Requirements: Transaction structure (Section A3.4)

+
+

This section describes the structure of transactions. The following sections define the address, data, and response +structures

+
+
+
3.5.3.1. Address structure (Section A3.4.1)
+
+

The AXI protocol is burst-based. The Manager begins each burst by driving control information and the address of the first byte in the transaction to the Subordinate. As the burst progresses, the Subordinate must calculate the addresses of subsequent transfers in the burst.

+
+
+

Burst length

+
+
+

The burst length is specified by:

+
+
+
    +
  • +

    ARLEN[7:0], for read transfers

    +
  • +
  • +

    AWLEN[7:0], for write transfers

    +
  • +
+
+
+

The burst length for AXI4 is defined as: Burst_Length = AxLEN[3:0] + 1.

+
+
+

CVA6 has some limitation governing the use of bursts:

+
+
+
    +
  • +

    All read transactions performed by CVA6 are of burst length equal to 0, ICACHE_LINE_WIDTH/64 or DCACHE_LINE_WIDTH/64.

    +
  • +
  • +

    All write transactions performed by CVA6 are of burst length equal to 1.

    +
  • +
+
+
+

Burst size

+
+
+

The maximum number of bytes to transfer in each data transfer, or beat, in a burst, is specified by:

+
+
+
    +
  • +

    ARSIZE[2:0], for read transfers

    +
  • +
  • +

    AWSIZE[2:0], for write transfers

    +
  • +
+
+
+

The maximum value can be taking by AxSIZE is log2(AXI DATA WIDTH/8) (8 bytes by transfer). +If(RV32) AWSIZE < 3 (The maximum store size is 4 bytes)

+
+
+

Burst type

+
+
+

The AXI protocol defines three burst types:

+
+
+
    +
  • +

    FIXED

    +
  • +
  • +

    INCR

    +
  • +
  • +

    WRAP

    +
  • +
+
+
+

The burst type is specified by:

+
+
+
    +
  • +

    ARBURST[1:0], for read transfers

    +
  • +
  • +

    AWBURST[1:0], for write transfers

    +
  • +
+
+
+

All transactions performed by CVA6 are of burst type INCR. (AxBURST = 0b01)

+
+
+
+
3.5.3.2. Data read and write structure: (Section A3.4.4)
+
+

Write strobes

+
+
+

The WSTRB[n:0] signals when HIGH, specify the byte lanes of the data bus that contain valid information. There is one write strobe +for each 8 bits of the write data bus, therefore WSTRB[n] corresponds to WDATA[(8n)+7: (8n)].

+
+
+

Write Strobe width is equal to (AXI_DATA_WIDTH/8) (n = (AXI_DATA_WIDTH/8)-1).

+
+
+

The size of transactions performed by cva6 is equal to the number of data byte lanes containing valid information. +This means 1, 2, 4, …​ or (AXI_DATA_WIDTH/8) byte lanes containing valid information. +CVA6 doesn’t perform unaligned memory acces, therefore the WSTRB take only combination of aligned access +If(RV32) WSTRB < 255 (Since AWSIZE lower than 3, so the data bus cannot have more than 4 valid byte lanes)

+
+
+

Unaligned transfers

+
+
+

For any burst that is made up of data transfers wider than 1 byte, the first bytes accessed might be unaligned with the natural +address boundary. For example, a 32-bit data packet that starts at a byte address of 0x1002 is not aligned to the natural 32-bit +transfer size.

+
+
+

CVA6 does not perform Unaligned transfers.

+
+
+
+
3.5.3.3. Read and write response structure (Section A3.4.5)
+
+

The AXI protocol provides response signaling for both read and write transactions:

+
+
+
    +
  • +

    For read transactions, the response information from the Subordinate is signaled on the read data channel.

    +
  • +
  • +

    For write transactions, the response information is signaled on the write response channel.

    +
  • +
+
+
+

CVA6 does not consider the responses sent by the memory except in the exclusive Access ( XRESP[1:0] = 0b01 ).

+
+
+
+
+

3.5.4. Transaction Attributes: Memory types (Section A4)

+
+

This section describes the attributes that determine how a transaction should be treated by the AXI subordinate that is connected to the CVA6.

+
+
+

AxCACHE always takeq 0b0010. The subordinate should be a Normal Non-cacheable Non-bufferable.

+
+
+

The required behavior for Normal Non-cacheable Non-bufferable memory is:

+
+
+
    +
  • +

    The write response must be obtained from the final destination.

    +
  • +
  • +

    Read data must be obtained from the final destination.

    +
  • +
  • +

    Transactions are modifiable.

    +
  • +
  • +

    Writes can be merged.

    +
  • +
+
+
+
+

3.5.5. Transaction Identifiers (Section A5)

+
+

The AXI protocol includes AXI ID transaction identifiers. A Manager can use these to identify separate transactions that must be returned in order.

+
+
+

The CVA6 identify each type of transaction with a specific ID:

+
+
+
    +
  • +

    For read transaction, id can be 0 or 1. (0 for instruction fetch and 1 for data)

    +
  • +
  • +

    For write transaction, id = 1.

    +
  • +
  • +

    For Atomic operation, id = 3. This ID must be sent in the write channels and also in the read channel if the transaction performed requires response data.

    +
  • +
  • +

    For Exclusive transaction, id = 3.

    +
  • +
+
+
+
+

3.5.6. AXI Ordering Model (Section A6)

+
+
3.5.6.1. AXI ordering model overview (Section A6.1)
+
+

The AXI ordering model is based on the use of the transaction identifier, which is signaled on ARID or AWID.

+
+
+

Transaction requests on the same channel, with the same ID and destination are guaranteed to remain in order.

+
+
+

Transaction responses with the same ID are returned in the same order as the requests were issued.

+
+
+

Write transaction requests, with the same destination are guaranteed to remain in order. Because all write transaction performed by CVA6 have the same ID.

+
+
+

CVA6 can perform multiple outstanding write address transactions.

+
+
+

CVA6 cannot perform a Read transaction and a Write one at the same time. Therefore there no ordering problems between Read and write transactions.

+
+
+

The ordering model does not give any ordering guarantees between:

+
+
+
    +
  • +

    Transactions from different Managers

    +
  • +
  • +

    Read Transactions with different IDs

    +
  • +
  • +

    Transactions to different Memory locations

    +
  • +
+
+
+

If the CVA6 requires ordering between transactions that have no ordering guarantee, the Manager must wait to receive a response to the first transaction before issuing the second transaction.

+
+
+
+
3.5.6.2. Memory locations and Peripheral regions (Section A6.2)
+
+

The address map in AMBA is made up of Memory locations and Peripheral regions. But the AXI is associated to the memory interface of CVA6.

+
+
+

A Memory location has all of the following properties:

+
+
+
    +
  • +

    A read of a byte from a Memory location returns the last value that was written to that byte location.

    +
  • +
  • +

    A write to a byte of a Memory location updates the value at that location to a new value that is obtained by a subsequent read of that location.

    +
  • +
  • +

    Reading or writing to a Memory location has no side-effects on any other Memory location.

    +
  • +
  • +

    Observation guarantees for Memory are given for each location.

    +
  • +
  • +

    The size of a Memory location is equal to the single-copy atomicity size for that component.

    +
  • +
+
+
+
+
3.5.6.3. Transactions and ordering (Section A6.3)
+
+

A transaction is a read or a write to one or more address locations. The locations are determined by AxADDR and any relevant qualifiers such as the Non-secure bit in AxPROT.

+
+
+
    +
  • +

    Ordering guarantees are given only between accesses to the same Memory location or Peripheral region.

    +
  • +
  • +

    A transaction to a Peripheral region must be entirely contained within that region.

    +
  • +
  • +

    A transaction that spans multiple Memory locations has multiple ordering guarantees.

    +
  • +
+
+
+

Transaction performed by CVA6 is of type Normal, because AxCACHE[1] is asserted.

+
+
+

Normal transactions are used to access Memory locations and are not expected to be used to access Peripheral regions.

+
+
+

A Normal access to a Peripheral region must complete in a protocol-compliant manner, but the result is IMPLEMENTATION DEFINED.

+
+
+

A write transaction performed by CVA6 is Non-bufferable (It is not possible to send an early response before the transaction reach the final destination), because AxCACHE[0] is deasserted.

+
+
+
+
3.5.6.4. Ordered write observation (Section A6.8)
+
+

To improve compatibility with interface protocols that support a different ordering model, a Subordinate interface can give stronger ordering guarantees for write transactions. A stronger ordering guarantee is known as Ordered Write Observation.

+
+
+

The CVA6 AXI interface exhibits Ordered Write Observation, so the Ordered_Write_Observation property is True.

+
+
+

An interface that exhibits Ordered Write Observation gives guarantees for write transactions that are not dependent on the destination or address:

+
+
+
    +
  • +

    A write W1 is guaranteed to be observed by a write W2, where W2 is issued after W1, from the same Manager, with the same ID.

    +
  • +
+
+
+
+
+

3.5.7. Atomic transactions (Section E1.1)

+
+

AMBA 5 introduces Atomic transactions, which perform more than just a single access and have an operation that is associated with the transaction. Atomic transactions enable sending the operation to the data, permitting the operation to be performed closer to where the data is located. Atomic transactions are suited to situations where the data is located a significant distance from the agent that must perform the operation.

+
+
+

If(RVA) AWATOP = 0 (If AMO instructions are not supported, CVA6 cannot perform Atomic transaction)

+
+
+

CVA6 supports just the AtomicLoad and AtomicSwap transaction. So AWATOP[5:4] can be 00, 10 or 11.

+
+
+

CVA6 performs only little-endian operation. So AWATOP[3] = 0.

+
+
+

For AtomicLoad, CVA6 supports all arithmetic operations encoded on the lower-order AWATOP[2:0] signals.

+
+
+
+

3.5.8. CVA6 Constraints

+
+

This section describes cross-cases between several features that are not supported by CVA6.

+
+
+
    +
  • +

    ARID = 0 && ARSIZE = log(AXI_DATA_WIDTH/8), CVA6 always requests max number of words in case of read transaction with ID 0 (instruction fetch)

    +
  • +
  • +

    if(RV32) ARSIZE != 3 && ARLEN = 0 && ARID = 1, the maximum load instruction size is 4 bytes

    +
  • +
  • +

    if(!RVA) AxLOCK = 0, if AMO instructions are not supported, CVA6 cannot perform exclusive transaction

    +
  • +
  • +

    if(RVA) AxLOCK = 1 ⇒ AxSIZE > 1, CVA6 doesn’t perform exclusive transaction with size lower than 4 bytes

    +
  • +
+
+
+
+
+

3.6. CV-X-IF Interface and Coprocessor

+
+

The CV-X-IF interface of CVA6 allows to extend its supported instruction +set with external coprocessors.

+
+
+

Applicability of this chapter to configurations:

+
+ ++++ + + + + + + + + + + + + + + + + + + + + +
ConfigurationImplementation

CV32A60AX

CV-X-IF included

CV32A60X

CV-X-IF included

CV64A6_MMU

CV-X-IF included

+
+

3.6.1. CV-X-IF interface specification

+
+
3.6.1.1. Description
+
+

This design specification presents global functionalities of +Core-V-eXtension-Interface (XIF, CVXIF, CV-X-IF, X-interface) in the CVA6 core.

+
+
+
+
The CORE-V X-Interface is a RISC-V eXtension interface that provides a
+generalized framework suitable to implement custom coprocessors and ISA
+extensions for existing RISC-V processors.
+
+--core-v-xif Readme, https://github.com/openhwgroup/core-v-xif
+
+
+
+

The specification of the CV-X-IF bus protocol can be found at [CV-X-IF].

+
+
+

CV-X-IF aims to:

+
+
+
    +
  • +

    Create interfaces to connect a coprocessor to the CVA6 to execute instructions.

    +
  • +
  • +

    Offload CVA6 illegal instrutions to the coprocessor to be executed.

    +
  • +
  • +

    Get the results of offloaded instructions from the coprocessor so they are written back into the CVA6 register file.

    +
  • +
  • +

    Add standard RISC-V instructions unsupported by CVA6 or custom instructions and implement them in a coprocessor.

    +
  • +
  • +

    Kill offloaded instructions to allow speculative execution in the coprocessor. (Unsupported in CVA6 yet)

    +
  • +
  • +

    Connect the coprocessor to memory via the CVA6 Load and Store Unit. (Unsupported in CVA6 yet)

    +
  • +
+
+
+

The coprocessor operates like another functional unit so it is connected +to the CVA6 in the execute stage.

+
+
+

Only the 3 mandatory interfaces from the CV-X-IF specification (issue, commit and result +) have been implemented. +Compressed interface, Memory Interface and Memory result interface are not yet +implemented in the CVA6.

+
+
+
+
3.6.1.2. Supported Parameters
+
+

The following table presents CVXIF parameters supported by CVA6.

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SignalValueDescription

X_NUM_RS

int: 2 or 3 (configurable)

+
Number of register file read ports that can
+be used by the eXtension interface
+

X_ID_WIDTH

int: 3

+
Identification width for the eXtension
+interface
+

X_MEM_WIDTH

n/a (feature not supported)

+
Memory access width for loads/stores via the
+eXtension interface
+

X_RFR_WIDTH

int: XLEN (32 or 64)

+
Register file read access width for the
+eXtension interface
+

X_RFW_WIDTH

int: XLEN (32 or 64)

+
Register file write access width for the
+eXtension interface
+

X_MISA

logic[31:0]: 0x0000_0000

+
MISA extensions implemented on the eXtension
+interface
+
+
+
+
3.6.1.3. CV-X-IF Enabling
+
+

CV-X-IF can be enabled or disabled via the CVA6ConfigCvxifEn parameter in the SystemVerilog source code.

+
+
+
+
3.6.1.4. Illegal instruction decoding
+
+

The CVA6 decoder module detects illegal instructions for the CVA6, prepares exception field +with relevant information (exception code "ILLEGAL INSTRUCTION", instruction value).

+
+
+

The exception valid flag is raised in CVA6 decoder when CV-X-IF is disabled. Otherwise +it is not raised at this stage because the decision belongs to the coprocessor +after the offload process.

+
+
+
+
3.6.1.5. RS3 support
+
+

The number of source registers used by the CV-X-IF coprocessor is configurable with 2 or +3 source registers.

+
+
+

If CV-X-IF is enabled and configured with 3 source registers, +a third read port is added to the CVA6 general purpose register file.

+
+
+
+
3.6.1.6. Description of interface connections between CVA6 and Coprocessor
+
+

In CVA6 execute stage, there is a new functional unit dedicated to drive the CV-X-IF interfaces. +Here is how and to what CV-X-IF interfaces are connected to the CVA6.

+
+
+
    +
  • +

    Issue interface::

    +
    +
      +
    • +

      Request;;

      +
      +
        +
      • +

        [verse] — Operands are connected to issue_req.rs signals — 

        +
      • +
      • +

        [verse] — Scoreboard transaction id is connected to issue_req.id signal. +Therefore scoreboard ids and offloaded instruction ids are linked +together (equal in this implementation). It allows the CVA6 to do out +of order execution with the coprocessor in the same way as other +functional units. — 

        +
      • +
      • +

        [verse] — Undecoded instruction is connected to issue_req.instruction — 

        +
      • +
      • +

        [verse] — Valid signal for CVXIF functional unit is connected to +issue_req.valid — 

        +
      • +
      • +

        [verse] — All issue_req.rs_valid signals are set to 1. The validity of source +registers is assured by the validity of valid signal sent from issue stage. — 

        +
      • +
      +
      +
    • +
    • +

      Response;;

      +
      +
        +
      • +

        [verse] — If issue_resp.accept is set during a transaction (i.e. issue valid +and ready are set), the offloaded instruction is accepted by the coprocessor +and a result transaction will happen. — 

        +
      • +
      • +

        [verse] — If issue_resp.accept is not set during a transaction, the offloaded +instruction is illegal and an illegal instruction exception will be +raised as soon as no result transaction are written on the writeback bus. — 

        +
      • +
      +
      +
    • +
    +
    +
  • +
  • +

    Commit interface::

    +
    +
      +
    • +

      [verse] — Valid signal of commit interface is connected to the valid signal of +issue interface. — 

      +
    • +
    • +

      [verse] — Id signal of commit interface is connected to issue interface id signal +(i.e. scoreboard id). — 

      +
    • +
    • +

      [verse] — Killing of offload instruction is never set. (Unsupported feature) — 

      +
    • +
    • +

      [verse] — Therefore all accepted offloaded instructions are commited to their +execution and no killing of instruction is possible in this implementation. — 

      +
    • +
    +
    +
  • +
  • +

    Result interface::

    +
    +
      +
    • +

      Request;;

      +
      +
        +
      • +

        [verse] — Ready signal of result interface is always set as CVA6 is always ready +to take a result from coprocessor for an accepted offloaded instruction. — 

        +
      • +
      +
      +
    • +
    • +

      Response;;

      +
      +
        +
      • +

        [verse] — Result response is directly connected to writeback bus of the CV-X-IF +functionnal unit. — 

        +
      • +
      • +

        [verse] — Valid signal of result interface is connected to valid signal of +writeback bus. — 

        +
      • +
      • +

        [verse] — Id signal of result interface is connected to scoreboard id of +writeback bus. — 

        +
      • +
      • +

        [verse] — Write enable signal of result interface is connected to a dedicated CV-X-IF WE +signal in CVA6 which signals scoreboard if a writeback should happen +or not to the CVA6 register file. — 

        +
      • +
      • +

        [verse] — exccode and exc signal of result interface are connected to exception +signals of writeback bus. Exception from coprocessor does not write +the tval field in exception signal of writeback bus. — 

        +
      • +
      • +

        [verse] — Three registers are added to hold illegal instruction information in +case a result transaction and a non-accepted issue transaction happen +in the same cycle. Result transactions will be written to the writeback +bus in this case having priority over the non-accepted instruction due +to being linked to an older offloaded instruction. Once the writeback +bus is free, an illegal instruction exception will be raised thanks to +information held in these three registers. — 

        +
      • +
      +
      +
    • +
    +
    +
  • +
+
+
+
+
+

3.6.2. Coprocessor recommendations for use with CVA6’s CV-X-IF

+
+

CVA6 supports all coprocessors supporting the CV-X-IF specification with the exception of :

+
+
+
    +
  • +

    Coprocessor requiring the Memory interface and Memory result interface (not implemented in CVA6 yet).::

    +
    +
      +
    • +

      All memory transaction should happen via the Issue interface, i.e. Load into CVA6 register file +then initialize an issue transaction.

      +
    • +
    +
    +
  • +
  • +

    Coprocessor requiring the Compressed interface (not implemented in CVA6 yet).::

    +
    +
      +
    • +

      RISC-V Compressed extension (RVC) is already implemented in CVA6 User Space for custom compressed instruction +is not big enough to have RVC and a custom compressed extension.

      +
    • +
    +
    +
  • +
  • +

    Stateful coprocessors.::

    +
    +
      +
    • +

      CVA6 will commit on the Commit interface all its issue transactions. Speculation +informations are only kept in the CVA6 and speculation process is only done in CVA6. +The coprocessor shall be stateless otherwise it will not be able to revert its state if CVA6 kills an +in-flight instruction (in case of mispredict or flush).

      +
    • +
    +
    +
  • +
+
+
+
+

3.6.3. How to use CVA6 without CV-X-IF interface

+
+

Select a configuration with CVA6ConfigCvxifEn parameter disabled or change it for your configuration.

+
+
+

Never let the CV-X-IF interface unconnected with the CVA6ConfigCvxifEn parameter enabled.

+
+
+
+

3.6.4. How to design a coprocessor for the CV-X-IF interface

+
+

The team is looking for a contributor to write this section.

+
+
+
+

3.6.5. How to program a CV-X-IF coprocessor

+
+

The team is looking for a contributor to write this section.

+
+
+
+
+
+
+

4. Architecture and Modules

+
+
+

The CV32A65X is fully synthesizable. It has been designed mainly for ASIC designs, but FPGA synthesis is supported as well.

+
+
+

For ASIC synthesis, the whole design is completely synchronous and uses positive-edge triggered flip-flops. The core occupies an area of about 80 kGE. The clock frequency can be more than 1GHz depending of technology.

+
+
+

The CV32A65X subsystem is composed of 8 modules.

+
+
+

CV32A65X modules

+
+
+

Connections between modules are illustrated in the following block diagram. FRONTEND, DECODE, ISSUE, EXECUTE, COMMIT and CONTROLLER are part of the pipeline. And CACHES implements the instruction and data caches and CSRFILE contains registers.

+
+
+

CV32A65X pipeline and modules

+
+
+

4.1. FRONTEND Module

+
+

4.1.1. Description

+
+

The FRONTEND module implements two first stages of the cva6 pipeline, +PC gen and Fetch stages.

+
+
+

PC gen stage is responsible for generating the next program counter. +It hosts a Branch Target Buffer (BTB), a Branch History Table (BHT) and a Return Address Stack (RAS) to speculate on control flow instructions.

+
+
+

Fetch stage requests data to the CACHE module, realigns the data to store them in instruction queue and transmits the instructions to the DECODE module. +FRONTEND can fetch up to 2 instructions per cycles when C extension instructions is enabled, but DECODE module decodes up to one instruction per cycles.

+
+
+

The module is connected to:

+
+
+
    +
  • +

    CACHES module provides fethed instructions to FRONTEND.

    +
  • +
  • +

    DECODE module receives instructions from FRONTEND.

    +
  • +
  • +

    CONTROLLER module can order to flush and to halt FRONTEND PC gen stage

    +
  • +
  • +

    EXECUTE, CONTROLLER, CSR and COMMIT modules trigger PC jumping due to +a branch misprediction, an exception, a return from an exception, a +debug entry or a pipeline flush. They provides the PC next value.

    +
  • +
  • +

    CSR module states about debug mode.

    +
  • +
+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 3. frontend module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

boot_addr_i

in

Next PC when reset

SUBSYSTEM

logic[CVA6Cfg.VLEN-1:0]

flush_i

in

Flush requested by FENCE, mis-predict and exception

CONTROLLER

logic

halt_i

in

Halt requested by WFI and Accelerate port

CONTROLLER

logic

set_pc_commit_i

in

Set COMMIT PC as next PC requested by FENCE, CSR side-effect and Accelerate port

CONTROLLER

logic

pc_commit_i

in

COMMIT PC

COMMIT

logic[CVA6Cfg.VLEN-1:0]

ex_valid_i

in

Exception event

COMMIT

logic

resolved_branch_i

in

Mispredict event and next PC

EXECUTE

bp_resolve_t

eret_i

in

Return from exception event

CSR

logic

epc_i

in

Next PC when returning from exception

CSR

logic[CVA6Cfg.VLEN-1:0]

trap_vector_base_i

in

Next PC when jumping into exception

CSR

logic[CVA6Cfg.VLEN-1:0]

icache_dreq_o

out

Handshake between CACHE and FRONTEND (fetch)

CACHES

icache_dreq_t

icache_dreq_i

in

Handshake between CACHE and FRONTEND (fetch)

CACHES

icache_drsp_t

fetch_entry_o

out

Handshake’s data between fetch and decode

ID_STAGE

fetch_entry_t[CVA6Cfg.NrIssuePorts-1:0]

fetch_entry_valid_o

out

Handshake’s valid between fetch and decode

ID_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

fetch_entry_ready_i

in

Handshake’s ready between fetch and decode

ID_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
For any HW configuration,
+
+
+
    +
  • +

    flush_bp_i input is tied to 0

    +
  • +
+
+
+
As DebugEn = False,
+
+
+
    +
  • +

    set_debug_pc_i input is tied to 0

    +
  • +
  • +

    debug_mode_i input is tied to 0

    +
  • +
+
+
+
+
+
+
+

4.1.2. Functionality

+ +
+
+

4.1.3. PC Generation stage

+
+

PC gen generates the next program counter. The next PC can originate from the following sources (listed in order of precedence):

+
+
+
    +
  • +

    Reset state: At reset, the PC is assigned to the boot address.

    +
  • +
  • +

    Branch Prediction: The fetched instruction is predecoded by the +instr_scan submodule. When the instruction is a control flow, three +cases are considered:

    +
    +
    +
    +
      +
    1. +

      When the instruction is a JALR which corresponds to a return (rs1 = x1 or rs1 = x5). +RAS provides next PC as a prediction.

      +
    2. +
    3. +

      When the instruction is a JALR which does not correspond to areturn. +If BTB (Branch Target Buffer) returns a valid address, then BTBpredicts next PC. +Else JALR is not considered as a control flow instruction, which will generate a mispredict.

      +
    4. +
    5. +

      When the instruction is a conditional branch. +If BHT (Branch History table) returns a valid address, then BHT predicts next PC. +Else the prediction depends on the PC relative jump offset sign: if sign is negative the prediction is taken, otherwise the prediction is not taken.

      +
    6. +
    +
    +
    +
    +
    +

    Then the PC gen informs the Fetch stage that it performed a prediction on the PC.

    +
    +
  • +
  • +

    Default: The next 32-bit block is fetched. +PC Gen fetches word boundary 32-bits block from CACHES module. And the fetch stage identifies the instructions from the 32-bits blocks.

    +
  • +
  • +

    Mispredict: Misprediction are feedbacked by EX_STAGE module. +In any case we need to correct our action and start fetching from the correct address.

    +
  • +
  • +

    Replay instruction fetch: When the instruction queue is full, the instr_queue submodule asks the fetch replay and provides the address to be replayed.

    +
  • +
  • +

    Return from environment call: When CSR requests a return from an environment call, next PC takes the value of the PC of the instruction after the one pointed to by the mepc CSR.

    +
  • +
  • +

    Exception/Interrupt: If an exception is triggered by CSR_REGISTER, next PC takes the value of the trap vector base address CSR.

    +
  • +
  • +

    Pipeline starting fetching from COMMIT PC: When the commit stage is halted by a WFI instruction or when the pipeline has been flushed due to CSR change, next PC takes the value of the PC coming from the COMMIT submodule. +As CSR instructions do not exist in a compressed form, PC is unconditionally incremented by 4.

    +
  • +
+
+
+

All program counters are logical addressed.

+
+
+
+

4.1.4. Fetch Stage

+
+

Fetch stage controls the CACHE module by a handshaking protocol. +Fetched data is a 32-bit block with a word-aligned address. +A granted fetch is processed by the instr_realign submodule to produce instructions. +Then instructions are pushed into an internal instruction FIFO called instruction queue (instr_queue submodule). +This submodule stores the instructions and sends them to the DECODE module.

+
+
+

Memory can feedback potential exceptions which can be bus errors, invalid accesses or instruction page faults. +The FRONTEND transmits the exception from CACHES to DECODE.

+
+
+
+

4.1.5. Submodules

+
+

FRONTEND submodules

+
+
+

FRONTEND submodule interconnections

+
+
+
4.1.5.1. Instr_realign submodule
+
+

The 32-bit aligned block coming from the CACHE module enters the instr_realign submodule. +This submodule extracts the instructions from the 32-bit blocks. +It is possible to fetch up to two instructions per cycle when C extension is used. +An not-compressed instruction can be misaligned on the block size, interleaved with two cache blocks. +In that case, two cache accesses are needed to get the whole instruction. +The instr_realign submodule provides at maximum two instructions per cycle when compressed extension is enabled, else one instruction per cycle. +Incomplete instruction is stored in instr_realign submodule until its second half is fetched.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 4. instr_realign module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

flush_i

in

Fetch flush request

CONTROLLER

logic

valid_i

in

32-bit block is valid

CACHE

logic

serving_unaligned_o

out

Instruction is unaligned

FRONTEND

logic

address_i

in

32-bit block address

CACHE

logic[CVA6Cfg.VLEN-1:0]

data_i

in

32-bit block

CACHE

logic[CVA6Cfg.FETCH_WIDTH-1:0]

valid_o

out

instruction is valid

FRONTEND

logic[CVA6Cfg.INSTR_PER_FETCH-1:0]

addr_o

out

Instruction address

FRONTEND

logic[CVA6Cfg.INSTR_PER_FETCH-1:0][CVA6Cfg.VLEN-1:0]

instr_o

out

Instruction

instr_scan&instr_queue

logic[CVA6Cfg.INSTR_PER_FETCH-1:0][31:0]

+
+
+
4.1.5.2. Instr_queue submodule
+
+

The instr_queue receives mutliple instructions from instr_realign submodule to create a valid stream of instructions to be decoded (by DECODE), to be issued (by ISSUE) and executed (by EXECUTE). +FRONTEND pushes in FIFO to store the instructions and related information needed in case of mispredict or exception: instructions, instruction control flow type, exception, exception address and predicted address. +DECODE pops them when decode stage is ready and indicates to the FRONTEND the instruction has been consummed.

+
+
+

The instruction queue contains max 4 instructions. +If the instruction queue is full, a replay request is sent to inform the fetch mechanism to replay the fetch.

+
+
+

The instruction queue can be flushed by CONTROLLER.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 5. instr_queue module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

flush_i

in

Fetch flush request

CONTROLLER

logic

instr_i

in

Instruction

instr_realign

logic[CVA6Cfg.INSTR_PER_FETCH-1:0][31:0]

addr_i

in

Instruction address

instr_realign

logic[CVA6Cfg.INSTR_PER_FETCH-1:0][CVA6Cfg.VLEN-1:0]

valid_i

in

Instruction is valid

instr_realign

logic[CVA6Cfg.INSTR_PER_FETCH-1:0]

ready_o

out

Handshake’s ready with CACHE

CACHE

logic

consumed_o

out

Indicates instructions consummed, or popped by ID_STAGE

FRONTEND

logic[CVA6Cfg.INSTR_PER_FETCH-1:0]

exception_i

in

Exception (which is page-table fault)

CACHE

ariane_pkg::frontend_exception_t

exception_addr_i

in

Exception address

CACHE

logic[CVA6Cfg.VLEN-1:0]

predict_address_i

in

Branch predict

FRONTEND

logic[CVA6Cfg.VLEN-1:0]

cf_type_i

in

Instruction predict address

FRONTEND

ariane_pkg::cf_t[CVA6Cfg.INSTR_PER_FETCH-1:0]

replay_o

out

Replay instruction because one of the FIFO was full

FRONTEND

logic

replay_addr_o

out

Address at which to replay the fetch

FRONTEND

logic[CVA6Cfg.VLEN-1:0]

fetch_entry_o

out

Handshake’s data with ID_STAGE

ID_STAGE

fetch_entry_t[CVA6Cfg.NrIssuePorts-1:0]

fetch_entry_valid_o

out

Handshake’s valid with ID_STAGE

ID_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

fetch_entry_ready_i

in

Handshake’s ready with ID_STAGE

ID_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As RVH = False,
+
+
+
    +
  • +

    exception_gpaddr_i input is tied to 0

    +
  • +
  • +

    exception_tinst_i input is tied to 0

    +
  • +
  • +

    exception_gva_i input is tied to 0

    +
  • +
+
+
+
+
+
+
+
4.1.5.3. instr_scan submodule
+
+

As compressed extension is enabled, two instr_scan are instantiated to handle up to two instructions per cycle.

+
+
+

Each instr_scan submodule pre-decodes the fetched instructions coming from the instr_realign module, instructions could be compressed or not. +The instr_scan submodule is a flox controler which provides the intruction type: branch, jump, return, jalr, imm, call or others. +These outputs are used by the branch prediction feature.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 6. instr_scan module IO ports
SignalIODescriptionconnexionType

instr_i

in

Instruction to be predecoded

instr_realign

logic[31:0]

rvi_return_o

out

Return instruction

FRONTEND

logic

rvi_call_o

out

JAL instruction

FRONTEND

logic

rvi_branch_o

out

Branch instruction

FRONTEND

logic

rvi_jalr_o

out

JALR instruction

FRONTEND

logic

rvi_jump_o

out

Unconditional jump instruction

FRONTEND

logic

rvi_imm_o

out

Instruction immediat

FRONTEND

logic[CVA6Cfg.VLEN-1:0]

rvc_branch_o

out

Branch compressed instruction

FRONTEND

logic

rvc_jump_o

out

Unconditional jump compressed instruction

FRONTEND

logic

rvc_jr_o

out

JR compressed instruction

FRONTEND

logic

rvc_return_o

out

Return compressed instruction

FRONTEND

logic

rvc_jalr_o

out

JALR compressed instruction

FRONTEND

logic

rvc_call_o

out

JAL compressed instruction

FRONTEND

logic

rvc_imm_o

out

Instruction compressed immediat

FRONTEND

logic[CVA6Cfg.VLEN-1:0]

+
+
+
4.1.5.4. BHT (Branch History Table) submodule
+
+

BHT is implemented as a memory which is composed of BHTDepth configuration parameter entries. The lower address bits of the virtual address point to the memory entry.

+
+
+

When a branch instruction is resolved by the EX_STAGE module, the branch PC and the taken (or not taken) status information is stored in the Branch History Table.

+
+
+

The Branch History Table is a table of two-bit saturating counters that takes the virtual address of the current fetched instruction by the CACHE. +It states whether the current branch request should be taken or not. +The two bit counter is updated by the successive execution of the instructions as shown in the following figure.

+
+
+

BHT saturation

+
+
+

When a branch instruction is pre-decoded by instr_scan submodule, the BHT valids whether the PC address is in the BHT and provides the taken or not prediction.

+
+
+

The BHT is never flushed.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 7. bht module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

vpc_i

in

Virtual PC

CACHE

logic[CVA6Cfg.VLEN-1:0]

bht_update_i

in

Update bht with resolved address

EXECUTE

bht_update_t

bht_prediction_o

out

Prediction from bht

FRONTEND

ariane_pkg::bht_prediction_t[CVA6Cfg.INSTR_PER_FETCH-1:0]

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
For any HW configuration,
+
+
+
    +
  • +

    flush_bp_i input is tied to 0

    +
  • +
+
+
+
As DebugEn = False,
+
+
+
    +
  • +

    debug_mode_i input is tied to 0

    +
  • +
+
+
+
+
+
+
+
4.1.5.5. BTB (Branch Target Buffer) submodule
+
+

BTB is implemented as an array which is composed of BTBDepth configuration parameter entries. +The lower address bits of the virtual address point to the memory entry.

+
+
+

When an JALR instruction is found mispredicted by the EX_STAGE module, the JALR PC and the target address are stored into the BTB.

+
+
+

When a JALR instruction is pre-decoded by instr_scan submodule, the BTB informs whether the input PC address is in the BTB. +In this case, the BTB provides the predicted target address.

+
+
+

The BTB is never flushed.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 8. btb module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

vpc_i

in

Virtual PC

CACHE

logic[CVA6Cfg.VLEN-1:0]

btb_update_i

in

Update BTB with resolved address

EXECUTE

btb_update_t

btb_prediction_o

out

BTB Prediction

FRONTEND

btb_prediction_t[CVA6Cfg.INSTR_PER_FETCH-1:0]

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
For any HW configuration,
+
+
+
    +
  • +

    flush_bp_i input is tied to 0

    +
  • +
+
+
+
As DebugEn = False,
+
+
+
    +
  • +

    debug_mode_i input is tied to 0

    +
  • +
+
+
+
+
+
+
+
4.1.5.6. RAS (Return Address Stack) submodule
+
+

RAS is implemented as a LIFO which is composed of RASDepth configuration parameter entries.

+
+
+

When a JAL instruction is pre-decoded by the instr_scan, the PC of the instruction following JAL instruction is pushed into the RAS when the JAL instruction is added to the instruction queue.

+
+
+

When a JALR instruction which corresponds to a return (rs1 = x1 or rs1 = x5) is pre-decoded by the instr_scan, the predicted return address is popped from the RAS when the JALR instruction is added to the instruction queue. +If the predicted return address is wrong due for instance to speculation or RAS depth limitation, a mis-repdiction will be generated.

+
+
+

The RAS is never flushed.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 9. ras module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

push_i

in

Push address in RAS

FRONTEND

logic

pop_i

in

Pop address from RAS

FRONTEND

logic

data_i

in

Data to be pushed

FRONTEND

logic[CVA6Cfg.VLEN-1:0]

data_o

out

Popped data

FRONTEND

ras_t

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
For any HW configuration,
+
+
+
    +
  • +

    flush_bp_i input is tied to 0

    +
  • +
+
+
+
+
+
+
+
+
+

4.2. ID_STAGE Module

+
+

4.2.1. Description

+
+

The ID_STAGE module implements the decode stage of the pipeline. Its +main purpose is to decode RISC-V instructions coming from FRONTEND +module (fetch stage) and send them to the ISSUE_STAGE module (issue +stage).

+
+
+

The compressed_decoder module checks whether the incoming instruction is +compressed and output the corresponding uncompressed instruction. Then +the decoder module decodes the instruction and send it to the issue +stage.

+
+
+

The module is connected to:

+
+
+
    +
  • +

    CONTROLLER module can flush ID_STAGE decode stage

    +
  • +
  • +

    FRONTEND module sends instrution to ID_STAGE module

    +
  • +
  • +

    ISSUE module receives the decoded instruction from ID_STAGE module

    +
  • +
  • +

    CSR_REGFILE module sends status information about privilege mode, +traps, extension support.

    +
  • +
+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 10. id_stage module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

flush_i

in

Fetch flush request

CONTROLLER

logic

fetch_entry_i

in

Handshake’s data between fetch and decode

FRONTEND

fetch_entry_t[CVA6Cfg.NrIssuePorts-1:0]

fetch_entry_valid_i

in

Handshake’s valid between fetch and decode

FRONTEND

logic[CVA6Cfg.NrIssuePorts-1:0]

fetch_entry_ready_o

out

Handshake’s ready between fetch and decode

FRONTEND

logic[CVA6Cfg.NrIssuePorts-1:0]

issue_entry_o

out

Handshake’s data between decode and issue

ISSUE

scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0]

orig_instr_o

out

Instruction value

ISSUE

logic[CVA6Cfg.NrIssuePorts-1:0][31:0]

issue_entry_valid_o

out

Handshake’s valid between decode and issue

ISSUE

logic[CVA6Cfg.NrIssuePorts-1:0]

is_ctrl_flow_o

out

Report if instruction is a control flow instruction

ISSUE

logic[CVA6Cfg.NrIssuePorts-1:0]

issue_instr_ack_i

in

Handshake’s acknowlege between decode and issue

ISSUE

logic[CVA6Cfg.NrIssuePorts-1:0]

irq_i

in

Level sensitive (async) interrupts

SUBSYSTEM

logic[1:0]

irq_ctrl_i

in

Interrupt control status

CSR_REGFILE

irq_ctrl_t

hart_id_i

in

none

none

logic[CVA6Cfg.XLEN-1:0]

compressed_ready_i

in

none

none

logic

compressed_resp_i

in

none

none

x_compressed_resp_t

compressed_valid_o

out

none

none

logic

compressed_req_o

out

none

none

x_compressed_req_t

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As DebugEn = False,
+
+
+
    +
  • +

    debug_req_i input is tied to 0

    +
  • +
  • +

    debug_mode_i input is tied to 0

    +
  • +
+
+
+
As IsRVFI = 0,
+
+
+
    +
  • +

    rvfi_is_compressed_o output is tied to 0

    +
  • +
+
+
+
As PRIV = MachineOnly,
+
+
+
    +
  • +

    priv_lvl_i input is tied to MachineMode

    +
  • +
  • +

    tvm_i input is tied to 0

    +
  • +
  • +

    tw_i input is tied to 0

    +
  • +
  • +

    tsr_i input is tied to 0

    +
  • +
+
+
+
As RVH = False,
+
+
+
    +
  • +

    v_i input is tied to 0

    +
  • +
  • +

    vfs_i input is tied to 0

    +
  • +
  • +

    vtw_i input is tied to 0

    +
  • +
  • +

    hu_i input is tied to 0

    +
  • +
+
+
+
As RVF = 0,
+
+
+
    +
  • +

    fs_i input is tied to 0

    +
  • +
  • +

    frm_i input is tied to 0

    +
  • +
+
+
+
As RVV = False,
+
+
+
    +
  • +

    vs_i input is tied to 0

    +
  • +
+
+
+
+
+
+
+

4.2.2. Functionality

+
+

TO BE COMPLETED

+
+
+
+

4.2.3. Submodules

+
+

ID_STAGE submodules

+
+
+
4.2.3.1. Compressed_decoder
+
+

The compressed_decoder module decompresses all the compressed +instructions taking a 16-bit compressed instruction and expanding it to +its 32-bit equivalent. All compressed instructions have a 32-bit +equivalent.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 11. compressed_decoder module IO ports
SignalIODescriptionconnexionType

instr_i

in

Input instruction coming from fetch stage

FRONTEND

logic[31:0]

instr_o

out

Output instruction in uncompressed format

decoder

logic[31:0]

illegal_instr_o

out

Input instruction is illegal

decoder

logic

is_macro_instr_o

out

Output instruction is macro

decoder

logic

is_compressed_o

out

Output instruction is compressed

decoder

logic

+
+
+
4.2.3.2. Decoder
+
+

The decoder module takes the output of compressed_decoder module and +decodes it. It transforms the instruction to the most fundamental +control structure in pipeline, a scoreboard entry.

+
+
+

The scoreboard entry contains an exception entry which is composed of a +valid field, a cause and a value called TVAL. As TVALEn configuration +parameter is zero, the TVAL field is not implemented.

+
+
+

A potential illegal instruction exception can be detected during +decoding. If no exception has happened previously in fetch stage, the +decoder will valid the exception and add the cause and tval value to the +scoreboard entry.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 12. decoder module IO ports
SignalIODescriptionconnexionType

pc_i

in

PC from fetch stage

FRONTEND

logic[CVA6Cfg.VLEN-1:0]

is_compressed_i

in

Is a compressed instruction

compressed_decoder

logic

compressed_instr_i

in

Compressed form of instruction

FRONTEND

logic[15:0]

is_illegal_i

in

Illegal compressed instruction

compressed_decoder

logic

instruction_i

in

Instruction from fetch stage

FRONTEND

logic[31:0]

is_macro_instr_i

in

Is a macro instruction

macro_decoder

logic

is_last_macro_instr_i

in

Is a last macro instruction

macro_decoder

logic

is_double_rd_macro_instr_i

in

Is mvsa01/mva01s macro instruction

macro_decoder

logic

branch_predict_i

in

Is a branch predict instruction

FRONTEND

branchpredict_sbe_t

ex_i

in

If an exception occured in fetch stage

FRONTEND

exception_t

irq_i

in

Level sensitive (async) interrupts

SUBSYSTEM

logic[1:0]

irq_ctrl_i

in

Interrupt control status

CSR_REGFILE

irq_ctrl_t

instruction_o

out

Instruction to be added to scoreboard entry

ISSUE_STAGE

scoreboard_entry_t

orig_instr_o

out

Instruction

ISSUE_STAGE

logic[31:0]

is_control_flow_instr_o

out

Is a control flow instruction

ISSUE_STAGE

logic

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As DebugEn = False,
+
+
+
    +
  • +

    debug_req_i input is tied to 0

    +
  • +
  • +

    debug_mode_i input is tied to 0

    +
  • +
+
+
+
As PRIV = MachineOnly,
+
+
+
    +
  • +

    priv_lvl_i input is tied to MachineMode

    +
  • +
  • +

    tvm_i input is tied to 0

    +
  • +
  • +

    tw_i input is tied to 0

    +
  • +
  • +

    tsr_i input is tied to 0

    +
  • +
+
+
+
As RVH = False,
+
+
+
    +
  • +

    v_i input is tied to 0

    +
  • +
  • +

    vfs_i input is tied to 0

    +
  • +
  • +

    vtw_i input is tied to 0

    +
  • +
  • +

    hu_i input is tied to 0

    +
  • +
+
+
+
As RVF = 0,
+
+
+
    +
  • +

    fs_i input is tied to 0

    +
  • +
  • +

    frm_i input is tied to 0

    +
  • +
+
+
+
As RVV = False,
+
+
+
    +
  • +

    vs_i input is tied to 0

    +
  • +
+
+
+
+
+
+
+
+
+

4.3. ISSUE_STAGE Module

+
+

4.3.1. Description

+
+

The execution can be roughly divided into four parts: issue(1), read +operands(2), execute(3) and write-back(4). The ISSUE_STAGE module +handles step one, two and four. The ISSUE_STAGE module receives the +decoded instructions and issues them to the various functional units.

+
+
+

A data structure called scoreboard is used to keep track of data related +to the issue instruction: which functional unit and which destination +register they are. The scoreboard handle the write-back data received +from the COMMIT_STAGE module.

+
+
+

Furthermore it contains the CPU’s register file.

+
+
+

The module is connected to:

+
+
+
    +
  • +

    TO BE COMPLETED

    +
  • +
+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 13. issue_stage module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

flush_unissued_instr_i

in

TO_BE_COMPLETED

CONTROLLER

logic

flush_i

in

TO_BE_COMPLETED

CONTROLLER

logic

decoded_instr_i

in

Handshake’s data with decode stage

ID_STAGE

scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0]

orig_instr_i

in

instruction value

ID_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0][31:0]

decoded_instr_valid_i

in

Handshake’s valid with decode stage

ID_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

is_ctrl_flow_i

in

Is instruction a control flow instruction

ID_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

decoded_instr_ack_o

out

Handshake’s acknowlege with decode stage

ID_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

rs1_forwarding_o

out

rs1 forwarding

EX_STAGE

[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0]

rs2_forwarding_o

out

rs2 forwarding

EX_STAGE

[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0]

fu_data_o

out

FU data useful to execute instruction

EX_STAGE

fu_data_t[CVA6Cfg.NrIssuePorts-1:0]

pc_o

out

Program Counter

EX_STAGE

logic[CVA6Cfg.VLEN-1:0]

is_compressed_instr_o

out

Is compressed instruction

EX_STAGE

logic

flu_ready_i

in

Fixed Latency Unit is ready

EX_STAGE

logic

alu_valid_o

out

ALU FU is valid

EX_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

resolve_branch_i

in

Signaling that we resolved the branch

EX_STAGE

logic

lsu_ready_i

in

Load store unit FU is ready

EX_STAGE

logic

lsu_valid_o

out

Load store unit FU is valid

EX_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

branch_valid_o

out

Branch unit is valid

EX_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

branch_predict_o

out

Information of branch prediction

EX_STAGE

branchpredict_sbe_t

mult_valid_o

out

Mult FU is valid

EX_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

alu2_valid_o

out

ALU2 FU is valid

EX_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

csr_valid_o

out

CSR is valid

EX_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

xfu_valid_o

out

CVXIF FU is valid

EX_STAGE

logic[CVA6Cfg.NrIssuePorts-1:0]

xfu_ready_i

in

CVXIF is FU ready

EX_STAGE

logic

x_off_instr_o

out

CVXIF offloader instruction value

EX_STAGE

logic[31:0]

hart_id_i

in

CVA6 Hart ID

SUBSYSTEM

logic[CVA6Cfg.XLEN-1:0]

x_issue_ready_i

in

none

none

logic

x_issue_resp_i

in

none

none

x_issue_resp_t

x_issue_valid_o

out

none

none

logic

x_issue_req_o

out

none

none

x_issue_req_t

x_register_ready_i

in

none

none

logic

x_register_valid_o

out

none

none

logic

x_register_o

out

none

none

x_register_t

x_commit_valid_o

out

none

none

logic

x_commit_o

out

none

none

x_commit_t

x_transaction_rejected_o

out

CVXIF Transaction rejected → instruction is illegal

EX_STAGE

logic

trans_id_i

in

Transaction ID

EX_STAGE

logic[CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0]

resolved_branch_i

in

The branch engine uses the write back from the ALU

EX_STAGE

bp_resolve_t

wbdata_i

in

TO_BE_COMPLETED

EX_STAGE

logic[CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.XLEN-1:0]

ex_ex_i

in

exception from execute stage or CVXIF

EX_STAGE

exception_t[CVA6Cfg.NrWbPorts-1:0]

wt_valid_i

in

TO_BE_COMPLETED

EX_STAGE

logic[CVA6Cfg.NrWbPorts-1:0]

x_we_i

in

CVXIF write enable

EX_STAGE

logic

x_rd_i

in

CVXIF destination register

ISSUE_STAGE

logic[4:0]

waddr_i

in

TO_BE_COMPLETED

EX_STAGE

logic[CVA6Cfg.NrCommitPorts-1:0][4:0]

wdata_i

in

TO_BE_COMPLETED

EX_STAGE

logic[CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0]

we_gpr_i

in

GPR write enable

EX_STAGE

logic[CVA6Cfg.NrCommitPorts-1:0]

commit_instr_o

out

Instructions to commit

COMMIT_STAGE

scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0]

commit_drop_o

out

Instruction is cancelled

COMMIT_STAGE

logic[CVA6Cfg.NrCommitPorts-1:0]

commit_ack_i

in

Commit acknowledge

COMMIT_STAGE

logic[CVA6Cfg.NrCommitPorts-1:0]

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As PerfCounterEn = 0,
+
+
+
    +
  • +

    sb_full_o output is tied to 0

    +
  • +
  • +

    stall_issue_o output is tied to 0

    +
  • +
+
+
+
As EnableAccelerator = 0,
+
+
+
    +
  • +

    stall_i input is tied to 0

    +
  • +
  • +

    issue_instr_o output is tied to 0

    +
  • +
  • +

    issue_instr_hs_o output is tied to 0

    +
  • +
+
+
+
As RVH = False,
+
+
+
    +
  • +

    tinst_o output is tied to 0

    +
  • +
+
+
+
As RVF = 0,
+
+
+
    +
  • +

    fpu_ready_i input is tied to 0

    +
  • +
  • +

    fpu_valid_o output is tied to 0

    +
  • +
  • +

    fpu_fmt_o output is tied to 0

    +
  • +
  • +

    fpu_rm_o output is tied to 0

    +
  • +
  • +

    we_fpr_i input is tied to 0

    +
  • +
+
+
+
As IsRVFI = 0,
+
+
+
    +
  • +

    rvfi_issue_pointer_o output is tied to 0

    +
  • +
  • +

    rvfi_commit_pointer_o output is tied to 0

    +
  • +
+
+
+
+
+
+
+

4.3.2. Functionality

+
+

TO BE COMPLETED

+
+
+
+

4.3.3. Submodules

+
+

ISSUE_STAGE submodules

+
+
+
4.3.3.1. Scoreboard
+
+

The scoreboard contains a FIFO to store the decoded instructions. Issued +instruction is pushed to the FIFO if it is not full. It indicates which +registers are going to be clobbered by a previously issued instruction.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 14. scoreboard module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

sb_full_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

flush_unissued_instr_i

in

Flush only un-issued instructions

TO_BE_COMPLETED

logic

flush_i

in

Flush whole scoreboard

TO_BE_COMPLETED

logic

rd_clobber_gpr_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

ariane_pkg::fu_t[2**ariane_pkg::REG_ADDR_SIZE-1:0]

rd_clobber_fpr_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

ariane_pkg::fu_t[2**ariane_pkg::REG_ADDR_SIZE-1:0]

x_transaction_accepted_i

in

none

none

logic

x_issue_writeback_i

in

none

none

logic

x_id_i

in

none

none

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

rs1_i

in

rs1 operand address

issue_read_operands

logic[CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0]

rs1_o

out

rs1 operand

issue_read_operands

logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0]

rs1_valid_o

out

rs1 operand is valid

issue_read_operands

logic[CVA6Cfg.NrIssuePorts-1:0]

rs2_i

in

rs2 operand address

issue_read_operands

logic[CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0]

rs2_o

out

rs2 operand

issue_read_operands

logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0]

rs2_valid_o

out

rs2 operand is valid

issue_read_operands

logic[CVA6Cfg.NrIssuePorts-1:0]

rs3_i

in

rs3 operand address

issue_read_operands

logic[CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0]

rs3_o

out

rs3 operand

issue_read_operands

rs3_len_t[CVA6Cfg.NrIssuePorts-1:0]

rs3_valid_o

out

rs3 operand is valid

issue_read_operands

logic[CVA6Cfg.NrIssuePorts-1:0]

commit_instr_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0]

commit_drop_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrCommitPorts-1:0]

commit_ack_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrCommitPorts-1:0]

decoded_instr_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0]

orig_instr_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0][31:0]

decoded_instr_valid_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

decoded_instr_ack_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

orig_instr_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0][31:0]

issue_instr_valid_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

issue_ack_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

resolved_branch_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

bp_resolve_t

trans_id_i

in

Transaction ID at which to write the result back

TO_BE_COMPLETED

logic[CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0]

wbdata_i

in

Results to write back

TO_BE_COMPLETED

logic[CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.XLEN-1:0]

ex_i

in

Exception from a functional unit (e.g.: ld/st exception)

TO_BE_COMPLETED

exception_t[CVA6Cfg.NrWbPorts-1:0]

wt_valid_i

in

Indicates valid results

TO_BE_COMPLETED

logic[CVA6Cfg.NrWbPorts-1:0]

x_we_i

in

Cvxif we for writeback

TO_BE_COMPLETED

logic

x_rd_i

in

CVXIF destination register

ISSUE_STAGE

logic[4:0]

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As EnableAccelerator = 0,
+
+
+
    +
  • +

    issue_instr_o output is tied to 0

    +
  • +
+
+
+
As IsRVFI = 0,
+
+
+
    +
  • +

    rvfi_issue_pointer_o output is tied to 0

    +
  • +
  • +

    rvfi_commit_pointer_o output is tied to 0

    +
  • +
+
+
+
+
+
+
+
4.3.3.2. Issue_read_operands
+
+

TO BE COMPLETED

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 15. issue_read_operands module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

flush_i

in

Flush

CONTROLLER

logic

issue_instr_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0]

orig_instr_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0][31:0]

issue_instr_valid_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

issue_ack_o

out

Issue stage acknowledge

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

rs1_o

out

rs1 operand address

scoreboard

logic[CVA6Cfg.NrIssuePorts-1:0][REG_ADDR_SIZE-1:0]

rs1_i

in

rs1 operand

scoreboard

logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0]

rs1_valid_i

in

rs1 operand is valid

scoreboard

logic[CVA6Cfg.NrIssuePorts-1:0]

rs2_o

out

rs2 operand address

scoreboard

logic[CVA6Cfg.NrIssuePorts-1:0][REG_ADDR_SIZE-1:0]

rs2_i

in

rs2 operand

scoreboard

logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0]

rs2_valid_i

in

rs2 operand is valid

scoreboard

logic[CVA6Cfg.NrIssuePorts-1:0]

rs3_o

out

rs3 operand address

scoreboard

logic[CVA6Cfg.NrIssuePorts-1:0][REG_ADDR_SIZE-1:0]

rs3_i

in

rs3 operand

scoreboard

rs3_len_t[CVA6Cfg.NrIssuePorts-1:0]

rs3_valid_i

in

rs3 operand is valid

scoreboard

logic[CVA6Cfg.NrIssuePorts-1:0]

rd_clobber_gpr_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

fu_t[2**REG_ADDR_SIZE-1:0]

rd_clobber_fpr_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

fu_t[2**REG_ADDR_SIZE-1:0]

fu_data_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

fu_data_t[CVA6Cfg.NrIssuePorts-1:0]

rs1_forwarding_o

out

Unregistered version of fu_data_o.operanda

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0]

rs2_forwarding_o

out

Unregistered version of fu_data_o.operandb

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0]

pc_o

out

Instruction pc

TO_BE_COMPLETED

logic[CVA6Cfg.VLEN-1:0]

is_compressed_instr_o

out

Is compressed instruction

TO_BE_COMPLETED

logic

flu_ready_i

in

Fixed Latency Unit ready to accept new request

TO_BE_COMPLETED

logic

alu_valid_o

out

ALU output is valid

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

branch_valid_o

out

Branch instruction is valid

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

branch_predict_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

branchpredict_sbe_t

lsu_ready_i

in

Load Store Unit is ready

TO_BE_COMPLETED

logic

lsu_valid_o

out

Load Store Unit result is valid

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

mult_valid_o

out

Mult result is valid

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

alu2_valid_o

out

ALU output is valid

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

csr_valid_o

out

CSR result is valid

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

cvxif_valid_o

out

CVXIF result is valid

TO_BE_COMPLETED

logic[CVA6Cfg.NrIssuePorts-1:0]

cvxif_ready_i

in

CVXIF is ready

TO_BE_COMPLETED

logic

cvxif_off_instr_o

out

CVXIF offloaded instruction

TO_BE_COMPLETED

logic[31:0]

hart_id_i

in

CVA6 Hart ID

SUBSYSTEM

logic[CVA6Cfg.XLEN-1:0]

x_issue_ready_i

in

none

none

logic

x_issue_resp_i

in

none

none

x_issue_resp_t

x_issue_valid_o

out

none

none

logic

x_issue_req_o

out

none

none

x_issue_req_t

x_register_ready_i

in

none

none

logic

x_register_valid_o

out

none

none

logic

x_register_o

out

none

none

x_register_t

x_commit_valid_o

out

none

none

logic

x_commit_o

out

none

none

x_commit_t

x_transaction_accepted_o

out

none

none

logic

x_transaction_rejected_o

out

none

none

logic

x_issue_writeback_o

out

none

none

logic

x_id_o

out

none

none

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

waddr_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrCommitPorts-1:0][4:0]

wdata_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0]

we_gpr_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic[CVA6Cfg.NrCommitPorts-1:0]

stall_issue_o

out

Stall signal, we do not want to fetch any more entries

TO_BE_COMPLETED

logic

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As EnableAccelerator = 0,
+
+
+
    +
  • +

    stall_i input is tied to 0

    +
  • +
+
+
+
As RVH = False,
+
+
+
    +
  • +

    tinst_o output is tied to 0

    +
  • +
+
+
+
As RVF = 0,
+
+
+
    +
  • +

    fpu_ready_i input is tied to 0

    +
  • +
  • +

    fpu_valid_o output is tied to 0

    +
  • +
  • +

    fpu_fmt_o output is tied to 0

    +
  • +
  • +

    fpu_rm_o output is tied to 0

    +
  • +
  • +

    we_fpr_i input is tied to 0

    +
  • +
+
+
+
+
+
+
+
+
+

4.4. EX_STAGE Module

+
+

4.4.1. Description

+
+

The EX_STAGE module is a logical stage which implements the execute stage. +It encapsulates the following functional units: ALU, Branch Unit, CSR buffer, Mult, load and store and CVXIF.

+
+
+

The module is connected to:

+
+
+
    +
  • +

    ID_STAGE module provides scoreboard entry. +*

    +
  • +
+
+
+
+

4.4.2. Functionality

+
+

TO BE COMPLETED

+
+
+
+

4.4.3. Submodules

+
+

EX_STAGE submodules

+
+
+
4.4.3.1. alu
+
+

The arithmetic logic unit (ALU) is a small piece of hardware which performs 32 and 64-bit arithmetic and bitwise operations: subtraction, addition, shifts, comparisons…​ +It always completes its operation in a single cycle.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 16. alu module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

fu_data_i

in

FU data needed to execute instruction

ISSUE_STAGE

fu_data_t

result_o

out

ALU result

ISSUE_STAGE

logic[CVA6Cfg.XLEN-1:0]

alu_branch_res_o

out

ALU branch compare result

branch_unit

logic

+
+
+
4.4.3.2. branch_unit
+
+

The branch unit module manages all kinds of control flow changes i.e.: conditional and unconditional jumps. +It calculates the target address and decides whether to take the branch or not. +It also decides if a branch was mis-predicted or not and reports corrective actions to the pipeline stages.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 17. branch_unit module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

fu_data_i

in

FU data needed to execute instruction

ISSUE_STAGE

fu_data_t

pc_i

in

Instruction PC

ISSUE_STAGE

logic[CVA6Cfg.VLEN-1:0]

is_compressed_instr_i

in

Instruction is compressed

ISSUE_STAGE

logic

branch_valid_i

in

Branch unit instruction is valid

ISSUE_STAGE

logic

branch_comp_res_i

in

ALU branch compare result

ALU

logic

branch_result_o

out

Brach unit result

ISSUE_STAGE

logic[CVA6Cfg.VLEN-1:0]

branch_predict_i

in

Information of branch prediction

ISSUE_STAGE

branchpredict_sbe_t

resolved_branch_o

out

Signaling that we resolved the branch

ISSUE_STAGE

bp_resolve_t

resolve_branch_o

out

Branch is resolved, new entries can be accepted by scoreboard

ID_STAGE

logic

branch_exception_o

out

Branch exception out

TO_BE_COMPLETED

exception_t

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As RVH = False,
+
+
+
    +
  • +

    v_i input is tied to 0

    +
  • +
+
+
+
As DebugEn = False,
+
+
+
    +
  • +

    debug_mode_i input is tied to 0

    +
  • +
+
+
+
+
+
+
+
4.4.3.3. CSR_buffer
+
+

The CSR buffer module stores the CSR address at which the instruction is going to read/write. +As the CSR instruction alters the processor architectural state, this instruction has to be buffered until the commit stage decides to execute the instruction.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 18. csr_buffer module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

flush_i

in

Flush CSR

CONTROLLER

logic

fu_data_i

in

FU data needed to execute instruction

ISSUE_STAGE

fu_data_t

csr_ready_o

out

CSR FU is ready

ISSUE_STAGE

logic

csr_valid_i

in

CSR instruction is valid

ISSUE_STAGE

logic

csr_result_o

out

CSR buffer result

ISSUE_STAGE

logic[CVA6Cfg.XLEN-1:0]

csr_commit_i

in

commit the pending CSR OP

TO_BE_COMPLETED

logic

csr_addr_o

out

CSR address to write

COMMIT_STAGE

logic[11:0]

+
+
+
4.4.3.4. mult
+
+

The multiplier module supports the division and multiplication operations.

+
+
+

mult submodules

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 19. mult module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

flush_i

in

Flush

CONTROLLER

logic

fu_data_i

in

FU data needed to execute instruction

ISSUE_STAGE

fu_data_t

mult_valid_i

in

Mult instruction is valid

ISSUE_STAGE

logic

result_o

out

Mult result

ISSUE_STAGE

logic[CVA6Cfg.XLEN-1:0]

mult_valid_o

out

Mult result is valid

ISSUE_STAGE

logic

mult_ready_o

out

Mutl is ready

ISSUE_STAGE

logic

mult_trans_id_o

out

Mult transaction ID

ISSUE_STAGE

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

+
+
4.4.3.4.1. multiplier
+
+

Multiplication is performed in two cycles and is fully pipelined.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 20. multiplier module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

trans_id_i

in

Multiplier transaction ID

Mult

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

mult_valid_i

in

Multiplier instruction is valid

Mult

logic

operation_i

in

Multiplier operation

Mult

fu_op

operand_a_i

in

A operand

Mult

logic[CVA6Cfg.XLEN-1:0]

operand_b_i

in

B operand

Mult

logic[CVA6Cfg.XLEN-1:0]

result_o

out

Multiplier result

Mult

logic[CVA6Cfg.XLEN-1:0]

mult_valid_o

out

Mutliplier result is valid

Mult

logic

mult_ready_o

out

Multiplier FU is ready

Mult

logic

mult_trans_id_o

out

Multiplier transaction ID

Mult

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

+
+
+
4.4.3.4.2. serdiv
+
+

The division is a simple serial divider which needs 64 cycles in the worst case.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 21. serdiv module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

id_i

in

Serdiv translation ID

Mult

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

op_a_i

in

A operand

Mult

logic[WIDTH-1:0]

op_b_i

in

B operand

Mult

logic[WIDTH-1:0]

rem

in

Serdiv operation

Mult

logic[1:0]opcode_i,//0:udiv,2:urem,1:div,3:

in_vld_i

in

Serdiv instruction is valid

Mult

logic

in_rdy_o

out

Serdiv FU is ready

Mult

logic

flush_i

in

Flush

CONTROLLER

logic

out_vld_o

out

Serdiv result is valid

Mult

logic

out_rdy_i

in

Serdiv is ready

Mult

logic

id_o

out

Serdiv transaction ID

Mult

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

res_o

out

Serdiv result

Mult

logic[WIDTH-1:0]

+
+
+
+
4.4.3.5. load_store_unit (LSU)
+
+

The load store module interfaces with the data cache (D$) to manage the load and store operations.

+
+
+

The LSU does not handle misaligned accesses. +Misaligned accesses are double word accesses which are not aligned to a 64-bit boundary, word accesses which are not aligned to a 32-bit boundary and half word accesses which are not aligned on 16-bit boundary. +If the LSU encounters a misaligned load or store, it throws a misaligned exception.

+
+
+

load_store_unit submodules

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 22. load_store_unit module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

flush_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

stall_st_pending_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

no_st_pending_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

fu_data_i

in

FU data needed to execute instruction

ISSUE_STAGE

fu_data_t

lsu_ready_o

out

Load Store Unit is ready

ISSUE_STAGE

logic

lsu_valid_i

in

Load Store Unit instruction is valid

ISSUE_STAGE

logic

load_trans_id_o

out

Load transaction ID

ISSUE_STAGE

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

load_result_o

out

Load result

ISSUE_STAGE

logic[CVA6Cfg.XLEN-1:0]

load_valid_o

out

Load result is valid

ISSUE_STAGE

logic

load_exception_o

out

Load exception

ISSUE_STAGE

exception_t

store_trans_id_o

out

Store transaction ID

ISSUE_STAGE

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

store_result_o

out

Store result

ISSUE_STAGE

logic[CVA6Cfg.XLEN-1:0]

store_valid_o

out

Store result is valid

ISSUE_STAGE

logic

store_exception_o

out

Store exception

ISSUE_STAGE

exception_t

commit_i

in

Commit the first pending store

TO_BE_COMPLETED

logic

commit_ready_o

out

Commit queue is ready to accept another commit request

TO_BE_COMPLETED

logic

commit_tran_id_i

in

Commit transaction ID

TO_BE_COMPLETED

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

icache_areq_i

in

Instruction cache input request

CACHES

icache_arsp_t

icache_areq_o

out

Instruction cache output request

CACHES

icache_areq_t

dcache_req_ports_i

in

Data cache request output

CACHES

dcache_req_o_t[2:0]

dcache_req_ports_o

out

Data cache request input

CACHES

dcache_req_i_t[2:0]

dcache_wbuffer_empty_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

dcache_wbuffer_not_ni_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

pmpcfg_i

in

PMP configuration

CSR_REGFILE

riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries:0]

pmpaddr_i

in

PMP address

CSR_REGFILE

logic[CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0]

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As RVA = False,
+
+
+
    +
  • +

    amo_valid_commit_i input is tied to 0

    +
  • +
  • +

    amo_req_o output is tied to 0

    +
  • +
  • +

    amo_resp_i input is tied to 0

    +
  • +
+
+
+
As RVH = False,
+
+
+
    +
  • +

    tinst_i input is tied to 0

    +
  • +
  • +

    enable_g_translation_i input is tied to 0

    +
  • +
  • +

    en_ld_st_g_translation_i input is tied to 0

    +
  • +
  • +

    v_i input is tied to 0

    +
  • +
  • +

    ld_st_v_i input is tied to 0

    +
  • +
  • +

    csr_hs_ld_st_inst_o output is tied to 0

    +
  • +
  • +

    vs_sum_i input is tied to 0

    +
  • +
  • +

    vmxr_i input is tied to 0

    +
  • +
  • +

    vsatp_ppn_i input is tied to 0

    +
  • +
  • +

    vs_asid_i input is tied to 0

    +
  • +
  • +

    hgatp_ppn_i input is tied to 0

    +
  • +
  • +

    vmid_i input is tied to 0

    +
  • +
  • +

    vmid_to_be_flushed_i input is tied to 0

    +
  • +
  • +

    gpaddr_to_be_flushed_i input is tied to 0

    +
  • +
  • +

    flush_tlb_vvma_i input is tied to 0

    +
  • +
  • +

    flush_tlb_gvma_i input is tied to 0

    +
  • +
+
+
+
As RVS = False,
+
+
+
    +
  • +

    enable_translation_i input is tied to 0

    +
  • +
  • +

    en_ld_st_translation_i input is tied to 0

    +
  • +
  • +

    sum_i input is tied to 0

    +
  • +
  • +

    mxr_i input is tied to 0

    +
  • +
  • +

    satp_ppn_i input is tied to 0

    +
  • +
  • +

    asid_i input is tied to 0

    +
  • +
  • +

    asid_to_be_flushed_i input is tied to 0

    +
  • +
  • +

    vaddr_to_be_flushed_i input is tied to 0

    +
  • +
+
+
+
As PRIV = MachineOnly,
+
+
+
    +
  • +

    priv_lvl_i input is tied to MachineMode

    +
  • +
  • +

    ld_st_priv_lvl_i input is tied to MAchineMode

    +
  • +
+
+
+
As MMUPresent = 0,
+
+
+
    +
  • +

    flush_tlb_i input is tied to 0

    +
  • +
+
+
+
As PerfCounterEn = 0,
+
+
+
    +
  • +

    itlb_miss_o output is tied to 0

    +
  • +
  • +

    dtlb_miss_o output is tied to 0

    +
  • +
+
+
+
As IsRVFI = 0,
+
+
+
    +
  • +

    rvfi_lsu_ctrl_o output is tied to 0

    +
  • +
  • +

    rvfi_mem_paddr_o output is tied to 0

    +
  • +
+
+
+
+
+
+
4.4.3.5.1. store_unit
+
+

The store_unit module manages the data store operations.

+
+
+

As stores can be speculative, the store instructions need to be committed by ISSUE_STAGE module before possibily altering the processor state. +Store buffer keeps track of store requests. +Outstanding store instructions (which are speculative) are differentiated from committed stores. +When ISSUE_STAGE module commits a store instruction, outstanding stores +become committed.

+
+
+

When commit buffer is not empty, the buffer automatically tries to write the oldest store to the data cache.

+
+
+

Furthermore, the store_unit module provides information to the load_unit to know if an outstanding store matches addresses with a load.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 23. store_unit module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

flush_i

in

Flush

CONTROLLER

logic

stall_st_pending_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

no_st_pending_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

store_buffer_empty_o

out

Store buffer is empty

TO_BE_COMPLETED

logic

valid_i

in

Store instruction is valid

ISSUE_STAGE

logic

lsu_ctrl_i

in

Data input

ISSUE_STAGE

lsu_ctrl_t

pop_st_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

commit_i

in

Instruction commit

TO_BE_COMPLETED

logic

commit_ready_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

valid_o

out

Store result is valid

ISSUE_STAGE

logic

trans_id_o

out

Transaction ID

ISSUE_STAGE

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

result_o

out

Store result

ISSUE_STAGE

logic[CVA6Cfg.XLEN-1:0]

ex_o

out

Store exception output

TO_BE_COMPLETED

exception_t

translation_req_o

out

Address translation request

TO_BE_COMPLETED

logic

vaddr_o

out

Virtual address

TO_BE_COMPLETED

logic[CVA6Cfg.VLEN-1:0]

paddr_i

in

Physical address

TO_BE_COMPLETED

logic[CVA6Cfg.PLEN-1:0]

ex_i

in

Exception raised before store

TO_BE_COMPLETED

exception_t

page_offset_i

in

Address to be checked

load_unit

logic[11:0]

page_offset_matches_o

out

Address check result

load_unit

logic

req_port_i

in

Data cache request

CACHES

dcache_req_o_t

req_port_o

out

Data cache response

CACHES

dcache_req_i_t

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As RVA = False,
+
+
+
    +
  • +

    amo_valid_commit_i input is tied to 0

    +
  • +
  • +

    amo_req_o output is tied to 0

    +
  • +
  • +

    amo_resp_i input is tied to 0

    +
  • +
+
+
+
As IsRVFI = 0,
+
+
+
    +
  • +

    rvfi_mem_paddr_o output is tied to 0

    +
  • +
+
+
+
As RVH = False,
+
+
+
    +
  • +

    tinst_o output is tied to 0

    +
  • +
  • +

    hs_ld_st_inst_o output is tied to 0

    +
  • +
  • +

    hlvx_inst_o output is tied to 0

    +
  • +
+
+
+
For any HW configuration,
+
+
+
    +
  • +

    dtlb_hit_i input is tied to 1

    +
  • +
+
+
+
+
+
+
+
4.4.3.5.2. load_unit
+
+

The load unit module manages the data load operations.

+
+
+

Before issuing a load, the load unit needs to check the store buffer for potential aliasing. +It stalls until it can satisfy the current request. This means:

+
+
+
    +
  • +

    Two loads to the same address are allowed.

    +
  • +
  • +

    Two stores to the same address are allowed.

    +
  • +
  • +

    A store after a load to the same address is allowed.

    +
  • +
  • +

    A load after a store to the same address can only be processed if the store has already been sent to the cache i.e there is no fowarding.

    +
  • +
+
+
+

After the check of the store buffer, a read request is sent to the D$ with the index field of the address (1). +The load unit stalls until the D$ acknowledges this request (2). +In the next cycle, the tag field of the address is sent to the D$ (3). +If the load request address is non-idempotent, it stalls until the write buffer of the D$ is empty of non-idempotent requests and the store buffer is empty. +It also stalls until the incoming load instruction is the next instruction to be committed. +When the D$ allows the read of the data, the data is sent to the load unit and the load instruction can be committed (4).

+
+
+

Load unit’s interactions

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 24. load_unit module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

flush_i

in

Flush signal

CONTROLLER

logic

valid_i

in

Load request is valid

LSU_BYPASS

logic

lsu_ctrl_i

in

Load request input

LSU_BYPASS

lsu_ctrl_t

pop_ld_o

out

Pop the load request from the LSU bypass FIFO

LSU_BYPASS

logic

valid_o

out

Load unit result is valid

ISSUE_STAGE

logic

trans_id_o

out

Load transaction ID

ISSUE_STAGE

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

result_o

out

Load result

ISSUE_STAGE

logic[CVA6Cfg.XLEN-1:0]

ex_o

out

Load exception

ISSUE_STAGE

exception_t

translation_req_o

out

Request address translation

MMU

logic

vaddr_o

out

Virtual address

MMU

logic[CVA6Cfg.VLEN-1:0]

paddr_i

in

Physical address

MMU

logic[CVA6Cfg.PLEN-1:0]

ex_i

in

Excepted which appears before load

MMU

exception_t

page_offset_o

out

Page offset for address checking

STORE_UNIT

logic[11:0]

page_offset_matches_i

in

Indicates if the page offset matches a store unit entry

STORE_UNIT

logic

store_buffer_empty_i

in

Store buffer is empty

STORE_UNIT

logic

commit_tran_id_i

in

Transaction ID of the committing instruction

COMMIT_STAGE

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

req_port_i

in

Data cache request out

CACHES

dcache_req_o_t

req_port_o

out

Data cache request in

CACHES

dcache_req_i_t

dcache_wbuffer_not_ni_i

in

Presence of non-idempotent operations in the D$ write buffer

CACHES

logic

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As RVH = False,
+
+
+
    +
  • +

    tinst_o output is tied to 0

    +
  • +
  • +

    hs_ld_st_inst_o output is tied to 0

    +
  • +
  • +

    hlvx_inst_o output is tied to 0

    +
  • +
+
+
+
For any HW configuration,
+
+
+
    +
  • +

    dtlb_hit_i input is tied to 1

    +
  • +
+
+
+
As MMUPresent = 0,
+
+
+
    +
  • +

    dtlb_ppn_i input is tied to 0

    +
  • +
+
+
+
+
+
+
+
4.4.3.5.3. lsu_bypass
+
+

The LSU bypass is a FIFO which keeps instructions from the issue stage when the store unit or the load unit are not available immediately.

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 25. lsu_bypass module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

flush_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

lsu_req_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

lsu_ctrl_t

lsu_req_valid_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

pop_ld_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

pop_st_i

in

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

lsu_ctrl_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

lsu_ctrl_t

ready_o

out

TO_BE_COMPLETED

TO_BE_COMPLETED

logic

+
+
+
+
4.4.3.6. CVXIF_fu
+
+

TO BE COMPLETED

+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 26. cvxif_fu module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

x_valid_i

in

CVXIF instruction is valid

ISSUE_STAGE

logic

x_trans_id_i

in

Transaction ID

ISSUE_STAGE

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

x_illegal_i

in

Instruction is illegal, determined during CVXIF issue transaction

ISSUE_STAGE

logic

x_off_instr_i

in

Offloaded instruction

ISSUE_STAGE

logic[31:0]

x_ready_o

out

CVXIF is ready

ISSUE_STAGE

logic

x_trans_id_o

out

CVXIF result transaction ID

ISSUE_STAGE

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

x_exception_o

out

CVXIF exception

ISSUE_STAGE

exception_t

x_result_o

out

CVXIF FU result

ISSUE_STAGE

logic[CVA6Cfg.XLEN-1:0]

x_valid_o

out

CVXIF result valid

ISSUE_STAGE

logic

x_we_o

out

CVXIF write enable

ISSUE_STAGE

logic

x_rd_o

out

CVXIF destination register

ISSUE_STAGE

logic[4:0]

result_valid_i

in

none

none

logic

result_i

in

none

none

x_result_t

result_ready_o

out

none

none

logic

+
+
+
+
+

4.5. COMMIT_STAGE Module

+
+

4.5.1. Description

+
+

The COMMIT_STAGE module implements the commit stage, which is the last +stage in the processor’s pipeline. For the instructions for which the +execution is completed, it updates the architectural state: writing CSR +registers, committing stores and writing back data to the register file. +The commit stage controls the stalling and the flushing of the +processor.

+
+
+

The commit stage also manages the exceptions. An exception can occur +during the first four pipeline stages (PCgen cannot generate an +exception) or happen in commit stage, coming from the CSR_REGFILE or +from an interrupt. Exceptions are precise: they are considered during +the commit only and associated with the related instruction.

+
+
+

The module is connected to:

+
+
+
    +
  • +

    TO BE COMPLETED

    +
  • +
+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 27. commit_stage module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

halt_i

in

Request to halt the core

CONTROLLER

logic

flush_dcache_i

in

request to flush dcache, also flush the pipeline

CACHE

logic

exception_o

out

TO_BE_COMPLETED

EX_STAGE

exception_t

commit_instr_i

in

The instruction we want to commit

ISSUE_STAGE

scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0]

commit_drop_i

in

The instruction is cancelled

ISSUE_STAGE

logic[CVA6Cfg.NrCommitPorts-1:0]

commit_ack_o

out

Acknowledge that we are indeed committing

ISSUE_STAGE

logic[CVA6Cfg.NrCommitPorts-1:0]

commit_macro_ack_o

out

Acknowledge that we are indeed committing

CSR_REGFILE

logic[CVA6Cfg.NrCommitPorts-1:0]

waddr_o

out

Register file write address

ISSUE_STAGE

logic[CVA6Cfg.NrCommitPorts-1:0][4:0]

wdata_o

out

Register file write data

ISSUE_STAGE

logic[CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0]

we_gpr_o

out

Register file write enable

ISSUE_STAGE

logic[CVA6Cfg.NrCommitPorts-1:0]

we_fpr_o

out

Floating point register enable

ISSUE_STAGE

logic[CVA6Cfg.NrCommitPorts-1:0]

pc_o

out

TO_BE_COMPLETED

FRONTEND_CSR_REGFILE

logic[CVA6Cfg.VLEN-1:0]

csr_op_o

out

Decoded CSR operation

CSR_REGFILE

fu_op

csr_wdata_o

out

Data to write to CSR

CSR_REGFILE

logic[CVA6Cfg.XLEN-1:0]

csr_rdata_i

in

Data to read from CSR

CSR_REGFILE

logic[CVA6Cfg.XLEN-1:0]

csr_exception_i

in

Exception or interrupt occurred in CSR stage (the same as commit)

CSR_REGFILE

exception_t

commit_lsu_o

out

Commit the pending store

EX_STAGE

logic

commit_lsu_ready_i

in

Commit buffer of LSU is ready

EX_STAGE

logic

commit_tran_id_o

out

Transaction id of first commit port

ID_STAGE

logic[CVA6Cfg.TRANS_ID_BITS-1:0]

no_st_pending_i

in

no store is pending

EX_STAGE

logic

commit_csr_o

out

Commit the pending CSR instruction

EX_STAGE

logic

flush_commit_o

out

Request a pipeline flush

CONTROLLER

logic

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As RVF = 0,
+
+
+
    +
  • +

    dirty_fp_state_o output is tied to 0

    +
  • +
  • +

    csr_write_fflags_o output is tied to 0

    +
  • +
+
+
+
As DebugEn = False,
+
+
+
    +
  • +

    single_step_i input is tied to 0

    +
  • +
+
+
+
As RVA = False,
+
+
+
    +
  • +

    amo_resp_i input is tied to 0

    +
  • +
  • +

    amo_valid_commit_o output is tied to 0

    +
  • +
+
+
+
As FenceEn = 0,
+
+
+
    +
  • +

    fence_i_o output is tied to 0

    +
  • +
  • +

    fence_o output is tied to 0

    +
  • +
+
+
+
As RVS = False,
+
+
+
    +
  • +

    sfence_vma_o output is tied to 0

    +
  • +
+
+
+
As RVH = False,
+
+
+
    +
  • +

    hfence_vvma_o output is tied to 0

    +
  • +
  • +

    hfence_gvma_o output is tied to 0

    +
  • +
+
+
+
+
+
+
+

4.5.2. Functionality

+
+

TO BE COMPLETED

+
+
+
+
+

4.6. CONTROLLER Module

+
+

4.6.1. Description

+
+

The CONTROLLER module implements …​ TO BE COMPLETED

+
+
+

The module is connected to:

+
+
+
    +
  • +

    TO BE COMPLETED

    +
  • +
+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 28. controller module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

set_pc_commit_o

out

Set PC om PC Gen

FRONTEND

logic

flush_if_o

out

Flush the IF stage

FRONTEND

logic

flush_unissued_instr_o

out

Flush un-issued instructions of the scoreboard

FRONTEND

logic

flush_id_o

out

Flush ID stage

ID_STAGE

logic

flush_ex_o

out

Flush EX stage

EX_STAGE

logic

flush_bp_o

out

Flush branch predictors

FRONTEND

logic

flush_icache_o

out

Flush ICache

CACHE

logic

flush_dcache_o

out

Flush DCache

CACHE

logic

flush_dcache_ack_i

in

Acknowledge the whole DCache Flush

CACHE

logic

halt_csr_i

in

Halt request from CSR (WFI instruction)

CSR_REGFILE

logic

halt_o

out

Halt signal to commit stage

COMMIT_STAGE

logic

eret_i

in

Return from exception

CSR_REGFILE

logic

ex_valid_i

in

We got an exception, flush the pipeline

FRONTEND

logic

resolved_branch_i

in

We got a resolved branch, check if we need to flush the front-end

EX_STAGE

bp_resolve_t

flush_csr_i

in

We got an instruction which altered the CSR, flush the pipeline

CSR_REGFILE

logic

flush_commit_i

in

Flush request from commit stage

COMMIT_STAGE

logic

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As RVH = False,
+
+
+
    +
  • +

    v_i input is tied to 0

    +
  • +
  • +

    flush_tlb_vvma_o output is tied to 0

    +
  • +
  • +

    flush_tlb_gvma_o output is tied to 0

    +
  • +
  • +

    hfence_vvma_i input is tied to 0

    +
  • +
  • +

    hfence_gvma_i input is tied to 0

    +
  • +
+
+
+
As MMUPresent = 0,
+
+
+
    +
  • +

    flush_tlb_o output is tied to 0

    +
  • +
+
+
+
As EnableAccelerator = 0,
+
+
+
    +
  • +

    halt_acc_i input is tied to 0

    +
  • +
  • +

    flush_acc_i input is tied to 0

    +
  • +
+
+
+
As DebugEn = False,
+
+
+
    +
  • +

    set_debug_pc_i input is tied to 0

    +
  • +
+
+
+
As FenceEn = 0,
+
+
+
    +
  • +

    fence_i_i input is tied to 0

    +
  • +
  • +

    fence_i input is tied to 0

    +
  • +
+
+
+
As RVS = False,
+
+
+
    +
  • +

    sfence_vma_i input is tied to 0

    +
  • +
+
+
+
+
+
+
+

4.6.2. Functionality

+
+

TO BE COMPLETED

+
+
+
+
+

4.7. CSR_REGFILE Module

+
+

4.7.1. Description

+
+

The CSR_REGFILE module implements …​ TO BE COMPLETED

+
+
+

The module is connected to:

+
+
+
    +
  • +

    TO BE COMPLETED

    +
  • +
+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 29. csr_regfile module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

time_irq_i

in

Timer threw a interrupt

SUBSYSTEM

logic

flush_o

out

send a flush request out when a CSR with a side effect changes

CONTROLLER

logic

halt_csr_o

out

halt requested

CONTROLLER

logic

commit_instr_i

in

Instruction to be committed

ID_STAGE

scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0]

commit_ack_i

in

Commit acknowledged a instruction → increase instret CSR

COMMIT_STAGE

logic[CVA6Cfg.NrCommitPorts-1:0]

boot_addr_i

in

Address from which to start booting, mtvec is set to the same address

SUBSYSTEM

logic[CVA6Cfg.VLEN-1:0]

hart_id_i

in

Hart id in a multicore environment (reflected in a CSR)

SUBSYSTEM

logic[CVA6Cfg.XLEN-1:0]

ex_i

in

We’ve got an exception from the commit stage, take it

COMMIT_STAGE

exception_t

csr_op_i

in

Operation to perform on the CSR file

COMMIT_STAGE

fu_op

csr_addr_i

in

Address of the register to read/write

EX_STAGE

logic[11:0]

csr_wdata_i

in

Write data in

COMMIT_STAGE

logic[CVA6Cfg.XLEN-1:0]

csr_rdata_o

out

Read data out

COMMIT_STAGE

logic[CVA6Cfg.XLEN-1:0]

pc_i

in

PC of instruction accessing the CSR

COMMIT_STAGE

logic[CVA6Cfg.VLEN-1:0]

csr_exception_o

out

attempts to access a CSR without appropriate privilege

COMMIT_STAGE

exception_t

epc_o

out

Output the exception PC to PC Gen, the correct CSR (mepc, sepc) is set accordingly

FRONTEND

logic[CVA6Cfg.VLEN-1:0]

eret_o

out

Return from exception, set the PC of epc_o

FRONTEND

logic

trap_vector_base_o

out

Output base of exception vector, correct CSR is output (mtvec, stvec)

FRONTEND

logic[CVA6Cfg.VLEN-1:0]

irq_ctrl_o

out

interrupt management to id stage

ID_STAGE

irq_ctrl_t

irq_i

in

external interrupt in

SUBSYSTEM

logic[1:0]

ipi_i

in

inter processor interrupt → connected to machine mode sw

SUBSYSTEM

logic

icache_en_o

out

L1 ICache Enable

CACHE

logic

dcache_en_o

out

L1 DCache Enable

CACHE

logic

rvfi_csr_o

out

none

none

rvfi_probes_csr_t

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As RVF = 0,
+
+
+
    +
  • +

    dirty_fp_state_i input is tied to 0

    +
  • +
  • +

    csr_write_fflags_i input is tied to 0

    +
  • +
  • +

    fs_o output is tied to 0

    +
  • +
  • +

    fflags_o output is tied to 0

    +
  • +
  • +

    frm_o output is tied to 0

    +
  • +
  • +

    fprec_o output is tied to 0

    +
  • +
+
+
+
As EnableAccelerator = 0,
+
+
+
    +
  • +

    dirty_v_state_i input is tied to 0

    +
  • +
  • +

    acc_fflags_ex_i input is tied to 0

    +
  • +
  • +

    acc_fflags_ex_valid_i input is tied to 0

    +
  • +
  • +

    acc_cons_en_o output is tied to 0

    +
  • +
  • +

    pmpcfg_o output is tied to 0

    +
  • +
  • +

    pmpaddr_o output is tied to 0

    +
  • +
+
+
+
As PRIV = MachineOnly,
+
+
+
    +
  • +

    priv_lvl_o output is tied to MachineMode

    +
  • +
  • +

    ld_st_priv_lvl_o output is tied to MAchineMode

    +
  • +
  • +

    tvm_o output is tied to 0

    +
  • +
  • +

    tw_o output is tied to 0

    +
  • +
  • +

    tsr_o output is tied to 0

    +
  • +
+
+
+
As RVH = False,
+
+
+
    +
  • +

    v_o output is tied to 0

    +
  • +
  • +

    vfs_o output is tied to 0

    +
  • +
  • +

    en_g_translation_o output is tied to 0

    +
  • +
  • +

    en_ld_st_g_translation_o output is tied to 0

    +
  • +
  • +

    ld_st_v_o output is tied to 0

    +
  • +
  • +

    csr_hs_ld_st_inst_i input is tied to 0

    +
  • +
  • +

    vs_sum_o output is tied to 0

    +
  • +
  • +

    vmxr_o output is tied to 0

    +
  • +
  • +

    vsatp_ppn_o output is tied to 0

    +
  • +
  • +

    vs_asid_o output is tied to 0

    +
  • +
  • +

    hgatp_ppn_o output is tied to 0

    +
  • +
  • +

    vmid_o output is tied to 0

    +
  • +
  • +

    vtw_o output is tied to 0

    +
  • +
  • +

    hu_o output is tied to 0

    +
  • +
+
+
+
As RVV = False,
+
+
+
    +
  • +

    vs_o output is tied to 0

    +
  • +
+
+
+
As RVS = False,
+
+
+
    +
  • +

    en_translation_o output is tied to 0

    +
  • +
  • +

    en_ld_st_translation_o output is tied to 0

    +
  • +
  • +

    sum_o output is tied to 0

    +
  • +
  • +

    mxr_o output is tied to 0

    +
  • +
  • +

    satp_ppn_o output is tied to 0

    +
  • +
  • +

    asid_o output is tied to 0

    +
  • +
+
+
+
As DebugEn = False,
+
+
+
    +
  • +

    debug_req_i input is tied to 0

    +
  • +
  • +

    set_debug_pc_o output is tied to 0

    +
  • +
  • +

    debug_mode_o output is tied to 0

    +
  • +
  • +

    single_step_o output is tied to 0

    +
  • +
+
+
+
As PerfCounterEn = 0,
+
+
+
    +
  • +

    perf_addr_o output is tied to 0

    +
  • +
  • +

    perf_data_o output is tied to 0

    +
  • +
  • +

    perf_data_i input is tied to 0

    +
  • +
  • +

    perf_we_o output is tied to 0

    +
  • +
  • +

    mcountinhibit_o output is tied to 0

    +
  • +
+
+
+
+
+
+
+

4.7.2. Functionality

+
+

TO BE COMPLETED

+
+
+
+
+

4.8. CACHES Module

+
+

4.8.1. Description

+
+

The CACHES module implements an instruction cache, a data cache and an +AXI adapter.

+
+
+

The module is connected to:

+
+
+
    +
  • +

    TO_BE_COMPLETED

    +
  • +
+
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 30. cva6_hpdcache_subsystem module IO ports
SignalIODescriptionconnexionType

clk_i

in

Subsystem Clock

SUBSYSTEM

logic

rst_ni

in

Asynchronous reset active low

SUBSYSTEM

logic

noc_req_o

out

noc request, can be AXI or OpenPiton

SUBSYSTEM

noc_req_t

noc_resp_i

in

noc response, can be AXI or OpenPiton

SUBSYSTEM

noc_resp_t

icache_en_i

in

Instruction cache enable

CSR_REGFILE

logic

icache_flush_i

in

Flush the instruction cache

CONTROLLER

logic

icache_areq_i

in

Input address translation request

EX_STAGE

icache_areq_t

icache_areq_o

out

Output address translation request

EX_STAGE

icache_arsp_t

icache_dreq_i

in

Input data translation request

FRONTEND

icache_dreq_t

icache_dreq_o

out

Output data translation request

FRONTEND

icache_drsp_t

dcache_enable_i

in

Data cache enable

CSR_REGFILE

logic

dcache_flush_i

in

Data cache flush

CONTROLLER

logic

dcache_flush_ack_o

out

Flush acknowledge

CONTROLLER

logic

dcache_amo_req_i

in

AMO request

EX_STAGE

ariane_pkg::amo_req_t

dcache_amo_resp_o

out

AMO response

EX_STAGE

ariane_pkg::amo_resp_t

dcache_req_ports_i

in

Data cache input request ports

EX_STAGE

dcache_req_i_t[NumPorts-1:0]

dcache_req_ports_o

out

Data cache output request ports

EX_STAGE

dcache_req_o_t[NumPorts-1:0]

wbuffer_empty_o

out

Write buffer status to know if empty

EX_STAGE

logic

wbuffer_not_ni_o

out

Write buffer status to know if not non idempotent

EX_STAGE

logic

+
+

Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below

+
+
+
+
As PerfCounterEn = 0,
+
+
+
    +
  • +

    icache_miss_o output is tied to 0

    +
  • +
  • +

    dcache_miss_o output is tied to 0

    +
  • +
+
+
+
For any HW configuration,
+
+
+
    +
  • +

    dcache_cmo_req_i input is tied to 0

    +
  • +
  • +

    dcache_cmo_resp_o output is tied to open

    +
  • +
  • +

    hwpf_base_set_i input is tied to 0

    +
  • +
  • +

    hwpf_base_i input is tied to 0

    +
  • +
  • +

    hwpf_base_o output is tied to 0

    +
  • +
  • +

    hwpf_param_set_i input is tied to 0

    +
  • +
  • +

    hwpf_param_i input is tied to 0

    +
  • +
  • +

    hwpf_param_o output is tied to 0

    +
  • +
  • +

    hwpf_throttle_set_i input is tied to 0

    +
  • +
  • +

    hwpf_throttle_i input is tied to 0

    +
  • +
  • +

    hwpf_throttle_o output is tied to 0

    +
  • +
  • +

    hwpf_status_o output is tied to 0

    +
  • +
+
+
+
+
+
+
+

4.8.2. Functionality

+
+

TO BE COMPLETED

+
+
+
+

4.8.3. Submodules

+
+

CACHES submodules

+
+
+
+
+
+
+

5. Glossary

+
+
+
    +
  • +

    ALU: Arithmetic/Logic Unit

    +
  • +
  • +

    APU: Application Processing Unit

    +
  • +
  • +

    ASIC: Application-Specific Integrated Circuit

    +
  • +
  • +

    AXI: Advanced eXtensible Interface

    +
  • +
  • +

    BHT: Branch History Table

    +
  • +
  • +

    BTB: Branch Target Buffer

    +
  • +
  • +

    Byte: 8-bit data item

    +
  • +
  • +

    CPU: Central Processing Unit, processor

    +
  • +
  • +

    CSR: Control and Status Register

    +
  • +
  • +

    Custom extension: Non-Standard extension to the RISC-V base +instruction set (RISC-V Instruction Set Manual, Volume I: User-Level +ISA)

    +
  • +
  • +

    CVA6: Core-V Application class processor with a 6 stage pipeline

    +
  • +
  • +

    D$: Data Cache

    +
  • +
  • +

    DPI: Direct Programming Interface

    +
  • +
  • +

    EX or EXE: Instruction Execute

    +
  • +
  • +

    FPGA: Field Programmable Gate Array

    +
  • +
  • +

    FPU: Floating Point Unit

    +
  • +
  • +

    Halfword: 16-bit data item

    +
  • +
  • +

    Halfword aligned address: An address is halfword aligned if it is +divisible by 2

    +
  • +
  • +

    I$: Instruction Cache

    +
  • +
  • +

    ID: Instruction Decode

    +
  • +
  • +

    IF: Instruction Fetch

    +
  • +
  • +

    ISA: Instruction Set Architecture

    +
  • +
  • +

    KGE: Kilo Gate Equivalents (NAND2)

    +
  • +
  • +

    LSU: Load Store Unit

    +
  • +
  • +

    M-Mode: Machine Mode (RISC-V Instruction Set Manual, Volume II: +Privileged Architecture)

    +
  • +
  • +

    MMU: Memory Management Unit

    +
  • +
  • +

    NC: Not Cacheable

    +
  • +
  • +

    OBI: Open Bus Interface

    +
  • +
  • +

    OoO: Out Of Order

    +
  • +
  • +

    PC: Program Counter

    +
  • +
  • +

    PMP: Physical memory protection (RISC-V Instruction Set Manual, +Volume II: Privileged Architecture)

    +
  • +
  • +

    PTW: Page Table Walker

    +
  • +
  • +

    PULP platform: Parallel Ultra Low Power Platform +(https://pulp-platform.org)

    +
  • +
  • +

    RAS: Return Address Stack

    +
  • +
  • +

    RV32C: RISC-V Compressed (C extension)

    +
  • +
  • +

    RV32F: RISC-V Floating Point (F extension)

    +
  • +
  • +

    S-Mode: Supervisor Mode (RISC-V Instruction Set Manual, Volume II: +Privileged Architecture)

    +
  • +
  • +

    SIMD: Single Instruction/Multiple Data

    +
  • +
  • +

    Standard extension: Standard extension to the RISC-V base +instruction set (RISC-V Instruction Set Manual, Volume I: User-Level +ISA)

    +
  • +
  • +

    TLB: Translation Lookaside Buffer

    +
  • +
  • +

    U-Mode: User Mode (RISC-V Instruction Set Manual, Volume II: +Privileged Architecture)

    +
  • +
  • +

    VLEN: Virtual address length

    +
  • +
  • +

    WARL: Write Any Values, Reads Legal Values

    +
  • +
  • +

    WB: Write Back of instruction results

    +
  • +
  • +

    WLRL: Write/Read Only Legal Values

    +
  • +
  • +

    Word: 32-bit data item

    +
  • +
  • +

    Word aligned address: An address is word aligned if it is divisible +by 4

    +
  • +
  • +

    WPRI: Reserved Writes Preserve Values, Reads Ignore Values

    +
  • +
  • +

    XLEN: RISC-V processor data length

    +
  • +
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/04_cv32a65x/design/source/traps.rst b/docs/04_cv32a65x/design/design.rst similarity index 60% rename from docs/04_cv32a65x/design/source/traps.rst rename to docs/04_cv32a65x/design/design.rst index 4f2988563c..082d32e3a1 100644 --- a/docs/04_cv32a65x/design/source/traps.rst +++ b/docs/04_cv32a65x/design/design.rst @@ -1,5 +1,5 @@ .. - Copyright 2023 Thales DIS France SAS + Copyright (c) 2024 Thales Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 @@ -7,5 +7,16 @@ Original Author: Jean-Roch COULON - Thales +CV32A65X DESIGN DOCUMENT +======================== -.. include:: ../../../01_cva6_user/Traps_Interrupts_Exceptions.rst +.. raw:: html + + + +.. raw:: html + :file: design-cv32a65x.html diff --git a/docs/04_cv32a65x/design/make.bat b/docs/04_cv32a65x/design/make.bat deleted file mode 100644 index 543c6b13b4..0000000000 --- a/docs/04_cv32a65x/design/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=source -set BUILDDIR=build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% - -:end -popd diff --git a/docs/04_cv32a65x/design/requirements.txt b/docs/04_cv32a65x/design/requirements.txt deleted file mode 100644 index ed9ee59efb..0000000000 --- a/docs/04_cv32a65x/design/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -sphinx -sphinx-rtd-theme -recommonmark -sphinxcontrib-svg2pdfconverter -sphinx_github_changelog diff --git a/docs/04_cv32a65x/design/source/CSRs.rst b/docs/04_cv32a65x/design/source/CSRs.rst deleted file mode 100644 index a3dd55d115..0000000000 --- a/docs/04_cv32a65x/design/source/CSRs.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../../../config/gen_from_riscv_config/cv32a65x/csr/csr.rst diff --git a/docs/04_cv32a65x/design/source/conf.py b/docs/04_cv32a65x/design/source/conf.py deleted file mode 100644 index 976ee3774a..0000000000 --- a/docs/04_cv32a65x/design/source/conf.py +++ /dev/null @@ -1,214 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (c) 2020 OpenHW Group -# -# Licensed under the Solderpad Hardware Licence, 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 -# -# https://solderpad.org/licenses/ -# -# 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 WITH SHL-2.0 -# -############################################################################### -# -# Configuration file for the Sphinx documentation builder. -# -# This file does only contain a selection of the most common options. For a -# full list see the documentation: -# http://www.sphinx-doc.org/en/master/config - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - -project = u'CORE-V CV32A6 v0.1.0 Design Document' -copyright = u'2022, Thales Group' -author = u'Thales and OpenHW Group' - -# The short X.Y version -version = u'' -# The full version, including alpha/beta/rc tags -release = u'' - - -# -- General configuration --------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.todo', - 'recommonmark', - 'sphinxcontrib.inkscapeconverter', - 'sphinx_github_changelog', -# 'sphinxcontrib.wavedrom', -] -#wavedrom_html_jsinline = False - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['ytemplates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = 'en' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = [] - -# Numbering -numfig=True -numfig_format = {'figure': 'Figure %s', 'table': 'Table %s', 'code-block': 'Listing %s'} - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = None - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -#html_theme = 'alabaster' -html_theme = 'sphinx_rtd_theme' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -html_theme_options = {'style_nav_header_background': '#DDDDDD'} -html_logo = '../images/openhw-landscape.svg' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['ystatic'] -# Set html_static_path to null on the advice of RTDs: -html_static_path = [] - -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# The default sidebars (for documents that don't match any pattern) are -# defined by theme itself. Builtin themes are using these templates by -# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', -# 'searchbox.html']``. -# -# html_sidebars = {} - - -# -- Options for HTMLHelp output --------------------------------------------- - -# Output file base name for HTML help builder. -htmlhelp_basename = 'CORE-V_CV32A6_V0.1.0_DESIGN_DOC' - - -# -- Options for LaTeX output ------------------------------------------------ - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'CV32A6-v0.1.0_Design_Spec.tex', u'CORE-V-Docs Documentation', - u'Jean-Roch Coulon', 'manual'), -] - - -# -- Options for manual page output ------------------------------------------ - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'CV32A6-v0.1.0_Design_Spec.tex', u'CORE-V-Docs Documentation', - [author], 1) -] - - -# -- Options for Texinfo output ---------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'CV32A6-v0.1.0_Design_Spec.tex', u'CORE-V-Docs Documentation', - author, 'UserManual', 'User Manual for CV32A6 v0.1.0 CORE-V processor core.', - 'Miscellaneous'), -] - - -# -- Options for Epub output ------------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = project - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -# -# epub_identifier = '' - -# A unique identification for the text. -# -# epub_uid = '' - -# A list of files that should not be packed into the epub file. -epub_exclude_files = ['search.html'] - - -# -- Extension configuration ------------------------------------------------- - -# -- Options for todo extension ---------------------------------------------- - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True diff --git a/docs/04_cv32a65x/design/source/cv32a6_glossary.rst b/docs/04_cv32a65x/design/source/cv32a6_glossary.rst deleted file mode 100644 index 247cf315cd..0000000000 --- a/docs/04_cv32a65x/design/source/cv32a6_glossary.rst +++ /dev/null @@ -1,71 +0,0 @@ -.. - Copyright (c) 2020 OpenHW Group - - Licensed under the Solderpad Hardware Licence, 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 - - https://solderpad.org/licenses/ - - 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 WITH SHL-2.0 - -.. _CV32A6_GLOSSARY: - -Glossary -======== - -* **ALU**: Arithmetic/Logic Unit -* **APU**: Application Processing Unit -* **ASIC**: Application-Specific Integrated Circuit -* **AXI**: Advanced eXtensible Interface -* **BHT**: Branch History Table -* **BTB**: Branch Target Buffer -* **Byte**: 8-bit data item -* **CPU**: Central Processing Unit, processor -* **CSR**: Control and Status Register -* **Custom extension**: Non-Standard extension to the RISC-V base instruction set (RISC-V Instruction Set Manual, Volume I: User-Level ISA) -* **CVA6**: Core-V Application class processor with a 6 stage pipeline -* **D$**: Data Cache -* **DPI**: Direct Programming Interface -* **EX** or **EXE**: Instruction Execute -* **FPGA**: Field Programmable Gate Array -* **FPU**: Floating Point Unit -* **Halfword**: 16-bit data item -* **Halfword aligned address**: An address is halfword aligned if it is divisible by 2 -* **I$**: Instruction Cache -* **ID**: Instruction Decode -* **IF**: Instruction Fetch -* **ISA**: Instruction Set Architecture -* **KGE**: Kilo Gate Equivalents (NAND2) -* **LSU**: Load Store Unit -* **M-Mode**: Machine Mode (RISC-V Instruction Set Manual, Volume II: Privileged Architecture) -* **MMU**: Memory Management Unit -* **NC**: Not Cacheable -* **OBI**: Open Bus Interface -* **OoO**: Out Of Order -* **PC**: Program Counter -* **PMP**: Physical memory protection (RISC-V Instruction Set Manual, Volume II: Privileged Architecture) -* **PTW**: Page Table Walker -* **PULP platform**: Parallel Ultra Low Power Platform () -* **RAS**: Return Address Stack -* **RV32C**: RISC-V Compressed (C extension) -* **RV32F**: RISC-V Floating Point (F extension) -* **S-Mode**: Supervisor Mode (RISC-V Instruction Set Manual, Volume II: Privileged Architecture) -* **SIMD**: Single Instruction/Multiple Data -* **Standard extension**: Standard extension to the RISC-V base instruction set (RISC-V Instruction Set Manual, Volume I: User-Level ISA) -* **TLB**: Translation Lookaside Buffer -* **U-Mode**: User Mode (RISC-V Instruction Set Manual, Volume II: Privileged Architecture) -* **VLEN**: Virtual address length -* **WARL**: Write Any Values, Reads Legal Values -* **WB**: Write Back of instruction results -* **WLRL**: Write/Read Only Legal Values -* **Word**: 32-bit data item -* **Word aligned address**: An address is word aligned if it is divisible by 4 -* **WPRI**: Reserved Writes Preserve Values, Reads Ignore Values -* **XLEN**: RISC-V processor data length diff --git a/docs/04_cv32a65x/design/source/cva6_commit_stage.rst b/docs/04_cv32a65x/design/source/cva6_commit_stage.rst deleted file mode 100644 index b4dde9e917..0000000000 --- a/docs/04_cv32a65x/design/source/cva6_commit_stage.rst +++ /dev/null @@ -1,36 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_COMMIT_STAGE: - -COMMIT_STAGE Module -=================== - -Description ------------ - -The COMMIT_STAGE module implements the commit stage, which is the last stage in the processor’s pipeline. -For the instructions for which the execution is completed, it updates the architectural state: writing CSR registers, committing stores and writing back data to the register file. -The commit stage controls the stalling and the flushing of the processor. - -The commit stage also manages the exceptions. -An exception can occur during the first four pipeline stages (PCgen cannot generate an exception) or happen in commit stage, coming from the CSR_REGFILE or from an interrupt. -Exceptions are precise: they are considered during the commit only and associated with the related instruction. - -The module is connected to: - -* TO BE COMPLETED - -.. include:: port_commit_stage.rst - -Functionality -------------- - -TO BE COMPLETED - diff --git a/docs/04_cv32a65x/design/source/cva6_issue_stage.rst b/docs/04_cv32a65x/design/source/cva6_issue_stage.rst deleted file mode 100644 index a0d542d763..0000000000 --- a/docs/04_cv32a65x/design/source/cva6_issue_stage.rst +++ /dev/null @@ -1,64 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_ISSUE_STAGE: - -ISSUE_STAGE Module -================== - -Description ------------ - -The execution can be roughly divided into four parts: issue(1), read operands(2), execute(3) and write-back(4). -The ISSUE_STAGE module handles step one, two and four. -The ISSUE_STAGE module receives the decoded instructions and issues them to the various functional units. - -A data structure called scoreboard is used to keep track of data related to the issue instruction: which functional unit and which destination register they are. -The scoreboard handle the write-back data received from the COMMIT_STAGE module. - -Furthermore it contains the CPU’s register file. - - -The module is connected to: - -* TO BE COMPLETED - -.. include:: port_issue_stage.rst - -Functionality -------------- - -TO BE COMPLETED - - -Submodules ----------- - -.. figure:: ../images/issue_stage_modules.png - :name: ISSUE_STAGE submodules - :align: center - :alt: - - ISSUE_STAGE submodules - -Scoreboard -~~~~~~~~~~ - -The scoreboard contains a FIFO to store the decoded instructions. -Issued instruction is pushed to the FIFO if it is not full. -It indicates which registers are going to be clobbered by a previously issued instruction. - -.. include:: port_scoreboard.rst - -Issue_read_operands -~~~~~~~~~~~~~~~~~~~ - -TO BE COMPLETED - -.. include:: port_issue_read_operands.rst diff --git a/docs/04_cv32a65x/design/images/CV32A65X_subsystems.png b/docs/04_cv32a65x/design/source/images/CV32A65X_subsystems.png similarity index 100% rename from docs/04_cv32a65x/design/images/CV32A65X_subsystems.png rename to docs/04_cv32a65x/design/source/images/CV32A65X_subsystems.png diff --git a/docs/04_cv32a65x/design/source/index.rst b/docs/04_cv32a65x/design/source/index.rst deleted file mode 100644 index f4efb056b4..0000000000 --- a/docs/04_cv32a65x/design/source/index.rst +++ /dev/null @@ -1,23 +0,0 @@ -.. - Copyright (c) 2022 Thales - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - - -Design Document -=============== -Editor: **Jean Roch Coulon** - -.. toctree:: - :maxdepth: 4 - :caption: Contents: - - intro - subsystem - functionality - architecture - cv32a6_glossary diff --git a/docs/04_cv32a65x/design/source/instructions.rst b/docs/04_cv32a65x/design/source/instructions.rst deleted file mode 100644 index c4efe68443..0000000000 --- a/docs/04_cv32a65x/design/source/instructions.rst +++ /dev/null @@ -1,31 +0,0 @@ -.. - Copyright 2023 Thales DIS France SAS - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -Instructions -============ - -The next first subchapter lists the extensions implemented in CVA6. -By configuration, we can enable/disable the extensions. -CV32A65X supports the extensions described in the next subchapters. -RVZicond, RV32A and RVZifencei extensions are not supported by CV32A65X. - - -.. toctree:: - :maxdepth: 1 - - ../../../01_cva6_user/RISCV_Instructions - ../../../01_cva6_user/RISCV_Instructions_RV32I - ../../../01_cva6_user/RISCV_Instructions_RV32M - ../../../01_cva6_user/RISCV_Instructions_RV32C - ../../../01_cva6_user/RISCV_Instructions_RV32ZCb - ../../../01_cva6_user/RISCV_Instructions_RVZba - ../../../01_cva6_user/RISCV_Instructions_RVZbb - ../../../01_cva6_user/RISCV_Instructions_RVZbc - ../../../01_cva6_user/RISCV_Instructions_RVZbs - ../../../01_cva6_user/RISCV_Instructions_RVZicsr diff --git a/docs/04_cv32a65x/design/source/intro.rst b/docs/04_cv32a65x/design/source/intro.rst deleted file mode 100644 index 20e808b01f..0000000000 --- a/docs/04_cv32a65x/design/source/intro.rst +++ /dev/null @@ -1,95 +0,0 @@ -.. - Copyright 2022 Thales DIS design services SAS - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - - - -Introduction -============ - -The OpenHW Group uses `semantic versioning `_ to describe the release status of its IP. -This document describes the CV32A65X configuration version of CVA6. -This intends to be the first formal release of CVA6. - -CVA6 is a 6-stage in-order and single issue processor core which implements the RISC-V instruction set. -CVA6 can be configured as a 32- or 64-bit core (RV32 or RV64), called CV32A6 or CV64A6. - -The objective of this document is to provide enough information to allow the RTL modification (by designers) and the RTL verification (by verificators). -This document is not dedicated to CVA6 users looking for information to develop software like instructions or registers. - -The CVA6 architecture is illustrated in the following figure. - -.. figure:: ../images/ariane_overview.drawio.png - :name: CVA6 Architecute - :align: center - :alt: - - CVA6 Architecture - - -License -------- - -| Copyright 2022 Thales -| Copyright 2018 ETH Zürich and University of Bologna -| SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -| Licensed under the Solderpad Hardware License v 2.1 (the “License”); - you may not use this file except in compliance with the License, or, - at your option, the Apache License version 2.0. You may obtain a copy - of the License at https://solderpad.org/licenses/SHL-2.1/. -| Unless required by applicable law or agreed to in writing, any work - 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. - - -Standards Compliance --------------------- - -To ease the reading, the reference to these specifications can be implicit in the requirements below. For the sake of precision, the requirements identify the versions of RISC-V extensions from these specifications. - -* **[CVA6req]** “CVA6 requirement specification”, https://github.com/openhwgroup/cva6/blob/master/docs/specifications/cva6_requirement_specification.rst, HASH#767c465. -* **[RVunpriv]** “The RISC-V Instruction Set Manual, Volume I: User-Level ISA, Document Version 20191213”, Editors Andrew Waterman and Krste Asanović, RISC-V Foundation, December 13, 2019. -* **[RVpriv]** “The RISC-V Instruction Set Manual, Volume II: Privileged Architecture, Document Version 20211203”, Editors Andrew Waterman, Krste Asanović and John Hauser, RISC-V Foundation, December 4, 2021. -* **[RVdbg]** “RISC-V External Debug Support, Document Version 0.13.2”, Editors Tim Newsome and Megan Wachs, RISC-V Foundation, March 22, 2019. -* **[RVcompat]** “RISC-V Architectural Compatibility Test Framework”, https://github.com/riscv-non-isa/riscv-arch-test. -* **[AXI]** AXI Specification, https://developer.arm.com/documentation/ihi0022/hc. -* **[CV-X-IF]** Placeholder for the CV-X-IF coprocessor interface currently prepared at OpenHW Group; current version in https://docs.openhwgroup.org/projects/openhw-group-core-v-xif/. -* **[OpenPiton]** “OpenPiton Microarchitecture Specification”, Princeton University, https://parallel.princeton.edu/openpiton/docs/micro_arch.pdf. - -CV32A6 is a standards-compliant 32-bit processor fully compliant with RISC-V specifications: [RVunpriv], [RVpriv] and [RVdbg] and passes [RVcompat] compatibility tests, as requested by [GEN-10] in [CVA6req]. - - -Documentation framework ------------------------ - -The framework of this document is inspired by the Common Criteria. The Common Criteria for Information Technology Security Evaluation (referred to as Common Criteria or CC) is an international standard (ISO/IEC 15408) for computer security certification. - -Description of the framework: - -* Processor is split into module corresponding to the main modules of the design -* Modules can contain several modules -* Each module is described in a chapter, which contains the following subchapters: *Description*, *Functionalities*, *Architecture and Modules* and *Registers* (if any) -* The subchapter *Description* describes the main features of the submodule, the interconnections between the current module and the others and the inputs/outputs interface. -* The subchapter *Functionality* lists in details the module functionalities. Please avoid using the RTL signal names to explain the functionalities. -* The subchapter *Architecture and Modules* provides a drawing to present the module hierarchy, then the functionalities covered by the module -* The subchapter *Registers* specifies the module registers if any - - -Contributors ------------- - -| Jean-Roch Coulon - Thales -| Ayoub Jalali - (`ayoub.jalali@external.thalesgroup.com `__) -| Alae Eddine Ezzejjari - (`alae-eddine.ez-zejjari@external.thalesgroup.com `__) - -[TO BE COMPLETED] - diff --git a/docs/04_cv32a65x/design/source/mmu.rst b/docs/04_cv32a65x/design/source/mmu.rst deleted file mode 100644 index 1f5493f0e9..0000000000 --- a/docs/04_cv32a65x/design/source/mmu.rst +++ /dev/null @@ -1,1587 +0,0 @@ -.. _CVA6_MMU: - - ----------------------- -Memory Management Unit ----------------------- - -The Memory Management Unit (MMU) SV32 module is a crucial component in the RISC-V-based processor, serving as the backbone for virtual memory management and address translation. - -.. figure:: ../images/mmu_in_out.png - :name: **Figure 1:** Inputs and Outputs of CVA6 MMU SV32 - :align: center - :width: 70% - :alt: mmu_in_out - - **Figure 1:** Inputs and Outputs of CVA6 MMU SV32 - -At its core, the MMU SV32 plays a pivotal role in translating virtual addresses into their corresponding physical counterparts. -This translation process is paramount for providing memory protection, isolation, and efficient memory management in modern computer systems. -Importantly, it handles both instruction and data accesses, ensuring a seamless interaction between the processor and virtual memory. -Within the MMU, several major blocks play pivotal roles in this address translation process. These includes: - -* Instruction TLB (ITLB) -* Data TLB (DTLB) -* Shared TLB -* Page Table Walker (PTW) - -.. figure:: ../images/mmu_major_blocks.png - :name: **Figure 2:** Major Blocks in CVA6 MMU SV32 - :align: center - :width: 60% - :alt: mmu_major_blocks - - **Figure 2:** Major Blocks in CVA6 MMU SV32 - -The MMU SV32 manages privilege levels and access control, enforcing permissions for user and supervisor modes while handling access exceptions. -It employs Translation Lookaside Buffers (TLBs) for efficient address translation, reducing the need for page table access. -TLB hits yield quick translations, but on misses, the shared TLB is consulted, and if necessary, the Page Table Walker (PTW) performs page table walks, updating TLBs and managing exceptions during the process. - -In addition to these functionalities, the MMU SV32 seamlessly integrates support for Physical Memory Protection (PMP), enabling it to enforce access permissions and memory protection configurations as specified by the PMP settings. -This additional layer of security and control enhances the management of memory accesses - -.. raw:: html - - Instruction and Data Interfaces - -The MMU SV32 maintains interfaces with the instruction cache (ICache) and the load-store unit (LSU). -It receives virtual addresses from these components and proceeds to translate them into physical addresses, a fundamental task for ensuring proper program execution and memory access. - -.. raw:: html - - Signal Description of MMU - -.. raw:: html - -

Table 1: CVA6 MMU SV32 Input Output Signals

- -.. list-table:: - :header-rows: 1 - - * - Signal - - IO - - Connection Type - - Type - - Description - - * - ``clk_i`` - - in - - Subsystem - - logic - - Subsystem Clock - - * - ``rst_ni`` - - in - - Subsystem - - logic - - Asynchronous reset active low - - * - ``flush_i`` - - in - - Controller - - logic - - Sfence Committed - - * - ``enable_translation_i`` - - in - - CSR RegFile - - logic - - Indicate address translation request for instruction - - * - ``en_ld_st_translation_i`` - - in - - CSR RegFile - - logic - - Indicate address translation request for load or store - - * - ``icache_areq_i`` - - in - - Cache Subsystem - - icache_arsp_t - - Icache Response - - * - ``icache_areq_o`` - - out - - Cache Subsystem - - icache_areq_t - - Icache Request - - * - ``misaligned_ex_i`` - - in - - Load Store Unit - - exception_t - - Indicate misaligned exception - - * - ``lsu_req_i`` - - in - - Load Store Unit - - logic - - Request address translation - - * - ``lsu_vaddr_i`` - - in - - Load Store Unit - - logic [riscv::VLEN-1:0] - - Virtual Address In - - * - ``lsu_is_store_i`` - - in - - Store Unit - - logic - - Translation is requested by a store - - * - ``lsu_dtlb_hit_o`` - - out - - Store / Load Unit - - logic - - Indicate a DTLB hit - - * - ``lsu_dtlb_ppn_o`` - - out - - Load Unit - - logic [riscv::PPNW-1:0] - - Send PNN to LSU - - * - ``lsu_valid_o`` - - out - - Load Store Unit - - logic - - Indicate a valid translation - - * - ``lsu_paddr_o`` - - out - - Store / Load Unit - - logic [riscv::PLEN-1:0] - - Translated Address - - * - ``lsu_exception_o`` - - out - - Store / Load Unit - - exception_t - - Address Translation threw an exception - - * - ``priv_lvl_i`` - - in - - CSR RegFile - - riscv::priv_lvl_t - - Privilege level for instruction fetch interface - - * - ``ld_st_priv_lvl_i`` - - in - - CSR RegFile - - riscv::priv_lvl_t - - Privilege Level for Data Interface - - * - ``sum_i`` - - in - - CSR RegFile - - logic - - Supervisor User Memory Access bit in xSTATUS CSR register - - * - ``mxr_i`` - - in - - CSR RegFile - - logic - - Make Executable Readable bit in xSTATUS CSR register - - * - ``satp_ppn_I`` - - in - - CSR RegFile - - logic [riscv::PPNW-1:0] - - PPN of top level page table from SATP register - - * - ``asid_i`` - - in - - CSR RegFile - - logic [ASID_WIDTH-1:0] - - ASID to for the lookup - - * - ``asid_to_be_flushed`` - - in - - Execute Stage - - logic [ASID_WIDTH-1:0] - - ASID of the entry to be flushed. - - * - ``vaddr_to_be_flushed_i`` - - in - - Execute Stage - - logic [riscv::VLEN-1:0] - - Virtual address of the entry to be flushed. - - * - ``flush_tlb_i`` - - in - - Controller - - logic - - SFENCE.VMA committed - - * - ``itlb_miss_o`` - - out - - Performance Counter - - logic - - Indicate an ITLB miss - - * - ``dtlb_miss_o`` - - out - - Performance Counter - - logic - - Indicate a DTLB miss - - * - ``req_port_i`` - - in - - Cache Subsystem - - dcache_req_o_t - - D Cache Data Requests - - * - ``req_port_o`` - - out - - Cache Subsystem - - dcache_req_i_t - - D Cache Data Response - - * - ``pmpcfg_i`` - - in - - CSR RegFile - - riscv::pmpcfg_t [15:0] - - PMP configurations - - * - ``pmpaddr_i`` - - in - - CSR RegFile - - logic [15:0][riscv::PLEN-3:0] - - PMP Address - -.. raw:: html - - Struct Description - -.. raw:: html - -

Table 2: I Cache Request Struct (icache_areq_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``fetch_valid`` - - logic - - Address Translation Valid - - * - ``fetch_paddr`` - - logic [riscv::PLEN-1:0] - - Physical Address In - - * - ``fetch_exception`` - - exception_t - - Exception occurred during fetch - -.. raw:: html - -

Table 3: I Cache Response Struct (icache_arsq_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``fetch_req`` - - logic - - Address Translation Request - - * - ``fetch_vaddr`` - - logic [riscv::VLEN-1:0] - - Virtual Address out - -.. raw:: html - -

Table 4: Exception Struct (exception_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``cause`` - - riscv::xlen_t - - Cause of exception - - * - ``tval`` - - riscv::xlen_t - - Additional information of causing exception (e.g. instruction causing it), address of LD/ST fault - - * - ``valid`` - - logic - - Indicate that exception is valid - -.. raw:: html - -

Table 5: PMP Configuration Struct (pmpcfg_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``locked`` - - logic - - Lock this configuration - - * - ``reserved`` - - logic[1:0] - - Reserved bits in pmpcfg CSR - - * - ``addr_mode`` - - pmp_addr_mode_t - - Addressing Modes: OFF, TOR, NA4, NAPOT - - * - ``access_type`` - - pmpcfg_access_t - - None, read, write, execute - -.. raw:: html - - Control Flow in MMU SV32 Module - -.. figure:: ../images/mmu_control_flow.png - :name: **Figure 3:** Control Flow in CVA6 MMU SV32 - :align: center - :width: 95% - :alt: mmu_control_flow - - **Figure 3:** Control Flow in CVA6 MMU SV32 - -.. raw:: html - - Exception Sources with Address Translation Enabled - -Two potential exception sources exist: - -* Hardware Page Table Walker (HPTW) throwing an exception, signifying a page fault exception. -* Access error due to insufficient permissions of PMP, known as an access exception. - -.. raw:: html - - Instruction Fetch Interface - -The IF stage initiates a request to retrieve memory content at a specific virtual address. When the MMU is disabled, the instruction fetch request is directly passed to the I$ without modifications. - -.. raw:: html - - Address Translation in Instruction Interface - -If virtual memory translation is enabled for instruction fetches, the following operations are performed in the instruction interface: - -* Compatibility of requested virtual address with selected page based address translation scheme is checked. -* For 4K page translation, the module determines the fetch physical address by combining the physical page number (PPN) from ITLB content and the offset from the virtual address. -* In the case of Mega page translation, if the ITLB indicates a 4M page, the VPN0 from the fetch virtual address is written to the PPN0 of the fetch physical address to ensure alignment for superpage translation. -* If the Instruction TLB (ITLB) lookup hits, the fetch valid signal (which indicates a valid physical address) is activated in response to the input fetch request. Memory region accessibility is checked from the perspective of the fetch operation, potentially triggering a page fault exception in case of an access error or insufficient PMP permission. -* In case of an ITLB miss, if the page table walker (PTW) is active (only active if there is a shared TLB miss) and handling instruction fetches, the fetch valid signal is determined based on PTW errors or access exceptions. - -If the fetch physical address doesn't match any execute region, an Instruction Access Fault is raised. When not translating, PMPs are immediately checked against the physical address for access verification. - -.. raw:: html - - Data Interface - -.. raw:: html - - Address Translation in Data Interface - -If address translation is enabled for load or store, and no misaligned exception has occurred, the following operations are performed in the data interface: - -* Initially, translation is assumed to be invalid, signified by the MMU to LSU. -* The translated physical address is formed by combining the PPN from the Page Table Entry (PTE) and the offset from the virtual address requiring translation. This send one cycle later due to the additional bank of registers which delayed the MMU’s answer. The PPN from the PTE is also shared separately with LSU in the same cycle as the hit. -* In the case of superpage translation, as in SV32, known as the 4M page, PPN0 of the translated physical address and the separately shared PPN are updated with the VPN0 of the virtual address. - -If a Data TLB (DTLB) hit occurs, it indicates a valid translation, and various fault checks are performed depending on whether it's a load or store request. - -* For store requests, if the page is not writable, the dirty flag isn't set, or privileges are violated, it results in a page fault corresponding to the store access. If PMPs are also violated, it leads to an access fault corresponding to the store access. Page faults take precedence over access faults. -* For load requests, a page fault is triggered if there are insufficient access privileges. PMPs are checked again during load access, resulting in an access fault corresponding to load access if PMPs are violated. - -In case of a DTLB miss, potential exceptions are monitored during the page table walk. If the PTW indicates a page fault, the corresponding page fault related to the requested type is signaled. If the PTW indicates an access exception, the load access fault is indicated through address translation because the page table walker can only throw load access faults. - -.. raw:: html - - Address Translation is Disabled - -When address translation is not enabled, the physical address is immediately checked against Physical Memory Protections (PMPs). If there is a request from LSU, no misaligned exception, and PMPs are violated, it results in an access fault corresponding to the request being indicated. - ----------------------------- -Translation Lookaside Buffer ----------------------------- - -Page tables are accessed for translating virtual memory addresses to physical memory addresses. This translation needs to be carried out for every load and store instruction and also for every instruction fetch. Since page tables are resident in physical memory, accessing these tables in all these situations has a significant impact on performance. Page table accesses occur in patterns that are closely related in time. Furthermore, the spatial and temporal locality of data accesses or instruction fetches mean that the same page is referenced repeatedly. Taking advantage of these access patterns the processor keeps the information of recent address translations, to enable fast retrieval, in a small cache called the Translation Lookaside Buffer (TLB) or an address-translation cache. - -The CVA6 TLB is structured as a fully associative cache, where the virtual address that needs to be translated is compared against all the individual TLB entries. Given a virtual address, the processor examines the TLB (TLB lookup) to determine if the virtual page number (VPN) of the page being accessed is in the TLB. When a TLB entry is found (TLB hit), the TLB returns the corresponding physical page number (PPN) which is used to calculate the target physical address. If no TLB entry is found (TLB miss) the processor has to read individual page table entries from memory (Table walk). In CVA6 table walking is supported by dedicated hardware. Once the processor finishes the table walk it has the Physical Page Number (PPN) corresponding to the Virtual Page Number (VPN) That needs to be translated. The processor adds an entry for this address translation to the TLB so future translations of that virtual address will happen quickly through the TLB. During the table walk the processor may find out that the corresponding physical page is not resident in memory. At this stage a page table exception (Page Fault) is generated which gets handled by the operating system. The operating system places the appropriate page in memory, updates the appropriate page tables and returns execution to the instruction which generated the exception. - -The inputs and output signals of the TLB are shown in the following two figures. - -.. figure:: ../images/in_out_tlb.png - :name: **Figure 4:** Inputs and Outputs of CVA6 TLB - :align: center - :width: 65% - :alt: in_out_tlb - - **Figure 4:** Inputs and Outputs of CVA6 TLB - -.. raw:: html - - Signal Description of TLB - -.. raw:: html - -

Table 6: CVA6 TLB Input Output Signals

- -.. list-table:: - :header-rows: 1 - - * - Signal - - IO - - connection - - Type - - Description - - * - ``clk_i`` - - in - - SUBSYSTEM - - logic - - Subsystem Clock - - * - ``rst_ni`` - - in - - SUBSYSTEM - - logic - - Asynchronous reset active low - - * - ``flush_i`` - - in - - Controller - - logic - - Asynchronous reset active low - - * - ``update_i`` - - in - - Shared TLB - - tlb_update_sv32_t - - Updated tag and content of TLB - - * - ``lu_access_i`` - - in - - Cache Subsystem - - logic - - Signal indicating a lookup access is being requested - - * - ``lu_asid_i`` - - in - - CSR RegFile - - logic[ASID_WIDTH-1:0] - - ASID (Address Space Identifier) for the lookup - - * - ``lu_vaddr_i`` - - in - - Cache Subsystem - - logic[riscv::VLEN-1:0] - - Virtual address for the lookup - - * - ``lu_content_o`` - - out - - MMU SV32 - - riscv::pte_sv32_t - - Output for the content of the TLB entry - - * - ``asid_to_be_flushed_i`` - - in - - Execute Stage - - logic[ASID_WIDTH-1:0] - - ASID of the entry to be flushed - - * - ``vaddr_to_be_flushed_i`` - - in - - Execute Stage - - logic[riscv::VLEN-1:0] - - Virtual address of the entry to be flushed - - * - ``lu_is_4M_o`` - - out - - MMU SV32 - - logic - - Output indicating whether the TLB entry corresponds to a 4MB page - - * - ``lu_hit_o`` - - out - - MMU SV32 - - logic - - Output indicating whether the lookup resulted in a hit or miss - -.. raw:: html - - Struct Description - -.. raw:: html - -

Table 7: SV32 TLB Update Struct (tlb_update_sv32_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``valid`` - - logic - - Indicates whether the TLB update entry is valid or not - - * - ``is_4M`` - - logic - - Indicates if the TLB entry corresponds to a 4MB page - - * - ``vpn`` - - logic[19:0] - - Virtual Page Number (VPN) used for updating the TLB, consisting of 20 bits - - * - ``asid`` - - logic[8:0] - - Address Space Identifier (ASID) used for updating the TLB, with a length of 9 bits for Sv32 MMU - - * - ``content`` - - riscv::pte_sv32_t - - Content of the TLB update entry, defined by the structure - -.. raw:: html - -

Table 8: SV32 PTE Struct (riscv::pte_sv32_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``ppn`` - - logic[21:0] - - 22 bit Physical Page Number (PPN) - - * - ``rsw`` - - logic[1:0] - - Reserved for use by supervisor software - - * - ``d`` - - logic - - | Dirty bit indicating whether the page has been modified (dirty) or not - | 0: Page is clean i.e., has not been written - | 1: Page is dirty i.e., has been written - - * - ``a`` - - logic - - | Accessed bit indicating whether the page has been accessed - | 0: Virtual page has not been accessed since the last time A bit was cleared - | 1: Virtual page has been read, written, or fetched from since the last time the A bit was cleared - - * - ``g`` - - logic - - | Global bit marking a page as part of a global address space valid for all ASIDs - | 0: Translation is valid for specific ASID - | 1: Translation is valid for all ASIDs - - * - ``u`` - - logic - - | User bit indicating privilege level of the page - | 0: Page is not accessible in user mode but in supervisor mode - | 1: Page is accessible in user mode but not in supervisor mode - - * - ``x`` - - logic - - | Execute bit which allows execution of code from the page - | 0: Code execution is not allowed - | 1: Code execution is permitted - - * - ``w`` - - logic - - | Write bit allows the page to be written - | 0: Write operations are not allowed - | 1: Write operations are permitted - - * - ``r`` - - logic - - | Read bit allows read access to the page - | 0: Read operations are not allowed - | 1: Read operations are permitted - - * - ``v`` - - logic - - | Valid bit indicating the page table entry is valid - | 0: Page is invalid i.e. page is not in DRAM, translation is not valid - | 1: Page is valid i.e. page resides in the DRAM, translation is valid - -.. raw:: html - - TLB Entry Fields - -The number of TLB entries can be changed via a design parameter. In 32-bit configurations of CVA6 only 2 TLB entries are instantiated. Each TLB entry is made up of two fields: Tag and Content. The Tag field holds the virtual page number (VPN1, VPN0), ASID, page size (is_4M) along with a valid bit (VALID) indicating that the entry is valid. The SV32 virtual page number, which is supported by CV32A6X, is further split into two separate virtual page numbers VPN1 and VPN0. The Content field contains two physical page numbers (PPN1, PPN0) along with a number of bits which specify various attributes of the physical page. Note that the V bit in the Content field is the V bit which is present in the page table in memory. It is copied from the page table, as is, and the VALID bit in the Tag is set based on its value.The TLB entry fields are shown in **Figure 2**. - -.. figure:: ../images/cva6_tlb_entry.png - :name: **Figure 5:** Fields in CVA6 TLB entry - :align: center - :width: 80% - :alt: cva6_tlb_entry - - **Figure 5:** Fields in CVA6 TLB entry - -.. raw:: html - - CVA6 TLB Management / Implementation - -The CVA6 TLB implements the following three functions: - -* **Translation:** This function implements the address lookup and match logic. -* **Update and Flush:** This function implements the update and flush logic. -* **Pseudo Least Recently Used Replacement Policy:** This function implements the replacement policy for TLB entries. - -.. raw:: html - - Translation - -This function takes in the virtual address and certain other fields, examines the TLB to determine if the virtual page number of the page being accessed is in the TLB or not. If a TLB entry is found (TLB hit), the TLB returns the corresponding physical page number (PPN) which is then used to calculate the target physical address. The following checks are done as part of this lookup function to find a match in the TLB: - -* **Validity Check:** For a TLB hit, the associated TLB entry must be valid . -* **ASID and Global Flag Check:** The TLB entry's ASID must match the given ASID (ASID associated with the Virtual address). If the TLB entry’s Global bit (G) bit is set then this check is not done. This ensures that the translation is either specific to the provided ASID or it is globally applicable. -* **Level 1 VPN match:** SV32 implements a two-level page table. As such the virtual address is broken up into three parts which are the virtual page number 1, virtual page number 0 and displacement. So the condition that is checked next is that the virtual page number 1 of the virtual address matches the virtual page number 1(VPN1) of the TLB entry. -* **Level 0 VPN match or 4-Mega Page:** The last condition to be checked, for a TLB hit, is that the virtual page number 0 of the virtual address matches the virtual page number 0 of the TLB entry (VPN0). This match is ignored if the is_4M bit in the Tag is set which implies a super 4M page. - -All the conditions listed above are checked against every TLB entry. If there is a TLB hit then the corresponding bit in the hit array is set. **Figure 3** Illustrates the TLB hit/miss process listed above. - -.. figure:: ../images/cva6_tlb_hit.png - :name: **Figure 6:** Block diagram of CVA6 TLB hit or miss - :align: center - :width: 75% - :alt: cva6_tlb_hit - - **Figure 6:** Block diagram of CVA6 TLB hit or miss - -.. raw:: html - - Flushing TLB entries - -The SFENCE.VMA instruction can be used with certain specific source register specifiers (rs1 & rs2) to flush a specific TLB entry, some set of TLB entries or all TLB entries. Like all instructions this action only takes place when the SFENCE.VMA instruction is committed (shown via the commit_sfence signal in the following figures.) The behavior of the instruction is as follows: - -* **If rs1 is not equal to x0 and rs2 is not equal to x0:** Invalidate all TLB entries which contain leaf page table entries corresponding to the virtual address in rs1 (shown below as Virtual Address to be flushed) and that match the address space identifier as specified by integer register rs2 (shown below as asid_to_be_flushed_i), except for entries containing global mappings. This is referred to as the “SFENCE.VMA vaddr asid” case. - -.. figure:: ../images/sfence_vaddr_asid.png - :name: **Figure 7:** Invalidate TLB entry if ASID and virtual address match - :align: center - :width: 75% - :alt: sfence_vaddr_asid - - **Figure 7:** Invalidate TLB entry if ASID and virtual address match - -* **If rs1 is equal to x0 and rs2 is equal to x0:** Invalidate all TLB entries for all address spaces. This is referred to as the "SFENCE.VMA x0 x0" case. - -.. figure:: ../images/sfence_x0_x0.png - :name: **Figure 8:** Invalidate all TLB entries if both source register specifiers are x0 - :align: center - :width: 62% - :alt: sfence_x0_x0 - - **Figure 8:** Invalidate all TLB entries if both source register specifiers are x0 - -* **If rs1 is not equal to x0 and rs2 is equal to x0:** invalidate all TLB entries that contain leaf page table entries corresponding to the virtual address in rs1, for all address spaces. This is referred to as the “SFENCE.VMA vaddr x0” case. - -.. figure:: ../images/sfence_vaddr_x0.png - :name: **Figure 9:** Invalidate TLB entry with matching virtual address for all address spaces - :align: center - :width: 75% - :alt: sfence_vaddr_x0 - - **Figure 9:** Invalidate TLB entry with matching virtual address for all address spaces - -* **If rs1 is equal to x0 and rs2 is not equal to x0:** Invalidate all TLB entries matching the address space identified by integer register rs2, except for entries containing global mappings. This is referred to as the “SFENCE.VMA 0 asid” case. - -.. figure:: ../images/sfence_x0_asid.png - :name: **Figure 10:** Invalidate TLB entry for matching ASIDs - :align: center - :width: 75% - :alt: sfence_x0_asid - - **Figure 10:** Invalidate TLB entry for matching ASIDs - -.. raw:: html - - Updating TLB - -When a TLB valid update request is signaled by the shared TLB, and the replacement policy select the update of a specific TLB entry, the corresponding entry's tag is updated with the new tag, and its associated content is refreshed with the information from the update request. This ensures that the TLB entry accurately reflects the new translation information. - -.. raw:: html - - Pseudo Least Recently Used Replacement Policy - -Cache replacement algorithms are used to determine which TLB entry should be replaced, because it is not likely to be used in the near future. The Pseudo-Least-Recently-Used (PLRU) is a cache entry replacement algorithm, derived from Least-Recently-Used (LRU) cache entry replacement algorithm, used by the TLB. Instead of precisely tracking recent usage as the LRU algorithm does, PLRU employs an approximate measure to determine which entry in the cache has not been recently used and as such can be replaced. - -CVA6 implements the PLRU algorithm via the Tree-PLRU method which implements a binary tree. The TLB entries are the leaf nodes of the tree. Each internal node, of the tree, consists of a single bit, referred to as the state bit or plru bit, indicating which subtree contains the (pseudo) least recently used entry (the PLRU); 0 for the left hand tree and 1 for the right hand tree. Following this traversal, the leaf node reached, corresponds to the PLRU entry which can be replaced. Having accessed an entry (so as to replace it) we need to promote that entry to be the Most Recently Used (MRU) entry. This is done by updating the value of each node along the access path to point away from that entry. If the accessed entry is a right child i.e., its parent node value is 1, it is set to 0, and if the parent is the left child of its parent (the grandparent of the accessed node) then its node value is set to 1 and so on all the way up to the root node. - -The PLRU binary tree is implemented as an array of node values. Nodes are organized in the array based on levels, with those from lower levels appearing before higher ones. Furthermore those on the left side of a node appear before those on the right side of a node. The figure below shows a tree and the corresponding array. - -.. figure:: ../images/plru_tree_indexing.png - :name: **Figure 11:** PLRU Tree Indexing - :align: center - :width: 60% - :alt: plru_tree_indexing - - **Figure 11:** PLRU Tree Indexing - -For n-way associative, we require n - 1 internal nodes in the tree. With those nodes, two operations need to be performed efficiently. - -* Promote the accessed entry to be MRU -* Identify which entry to replace (i.e. the PLRU entry) - -.. raw:: html - - Updating the PLRU-Tree - -For a TLB entry which is accessed, the following steps are taken to make it the MRU: - -1. Iterate through each level of the binary tree. -2. Calculate the index of the leftmost child within the current level. Let us call that index the index base. -3. Calculate the shift amount to identify the relevant node based on the level and TLB entry index. -4. Calculate the new value that the node should have in order to make the accessed entry the Most Recently Used (MRU). The new value of the root node is the opposite of the TLB entry index, MSB at the root node, MSB - 1 at node at next level and so on. -5. Assign this new value to the relevant node, ensuring that the hit entry becomes the MRU within the binary tree structure. - -At level 0, no bit of the TLB entry’s index determines the offset from the index base because it’s a root node. At level 1, MSB of entry’s index determines the amount of offset from index base at that level. At level 2, the first two bits of the entry's index from MSB side determine the offset from the index base because there are 4 nodes at the level 2 and so on. - -.. figure:: ../images/update_tree.png - :name: **Figure 12:** Promote Entry to be MRU - :align: center - :width: 82% - :alt: update_tree - - **Figure 12:** Promote Entry to be MRU - -In the above figure entry at index 5, is accessed. To make it MRU entry, every node along the access path should point away from it. Entry 5 is a right child, therefore, its parent plru bit set to 0, its parent is a left child, its grand parent’s plru bit set to 1, and great grandparent’s plru bit set to 0. - -.. raw:: html - - Entry Selection for Replacement - -Every TLB entry is checked for the replacement entry. The following steps are taken: - -1. Iterate through each level of the binary tree. -2. Calculate the index of the leftmost child within the current level. Let us call that index the index base. -3. Calculate the shift amount to identify the relevant node based on the level and TLB entry index. -4. If the corresponding bit of the entry's index matches the value of the node being traversed at the current level, keep the replacement signal high for that entry; otherwise, set the replacement signal to low. - -.. figure:: ../images/replacement_entry.png - :name: **Figure 13:** Possible path traverse for entry selection for replacement - :align: center - :width: 65% - :alt: replacement_entry - - **Figure 13:** Possible path traverse for entry selection for replacement - -Figure shows every possible path that traverses to find out the PLRU entry. If the plru bit at each level matches with the corresponding bit of the entry's index, that’s the next entry to replace. Below Table shows the entry selection for replacement. - -.. raw:: html - -

Table 9: Entry Selection for Reaplacement

- -+-------------------+---------------+----------------------+ -| **Path Traverse** | **PLRU Bits** | **Entry to replace** | -+-------------------+---------------+----------------------+ -| 0 -> 1 -> 3 | 000 | 0 | -| +---------------+----------------------+ -| | 001 | 1 | -+-------------------+---------------+----------------------+ -| 0 -> 1 -> 4 | 010 | 2 | -| +---------------+----------------------+ -| | 011 | 3 | -+-------------------+---------------+----------------------+ -| 0 -> 2 -> 5 | 100 | 4 | -| +---------------+----------------------+ -| | 101 | 5 | -+-------------------+---------------+----------------------+ -| 0 -> 2 -> 6 | 110 | 6 | -| +---------------+----------------------+ -| | 111 | 7 | -+-------------------+---------------+----------------------+ - ------------------------------------ -Shared Translation Lookaside Buffer ------------------------------------ - -The CVA6 shared TLB is structured as a 2-way associative cache, where the virtual address requiring translation is compared with the set indicated by the virtual page number. The shared TLB is looked up in case of an Instruction TLB (ITLB) or data TLB (DTLB) miss, signaled by these TLBs. If the entry is found in the shared TLB set, the respective TLB, whose translation is being requested, is updated. If the entry is not found in the shared TLB, then the processor has to perform a page table walk. Once the processor obtains a PPN corresponding to the VPN, the shared TLB is updated with this information. If the physical page is not found in the page table, it results in a page fault, which is handled by the operating system. The operating system will then place the corresponding physical page in memory. - -The inputs and output signals of the shared TLB are shown in the following two figures. - -.. figure:: ../images/shared_tlb_in_out.png - :name: **Figure 14:** Inputs and outputs of CVA6 shared TLB - :align: center - :width: 60% - :alt: shared_tlb_in_out - - **Figure 14:** Inputs and outputs of CVA6 shared TLB - -.. raw:: html - - Signal Description - -.. raw:: html - -

Table 10: Signal Description of CVA6 shared TLB

- -.. list-table:: - :header-rows: 1 - - * - Signal - - IO - - Connection - - Type - - Description - - * - ``clk_i`` - - in - - Subsystem - - logic - - Subsystem Clock - - * - ``rst_ni`` - - in - - Subsystem - - logic - - Asynchronous reset active low - - * - ``flush_i`` - - in - - Controller - - logic - - TLB flush request - - * - ``enable_translation_i`` - - in - - CSR Regfile - - logic - - CSRs indicate to enable Sv32 - - * - ``en_ld_st_translation_i`` - - in - - CSR Regfile - - logic - - Enable virtual memory translation for load/stores - - * - ``asid_i`` - - in - - CSR Regfile - - logic - - ASID for the lookup - - * - ``itlb_access_i`` - - in - - Cache Subsystem - - logic - - Signal indicating a lookup access in ITLB is being requested. - - * - ``itlb_hit_i`` - - in - - ITLB - - logic - - Signal indicating an ITLB hit - - * - ``itlb_vaddr_i`` - - in - - Cache Subsystem - - logic[31:0] - - Virtual address lookup in ITLB - - * - ``dtlb_access_i`` - - in - - Load/Store Unit - - logic - - Signal indicating a lookup access in DTLB is being requested. - - * - ``dtlb_hit_i`` - - in - - DTLB - - logic - - Signal indicating a DTLB hit - - * - ``dtlb_vaddr_i`` - - in - - Load/Store Unit - - logic[31:0] - - Virtual address lookup in DTLB - - * - ``itlb_update_o`` - - out - - ITLB - - tlb_update_sv32_t - - Tag and content to update ITLB - - * - ``dtlb_update_o`` - - out - - DTLB - - tlb_update_sv32_t - - Tag and content to update DTLB - - * - ``itlb_miss_o`` - - out - - Performance Counter - - logic - - Signal indicating an ITLB miss - - * - ``dtlb_miss_o`` - - out - - Performance Counter - - logic - - Signal indicating a DTLB miss - - * - ``shared_tlb_access_o`` - - out - - PTW - - logic - - Signal indicating a lookup access in shared TLB is being requested - - * - ``shared_tlb_hit_o`` - - out - - PTW - - logic - - Signal indicating a shared TLB hit - - * - ``shared_tlb_vadd_o`` - - out - - PTW - - logic[31:0] - - Virtual address lookup in shared TLB - - * - ``itlb_req_o`` - - out - - PTW - - logic - - ITLB Request Output - - * - ``shared_tlb_update_i`` - - in - - PTW - - tlb_update_sv32_t - - Updated tag and content of shared TLB - -.. raw:: html - - Struct Description - -.. raw:: html - -

Table 11: Shared TLB Update Struct (shared_tag_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``is_4M`` - - logic - - Indicates if the shared TLB entry corresponds to a 4MB page. - - * - ``vpn1`` - - logic[9:0] - - Virtual Page Number (VPN) represents the index of PTE in the page table level 1. - - * - ``vpn0`` - - logic[9:0] - - Virtual Page Number (VPN) represents the index of PTE in the page table level 0. - - * - ``asid`` - - logic - - Address Space Identifier (ASID) used to identify different address spaces - -.. raw:: html - - Shared TLB Entry Structure - -Shared TLB is 2-way associative, with a depth of 64. A single entry in the set contains the valid bit, tag and the content. The Tag segment stores details such as the virtual page number (VPN1, VPN0), ASID, and page size (is_4M). The Content field contains two physical page numbers (PPN1, PPN0) along with a number of bits which specify various attributes of the physical page. - -.. figure:: ../images/shared_tlb.png - :name: **Figure 15:** CVA6 Shared TLB Structure - :align: center - :width: 60% - :alt: shared_tlb - - **Figure 15:** CVA6 Shared TLB Structure - -.. raw:: html - - Shared TLB Implementation in CVA6 - -The implementation of a shared TLB in CVA6 is described in the following sections: - -* **ITLB and DTLB Miss:** Prepare a shared TLB lookup if the entry is not found in ITLB or DTLB. -* **Tag Comparison:** Look up the provided virtual address in the shared TLB. -* **Update and Flush:** Flush the shared TLB or update it. -* **Replacement Policies:** First non-valid entry and random replacement policy. - -.. raw:: html - - ITLB and DTLB Miss - -Consider a scenario where an entry is found in the ITLB or DTLB. In this case, there is no need to perform a lookup in the shared TLB since the entry has already been found. Next, there are two scenarios: an ITLB miss or a DTLB miss. - -To identify an ITLB miss, the following conditions need to be fulfilled: - -* Address translation must be enabled. -* There must be an access request to the ITLB. -* The ITLB should indicate an ITLB miss. -* There should be no access request to the DTLB. - -During an ITLB miss, access is granted to read the tag and content of the shared TLB from their respective sram. The address for reading the tag and content of the shared TLB entry is calculated using the virtual address for which translation is not found in the ITLB. The ITLB miss is also explicitly indicated by the shared TLB. A request for shared TLB access is initiated. - -To identify the DTLB miss, the following conditions need to be fulfilled: - -* Address translation for load and stores must be enabled. -* There must be an access request to the DTLB. -* The DTLB should indicate a DTLB miss. - -In the case of a DTLB miss, the same logic is employed as described for an ITLB miss. - -.. raw:: html - - Tag Comparison - -Shared TLB lookup for a hit occurs under the same conditions as described for the TLB modules used as ITLB and DTLB. However, there are some distinctions. In both the ITLB and DTLB, the virtual address requiring translation is compared against all TLB entries. In contrast, the shared TLB only compares the tag and content of the set indicated by the provided virtual page number. The index of the set is extracted from VPN0 of the requested virtual address. Given that the shared TLB is 2-way associative, each set contains two entries. Consequently, both of these entries are compared. Below figure illustrates how the set is opted for the lookup. - -.. figure:: ../images/shared_tlb_set.png - :name: **Figure 16:** Set opted for lookup in shared TLB - :align: center - :width: 60% - :alt: shared_tlb_set - - **Figure 16:** Set opted for lookup in shared TLB - -.. raw:: html - - Update and Flush - -Differing from the ITLB and DTLB, a specific virtual address or addressing space cannot be flushed in the shared TLB. When SFENCE.VMA is committed, all entries in the shared TLB are invalidated. (Cases of SFENCE.VMA should also be added in shared TLB) - -.. raw:: html - - Updating Shared TLB - -When the Page Table Walker signals a valid update request, the shared TLB is updated by selecting an entry through the replacement policy and marking it as valid. This also triggers the writing of the new tag and content to the respective SRAM. - -.. raw:: html - - Replacement Policy Implemented in CVA6 Shared TLB - -In CVA6's shared TLB, two replacement policies are employed for replacements based on a specific condition. These replacement policies select the entry within the set indicated by the virtual page number. The two policies are: - -* First non-valid encounter replacement policy -* Random replacement policy - -First replacement policy failed if all ways are valid. Therefore, a random replacement policy is opted for. - -.. raw:: html - - First non-valid encounter replacement policy - -The module implemented in CVA6 to find the first non-valid entry in the shared TLB is the Leading Zero Counter (LZC). It takes three parameters as input: - -1. **WIDTH:** The width of the input vector. -2. **MODE:** Mode selection - 0 for trailing zero, 1 for leading zero. -3. **CNT WIDTH:** Width of the output signal containing the zero count. - -The input signal is the vector to be counted, and the output represents the count of trailing/leading zeros. If all bits in the input vector are zero, it will also be indicated. - -When initializing the module, the width of the input vector is set to the number of shared TLB ways. The trailing zero counter mode is selected. The vector of valid bits is set as the input vector, but with negation. This is because we want the index of the first non-valid entry, and LZC returns the count of trailing zeros, which actually corresponds to the index of the first occurrence of 1 from the least significant bit (LSB). if there is at least one non-valid entry, that entry is opted for the replacement, and If not then this is signaled by LZC. - -.. figure:: ../images/LZC.png - :name: **Figure 17:** Replacement of First invalid entry. - :align: center - :width: 60% - :alt: LZC - - **Figure 17:** Replacement of First invalid entry. - -.. raw:: html - - Random replacement policy - -If all ways are valid, a random replacement policy is employed for the replacement process. The Linear Feedback Shift Register (LFSR) is utilized to select the replacement entry randomly. LFSR is commonly used in generating sequences of pseudo-random numbers. When the enable signal is active, the current state of the LFSR undergoes a transformation. Specifically, the state is shifted right by one bit, and the result is combined with a predetermined masking pattern. This masking pattern is derived from the predefined “Masks” array, introducing a non-linear behavior to the sequence generation of the LFSR. The masking process involves XOR operations between the shifted state bits and specific pattern bits, contributing to the complexity and unpredictability of the generated sequence. - -.. figure:: ../images/RR.png - :name: **Figure 18:** Entry selection for replacement using LFSR - :align: center - :width: 95% - :alt: RR - - **Figure 18:** Entry selection for replacement using LFSR - ------------------ -Page Table Walker ------------------ - -The "CVA6 Page Table Walker (PTW) for MMU Sv32" is a hardware module developed for the CV32A6 processor architecture, designed to facilitate the translation of virtual addresses into physical addresses, a crucial task in memory access management. - -.. figure:: ../images/ptw_in_out.png - :name: **Figure 19:** Input and Outputs of Page Table Walker - :align: center - :width: 60% - :alt: ptw_in_out - - **Figure 19:** Input and Outputs of Page Table Walker - -.. raw:: html - - Operation of PTW Module - -The PTW module operates through various states, each with its specific function, such as handling memory access requests, validating page table entries, and responding to errors. - -.. raw:: html - - Key Features and Capabilities - -Key features of this PTW module include support for two levels of page tables (LVL1 and LVL2) in the Sv32 standard, accommodating instruction and data page table walks. It rigorously validates and verifies page table entries (PTEs) to ensure translation accuracy and adherence to access permissions. This module seamlessly integrates with the CV32A6 processor's memory management unit (MMU), which governs memory access control. It also takes into account global mapping, access flags, and privilege levels during the translation process, ensuring that memory access adheres to the processor's security and privilege settings. - -.. raw:: html - - Exception Handling - -In addition to its translation capabilities, the PTW module is equipped to detect and manage errors, including page-fault exceptions and access exceptions, contributing to the robustness of the memory access system. It works harmoniously with physical memory protection (PMP) configurations, a critical aspect of modern processors' memory security. Moreover, the module efficiently processes virtual addresses, generating corresponding physical addresses, all while maintaining speculative translation, a feature essential for preserving processor performance during memory access operations. - -.. raw:: html - - Signal Description - -.. raw:: html - -

Table 12: Signal Description of PTW

- -.. list-table:: - :header-rows: 1 - - * - Signal - - IO - - Connection - - Type - - Description - - * - ``clk_i`` - - in - - Subsystem - - logic - - Subsystem Clock - - * - ``rst_ni`` - - in - - Subsystem - - logic - - Asynchronous reset active low - - * - ``flush_i`` - - in - - Controller - - logic - - Sfence Committed - - * - ``ptw_active_o`` - - out - - MMU - - logic - - Output signal indicating whether the Page Table Walker (PTW) is currently active - - * - ``walking_instr_o`` - - out - - MMU - - logic - - Indicating it's an instruction page table walk or not - - * - ``ptw_error_o`` - - out - - MMU - - logic - - Output signal indicating that an error occurred during PTW operation - - * - ``ptw_access_exception_o`` - - out - - MMU - - logic - - Output signal indicating that a PMP (Physical Memory Protection) access exception occurred during PTW operation. - - * - ``lsu_is_store_i`` - - in - - Store Unit - - logic - - Input signal indicating whether the translation was triggered by a store operation. - - * - ``req_port_i`` - - in - - Cache Subsystem - - dcache_req_o_t - - D Cache Data Requests - - * - ``req_port_o`` - - out - - Cache Subsystem / Perf Counter - - dcache_req_u_t - - D Cache Data Response - - * - ``shared_tlb_update_o`` - - out - - Shared TLB - - tlb_update_sv32_t - - Updated tag and content of shared TLB - - * - ``update_vaddr_o`` - - out - - MMU - - logic[riscv::VLEN-1:0] - - Updated VADDR from shared TLB - - * - ``asid_i`` - - in - - CSR RegFile - - logic[ASID_WIDTH-1:0] - - ASID for the lookup - - * - ``shared_tlb_access_i`` - - in - - Shared TLB - - logic - - Access request of shared TLB - - * - ``shared_tlb_hit_i`` - - in - - Shared TLB - - logic - - Indicate shared TLB hit - - * - ``shared_tlb_vaddr_i`` - - in - - Shared TLB - - logic[riscv::VLEN-1:0] - - Virtual Address from shared TLB - - * - ``itlb_req_i`` - - in - - Shared TLB - - logic - - Indicate request to ITLB - - * - ``satp_ppn_i`` - - in - - CSR RegFile - - logic[riscv::PPNW-1:0] - - PPN of top level page table from SATP register - - * - ``mxr_i`` - - in - - CSR RegFile - - logic - - Make Executable Readable bit in xSTATUS CSR register - - * - ``shared_tlb_miss_o`` - - out - - OPEN - - logic - - Indicate a shared TLB miss - - * - ``pmpcfg_i`` - - in - - CSR RegFile - - riscv::pmpcfg_t[15:0] - - PMP configuration - - * - ``pmpaddr_i`` - - in - - CSR RegFile - - logic[15:0][riscv::PLEN-3:0] - - PMP Address - - * - ``bad_paddr_o`` - - out - - MMU - - logic[riscv::PLEN-1:0] - - Bad Physical Address in case of access exception - -.. raw:: html - - Struct Description - -.. raw:: html - -

Table 13: D Cache Response Struct (dcache_req_i_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``address_index`` - - logic [DCACHE_INDEX_WIDTH-1:0] - - Index of the Dcache Line - - * - ``address_tag`` - - logic [DCACHE_TAG_WIDTH-1:0] - - Tag of the Dcache Line - - * - ``data_wdata`` - - riscv::xlen_t - - Data to write in the Dcache - - * - ``data_wuser`` - - logic [DCACHE_USER_WIDTH-1:0] - - data_wuser - - * - ``data_req`` - - logic - - Data Request - - * - ``data_we`` - - logic - - Data Write enabled - - * - ``data_be`` - - logic [(riscv::XLEN/8)-1:0] - - Data Byte enable - - * - ``data_size`` - - logic [1:0] - - Size of data - - * - ``data_id`` - - logic [DCACHE_TID_WIDTH-1:0] - - Data ID - - * - ``kill_req`` - - logic - - Kill the D cache request - - * - ``tag_valid`` - - logic - - Indicate that teh tag is valid - -.. raw:: html - -

Table 14: D Cache Request Struct (dcache_req_o_t)

- -.. list-table:: - :header-rows: 1 - - * - Signal - - Type - - Description - - * - ``data_gnt`` - - logic - - Grant of data is given in response to the data request - - * - ``data_rvalid`` - - logic - - Indicate that data is valid which is sent by D cache - - * - ``data_rid`` - - logic [DCACHE_TID_WIDTH-1:0] - - Requested data ID - - * - ``data_rdata`` - - riscv::xlen_t - - Data from D cache - - * - ``data_ruser`` - - logic [DCACHE_USER_WIDTH-1:0] - - Requested data user - -.. raw:: html - - PTW State Machine - -Page Table Walker is implemented as a finite state machine. It listens to shared TLB for incoming translation requests. If there is a shared TLB miss, it saves the virtual address and starts the page table walk. Page table walker transition between 7 states in CVA6. - -* **IDLE:** The initial state where the PTW is awaiting a trigger, often a Shared TLB miss, to initiate a memory access request. -* **WAIT_GRANT:** Request memory access and wait for data grant -* **PTE_LOOKUP:** Once granted access, the PTW examines the valid Page Table Entry (PTE), checking attributes to determine the appropriate course of action. -* **PROPOGATE_ERROR:** If the PTE is invalid, this state handles the propagation of an error, often leading to a page-fault exception due to non-compliance with access conditions -* **PROPOGATE_ACCESS_ERROR:** Propagate access fault if access is not allowed from a PMP perspective -* **WAIT_RVALID:** After processing a PTE, the PTW waits for a valid data signal, indicating that relevant data is ready for further processing. -* **LATENCY:** Introduces a delay to account for synchronization or timing requirements between states. - -.. figure:: ../images/ptw_state_diagram.png - :name: **Figure 20:** State Machine Diagram of CVA6 PTW - :align: center - :width: 95% - :alt: ptw_state_diagram - - **Figure 20:** State Machine Diagram of CVA6 PTW - -.. raw:: html - - IDLE state - -In the IDLE state of the Page Table Walker (PTW) finite state machine, the system awaits a trigger to initiate the page table walk process. This trigger is often prompted by a Shared Translation Lookaside Buffer (TLB) miss, indicating that the required translation is not present in the shared TLB cache. The PTW's behavior in this state is explained as follows: - -1. The top-most page table is selected for the page table walk. In the case of SV32, which implements a two-level page table, the level 1 page table is chosen. -2. In the IDLE state, translations are assumed to be invalid in all addressing spaces. -3. The signal indicating the instruction page table walk is set to 0. -4. A conditional check is performed: if there is a shared TLB access request and the entry is not found in the shared TLB (indicating a shared TLB miss), the following steps are executed: - - a. The address of the desired Page Table Entry within the level 1 page table is calculated by multiplying the Physical Page Number (PPN) of the level 1 page table from the SATP register by the page size (4kB). This result is then added to the product of the Virtual Page Number (VPN1), and the size of a page table entry(4 bytes). - -.. figure:: ../images/ptw_idle.png - :name: **Figure 21:** Address of Desired PTE at Level 1 - :align: center - :width: 68% - :alt: ptw_idle - - **Figure 21:** Address of Desired PTE at Level 1 - -.. _example: - - b. The signal indicating whether it's an instruction page table walk is updated based on the ITLB miss. - c. The ASID and virtual address are saved for the page table walk. - d. A shared TLB miss is indicated. - -.. raw:: html - - WAIT GRANT state - -In the **WAIT_GRANT** state of the Page Table Walker's finite state machine, a data request is sent to retrieve memory information. It waits for a data grant signal from the Dcache controller, remaining in this state until granted. Once granted, it activates a tag valid signal, marking data validity. The state then transitions to "PTE_LOOKUP" for page table entry lookup. - -.. raw:: html - - PTE LOOKUP state - -In the **PTE_LOOKUP** state of the Page Table Walker (PTW) finite state machine, the PTW performs the actual lookup and evaluation of the page table entry (PTE) based on the virtual address translation. The behavior and operations performed in this state are detailed as follows: - -1. The state waits for a valid signal indicating that the data from the memory subsystem, specifically the page table entry, is available for processing. -2. Upon receiving the valid signal, the PTW proceeds with examining the retrieved page table entry to determine its properties and validity. -3. The state checks if the global mapping bit in the PTE is set, and if so, sets the global mapping signal to indicate that the translation applies globally across all address spaces. -4. The state distinguishes between two cases: Invalid PTE and Valid PTE. - - a. If the valid bit of the PTE is not set, or if the PTE has reserved RWX field encodings, it signifies an Invalid PTE. In such cases, the state transitions to the "PROPAGATE_ERROR" state, indicating a page-fault exception due to an invalid translation. - -.. figure:: ../images/ptw_pte_1.png - :name: **Figure 22:** Invalid PTE and reserved RWX encoding leads to page fault - :align: center - :width: 70% - :alt: ptw_pte_1 - - **Figure 22:** Invalid PTE and reserved RWX encoding leads to page fault - -.. _example1: - - b. If the PTE is valid, the state advances to the "LATENCY" state, indicating a period of processing latency. Additionally, if the "read" flag (pte.r) or the "execute" flag (pte.x) is set, the PTE is considered valid. - -5. Within the Valid PTE scenario, the state performs further checks based on whether the translation is intended for instruction fetching or data access: - - a. For instruction page table walk, if the page is not executable (pte.x is not set) or not marked as accessible (pte.a is not set), the state transitions to the "PROPAGATE_ERROR" state. - -.. figure:: ../images/ptw_iptw.png - :name: **Figure 23:** For Instruction Page Table Walk - :align: center - :width: 70% - :alt: ptw_iptw - - **Figure 23:** For Instruction Page Table Walk - -.. _example2: - - b. For data page table walk, the state checks if the page is readable (pte.r is set) or if the page is executable only but made readable by setting the MXR bit in xSTATUS CSR register. If either condition is met, it indicates a valid translation. If not, the state transitions to the "PROPAGATE_ERROR" state. - -.. figure:: ../images/ptw_dptw.png - :name: **Figure 24:** Data Access Page Table Walk - :width: 70% - :alt: ptw_dptw - - **Figure 24:** Data Access Page Table Walk - -.. _example3: - - c. If the access is intended for storing data, additional checks are performed: If the page is not writable (pte.w is not set) or if it is not marked as dirty (pte.d is not set), the state transitions to the "PROPAGATE_ERROR" state. - -.. figure:: ../images/ptw_dptw_s.png - :name: **Figure 25:** Data Access Page Table Walk, Store requested - :align: center - :width: 70% - :alt: ptw_dptw_s - - **Figure 25:** Data Access Page Table Walk, Store requested - -6. The state also checks for potential misalignment issues in the translation: If the current page table level is the first level (LVL1) and if the PPN0 of in PTE is not zero, it indicates a misaligned superpage, leading to a transition to the "PROPAGATE_ERROR" state. - -.. figure:: ../images/ptw_mis_sup.png - :name: **Figure 26:** Misaligned Superpage Check - :align: center - :width: 70% - :alt: ptw_mis_sup - - **Figure 26:** Misaligned Superpage Check - -7. If the PTE is valid but the page is neither readable nor executable, the PTW recognizes the PTE as a pointer to the next level of the page table, indicating that additional translation information can be found in the referenced page table at a lower level. -8. If the current page table level is the first level (LVL1), the PTW proceeds to switch to the second level (LVL2) page table, updating the next level pointer and calculating the address for the next page table entry using the Physical Page Number from the PTE and the index of the level 2 page table from virtual address. - -.. figure:: ../images/ptw_nlvl.png - :name: **Figure 27:** Address of desired PTE at next level of Page Table - :align: center - :width: 70% - :alt: ptw_nlvl - - **Figure 27:** Address of desired PTE at next level of Page Table - -9. The state then transitions to the "WAIT_GRANT" state, indicating that the PTW is awaiting the grant signal to proceed with requesting the next level page table entry. -10. If the current level is already the second level (LVL2), an error is flagged, and the state transitions to the "PROPAGATE_ERROR" state, signifying an unexpected situation where the PTW is already at the last level page table. -11. If the translation access is found to be restricted by the Physical Memory Protection (PMP) settings (allow_access is false), the state updates the shared TLB update signal to indicate that the TLB entry should not be updated. Additionally, the saved address for the page table walk is restored to its previous value, and the state transitions to the "PROPAGATE_ACCESS_ERROR" state. -12. Lastly, if the data request for the page table entry was granted, the state indicates to the cache subsystem that the tag associated with the data is now valid. - -.. figure:: ../images/ptw_pte_flowchart.png - :name: **Figure 28:** Flow Chart of PTE LOOKUP State - :align: center - :alt: ptw_pte_flowchart - - **Figure 28:** Flow Chart of PTE LOOKUP State - -.. raw:: html - - PROPAGATE ERROR state - -This state indicates a detected error in the page table walk process, and an error signal is asserted to indicate the Page Table Walker's error condition, triggering a transition to the "LATENCY" state for error signal propagation. - -.. raw:: html - - PROPAGATE ACCESS ERROR state - -This state indicates a detected access error in the page table walk process, and an access error signal is asserted to indicate the Page Table Walker's access error condition, triggering a transition to the "LATENCY" state for access error signal propagation. - -.. raw:: html - - WAIT RVALID state - -This state waits until it gets the "read valid" signal, and when it does, it's ready to start a new page table walk. - -.. raw:: html - - LATENCY state - -The LATENCY state introduces a latency period to allow for necessary system actions or signals to stabilize. After the latency period, the FSM transitions back to the IDLE state, indicating that the system is prepared for a new translation request. - -.. raw:: html - - Flush Scenario - -The first step when a flush is triggered is to check whether the Page Table Entry (PTE) lookup process is currently in progress. If the PTW (Page Table Walker) module is indeed in the middle of a PTE lookup operation, the code then proceeds to evaluate a specific aspect of this operation. - -* **Check for Data Validity (rvalid):** Within the PTE lookup operation, it's important to ensure that the data being used for the translation is valid. In other words, the code checks whether the "rvalid" signal (which likely indicates the validity of the data) is not active. If the data is not yet valid, it implies that the PTW module is waiting for the data to become valid before completing the lookup. In such a case, the code takes appropriate action to wait for the data to become valid before proceeding further. - -* **Check for Waiting on Grant:** The second condition the code checks for during a flush scenario is whether the PTW module is currently waiting for a "grant." This "grant" signal is typically used to indicate permission or authorization to proceed with an operation. If the PTW module is indeed in a state of waiting for this grant signal, it implies that it requires authorization before continuing its task. - - * **Waiting for Grant:** If the PTW module is in a state of waiting for the grant signal, the code ensures that it continues to wait for the grant signal to be asserted before proceeding further. - -* **Return to Idle State if Neither Condition is Met:** After evaluating the above two conditions, the code determines whether either of these conditions is true. If neither of these conditions applies, it suggests that the PTW module can return to its idle state, indicating that it can continue normal operations without any dependencies on the flush condition. diff --git a/docs/04_cv32a65x/design/source/parameters.adoc b/docs/04_cv32a65x/design/source/parameters.adoc new file mode 100644 index 0000000000..070d768175 --- /dev/null +++ b/docs/04_cv32a65x/design/source/parameters.adoc @@ -0,0 +1,93 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[cv32a65x_PARAMETERS]] + +.cv32a65x parameter configuration +|=== +|Name | description | description + +|XLEN | General Purpose Register Size (in bits) | 32 +|RVA | Atomic RISC-V extension | False +|RVB | Bit manipulation RISC-V extension | True +|RVV | Vector RISC-V extension | False +|RVC | Compress RISC-V extension | True +|RVH | Hypervisor RISC-V extension | False +|RVZCB | Zcb RISC-V extension | True +|RVZCMP | Zcmp RISC-V extension | False +|RVZiCond | Zicond RISC-V extension | False +|RVZicntr | Zicntr RISC-V extension | False +|RVZihpm | Zihpm RISC-V extension | False +|RVF | Floating Point | False +|RVD | Floating Point | False +|XF16 | Non standard 16bits Floating Point extension | False +|XF16ALT | Non standard 16bits Floating Point Alt extension | False +|XF8 | Non standard 8bits Floating Point extension | False +|XFVec | Non standard Vector Floating Point extension | False +|PerfCounterEn | Perf counters | False +|MmuPresent | MMU | False +|RVS | Supervisor mode | False +|RVU | User mode | False +|DebugEn | Debug support | False +|DmBaseAddress | Base address of the debug module | 0x0 +|HaltAddress | Address to jump when halt request | 0x800 +|ExceptionAddress | Address to jump when exception | 0x808 +|TvalEn | Tval Support Enable | False +|DirectVecOnly | MTVEC CSR supports only direct mode | True +|NrPMPEntries | PMP entries number | 8 +|PMPCfgRstVal | PMP CSR configuration reset values | [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0] +|PMPAddrRstVal | PMP CSR address reset values | [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0] +|PMPEntryReadOnly | PMP CSR read-only bits | 0 +|NrNonIdempotentRules | PMA non idempotent rules number | 0 +|NonIdempotentAddrBase | PMA NonIdempotent region base address | [0b0, 0b0] +|NonIdempotentLength | PMA NonIdempotent region length | [0b0, 0b0] +|NrExecuteRegionRules | PMA regions with execute rules number | 0 +|ExecuteRegionAddrBase | PMA Execute region base address | [0x80000000, 0x10000, 0x0] +|ExecuteRegionLength | PMA Execute region address base | [0x40000000, 0x10000, 0x1000] +|NrCachedRegionRules | PMA regions with cache rules number | 1 +|CachedRegionAddrBase | PMA cache region base address | [0x80000000] +|CachedRegionLength | PMA cache region rules | [0x40000000] +|CvxifEn | CV-X-IF coprocessor interface enable | True +|NOCType | NOC bus type | config_pkg::NOC_TYPE_AXI4_ATOP +|AxiAddrWidth | AXI address width | 64 +|AxiDataWidth | AXI data width | 64 +|AxiIdWidth | AXI ID width | 4 +|AxiUserWidth | AXI User width | 32 +|AxiBurstWriteEn | AXI burst in write | False +|MemTidWidth | TODO | 4 +|IcacheByteSize | Instruction cache size (in bytes) | 2048 +|IcacheSetAssoc | Instruction cache associativity (number of ways) | 2 +|IcacheLineWidth | Instruction cache line width | 128 +|DCacheType | Cache Type | config_pkg::HPDCACHE +|DcacheIdWidth | Data cache ID | 1 +|DcacheByteSize | Data cache size (in bytes) | 2028 +|DcacheSetAssoc | Data cache associativity (number of ways) | 2 +|DcacheLineWidth | Data cache line width | 128 +|DataUserEn | User field on data bus enable | 1 +|WtDcacheWbufDepth | Write-through data cache write buffer depth | 2 +|FetchUserEn | User field on fetch bus enable | 1 +|FetchUserWidth | Width of fetch user field | 32 +|FpgaEn | Is FPGA optimization of CV32A6 | False +|TechnoCut | Is Techno Cut instanciated | True +|SuperscalarEn | Enable superscalar* with 2 issue ports and 2 commit ports. | True +|NrCommitPorts | Number of commit ports. Forced to 2 if SuperscalarEn. | 1 +|NrLoadPipeRegs | Load cycle latency number | 0 +|NrStorePipeRegs | Store cycle latency number | 0 +|NrScoreboardEntries | Scoreboard length | 8 +|NrLoadBufEntries | Load buffer entry buffer | 2 +|MaxOutstandingStores | Maximum number of outstanding stores | 7 +|RASDepth | Return address stack depth | 2 +|BTBEntries | Branch target buffer entries | 0 +|BHTEntries | Branch history entries | 32 +|InstrTlbEntries | MMU instruction TLB entries | 2 +|DataTlbEntries | MMU data TLB entries | 2 +|UseSharedTlb | MMU option to use shared TLB | True +|SharedTlbDepth | MMU depth of shared TLB | 64 +|=== diff --git a/docs/04_cv32a65x/design/source/parameters_cv32a65x.rst b/docs/04_cv32a65x/design/source/parameters_cv32a65x.rst deleted file mode 100644 index 7ca2918dd3..0000000000 --- a/docs/04_cv32a65x/design/source/parameters_cv32a65x.rst +++ /dev/null @@ -1,321 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _cv32a65x_PARAMETERS: - -.. list-table:: cv32a65x parameter configuration - :header-rows: 1 - - * - Name - - description - - Value - - * - XLEN - - General Purpose Register Size (in bits) - - 32 - - * - RVA - - Atomic RISC-V extension - - False - - * - RVB - - Bit manipulation RISC-V extension - - True - - * - RVV - - Vector RISC-V extension - - False - - * - RVC - - Compress RISC-V extension - - True - - * - RVH - - Hypervisor RISC-V extension - - False - - * - RVZCB - - Zcb RISC-V extension - - True - - * - RVZCMP - - Zcmp RISC-V extension - - False - - * - RVZiCond - - Zicond RISC-V extension - - False - - * - RVZicntr - - Zicntr RISC-V extension - - False - - * - RVZihpm - - Zihpm RISC-V extension - - False - - * - RVF - - Floating Point - - False - - * - RVD - - Floating Point - - False - - * - XF16 - - Non standard 16bits Floating Point extension - - False - - * - XF16ALT - - Non standard 16bits Floating Point Alt extension - - False - - * - XF8 - - Non standard 8bits Floating Point extension - - False - - * - XFVec - - Non standard Vector Floating Point extension - - False - - * - PerfCounterEn - - Perf counters - - False - - * - MmuPresent - - MMU - - False - - * - RVS - - Supervisor mode - - False - - * - RVU - - User mode - - False - - * - DebugEn - - Debug support - - False - - * - DmBaseAddress - - Base address of the debug module - - 0x0 - - * - HaltAddress - - Address to jump when halt request - - 0x800 - - * - ExceptionAddress - - Address to jump when exception - - 0x808 - - * - TvalEn - - Tval Support Enable - - False - - * - DirectVecOnly - - MTVEC CSR supports only direct mode - - True - - * - NrPMPEntries - - PMP entries number - - 8 - - * - PMPCfgRstVal - - PMP CSR configuration reset values - - [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0] - - * - PMPAddrRstVal - - PMP CSR address reset values - - [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0] - - * - PMPEntryReadOnly - - PMP CSR read-only bits - - 0 - - * - NrNonIdempotentRules - - PMA non idempotent rules number - - 2 - - * - NonIdempotentAddrBase - - PMA NonIdempotent region base address - - [0b0, 0b0] - - * - NonIdempotentLength - - PMA NonIdempotent region length - - [0b0, 0b0] - - * - NrExecuteRegionRules - - PMA regions with execute rules number - - 3 - - * - ExecuteRegionAddrBase - - PMA Execute region base address - - [0x80000000, 0x10000, 0x0] - - * - ExecuteRegionLength - - PMA Execute region address base - - [0x40000000, 0x10000, 0x1000] - - * - NrCachedRegionRules - - PMA regions with cache rules number - - 1 - - * - CachedRegionAddrBase - - PMA cache region base address - - [0x80000000] - - * - CachedRegionLength - - PMA cache region rules - - [0x40000000] - - * - CvxifEn - - CV-X-IF coprocessor interface enable - - True - - * - NOCType - - NOC bus type - - config_pkg::NOC_TYPE_AXI4_ATOP - - * - AxiAddrWidth - - AXI address width - - 64 - - * - AxiDataWidth - - AXI data width - - 64 - - * - AxiIdWidth - - AXI ID width - - 4 - - * - AxiUserWidth - - AXI User width - - 32 - - * - AxiBurstWriteEn - - AXI burst in write - - False - - * - MemTidWidth - - TODO - - 4 - - * - IcacheByteSize - - Instruction cache size (in bytes) - - 2048 - - * - IcacheSetAssoc - - Instruction cache associativity (number of ways) - - 2 - - * - IcacheLineWidth - - Instruction cache line width - - 128 - - * - DCacheType - - Cache Type - - config_pkg::HPDCACHE - - * - DcacheIdWidth - - Data cache ID - - 1 - - * - DcacheByteSize - - Data cache size (in bytes) - - 2028 - - * - DcacheSetAssoc - - Data cache associativity (number of ways) - - 2 - - * - DcacheLineWidth - - Data cache line width - - 128 - - * - DataUserEn - - User field on data bus enable - - 1 - - * - WtDcacheWbufDepth - - Write-through data cache write buffer depth - - 2 - - * - FetchUserEn - - User field on fetch bus enable - - 1 - - * - FetchUserWidth - - Width of fetch user field - - 32 - - * - FpgaEn - - Is FPGA optimization of CV32A6 - - False - - * - TechnoCut - - Is Techno Cut instanciated - - True - - * - SuperscalarEn - - Enable superscalar* with 2 issue ports and 2 commit ports. - - True - - * - NrCommitPorts - - Number of commit ports. Forced to 2 if SuperscalarEn. - - 1 - - * - NrLoadPipeRegs - - Load cycle latency number - - 0 - - * - NrStorePipeRegs - - Store cycle latency number - - 0 - - * - NrScoreboardEntries - - Scoreboard length - - 8 - - * - NrLoadBufEntries - - Load buffer entry buffer - - 2 - - * - MaxOutstandingStores - - Maximum number of outstanding stores - - 7 - - * - RASDepth - - Return address stack depth - - 2 - - * - BTBEntries - - Branch target buffer entries - - 0 - - * - BHTEntries - - Branch history entries - - 32 - - * - InstrTlbEntries - - MMU instruction TLB entries - - 2 - - * - DataTlbEntries - - MMU data TLB entries - - 2 - - * - UseSharedTlb - - MMU option to use shared TLB - - True - - * - SharedTlbDepth - - MMU depth of shared TLB - - 64 diff --git a/docs/04_cv32a65x/design/source/port_alu.adoc b/docs/04_cv32a65x/design/source/port_alu.adoc new file mode 100644 index 0000000000..78dd11efe6 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_alu.adoc @@ -0,0 +1,28 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_alu_ports]] + +.*alu module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`fu_data_i` | in | FU data needed to execute instruction | ISSUE_STAGE | fu_data_t + +|`result_o` | out | ALU result | ISSUE_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`alu_branch_res_o` | out | ALU branch compare result | branch_unit | logic + +|=== + diff --git a/docs/04_cv32a65x/design/source/port_alu.rst b/docs/04_cv32a65x/design/source/port_alu.rst deleted file mode 100644 index 6da09d56b7..0000000000 --- a/docs/04_cv32a65x/design/source/port_alu.rst +++ /dev/null @@ -1,51 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_alu_ports: - -.. list-table:: **alu module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``fu_data_i`` - - in - - FU data needed to execute instruction - - ISSUE_STAGE - - fu_data_t - - * - ``result_o`` - - out - - ALU result - - ISSUE_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``alu_branch_res_o`` - - out - - ALU branch compare result - - branch_unit - - logic - - diff --git a/docs/04_cv32a65x/design/source/port_bht.adoc b/docs/04_cv32a65x/design/source/port_bht.adoc new file mode 100644 index 0000000000..e54d765432 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_bht.adoc @@ -0,0 +1,34 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_bht_ports]] + +.*bht module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`vpc_i` | in | Virtual PC | CACHE | logic[CVA6Cfg.VLEN-1:0] + +|`bht_update_i` | in | Update bht with resolved address | EXECUTE | bht_update_t + +|`bht_prediction_o` | out | Prediction from bht | FRONTEND | ariane_pkg::bht_prediction_t[CVA6Cfg.INSTR_PER_FETCH-1:0] + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +For any HW configuration,:: +* `flush_bp_i` input is tied to 0 +As DebugEn = False,:: +* `debug_mode_i` input is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_bht.rst b/docs/04_cv32a65x/design/source/port_bht.rst deleted file mode 100644 index 3661996fc9..0000000000 --- a/docs/04_cv32a65x/design/source/port_bht.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_bht_ports: - -.. list-table:: **bht module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``vpc_i`` - - in - - Virtual PC - - CACHE - - logic[CVA6Cfg.VLEN-1:0] - - * - ``bht_update_i`` - - in - - Update bht with resolved address - - EXECUTE - - bht_update_t - - * - ``bht_prediction_o`` - - out - - Prediction from bht - - FRONTEND - - ariane_pkg::bht_prediction_t[CVA6Cfg.INSTR_PER_FETCH-1:0] - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| For any HW configuration, -| ``flush_bp_i`` input is tied to 0 -| As DebugEn = False, -| ``debug_mode_i`` input is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_branch_unit.adoc b/docs/04_cv32a65x/design/source/port_branch_unit.adoc new file mode 100644 index 0000000000..42d209cdc5 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_branch_unit.adoc @@ -0,0 +1,48 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_branch_unit_ports]] + +.*branch_unit module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`fu_data_i` | in | FU data needed to execute instruction | ISSUE_STAGE | fu_data_t + +|`pc_i` | in | Instruction PC | ISSUE_STAGE | logic[CVA6Cfg.VLEN-1:0] + +|`is_compressed_instr_i` | in | Instruction is compressed | ISSUE_STAGE | logic + +|`branch_valid_i` | in | Branch unit instruction is valid | ISSUE_STAGE | logic + +|`branch_comp_res_i` | in | ALU branch compare result | ALU | logic + +|`branch_result_o` | out | Brach unit result | ISSUE_STAGE | logic[CVA6Cfg.VLEN-1:0] + +|`branch_predict_i` | in | Information of branch prediction | ISSUE_STAGE | branchpredict_sbe_t + +|`resolved_branch_o` | out | Signaling that we resolved the branch | ISSUE_STAGE | bp_resolve_t + +|`resolve_branch_o` | out | Branch is resolved, new entries can be accepted by scoreboard | ID_STAGE | logic + +|`branch_exception_o` | out | Branch exception out | TO_BE_COMPLETED | exception_t + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As RVH = False,:: +* `v_i` input is tied to 0 +As DebugEn = False,:: +* `debug_mode_i` input is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_branch_unit.rst b/docs/04_cv32a65x/design/source/port_branch_unit.rst deleted file mode 100644 index e9eb72fb75..0000000000 --- a/docs/04_cv32a65x/design/source/port_branch_unit.rst +++ /dev/null @@ -1,99 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_branch_unit_ports: - -.. list-table:: **branch_unit module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``fu_data_i`` - - in - - FU data needed to execute instruction - - ISSUE_STAGE - - fu_data_t - - * - ``pc_i`` - - in - - Instruction PC - - ISSUE_STAGE - - logic[CVA6Cfg.VLEN-1:0] - - * - ``is_compressed_instr_i`` - - in - - Instruction is compressed - - ISSUE_STAGE - - logic - - * - ``branch_valid_i`` - - in - - Branch unit instruction is valid - - ISSUE_STAGE - - logic - - * - ``branch_comp_res_i`` - - in - - ALU branch compare result - - ALU - - logic - - * - ``branch_result_o`` - - out - - Brach unit result - - ISSUE_STAGE - - logic[CVA6Cfg.VLEN-1:0] - - * - ``branch_predict_i`` - - in - - Information of branch prediction - - ISSUE_STAGE - - branchpredict_sbe_t - - * - ``resolved_branch_o`` - - out - - Signaling that we resolved the branch - - ISSUE_STAGE - - bp_resolve_t - - * - ``resolve_branch_o`` - - out - - Branch is resolved, new entries can be accepted by scoreboard - - ID_STAGE - - logic - - * - ``branch_exception_o`` - - out - - Branch exception out - - TO_BE_COMPLETED - - exception_t - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As RVH = False, -| ``v_i`` input is tied to 0 -| As DebugEn = False, -| ``debug_mode_i`` input is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_btb.adoc b/docs/04_cv32a65x/design/source/port_btb.adoc new file mode 100644 index 0000000000..809661bb04 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_btb.adoc @@ -0,0 +1,34 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_btb_ports]] + +.*btb module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`vpc_i` | in | Virtual PC | CACHE | logic[CVA6Cfg.VLEN-1:0] + +|`btb_update_i` | in | Update BTB with resolved address | EXECUTE | btb_update_t + +|`btb_prediction_o` | out | BTB Prediction | FRONTEND | btb_prediction_t[CVA6Cfg.INSTR_PER_FETCH-1:0] + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +For any HW configuration,:: +* `flush_bp_i` input is tied to 0 +As DebugEn = False,:: +* `debug_mode_i` input is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_btb.rst b/docs/04_cv32a65x/design/source/port_btb.rst deleted file mode 100644 index bda7f8244b..0000000000 --- a/docs/04_cv32a65x/design/source/port_btb.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_btb_ports: - -.. list-table:: **btb module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``vpc_i`` - - in - - Virtual PC - - CACHE - - logic[CVA6Cfg.VLEN-1:0] - - * - ``btb_update_i`` - - in - - Update BTB with resolved address - - EXECUTE - - btb_update_t - - * - ``btb_prediction_o`` - - out - - BTB Prediction - - FRONTEND - - btb_prediction_t[CVA6Cfg.INSTR_PER_FETCH-1:0] - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| For any HW configuration, -| ``flush_bp_i`` input is tied to 0 -| As DebugEn = False, -| ``debug_mode_i`` input is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_commit_stage.adoc b/docs/04_cv32a65x/design/source/port_commit_stage.adoc new file mode 100644 index 0000000000..c4351d619f --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_commit_stage.adoc @@ -0,0 +1,84 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_commit_stage_ports]] + +.*commit_stage module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`halt_i` | in | Request to halt the core | CONTROLLER | logic + +|`flush_dcache_i` | in | request to flush dcache, also flush the pipeline | CACHE | logic + +|`exception_o` | out | TO_BE_COMPLETED | EX_STAGE | exception_t + +|`commit_instr_i` | in | The instruction we want to commit | ISSUE_STAGE | scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] + +|`commit_drop_i` | in | The instruction is cancelled | ISSUE_STAGE | logic[CVA6Cfg.NrCommitPorts-1:0] + +|`commit_ack_o` | out | Acknowledge that we are indeed committing | ISSUE_STAGE | logic[CVA6Cfg.NrCommitPorts-1:0] + +|`commit_macro_ack_o` | out | Acknowledge that we are indeed committing | CSR_REGFILE | logic[CVA6Cfg.NrCommitPorts-1:0] + +|`waddr_o` | out | Register file write address | ISSUE_STAGE | logic[CVA6Cfg.NrCommitPorts-1:0][4:0] + +|`wdata_o` | out | Register file write data | ISSUE_STAGE | logic[CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] + +|`we_gpr_o` | out | Register file write enable | ISSUE_STAGE | logic[CVA6Cfg.NrCommitPorts-1:0] + +|`we_fpr_o` | out | Floating point register enable | ISSUE_STAGE | logic[CVA6Cfg.NrCommitPorts-1:0] + +|`pc_o` | out | TO_BE_COMPLETED | FRONTEND_CSR_REGFILE | logic[CVA6Cfg.VLEN-1:0] + +|`csr_op_o` | out | Decoded CSR operation | CSR_REGFILE | fu_op + +|`csr_wdata_o` | out | Data to write to CSR | CSR_REGFILE | logic[CVA6Cfg.XLEN-1:0] + +|`csr_rdata_i` | in | Data to read from CSR | CSR_REGFILE | logic[CVA6Cfg.XLEN-1:0] + +|`csr_exception_i` | in | Exception or interrupt occurred in CSR stage (the same as commit) | CSR_REGFILE | exception_t + +|`commit_lsu_o` | out | Commit the pending store | EX_STAGE | logic + +|`commit_lsu_ready_i` | in | Commit buffer of LSU is ready | EX_STAGE | logic + +|`commit_tran_id_o` | out | Transaction id of first commit port | ID_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`no_st_pending_i` | in | no store is pending | EX_STAGE | logic + +|`commit_csr_o` | out | Commit the pending CSR instruction | EX_STAGE | logic + +|`flush_commit_o` | out | Request a pipeline flush | CONTROLLER | logic + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As RVF = 0,:: +* `dirty_fp_state_o` output is tied to 0 +* `csr_write_fflags_o` output is tied to 0 +As DebugEn = False,:: +* `single_step_i` input is tied to 0 +As RVA = False,:: +* `amo_resp_i` input is tied to 0 +* `amo_valid_commit_o` output is tied to 0 +As FenceEn = 0,:: +* `fence_i_o` output is tied to 0 +* `fence_o` output is tied to 0 +As RVS = False,:: +* `sfence_vma_o` output is tied to 0 +As RVH = False,:: +* `hfence_vvma_o` output is tied to 0 +* `hfence_gvma_o` output is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_commit_stage.rst b/docs/04_cv32a65x/design/source/port_commit_stage.rst deleted file mode 100644 index 8625513436..0000000000 --- a/docs/04_cv32a65x/design/source/port_commit_stage.rst +++ /dev/null @@ -1,183 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_commit_stage_ports: - -.. list-table:: **commit_stage module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``halt_i`` - - in - - Request to halt the core - - CONTROLLER - - logic - - * - ``flush_dcache_i`` - - in - - request to flush dcache, also flush the pipeline - - CACHE - - logic - - * - ``exception_o`` - - out - - TO_BE_COMPLETED - - EX_STAGE - - exception_t - - * - ``commit_instr_i`` - - in - - The instruction we want to commit - - ISSUE_STAGE - - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] - - * - ``commit_drop_i`` - - in - - The instruction is cancelled - - ISSUE_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``commit_ack_o`` - - out - - Acknowledge that we are indeed committing - - ISSUE_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``commit_macro_ack_o`` - - out - - Acknowledge that we are indeed committing - - CSR_REGFILE - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``waddr_o`` - - out - - Register file write address - - ISSUE_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0][4:0] - - * - ``wdata_o`` - - out - - Register file write data - - ISSUE_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] - - * - ``we_gpr_o`` - - out - - Register file write enable - - ISSUE_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``we_fpr_o`` - - out - - Floating point register enable - - ISSUE_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``pc_o`` - - out - - TO_BE_COMPLETED - - FRONTEND_CSR_REGFILE - - logic[CVA6Cfg.VLEN-1:0] - - * - ``csr_op_o`` - - out - - Decoded CSR operation - - CSR_REGFILE - - fu_op - - * - ``csr_wdata_o`` - - out - - Data to write to CSR - - CSR_REGFILE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``csr_rdata_i`` - - in - - Data to read from CSR - - CSR_REGFILE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``csr_exception_i`` - - in - - Exception or interrupt occurred in CSR stage (the same as commit) - - CSR_REGFILE - - exception_t - - * - ``commit_lsu_o`` - - out - - Commit the pending store - - EX_STAGE - - logic - - * - ``commit_lsu_ready_i`` - - in - - Commit buffer of LSU is ready - - EX_STAGE - - logic - - * - ``commit_tran_id_o`` - - out - - Transaction id of first commit port - - ID_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``no_st_pending_i`` - - in - - no store is pending - - EX_STAGE - - logic - - * - ``commit_csr_o`` - - out - - Commit the pending CSR instruction - - EX_STAGE - - logic - - * - ``flush_commit_o`` - - out - - Request a pipeline flush - - CONTROLLER - - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As RVF = 0, -| ``dirty_fp_state_o`` output is tied to 0 -| ``csr_write_fflags_o`` output is tied to 0 -| As DebugEn = False, -| ``single_step_i`` input is tied to 0 -| As RVA = False, -| ``amo_resp_i`` input is tied to 0 -| ``amo_valid_commit_o`` output is tied to 0 -| As FenceEn = 0, -| ``fence_i_o`` output is tied to 0 -| ``fence_o`` output is tied to 0 -| As RVS = False, -| ``sfence_vma_o`` output is tied to 0 -| As RVH = False, -| ``hfence_vvma_o`` output is tied to 0 -| ``hfence_gvma_o`` output is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_compressed_decoder.adoc b/docs/04_cv32a65x/design/source/port_compressed_decoder.adoc new file mode 100644 index 0000000000..d0e4aeda07 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_compressed_decoder.adoc @@ -0,0 +1,28 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_compressed_decoder_ports]] + +.*compressed_decoder module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`instr_i` | in | Input instruction coming from fetch stage | FRONTEND | logic[31:0] + +|`instr_o` | out | Output instruction in uncompressed format | decoder | logic[31:0] + +|`illegal_instr_o` | out | Input instruction is illegal | decoder | logic + +|`is_macro_instr_o` | out | Output instruction is macro | decoder | logic + +|`is_compressed_o` | out | Output instruction is compressed | decoder | logic + +|=== + diff --git a/docs/04_cv32a65x/design/source/port_compressed_decoder.rst b/docs/04_cv32a65x/design/source/port_compressed_decoder.rst deleted file mode 100644 index 4a5cdb30cf..0000000000 --- a/docs/04_cv32a65x/design/source/port_compressed_decoder.rst +++ /dev/null @@ -1,51 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_compressed_decoder_ports: - -.. list-table:: **compressed_decoder module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``instr_i`` - - in - - Input instruction coming from fetch stage - - FRONTEND - - logic[31:0] - - * - ``instr_o`` - - out - - Output instruction in uncompressed format - - decoder - - logic[31:0] - - * - ``illegal_instr_o`` - - out - - Input instruction is illegal - - decoder - - logic - - * - ``is_macro_instr_o`` - - out - - Output instruction is macro - - decoder - - logic - - * - ``is_compressed_o`` - - out - - Output instruction is compressed - - decoder - - logic - - diff --git a/docs/04_cv32a65x/design/source/port_controller.adoc b/docs/04_cv32a65x/design/source/port_controller.adoc new file mode 100644 index 0000000000..771a05f71b --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_controller.adoc @@ -0,0 +1,74 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_controller_ports]] + +.*controller module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`set_pc_commit_o` | out | Set PC om PC Gen | FRONTEND | logic + +|`flush_if_o` | out | Flush the IF stage | FRONTEND | logic + +|`flush_unissued_instr_o` | out | Flush un-issued instructions of the scoreboard | FRONTEND | logic + +|`flush_id_o` | out | Flush ID stage | ID_STAGE | logic + +|`flush_ex_o` | out | Flush EX stage | EX_STAGE | logic + +|`flush_bp_o` | out | Flush branch predictors | FRONTEND | logic + +|`flush_icache_o` | out | Flush ICache | CACHE | logic + +|`flush_dcache_o` | out | Flush DCache | CACHE | logic + +|`flush_dcache_ack_i` | in | Acknowledge the whole DCache Flush | CACHE | logic + +|`halt_csr_i` | in | Halt request from CSR (WFI instruction) | CSR_REGFILE | logic + +|`halt_o` | out | Halt signal to commit stage | COMMIT_STAGE | logic + +|`eret_i` | in | Return from exception | CSR_REGFILE | logic + +|`ex_valid_i` | in | We got an exception, flush the pipeline | FRONTEND | logic + +|`resolved_branch_i` | in | We got a resolved branch, check if we need to flush the front-end | EX_STAGE | bp_resolve_t + +|`flush_csr_i` | in | We got an instruction which altered the CSR, flush the pipeline | CSR_REGFILE | logic + +|`flush_commit_i` | in | Flush request from commit stage | COMMIT_STAGE | logic + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As RVH = False,:: +* `v_i` input is tied to 0 +* `flush_tlb_vvma_o` output is tied to 0 +* `flush_tlb_gvma_o` output is tied to 0 +* `hfence_vvma_i` input is tied to 0 +* `hfence_gvma_i` input is tied to 0 +As MMUPresent = 0,:: +* `flush_tlb_o` output is tied to 0 +As EnableAccelerator = 0,:: +* `halt_acc_i` input is tied to 0 +* `flush_acc_i` input is tied to 0 +As DebugEn = False,:: +* `set_debug_pc_i` input is tied to 0 +As FenceEn = 0,:: +* `fence_i_i` input is tied to 0 +* `fence_i` input is tied to 0 +As RVS = False,:: +* `sfence_vma_i` input is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_controller.rst b/docs/04_cv32a65x/design/source/port_controller.rst deleted file mode 100644 index 7569ab898d..0000000000 --- a/docs/04_cv32a65x/design/source/port_controller.rst +++ /dev/null @@ -1,149 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_controller_ports: - -.. list-table:: **controller module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``set_pc_commit_o`` - - out - - Set PC om PC Gen - - FRONTEND - - logic - - * - ``flush_if_o`` - - out - - Flush the IF stage - - FRONTEND - - logic - - * - ``flush_unissued_instr_o`` - - out - - Flush un-issued instructions of the scoreboard - - FRONTEND - - logic - - * - ``flush_id_o`` - - out - - Flush ID stage - - ID_STAGE - - logic - - * - ``flush_ex_o`` - - out - - Flush EX stage - - EX_STAGE - - logic - - * - ``flush_bp_o`` - - out - - Flush branch predictors - - FRONTEND - - logic - - * - ``flush_icache_o`` - - out - - Flush ICache - - CACHE - - logic - - * - ``flush_dcache_o`` - - out - - Flush DCache - - CACHE - - logic - - * - ``flush_dcache_ack_i`` - - in - - Acknowledge the whole DCache Flush - - CACHE - - logic - - * - ``halt_csr_i`` - - in - - Halt request from CSR (WFI instruction) - - CSR_REGFILE - - logic - - * - ``halt_o`` - - out - - Halt signal to commit stage - - COMMIT_STAGE - - logic - - * - ``eret_i`` - - in - - Return from exception - - CSR_REGFILE - - logic - - * - ``ex_valid_i`` - - in - - We got an exception, flush the pipeline - - FRONTEND - - logic - - * - ``resolved_branch_i`` - - in - - We got a resolved branch, check if we need to flush the front-end - - EX_STAGE - - bp_resolve_t - - * - ``flush_csr_i`` - - in - - We got an instruction which altered the CSR, flush the pipeline - - CSR_REGFILE - - logic - - * - ``flush_commit_i`` - - in - - Flush request from commit stage - - COMMIT_STAGE - - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As RVH = False, -| ``v_i`` input is tied to 0 -| ``flush_tlb_vvma_o`` output is tied to 0 -| ``flush_tlb_gvma_o`` output is tied to 0 -| ``hfence_vvma_i`` input is tied to 0 -| ``hfence_gvma_i`` input is tied to 0 -| As MMUPresent = 0, -| ``flush_tlb_o`` output is tied to 0 -| As EnableAccelerator = 0, -| ``halt_acc_i`` input is tied to 0 -| ``flush_acc_i`` input is tied to 0 -| As DebugEn = False, -| ``set_debug_pc_i`` input is tied to 0 -| As FenceEn = 0, -| ``fence_i_i`` input is tied to 0 -| ``fence_i`` input is tied to 0 -| As RVS = False, -| ``sfence_vma_i`` input is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_csr_buffer.adoc b/docs/04_cv32a65x/design/source/port_csr_buffer.adoc new file mode 100644 index 0000000000..5db8d7aa72 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_csr_buffer.adoc @@ -0,0 +1,36 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_csr_buffer_ports]] + +.*csr_buffer module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`flush_i` | in | Flush CSR | CONTROLLER | logic + +|`fu_data_i` | in | FU data needed to execute instruction | ISSUE_STAGE | fu_data_t + +|`csr_ready_o` | out | CSR FU is ready | ISSUE_STAGE | logic + +|`csr_valid_i` | in | CSR instruction is valid | ISSUE_STAGE | logic + +|`csr_result_o` | out | CSR buffer result | ISSUE_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`csr_commit_i` | in | commit the pending CSR OP | TO_BE_COMPLETED | logic + +|`csr_addr_o` | out | CSR address to write | COMMIT_STAGE | logic[11:0] + +|=== + diff --git a/docs/04_cv32a65x/design/source/port_csr_buffer.rst b/docs/04_cv32a65x/design/source/port_csr_buffer.rst deleted file mode 100644 index e83ad5e34a..0000000000 --- a/docs/04_cv32a65x/design/source/port_csr_buffer.rst +++ /dev/null @@ -1,75 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_csr_buffer_ports: - -.. list-table:: **csr_buffer module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``flush_i`` - - in - - Flush CSR - - CONTROLLER - - logic - - * - ``fu_data_i`` - - in - - FU data needed to execute instruction - - ISSUE_STAGE - - fu_data_t - - * - ``csr_ready_o`` - - out - - CSR FU is ready - - ISSUE_STAGE - - logic - - * - ``csr_valid_i`` - - in - - CSR instruction is valid - - ISSUE_STAGE - - logic - - * - ``csr_result_o`` - - out - - CSR buffer result - - ISSUE_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``csr_commit_i`` - - in - - commit the pending CSR OP - - TO_BE_COMPLETED - - logic - - * - ``csr_addr_o`` - - out - - CSR address to write - - COMMIT_STAGE - - logic[11:0] - - diff --git a/docs/04_cv32a65x/design/source/port_csr_regfile.adoc b/docs/04_cv32a65x/design/source/port_csr_regfile.adoc new file mode 100644 index 0000000000..dd93ed3985 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_csr_regfile.adoc @@ -0,0 +1,125 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_csr_regfile_ports]] + +.*csr_regfile module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`time_irq_i` | in | Timer threw a interrupt | SUBSYSTEM | logic + +|`flush_o` | out | send a flush request out when a CSR with a side effect changes | CONTROLLER | logic + +|`halt_csr_o` | out | halt requested | CONTROLLER | logic + +|`commit_instr_i` | in | Instruction to be committed | ID_STAGE | scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] + +|`commit_ack_i` | in | Commit acknowledged a instruction -> increase instret CSR | COMMIT_STAGE | logic[CVA6Cfg.NrCommitPorts-1:0] + +|`boot_addr_i` | in | Address from which to start booting, mtvec is set to the same address | SUBSYSTEM | logic[CVA6Cfg.VLEN-1:0] + +|`hart_id_i` | in | Hart id in a multicore environment (reflected in a CSR) | SUBSYSTEM | logic[CVA6Cfg.XLEN-1:0] + +|`ex_i` | in | We've got an exception from the commit stage, take it | COMMIT_STAGE | exception_t + +|`csr_op_i` | in | Operation to perform on the CSR file | COMMIT_STAGE | fu_op + +|`csr_addr_i` | in | Address of the register to read/write | EX_STAGE | logic[11:0] + +|`csr_wdata_i` | in | Write data in | COMMIT_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`csr_rdata_o` | out | Read data out | COMMIT_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`pc_i` | in | PC of instruction accessing the CSR | COMMIT_STAGE | logic[CVA6Cfg.VLEN-1:0] + +|`csr_exception_o` | out | attempts to access a CSR without appropriate privilege | COMMIT_STAGE | exception_t + +|`epc_o` | out | Output the exception PC to PC Gen, the correct CSR (mepc, sepc) is set accordingly | FRONTEND | logic[CVA6Cfg.VLEN-1:0] + +|`eret_o` | out | Return from exception, set the PC of epc_o | FRONTEND | logic + +|`trap_vector_base_o` | out | Output base of exception vector, correct CSR is output (mtvec, stvec) | FRONTEND | logic[CVA6Cfg.VLEN-1:0] + +|`irq_ctrl_o` | out | interrupt management to id stage | ID_STAGE | irq_ctrl_t + +|`irq_i` | in | external interrupt in | SUBSYSTEM | logic[1:0] + +|`ipi_i` | in | inter processor interrupt -> connected to machine mode sw | SUBSYSTEM | logic + +|`icache_en_o` | out | L1 ICache Enable | CACHE | logic + +|`dcache_en_o` | out | L1 DCache Enable | CACHE | logic + +|`rvfi_csr_o` | out | none | none | rvfi_probes_csr_t + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As RVF = 0,:: +* `dirty_fp_state_i` input is tied to 0 +* `csr_write_fflags_i` input is tied to 0 +* `fs_o` output is tied to 0 +* `fflags_o` output is tied to 0 +* `frm_o` output is tied to 0 +* `fprec_o` output is tied to 0 +As EnableAccelerator = 0,:: +* `dirty_v_state_i` input is tied to 0 +* `acc_fflags_ex_i` input is tied to 0 +* `acc_fflags_ex_valid_i` input is tied to 0 +* `acc_cons_en_o` output is tied to 0 +* `pmpcfg_o` output is tied to 0 +* `pmpaddr_o` output is tied to 0 +As PRIV = MachineOnly,:: +* `priv_lvl_o` output is tied to MachineMode +* `ld_st_priv_lvl_o` output is tied to MAchineMode +* `tvm_o` output is tied to 0 +* `tw_o` output is tied to 0 +* `tsr_o` output is tied to 0 +As RVH = False,:: +* `v_o` output is tied to 0 +* `vfs_o` output is tied to 0 +* `en_g_translation_o` output is tied to 0 +* `en_ld_st_g_translation_o` output is tied to 0 +* `ld_st_v_o` output is tied to 0 +* `csr_hs_ld_st_inst_i` input is tied to 0 +* `vs_sum_o` output is tied to 0 +* `vmxr_o` output is tied to 0 +* `vsatp_ppn_o` output is tied to 0 +* `vs_asid_o` output is tied to 0 +* `hgatp_ppn_o` output is tied to 0 +* `vmid_o` output is tied to 0 +* `vtw_o` output is tied to 0 +* `hu_o` output is tied to 0 +As RVV = False,:: +* `vs_o` output is tied to 0 +As RVS = False,:: +* `en_translation_o` output is tied to 0 +* `en_ld_st_translation_o` output is tied to 0 +* `sum_o` output is tied to 0 +* `mxr_o` output is tied to 0 +* `satp_ppn_o` output is tied to 0 +* `asid_o` output is tied to 0 +As DebugEn = False,:: +* `debug_req_i` input is tied to 0 +* `set_debug_pc_o` output is tied to 0 +* `debug_mode_o` output is tied to 0 +* `single_step_o` output is tied to 0 +As PerfCounterEn = 0,:: +* `perf_addr_o` output is tied to 0 +* `perf_data_o` output is tied to 0 +* `perf_data_i` input is tied to 0 +* `perf_we_o` output is tied to 0 +* `mcountinhibit_o` output is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_csr_regfile.rst b/docs/04_cv32a65x/design/source/port_csr_regfile.rst deleted file mode 100644 index 7eb94e58fd..0000000000 --- a/docs/04_cv32a65x/design/source/port_csr_regfile.rst +++ /dev/null @@ -1,228 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_csr_regfile_ports: - -.. list-table:: **csr_regfile module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``time_irq_i`` - - in - - Timer threw a interrupt - - SUBSYSTEM - - logic - - * - ``flush_o`` - - out - - send a flush request out when a CSR with a side effect changes - - CONTROLLER - - logic - - * - ``halt_csr_o`` - - out - - halt requested - - CONTROLLER - - logic - - * - ``commit_instr_i`` - - in - - Instruction to be committed - - ID_STAGE - - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] - - * - ``commit_ack_i`` - - in - - Commit acknowledged a instruction -> increase instret CSR - - COMMIT_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``boot_addr_i`` - - in - - Address from which to start booting, mtvec is set to the same address - - SUBSYSTEM - - logic[CVA6Cfg.VLEN-1:0] - - * - ``hart_id_i`` - - in - - Hart id in a multicore environment (reflected in a CSR) - - SUBSYSTEM - - logic[CVA6Cfg.XLEN-1:0] - - * - ``ex_i`` - - in - - We've got an exception from the commit stage, take it - - COMMIT_STAGE - - exception_t - - * - ``csr_op_i`` - - in - - Operation to perform on the CSR file - - COMMIT_STAGE - - fu_op - - * - ``csr_addr_i`` - - in - - Address of the register to read/write - - EX_STAGE - - logic[11:0] - - * - ``csr_wdata_i`` - - in - - Write data in - - COMMIT_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``csr_rdata_o`` - - out - - Read data out - - COMMIT_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``pc_i`` - - in - - PC of instruction accessing the CSR - - COMMIT_STAGE - - logic[CVA6Cfg.VLEN-1:0] - - * - ``csr_exception_o`` - - out - - attempts to access a CSR without appropriate privilege - - COMMIT_STAGE - - exception_t - - * - ``epc_o`` - - out - - Output the exception PC to PC Gen, the correct CSR (mepc, sepc) is set accordingly - - FRONTEND - - logic[CVA6Cfg.VLEN-1:0] - - * - ``eret_o`` - - out - - Return from exception, set the PC of epc_o - - FRONTEND - - logic - - * - ``trap_vector_base_o`` - - out - - Output base of exception vector, correct CSR is output (mtvec, stvec) - - FRONTEND - - logic[CVA6Cfg.VLEN-1:0] - - * - ``irq_ctrl_o`` - - out - - interrupt management to id stage - - ID_STAGE - - irq_ctrl_t - - * - ``irq_i`` - - in - - external interrupt in - - SUBSYSTEM - - logic[1:0] - - * - ``ipi_i`` - - in - - inter processor interrupt -> connected to machine mode sw - - SUBSYSTEM - - logic - - * - ``icache_en_o`` - - out - - L1 ICache Enable - - CACHE - - logic - - * - ``dcache_en_o`` - - out - - L1 DCache Enable - - CACHE - - logic - - * - ``rvfi_csr_o`` - - out - - none - - none - - rvfi_probes_csr_t - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As RVF = 0, -| ``dirty_fp_state_i`` input is tied to 0 -| ``csr_write_fflags_i`` input is tied to 0 -| ``fs_o`` output is tied to 0 -| ``fflags_o`` output is tied to 0 -| ``frm_o`` output is tied to 0 -| ``fprec_o`` output is tied to 0 -| As EnableAccelerator = 0, -| ``dirty_v_state_i`` input is tied to 0 -| ``acc_fflags_ex_i`` input is tied to 0 -| ``acc_fflags_ex_valid_i`` input is tied to 0 -| ``acc_cons_en_o`` output is tied to 0 -| ``pmpcfg_o`` output is tied to 0 -| ``pmpaddr_o`` output is tied to 0 -| As PRIV = MachineOnly, -| ``priv_lvl_o`` output is tied to MachineMode -| ``ld_st_priv_lvl_o`` output is tied to MAchineMode -| ``tvm_o`` output is tied to 0 -| ``tw_o`` output is tied to 0 -| ``tsr_o`` output is tied to 0 -| As RVH = False, -| ``v_o`` output is tied to 0 -| ``vfs_o`` output is tied to 0 -| ``en_g_translation_o`` output is tied to 0 -| ``en_ld_st_g_translation_o`` output is tied to 0 -| ``ld_st_v_o`` output is tied to 0 -| ``csr_hs_ld_st_inst_i`` input is tied to 0 -| ``vs_sum_o`` output is tied to 0 -| ``vmxr_o`` output is tied to 0 -| ``vsatp_ppn_o`` output is tied to 0 -| ``vs_asid_o`` output is tied to 0 -| ``hgatp_ppn_o`` output is tied to 0 -| ``vmid_o`` output is tied to 0 -| ``vtw_o`` output is tied to 0 -| ``hu_o`` output is tied to 0 -| As RVV = False, -| ``vs_o`` output is tied to 0 -| As RVS = False, -| ``en_translation_o`` output is tied to 0 -| ``en_ld_st_translation_o`` output is tied to 0 -| ``sum_o`` output is tied to 0 -| ``mxr_o`` output is tied to 0 -| ``satp_ppn_o`` output is tied to 0 -| ``asid_o`` output is tied to 0 -| As DebugEn = False, -| ``debug_req_i`` input is tied to 0 -| ``set_debug_pc_o`` output is tied to 0 -| ``debug_mode_o`` output is tied to 0 -| ``single_step_o`` output is tied to 0 -| As PerfCounterEn = 0, -| ``perf_addr_o`` output is tied to 0 -| ``perf_data_o`` output is tied to 0 -| ``perf_data_i`` input is tied to 0 -| ``perf_we_o`` output is tied to 0 -| ``mcountinhibit_o`` output is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_cva6.adoc b/docs/04_cv32a65x/design/source/port_cva6.adoc new file mode 100644 index 0000000000..e7fc817ddc --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_cva6.adoc @@ -0,0 +1,46 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_cva6_ports]] + +.*cva6 module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`boot_addr_i` | in | Reset boot address | SUBSYSTEM | logic[CVA6Cfg.VLEN-1:0] + +|`hart_id_i` | in | Hard ID reflected as CSR | SUBSYSTEM | logic[CVA6Cfg.XLEN-1:0] + +|`irq_i` | in | Level sensitive (async) interrupts | SUBSYSTEM | logic[1:0] + +|`ipi_i` | in | Inter-processor (async) interrupt | SUBSYSTEM | logic + +|`time_irq_i` | in | Timer (async) interrupt | SUBSYSTEM | logic + +|`cvxif_req_o` | out | CVXIF request | SUBSYSTEM | cvxif_req_t + +|`cvxif_resp_i` | in | CVXIF response | SUBSYSTEM | cvxif_resp_t + +|`noc_req_o` | out | noc request, can be AXI or OpenPiton | SUBSYSTEM | noc_req_t + +|`noc_resp_i` | in | noc response, can be AXI or OpenPiton | SUBSYSTEM | noc_resp_t + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As DebugEn = False,:: +* `debug_req_i` input is tied to 0 +As IsRVFI = 0,:: +* `rvfi_probes_o` output is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_cva6.rst b/docs/04_cv32a65x/design/source/port_cva6.rst deleted file mode 100644 index 5d9fa282aa..0000000000 --- a/docs/04_cv32a65x/design/source/port_cva6.rst +++ /dev/null @@ -1,93 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_cva6_ports: - -.. list-table:: **cva6 module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``boot_addr_i`` - - in - - Reset boot address - - SUBSYSTEM - - logic[CVA6Cfg.VLEN-1:0] - - * - ``hart_id_i`` - - in - - Hard ID reflected as CSR - - SUBSYSTEM - - logic[CVA6Cfg.XLEN-1:0] - - * - ``irq_i`` - - in - - Level sensitive (async) interrupts - - SUBSYSTEM - - logic[1:0] - - * - ``ipi_i`` - - in - - Inter-processor (async) interrupt - - SUBSYSTEM - - logic - - * - ``time_irq_i`` - - in - - Timer (async) interrupt - - SUBSYSTEM - - logic - - * - ``cvxif_req_o`` - - out - - CVXIF request - - SUBSYSTEM - - cvxif_req_t - - * - ``cvxif_resp_i`` - - in - - CVXIF response - - SUBSYSTEM - - cvxif_resp_t - - * - ``noc_req_o`` - - out - - noc request, can be AXI or OpenPiton - - SUBSYSTEM - - noc_req_t - - * - ``noc_resp_i`` - - in - - noc response, can be AXI or OpenPiton - - SUBSYSTEM - - noc_resp_t - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As DebugEn = False, -| ``debug_req_i`` input is tied to 0 -| As IsRVFI = 0, -| ``rvfi_probes_o`` output is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_cva6_hpdcache_subsystem.adoc b/docs/04_cv32a65x/design/source/port_cva6_hpdcache_subsystem.adoc new file mode 100644 index 0000000000..bb2f5e43bf --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_cva6_hpdcache_subsystem.adoc @@ -0,0 +1,74 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_cva6_hpdcache_subsystem_ports]] + +.*cva6_hpdcache_subsystem module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`noc_req_o` | out | noc request, can be AXI or OpenPiton | SUBSYSTEM | noc_req_t + +|`noc_resp_i` | in | noc response, can be AXI or OpenPiton | SUBSYSTEM | noc_resp_t + +|`icache_en_i` | in | Instruction cache enable | CSR_REGFILE | logic + +|`icache_flush_i` | in | Flush the instruction cache | CONTROLLER | logic + +|`icache_areq_i` | in | Input address translation request | EX_STAGE | icache_areq_t + +|`icache_areq_o` | out | Output address translation request | EX_STAGE | icache_arsp_t + +|`icache_dreq_i` | in | Input data translation request | FRONTEND | icache_dreq_t + +|`icache_dreq_o` | out | Output data translation request | FRONTEND | icache_drsp_t + +|`dcache_enable_i` | in | Data cache enable | CSR_REGFILE | logic + +|`dcache_flush_i` | in | Data cache flush | CONTROLLER | logic + +|`dcache_flush_ack_o` | out | Flush acknowledge | CONTROLLER | logic + +|`dcache_amo_req_i` | in | AMO request | EX_STAGE | ariane_pkg::amo_req_t + +|`dcache_amo_resp_o` | out | AMO response | EX_STAGE | ariane_pkg::amo_resp_t + +|`dcache_req_ports_i` | in | Data cache input request ports | EX_STAGE | dcache_req_i_t[NumPorts-1:0] + +|`dcache_req_ports_o` | out | Data cache output request ports | EX_STAGE | dcache_req_o_t[NumPorts-1:0] + +|`wbuffer_empty_o` | out | Write buffer status to know if empty | EX_STAGE | logic + +|`wbuffer_not_ni_o` | out | Write buffer status to know if not non idempotent | EX_STAGE | logic + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As PerfCounterEn = 0,:: +* `icache_miss_o` output is tied to 0 +* `dcache_miss_o` output is tied to 0 +For any HW configuration,:: +* `dcache_cmo_req_i` input is tied to 0 +* `dcache_cmo_resp_o` output is tied to open +* `hwpf_base_set_i` input is tied to 0 +* `hwpf_base_i` input is tied to 0 +* `hwpf_base_o` output is tied to 0 +* `hwpf_param_set_i` input is tied to 0 +* `hwpf_param_i` input is tied to 0 +* `hwpf_param_o` output is tied to 0 +* `hwpf_throttle_set_i` input is tied to 0 +* `hwpf_throttle_i` input is tied to 0 +* `hwpf_throttle_o` output is tied to 0 +* `hwpf_status_o` output is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_cva6_hpdcache_subsystem.rst b/docs/04_cv32a65x/design/source/port_cva6_hpdcache_subsystem.rst deleted file mode 100644 index 225dc34f64..0000000000 --- a/docs/04_cv32a65x/design/source/port_cva6_hpdcache_subsystem.rst +++ /dev/null @@ -1,153 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_cva6_hpdcache_subsystem_ports: - -.. list-table:: **cva6_hpdcache_subsystem module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``noc_req_o`` - - out - - noc request, can be AXI or OpenPiton - - SUBSYSTEM - - noc_req_t - - * - ``noc_resp_i`` - - in - - noc response, can be AXI or OpenPiton - - SUBSYSTEM - - noc_resp_t - - * - ``icache_en_i`` - - in - - Instruction cache enable - - CSR_REGFILE - - logic - - * - ``icache_flush_i`` - - in - - Flush the instruction cache - - CONTROLLER - - logic - - * - ``icache_areq_i`` - - in - - Input address translation request - - EX_STAGE - - icache_areq_t - - * - ``icache_areq_o`` - - out - - Output address translation request - - EX_STAGE - - icache_arsp_t - - * - ``icache_dreq_i`` - - in - - Input data translation request - - FRONTEND - - icache_dreq_t - - * - ``icache_dreq_o`` - - out - - Output data translation request - - FRONTEND - - icache_drsp_t - - * - ``dcache_enable_i`` - - in - - Data cache enable - - CSR_REGFILE - - logic - - * - ``dcache_flush_i`` - - in - - Data cache flush - - CONTROLLER - - logic - - * - ``dcache_flush_ack_o`` - - out - - Flush acknowledge - - CONTROLLER - - logic - - * - ``dcache_amo_req_i`` - - in - - AMO request - - EX_STAGE - - ariane_pkg::amo_req_t - - * - ``dcache_amo_resp_o`` - - out - - AMO response - - EX_STAGE - - ariane_pkg::amo_resp_t - - * - ``dcache_req_ports_i`` - - in - - Data cache input request ports - - EX_STAGE - - dcache_req_i_t[NumPorts-1:0] - - * - ``dcache_req_ports_o`` - - out - - Data cache output request ports - - EX_STAGE - - dcache_req_o_t[NumPorts-1:0] - - * - ``wbuffer_empty_o`` - - out - - Write buffer status to know if empty - - EX_STAGE - - logic - - * - ``wbuffer_not_ni_o`` - - out - - Write buffer status to know if not non idempotent - - EX_STAGE - - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As PerfCounterEn = 0, -| ``icache_miss_o`` output is tied to 0 -| ``dcache_miss_o`` output is tied to 0 -| For any HW configuration, -| ``dcache_cmo_req_i`` input is tied to 0 -| ``dcache_cmo_resp_o`` output is tied to open -| ``hwpf_base_set_i`` input is tied to 0 -| ``hwpf_base_i`` input is tied to 0 -| ``hwpf_base_o`` output is tied to 0 -| ``hwpf_param_set_i`` input is tied to 0 -| ``hwpf_param_i`` input is tied to 0 -| ``hwpf_param_o`` output is tied to 0 -| ``hwpf_throttle_set_i`` input is tied to 0 -| ``hwpf_throttle_i`` input is tied to 0 -| ``hwpf_throttle_o`` output is tied to 0 -| ``hwpf_status_o`` output is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_cvxif_fu.adoc b/docs/04_cv32a65x/design/source/port_cvxif_fu.adoc new file mode 100644 index 0000000000..8a7e4b8e54 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_cvxif_fu.adoc @@ -0,0 +1,50 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_cvxif_fu_ports]] + +.*cvxif_fu module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`x_valid_i` | in | CVXIF instruction is valid | ISSUE_STAGE | logic + +|`x_trans_id_i` | in | Transaction ID | ISSUE_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`x_illegal_i` | in | Instruction is illegal, determined during CVXIF issue transaction | ISSUE_STAGE | logic + +|`x_off_instr_i` | in | Offloaded instruction | ISSUE_STAGE | logic[31:0] + +|`x_ready_o` | out | CVXIF is ready | ISSUE_STAGE | logic + +|`x_trans_id_o` | out | CVXIF result transaction ID | ISSUE_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`x_exception_o` | out | CVXIF exception | ISSUE_STAGE | exception_t + +|`x_result_o` | out | CVXIF FU result | ISSUE_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`x_valid_o` | out | CVXIF result valid | ISSUE_STAGE | logic + +|`x_we_o` | out | CVXIF write enable | ISSUE_STAGE | logic + +|`x_rd_o` | out | CVXIF destination register | ISSUE_STAGE | logic[4:0] + +|`result_valid_i` | in | none | none | logic + +|`result_i` | in | none | none | x_result_t + +|`result_ready_o` | out | none | none | logic + +|=== + diff --git a/docs/04_cv32a65x/design/source/port_cvxif_fu.rst b/docs/04_cv32a65x/design/source/port_cvxif_fu.rst deleted file mode 100644 index 7e481a15a4..0000000000 --- a/docs/04_cv32a65x/design/source/port_cvxif_fu.rst +++ /dev/null @@ -1,103 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_cvxif_fu_ports: - -.. list-table:: **cvxif_fu module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``fu_data_i`` - - in - - FU data needed to execute instruction - - ISSUE_STAGE - - fu_data_t - - * - ``x_valid_i`` - - in - - CVXIF instruction is valid - - ISSUE_STAGE - - logic - - * - ``x_ready_o`` - - out - - CVXIF is ready - - ISSUE_STAGE - - logic - - * - ``x_off_instr_i`` - - in - - Offloaded instruction - - ISSUE_STAGE - - logic[31:0] - - * - ``x_trans_id_o`` - - out - - CVXIF transaction ID - - ISSUE_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``x_exception_o`` - - out - - CVXIF exception - - ISSUE_STAGE - - exception_t - - * - ``x_result_o`` - - out - - CVXIF FU result - - ISSUE_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``x_valid_o`` - - out - - CVXIF result valid - - ISSUE_STAGE - - logic - - * - ``x_we_o`` - - out - - CVXIF write enable - - ISSUE_STAGE - - logic - - * - ``cvxif_req_o`` - - out - - CVXIF request - - SUBSYSTEM - - cvxif_pkg::cvxif_req_t - - * - ``cvxif_resp_i`` - - in - - CVXIF response - - SUBSYSTEM - - cvxif_pkg::cvxif_resp_t - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As PRIV = MachineOnly, -| ``priv_lvl_i`` input is tied to MachineMode - diff --git a/docs/04_cv32a65x/design/source/port_decoder.adoc b/docs/04_cv32a65x/design/source/port_decoder.adoc new file mode 100644 index 0000000000..6efc8f9671 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_decoder.adoc @@ -0,0 +1,68 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_decoder_ports]] + +.*decoder module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`pc_i` | in | PC from fetch stage | FRONTEND | logic[CVA6Cfg.VLEN-1:0] + +|`is_compressed_i` | in | Is a compressed instruction | compressed_decoder | logic + +|`compressed_instr_i` | in | Compressed form of instruction | FRONTEND | logic[15:0] + +|`is_illegal_i` | in | Illegal compressed instruction | compressed_decoder | logic + +|`instruction_i` | in | Instruction from fetch stage | FRONTEND | logic[31:0] + +|`is_macro_instr_i` | in | Is a macro instruction | macro_decoder | logic + +|`is_last_macro_instr_i` | in | Is a last macro instruction | macro_decoder | logic + +|`is_double_rd_macro_instr_i` | in | Is mvsa01/mva01s macro instruction | macro_decoder | logic + +|`branch_predict_i` | in | Is a branch predict instruction | FRONTEND | branchpredict_sbe_t + +|`ex_i` | in | If an exception occured in fetch stage | FRONTEND | exception_t + +|`irq_i` | in | Level sensitive (async) interrupts | SUBSYSTEM | logic[1:0] + +|`irq_ctrl_i` | in | Interrupt control status | CSR_REGFILE | irq_ctrl_t + +|`instruction_o` | out | Instruction to be added to scoreboard entry | ISSUE_STAGE | scoreboard_entry_t + +|`orig_instr_o` | out | Instruction | ISSUE_STAGE | logic[31:0] + +|`is_control_flow_instr_o` | out | Is a control flow instruction | ISSUE_STAGE | logic + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As DebugEn = False,:: +* `debug_req_i` input is tied to 0 +* `debug_mode_i` input is tied to 0 +As PRIV = MachineOnly,:: +* `priv_lvl_i` input is tied to MachineMode +* `tvm_i` input is tied to 0 +* `tw_i` input is tied to 0 +* `tsr_i` input is tied to 0 +As RVH = False,:: +* `v_i` input is tied to 0 +* `vfs_i` input is tied to 0 +* `vtw_i` input is tied to 0 +* `hu_i` input is tied to 0 +As RVF = 0,:: +* `fs_i` input is tied to 0 +* `frm_i` input is tied to 0 +As RVV = False,:: +* `vs_i` input is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_decoder.rst b/docs/04_cv32a65x/design/source/port_decoder.rst deleted file mode 100644 index 424dd7861d..0000000000 --- a/docs/04_cv32a65x/design/source/port_decoder.rst +++ /dev/null @@ -1,131 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_decoder_ports: - -.. list-table:: **decoder module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``pc_i`` - - in - - PC from fetch stage - - FRONTEND - - logic[CVA6Cfg.VLEN-1:0] - - * - ``is_compressed_i`` - - in - - Is a compressed instruction - - compressed_decoder - - logic - - * - ``compressed_instr_i`` - - in - - Compressed form of instruction - - FRONTEND - - logic[15:0] - - * - ``is_illegal_i`` - - in - - Illegal compressed instruction - - compressed_decoder - - logic - - * - ``instruction_i`` - - in - - Instruction from fetch stage - - FRONTEND - - logic[31:0] - - * - ``is_macro_instr_i`` - - in - - Is a macro instruction - - macro_decoder - - logic - - * - ``is_last_macro_instr_i`` - - in - - Is a last macro instruction - - macro_decoder - - logic - - * - ``is_double_rd_macro_instr_i`` - - in - - Is mvsa01/mva01s macro instruction - - macro_decoder - - logic - - * - ``branch_predict_i`` - - in - - Is a branch predict instruction - - FRONTEND - - branchpredict_sbe_t - - * - ``ex_i`` - - in - - If an exception occured in fetch stage - - FRONTEND - - exception_t - - * - ``irq_i`` - - in - - Level sensitive (async) interrupts - - SUBSYSTEM - - logic[1:0] - - * - ``irq_ctrl_i`` - - in - - Interrupt control status - - CSR_REGFILE - - irq_ctrl_t - - * - ``instruction_o`` - - out - - Instruction to be added to scoreboard entry - - ISSUE_STAGE - - scoreboard_entry_t - - * - ``orig_instr_o`` - - out - - Instruction - - ISSUE_STAGE - - logic[31:0] - - * - ``is_control_flow_instr_o`` - - out - - Is a control flow instruction - - ISSUE_STAGE - - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As DebugEn = False, -| ``debug_req_i`` input is tied to 0 -| ``debug_mode_i`` input is tied to 0 -| As PRIV = MachineOnly, -| ``priv_lvl_i`` input is tied to MachineMode -| ``tvm_i`` input is tied to 0 -| ``tw_i`` input is tied to 0 -| ``tsr_i`` input is tied to 0 -| As RVH = False, -| ``v_i`` input is tied to 0 -| ``vfs_i`` input is tied to 0 -| ``vtw_i`` input is tied to 0 -| ``hu_i`` input is tied to 0 -| As RVF = 0, -| ``fs_i`` input is tied to 0 -| ``frm_i`` input is tied to 0 -| As RVV = False, -| ``vs_i`` input is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_ex_stage.adoc b/docs/04_cv32a65x/design/source/port_ex_stage.adoc new file mode 100644 index 0000000000..8473147904 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_ex_stage.adoc @@ -0,0 +1,189 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_ex_stage_ports]] + +.*ex_stage module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`flush_i` | in | Fetch flush request | CONTROLLER | logic + +|`rs1_forwarding_i` | in | rs1 forwarding | ISSUE_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] + +|`rs2_forwarding_i` | in | rs2 forwarding | ISSUE_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] + +|`fu_data_i` | in | FU data useful to execute instruction | ISSUE_STAGE | fu_data_t[CVA6Cfg.NrIssuePorts-1:0] + +|`pc_i` | in | PC of the current instruction | ISSUE_STAGE | logic[CVA6Cfg.VLEN-1:0] + +|`is_compressed_instr_i` | in | Report whether instruction is compressed | ISSUE_STAGE | logic + +|`flu_result_o` | out | Fixed Latency Unit result | ISSUE_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`flu_trans_id_o` | out | ID of the scoreboard entry at which a=to write back | ISSUE_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`flu_exception_o` | out | Fixed Latency Unit exception | ISSUE_STAGE | exception_t + +|`flu_ready_o` | out | FLU is ready | ISSUE_STAGE | logic + +|`flu_valid_o` | out | FLU result is valid | ISSUE_STAGE | logic + +|`alu_valid_i` | in | ALU instruction is valid | ISSUE_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`branch_valid_i` | in | Branch unit instruction is valid | ISSUE_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`branch_predict_i` | in | Information of branch prediction | ISSUE_STAGE | branchpredict_sbe_t + +|`resolved_branch_o` | out | The branch engine uses the write back from the ALU | several_modules | bp_resolve_t + +|`resolve_branch_o` | out | Signaling that we resolved the branch | ISSUE_STAGE | logic + +|`csr_valid_i` | in | CSR instruction is valid | ISSUE_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`csr_addr_o` | out | CSR address to write | COMMIT_STAGE | logic[11:0] + +|`csr_commit_i` | in | CSR commit | COMMIT_STAGE | logic + +|`mult_valid_i` | in | MULT instruction is valid | ISSUE_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`lsu_ready_o` | out | LSU is ready | ISSUE_STAGE | logic + +|`lsu_valid_i` | in | LSU instruction is valid | ISSUE_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`load_valid_o` | out | Load result is valid | ISSUE_STAGE | logic + +|`load_result_o` | out | Load result valid | ISSUE_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`load_trans_id_o` | out | Load instruction ID | ISSUE_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`load_exception_o` | out | Exception generated by load instruction | ISSUE_STAGE | exception_t + +|`store_valid_o` | out | Store result is valid | ISSUe_STAGE | logic + +|`store_result_o` | out | Store result | ISSUE_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`store_trans_id_o` | out | Store instruction ID | ISSUE_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`store_exception_o` | out | Exception generated by store instruction | ISSUE_STAGE | exception_t + +|`lsu_commit_i` | in | LSU commit | COMMIT_STAGE | logic + +|`lsu_commit_ready_o` | out | Commit queue ready to accept another commit request | COMMIT_STAGE | logic + +|`commit_tran_id_i` | in | Commit transaction ID | COMMIT_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`no_st_pending_o` | out | TO_BE_COMPLETED | COMMIT_STAGE | logic + +|`alu2_valid_i` | in | ALU2 instruction is valid | ISSUE_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`x_valid_i` | in | CVXIF instruction is valid | ISSUE_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`x_ready_o` | out | CVXIF is ready | ISSUE_STAGE | logic + +|`x_off_instr_i` | in | none | none | logic[31:0] + +|`x_trans_id_o` | out | CVXIF transaction ID | ISSUE_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`x_exception_o` | out | CVXIF exception | ISSUE_STAGE | exception_t + +|`x_result_o` | out | CVXIF result | ISSUE_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`x_valid_o` | out | CVXIF result valid | ISSUE_STAGE | logic + +|`x_we_o` | out | CVXIF write enable | ISSUE_STAGE | logic + +|`x_rd_o` | out | CVXIF destination register | ISSUE_STAGE | logic[4:0] + +|`x_result_valid_i` | in | CVXIF Result interface | SUBSYSTEM | logic + +|`x_result_i` | in | none | none | x_result_t + +|`x_result_ready_o` | out | none | none | logic + +|`x_transaction_rejected_i` | in | CVXIF Issue transaction rejected -> illegal instruction | ISSUE_STAGE | logic + +|`icache_areq_i` | in | icache translation response | CACHE | icache_arsp_t + +|`icache_areq_o` | out | icache translation request | CACHE | icache_areq_t + +|`dcache_req_ports_i` | in | Data cache request ouput | CACHE | dcache_req_o_t[2:0] + +|`dcache_req_ports_o` | out | Data cache request input | CACHE | dcache_req_i_t[2:0] + +|`dcache_wbuffer_empty_i` | in | Write buffer is empty | CACHE | logic + +|`dcache_wbuffer_not_ni_i` | in | TO_BE_COMPLETED | CACHE | logic + +|`pmpcfg_i` | in | Report the PMP configuration | CSR_REGFILE | riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries:0] + +|`pmpaddr_i` | in | Report the PMP addresses | CSR_REGFILE | logic[CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As DebugEn = False,:: +* `debug_mode_i` input is tied to 0 +As RVH = False,:: +* `tinst_i` input is tied to 0 +* `enable_g_translation_i` input is tied to 0 +* `en_ld_st_g_translation_i` input is tied to 0 +* `flush_tlb_vvma_i` input is tied to 0 +* `flush_tlb_gvma_i` input is tied to 0 +* `v_i` input is tied to 0 +* `ld_st_v_i` input is tied to 0 +* `csr_hs_ld_st_inst_o` output is tied to 0 +* `vs_sum_i` input is tied to 0 +* `vmxr_i` input is tied to 0 +* `vsatp_ppn_i` input is tied to 0 +* `vs_asid_i` input is tied to 0 +* `hgatp_ppn_i` input is tied to 0 +* `vmid_i` input is tied to 0 +As EnableAccelerator = 0,:: +* `stall_st_pending_i` input is tied to 0 +* `acc_valid_i` input is tied to 0 +As RVA = False,:: +* `amo_valid_commit_i` input is tied to 0 +* `amo_req_o` output is tied to 0 +* `amo_resp_i` input is tied to 0 +As RVF = 0,:: +* `fpu_ready_o` output is tied to 0 +* `fpu_valid_i` input is tied to 0 +* `fpu_fmt_i` input is tied to 0 +* `fpu_rm_i` input is tied to 0 +* `fpu_frm_i` input is tied to 0 +* `fpu_prec_i` input is tied to 0 +* `fpu_trans_id_o` output is tied to 0 +* `fpu_result_o` output is tied to 0 +* `fpu_valid_o` output is tied to 0 +* `fpu_exception_o` output is tied to 0 +As RVS = False,:: +* `enable_translation_i` input is tied to 0 +* `en_ld_st_translation_i` input is tied to 0 +* `sum_i` input is tied to 0 +* `mxr_i` input is tied to 0 +* `satp_ppn_i` input is tied to 0 +* `asid_i` input is tied to 0 +As MMUPresent = 0,:: +* `flush_tlb_i` input is tied to 0 +As PRIV = MachineOnly,:: +* `priv_lvl_i` input is tied to MachineMode +* `ld_st_priv_lvl_i` input is tied to MAchineMode +As PerfCounterEn = 0,:: +* `itlb_miss_o` output is tied to 0 +* `dtlb_miss_o` output is tied to 0 +As IsRVFI = 0,:: +* `rvfi_lsu_ctrl_o` output is tied to 0 +* `rvfi_mem_paddr_o` output is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_ex_stage.rst b/docs/04_cv32a65x/design/source/port_ex_stage.rst deleted file mode 100644 index 18a84056f5..0000000000 --- a/docs/04_cv32a65x/design/source/port_ex_stage.rst +++ /dev/null @@ -1,406 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_ex_stage_ports: - -.. list-table:: **ex_stage module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``flush_i`` - - in - - Fetch flush request - - CONTROLLER - - logic - - * - ``rs1_forwarding_i`` - - in - - rs1 forwarding - - ISSUE_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] - - * - ``rs2_forwarding_i`` - - in - - rs2 forwarding - - ISSUE_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] - - * - ``fu_data_i`` - - in - - FU data useful to execute instruction - - ISSUE_STAGE - - fu_data_t[CVA6Cfg.NrIssuePorts-1:0] - - * - ``pc_i`` - - in - - PC of the current instruction - - ISSUE_STAGE - - logic[CVA6Cfg.VLEN-1:0] - - * - ``is_compressed_instr_i`` - - in - - Report whether instruction is compressed - - ISSUE_STAGE - - logic - - * - ``flu_result_o`` - - out - - Fixed Latency Unit result - - ISSUE_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``flu_trans_id_o`` - - out - - ID of the scoreboard entry at which a=to write back - - ISSUE_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``flu_exception_o`` - - out - - Fixed Latency Unit exception - - ISSUE_STAGE - - exception_t - - * - ``flu_ready_o`` - - out - - FLU is ready - - ISSUE_STAGE - - logic - - * - ``flu_valid_o`` - - out - - FLU result is valid - - ISSUE_STAGE - - logic - - * - ``alu_valid_i`` - - in - - ALU instruction is valid - - ISSUE_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``branch_valid_i`` - - in - - Branch unit instruction is valid - - ISSUE_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``branch_predict_i`` - - in - - Information of branch prediction - - ISSUE_STAGE - - branchpredict_sbe_t - - * - ``resolved_branch_o`` - - out - - The branch engine uses the write back from the ALU - - several_modules - - bp_resolve_t - - * - ``resolve_branch_o`` - - out - - Signaling that we resolved the branch - - ISSUE_STAGE - - logic - - * - ``csr_valid_i`` - - in - - CSR instruction is valid - - ISSUE_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``csr_addr_o`` - - out - - CSR address to write - - COMMIT_STAGE - - logic[11:0] - - * - ``csr_commit_i`` - - in - - CSR commit - - COMMIT_STAGE - - logic - - * - ``mult_valid_i`` - - in - - MULT instruction is valid - - ISSUE_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``lsu_ready_o`` - - out - - LSU is ready - - ISSUE_STAGE - - logic - - * - ``lsu_valid_i`` - - in - - LSU instruction is valid - - ISSUE_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``load_valid_o`` - - out - - Load result is valid - - ISSUE_STAGE - - logic - - * - ``load_result_o`` - - out - - Load result valid - - ISSUE_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``load_trans_id_o`` - - out - - Load instruction ID - - ISSUE_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``load_exception_o`` - - out - - Exception generated by load instruction - - ISSUE_STAGE - - exception_t - - * - ``store_valid_o`` - - out - - Store result is valid - - ISSUe_STAGE - - logic - - * - ``store_result_o`` - - out - - Store result - - ISSUE_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``store_trans_id_o`` - - out - - Store instruction ID - - ISSUE_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``store_exception_o`` - - out - - Exception generated by store instruction - - ISSUE_STAGE - - exception_t - - * - ``lsu_commit_i`` - - in - - LSU commit - - COMMIT_STAGE - - logic - - * - ``lsu_commit_ready_o`` - - out - - Commit queue ready to accept another commit request - - COMMIT_STAGE - - logic - - * - ``commit_tran_id_i`` - - in - - Commit transaction ID - - COMMIT_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``no_st_pending_o`` - - out - - TO_BE_COMPLETED - - COMMIT_STAGE - - logic - - * - ``alu2_valid_i`` - - in - - ALU2 instruction is valid - - ISSUE_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``x_valid_i`` - - in - - CVXIF instruction is valid - - ISSUE_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``x_ready_o`` - - out - - CVXIF is ready - - ISSUE_STAGE - - logic - - * - ``x_off_instr_i`` - - in - - undecoded instruction - - ISSUE_STAGE - - logic[31:0] - - * - ``x_trans_id_o`` - - out - - CVXIF transaction ID - - ISSUE_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``x_exception_o`` - - out - - CVXIF exception - - ISSUE_STAGE - - exception_t - - * - ``x_result_o`` - - out - - CVXIF result - - ISSUE_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``x_valid_o`` - - out - - CVXIF result valid - - ISSUE_STAGE - - logic - - * - ``x_we_o`` - - out - - CVXIF write enable - - ISSUE_STAGE - - logic - - * - ``cvxif_req_o`` - - out - - CVXIF request - - SUBSYSTEM - - cvxif_pkg::cvxif_req_t - - * - ``cvxif_resp_i`` - - in - - CVXIF response - - SUBSYSTEM - - cvxif_pkg::cvxif_resp_t - - * - ``icache_areq_i`` - - in - - icache translation response - - CACHE - - icache_arsp_t - - * - ``icache_areq_o`` - - out - - icache translation request - - CACHE - - icache_areq_t - - * - ``dcache_req_ports_i`` - - in - - Data cache request ouput - - CACHE - - dcache_req_o_t[2:0] - - * - ``dcache_req_ports_o`` - - out - - Data cache request input - - CACHE - - dcache_req_i_t[2:0] - - * - ``dcache_wbuffer_empty_i`` - - in - - Write buffer is empty - - CACHE - - logic - - * - ``dcache_wbuffer_not_ni_i`` - - in - - TO_BE_COMPLETED - - CACHE - - logic - - * - ``pmpcfg_i`` - - in - - Report the PMP configuration - - CSR_REGFILE - - riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries:0] - - * - ``pmpaddr_i`` - - in - - Report the PMP addresses - - CSR_REGFILE - - logic[CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As DebugEn = False, -| ``debug_mode_i`` input is tied to 0 -| As RVH = False, -| ``tinst_i`` input is tied to 0 -| ``enable_g_translation_i`` input is tied to 0 -| ``en_ld_st_g_translation_i`` input is tied to 0 -| ``flush_tlb_vvma_i`` input is tied to 0 -| ``flush_tlb_gvma_i`` input is tied to 0 -| ``v_i`` input is tied to 0 -| ``ld_st_v_i`` input is tied to 0 -| ``csr_hs_ld_st_inst_o`` output is tied to 0 -| ``vs_sum_i`` input is tied to 0 -| ``vmxr_i`` input is tied to 0 -| ``vsatp_ppn_i`` input is tied to 0 -| ``vs_asid_i`` input is tied to 0 -| ``hgatp_ppn_i`` input is tied to 0 -| ``vmid_i`` input is tied to 0 -| As EnableAccelerator = 0, -| ``stall_st_pending_i`` input is tied to 0 -| ``acc_valid_i`` input is tied to 0 -| As RVA = False, -| ``amo_valid_commit_i`` input is tied to 0 -| ``amo_req_o`` output is tied to 0 -| ``amo_resp_i`` input is tied to 0 -| As RVF = 0, -| ``fpu_ready_o`` output is tied to 0 -| ``fpu_valid_i`` input is tied to 0 -| ``fpu_fmt_i`` input is tied to 0 -| ``fpu_rm_i`` input is tied to 0 -| ``fpu_frm_i`` input is tied to 0 -| ``fpu_prec_i`` input is tied to 0 -| ``fpu_trans_id_o`` output is tied to 0 -| ``fpu_result_o`` output is tied to 0 -| ``fpu_valid_o`` output is tied to 0 -| ``fpu_exception_o`` output is tied to 0 -| As RVS = False, -| ``enable_translation_i`` input is tied to 0 -| ``en_ld_st_translation_i`` input is tied to 0 -| ``sum_i`` input is tied to 0 -| ``mxr_i`` input is tied to 0 -| ``satp_ppn_i`` input is tied to 0 -| ``asid_i`` input is tied to 0 -| As MMUPresent = 0, -| ``flush_tlb_i`` input is tied to 0 -| As PRIV = MachineOnly, -| ``priv_lvl_i`` input is tied to MachineMode -| ``ld_st_priv_lvl_i`` input is tied to MAchineMode -| As PerfCounterEn = 0, -| ``itlb_miss_o`` output is tied to 0 -| ``dtlb_miss_o`` output is tied to 0 -| As IsRVFI = 0, -| ``rvfi_lsu_ctrl_o`` output is tied to 0 -| ``rvfi_mem_paddr_o`` output is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_frontend.adoc b/docs/04_cv32a65x/design/source/port_frontend.adoc new file mode 100644 index 0000000000..2ee13da958 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_frontend.adoc @@ -0,0 +1,59 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_frontend_ports]] + +.*frontend module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`boot_addr_i` | in | Next PC when reset | SUBSYSTEM | logic[CVA6Cfg.VLEN-1:0] + +|`flush_i` | in | Flush requested by FENCE, mis-predict and exception | CONTROLLER | logic + +|`halt_i` | in | Halt requested by WFI and Accelerate port | CONTROLLER | logic + +|`set_pc_commit_i` | in | Set COMMIT PC as next PC requested by FENCE, CSR side-effect and Accelerate port | CONTROLLER | logic + +|`pc_commit_i` | in | COMMIT PC | COMMIT | logic[CVA6Cfg.VLEN-1:0] + +|`ex_valid_i` | in | Exception event | COMMIT | logic + +|`resolved_branch_i` | in | Mispredict event and next PC | EXECUTE | bp_resolve_t + +|`eret_i` | in | Return from exception event | CSR | logic + +|`epc_i` | in | Next PC when returning from exception | CSR | logic[CVA6Cfg.VLEN-1:0] + +|`trap_vector_base_i` | in | Next PC when jumping into exception | CSR | logic[CVA6Cfg.VLEN-1:0] + +|`icache_dreq_o` | out | Handshake between CACHE and FRONTEND (fetch) | CACHES | icache_dreq_t + +|`icache_dreq_i` | in | Handshake between CACHE and FRONTEND (fetch) | CACHES | icache_drsp_t + +|`fetch_entry_o` | out | Handshake's data between fetch and decode | ID_STAGE | fetch_entry_t[CVA6Cfg.NrIssuePorts-1:0] + +|`fetch_entry_valid_o` | out | Handshake's valid between fetch and decode | ID_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`fetch_entry_ready_i` | in | Handshake's ready between fetch and decode | ID_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +For any HW configuration,:: +* `flush_bp_i` input is tied to 0 +As DebugEn = False,:: +* `set_debug_pc_i` input is tied to 0 +* `debug_mode_i` input is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_frontend.rst b/docs/04_cv32a65x/design/source/port_frontend.rst deleted file mode 100644 index 2f715e294d..0000000000 --- a/docs/04_cv32a65x/design/source/port_frontend.rst +++ /dev/null @@ -1,130 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_frontend_ports: - -.. list-table:: **frontend module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``boot_addr_i`` - - in - - Next PC when reset - - SUBSYSTEM - - logic[CVA6Cfg.VLEN-1:0] - - * - ``flush_i`` - - in - - Flush requested by FENCE, mis-predict and exception - - CONTROLLER - - logic - - * - ``halt_i`` - - in - - Halt requested by WFI and Accelerate port - - CONTROLLER - - logic - - * - ``set_pc_commit_i`` - - in - - Set COMMIT PC as next PC requested by FENCE, CSR side-effect and Accelerate port - - CONTROLLER - - logic - - * - ``pc_commit_i`` - - in - - COMMIT PC - - COMMIT - - logic[CVA6Cfg.VLEN-1:0] - - * - ``ex_valid_i`` - - in - - Exception event - - COMMIT - - logic - - * - ``resolved_branch_i`` - - in - - Mispredict event and next PC - - EXECUTE - - bp_resolve_t - - * - ``eret_i`` - - in - - Return from exception event - - CSR - - logic - - * - ``epc_i`` - - in - - Next PC when returning from exception - - CSR - - logic[CVA6Cfg.VLEN-1:0] - - * - ``trap_vector_base_i`` - - in - - Next PC when jumping into exception - - CSR - - logic[CVA6Cfg.VLEN-1:0] - - * - ``icache_dreq_o`` - - out - - Handshake between CACHE and FRONTEND (fetch) - - CACHES - - icache_dreq_t - - * - ``icache_dreq_i`` - - in - - Handshake between CACHE and FRONTEND (fetch) - - CACHES - - icache_drsp_t - - * - ``fetch_entry_o`` - - out - - Handshake's data between fetch and decode - - ID_STAGE - - fetch_entry_t[CVA6Cfg.NrIssuePorts-1:0] - - * - ``fetch_entry_valid_o`` - - out - - Handshake's valid between fetch and decode - - ID_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``fetch_entry_ready_i`` - - in - - Handshake's ready between fetch and decode - - ID_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| For any HW configuration, -| ``flush_bp_i`` input is tied to 0 -| As DebugEn = False, -| ``set_debug_pc_i`` input is tied to 0 -| ``debug_mode_i`` input is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_id_stage.adoc b/docs/04_cv32a65x/design/source/port_id_stage.adoc new file mode 100644 index 0000000000..82538a3b41 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_id_stage.adoc @@ -0,0 +1,76 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_id_stage_ports]] + +.*id_stage module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`flush_i` | in | Fetch flush request | CONTROLLER | logic + +|`fetch_entry_i` | in | Handshake's data between fetch and decode | FRONTEND | fetch_entry_t[CVA6Cfg.NrIssuePorts-1:0] + +|`fetch_entry_valid_i` | in | Handshake's valid between fetch and decode | FRONTEND | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`fetch_entry_ready_o` | out | Handshake's ready between fetch and decode | FRONTEND | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`issue_entry_o` | out | Handshake's data between decode and issue | ISSUE | scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0] + +|`orig_instr_o` | out | Instruction value | ISSUE | logic[CVA6Cfg.NrIssuePorts-1:0][31:0] + +|`issue_entry_valid_o` | out | Handshake's valid between decode and issue | ISSUE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`is_ctrl_flow_o` | out | Report if instruction is a control flow instruction | ISSUE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`issue_instr_ack_i` | in | Handshake's acknowlege between decode and issue | ISSUE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`irq_i` | in | Level sensitive (async) interrupts | SUBSYSTEM | logic[1:0] + +|`irq_ctrl_i` | in | Interrupt control status | CSR_REGFILE | irq_ctrl_t + +|`hart_id_i` | in | none | none | logic[CVA6Cfg.XLEN-1:0] + +|`compressed_ready_i` | in | none | none | logic + +|`compressed_resp_i` | in | none | none | x_compressed_resp_t + +|`compressed_valid_o` | out | none | none | logic + +|`compressed_req_o` | out | none | none | x_compressed_req_t + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As DebugEn = False,:: +* `debug_req_i` input is tied to 0 +* `debug_mode_i` input is tied to 0 +As IsRVFI = 0,:: +* `rvfi_is_compressed_o` output is tied to 0 +As PRIV = MachineOnly,:: +* `priv_lvl_i` input is tied to MachineMode +* `tvm_i` input is tied to 0 +* `tw_i` input is tied to 0 +* `tsr_i` input is tied to 0 +As RVH = False,:: +* `v_i` input is tied to 0 +* `vfs_i` input is tied to 0 +* `vtw_i` input is tied to 0 +* `hu_i` input is tied to 0 +As RVF = 0,:: +* `fs_i` input is tied to 0 +* `frm_i` input is tied to 0 +As RVV = False,:: +* `vs_i` input is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_id_stage.rst b/docs/04_cv32a65x/design/source/port_id_stage.rst deleted file mode 100644 index f7a4b0c799..0000000000 --- a/docs/04_cv32a65x/design/source/port_id_stage.rst +++ /dev/null @@ -1,121 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_id_stage_ports: - -.. list-table:: **id_stage module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``flush_i`` - - in - - Fetch flush request - - CONTROLLER - - logic - - * - ``fetch_entry_i`` - - in - - Handshake's data between fetch and decode - - FRONTEND - - fetch_entry_t[CVA6Cfg.NrIssuePorts-1:0] - - * - ``fetch_entry_valid_i`` - - in - - Handshake's valid between fetch and decode - - FRONTEND - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``fetch_entry_ready_o`` - - out - - Handshake's ready between fetch and decode - - FRONTEND - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``issue_entry_o`` - - out - - Handshake's data between decode and issue - - ISSUE - - scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0] - - * - ``orig_instr_o`` - - out - - Instruction value - - ISSUE - - logic[CVA6Cfg.NrIssuePorts-1:0][31:0] - - * - ``issue_entry_valid_o`` - - out - - Handshake's valid between decode and issue - - ISSUE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``is_ctrl_flow_o`` - - out - - Report if instruction is a control flow instruction - - ISSUE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``issue_instr_ack_i`` - - in - - Handshake's acknowlege between decode and issue - - ISSUE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``irq_i`` - - in - - Level sensitive (async) interrupts - - SUBSYSTEM - - logic[1:0] - - * - ``irq_ctrl_i`` - - in - - Interrupt control status - - CSR_REGFILE - - irq_ctrl_t - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As DebugEn = False, -| ``debug_req_i`` input is tied to 0 -| ``debug_mode_i`` input is tied to 0 -| As IsRVFI = 0, -| ``rvfi_is_compressed_o`` output is tied to 0 -| As PRIV = MachineOnly, -| ``priv_lvl_i`` input is tied to MachineMode -| ``tvm_i`` input is tied to 0 -| ``tw_i`` input is tied to 0 -| ``tsr_i`` input is tied to 0 -| As RVH = False, -| ``v_i`` input is tied to 0 -| ``vfs_i`` input is tied to 0 -| ``vtw_i`` input is tied to 0 -| ``hu_i`` input is tied to 0 -| As RVF = 0, -| ``fs_i`` input is tied to 0 -| ``frm_i`` input is tied to 0 -| As RVV = False, -| ``vs_i`` input is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_instr_queue.adoc b/docs/04_cv32a65x/design/source/port_instr_queue.adoc new file mode 100644 index 0000000000..7c796313f4 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_instr_queue.adoc @@ -0,0 +1,58 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_instr_queue_ports]] + +.*instr_queue module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`flush_i` | in | Fetch flush request | CONTROLLER | logic + +|`instr_i` | in | Instruction | instr_realign | logic[CVA6Cfg.INSTR_PER_FETCH-1:0][31:0] + +|`addr_i` | in | Instruction address | instr_realign | logic[CVA6Cfg.INSTR_PER_FETCH-1:0][CVA6Cfg.VLEN-1:0] + +|`valid_i` | in | Instruction is valid | instr_realign | logic[CVA6Cfg.INSTR_PER_FETCH-1:0] + +|`ready_o` | out | Handshake’s ready with CACHE | CACHE | logic + +|`consumed_o` | out | Indicates instructions consummed, or popped by ID_STAGE | FRONTEND | logic[CVA6Cfg.INSTR_PER_FETCH-1:0] + +|`exception_i` | in | Exception (which is page-table fault) | CACHE | ariane_pkg::frontend_exception_t + +|`exception_addr_i` | in | Exception address | CACHE | logic[CVA6Cfg.VLEN-1:0] + +|`predict_address_i` | in | Branch predict | FRONTEND | logic[CVA6Cfg.VLEN-1:0] + +|`cf_type_i` | in | Instruction predict address | FRONTEND | ariane_pkg::cf_t[CVA6Cfg.INSTR_PER_FETCH-1:0] + +|`replay_o` | out | Replay instruction because one of the FIFO was full | FRONTEND | logic + +|`replay_addr_o` | out | Address at which to replay the fetch | FRONTEND | logic[CVA6Cfg.VLEN-1:0] + +|`fetch_entry_o` | out | Handshake’s data with ID_STAGE | ID_STAGE | fetch_entry_t[CVA6Cfg.NrIssuePorts-1:0] + +|`fetch_entry_valid_o` | out | Handshake’s valid with ID_STAGE | ID_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`fetch_entry_ready_i` | in | Handshake’s ready with ID_STAGE | ID_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As RVH = False,:: +* `exception_gpaddr_i` input is tied to 0 +* `exception_tinst_i` input is tied to 0 +* `exception_gva_i` input is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_instr_queue.rst b/docs/04_cv32a65x/design/source/port_instr_queue.rst deleted file mode 100644 index 5217fcd227..0000000000 --- a/docs/04_cv32a65x/design/source/port_instr_queue.rst +++ /dev/null @@ -1,129 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_instr_queue_ports: - -.. list-table:: **instr_queue module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``flush_i`` - - in - - Fetch flush request - - CONTROLLER - - logic - - * - ``instr_i`` - - in - - Instruction - - instr_realign - - logic[CVA6Cfg.INSTR_PER_FETCH-1:0][31:0] - - * - ``addr_i`` - - in - - Instruction address - - instr_realign - - logic[CVA6Cfg.INSTR_PER_FETCH-1:0][CVA6Cfg.VLEN-1:0] - - * - ``valid_i`` - - in - - Instruction is valid - - instr_realign - - logic[CVA6Cfg.INSTR_PER_FETCH-1:0] - - * - ``ready_o`` - - out - - Handshake’s ready with CACHE - - CACHE - - logic - - * - ``consumed_o`` - - out - - Indicates instructions consummed, or popped by ID_STAGE - - FRONTEND - - logic[CVA6Cfg.INSTR_PER_FETCH-1:0] - - * - ``exception_i`` - - in - - Exception (which is page-table fault) - - CACHE - - ariane_pkg::frontend_exception_t - - * - ``exception_addr_i`` - - in - - Exception address - - CACHE - - logic[CVA6Cfg.VLEN-1:0] - - * - ``predict_address_i`` - - in - - Branch predict - - FRONTEND - - logic[CVA6Cfg.VLEN-1:0] - - * - ``cf_type_i`` - - in - - Instruction predict address - - FRONTEND - - ariane_pkg::cf_t[CVA6Cfg.INSTR_PER_FETCH-1:0] - - * - ``replay_o`` - - out - - Replay instruction because one of the FIFO was full - - FRONTEND - - logic - - * - ``replay_addr_o`` - - out - - Address at which to replay the fetch - - FRONTEND - - logic[CVA6Cfg.VLEN-1:0] - - * - ``fetch_entry_o`` - - out - - Handshake’s data with ID_STAGE - - ID_STAGE - - fetch_entry_t[CVA6Cfg.NrIssuePorts-1:0] - - * - ``fetch_entry_valid_o`` - - out - - Handshake’s valid with ID_STAGE - - ID_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``fetch_entry_ready_i`` - - in - - Handshake’s ready with ID_STAGE - - ID_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As RVH = False, -| ``exception_gpaddr_i`` input is tied to 0 -| ``exception_tinst_i`` input is tied to 0 -| ``exception_gva_i`` input is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_instr_realign.adoc b/docs/04_cv32a65x/design/source/port_instr_realign.adoc new file mode 100644 index 0000000000..1e51e1afc5 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_instr_realign.adoc @@ -0,0 +1,38 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_instr_realign_ports]] + +.*instr_realign module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`flush_i` | in | Fetch flush request | CONTROLLER | logic + +|`valid_i` | in | 32-bit block is valid | CACHE | logic + +|`serving_unaligned_o` | out | Instruction is unaligned | FRONTEND | logic + +|`address_i` | in | 32-bit block address | CACHE | logic[CVA6Cfg.VLEN-1:0] + +|`data_i` | in | 32-bit block | CACHE | logic[CVA6Cfg.FETCH_WIDTH-1:0] + +|`valid_o` | out | instruction is valid | FRONTEND | logic[CVA6Cfg.INSTR_PER_FETCH-1:0] + +|`addr_o` | out | Instruction address | FRONTEND | logic[CVA6Cfg.INSTR_PER_FETCH-1:0][CVA6Cfg.VLEN-1:0] + +|`instr_o` | out | Instruction | instr_scan&instr_queue | logic[CVA6Cfg.INSTR_PER_FETCH-1:0][31:0] + +|=== + diff --git a/docs/04_cv32a65x/design/source/port_instr_realign.rst b/docs/04_cv32a65x/design/source/port_instr_realign.rst deleted file mode 100644 index fef98d99e6..0000000000 --- a/docs/04_cv32a65x/design/source/port_instr_realign.rst +++ /dev/null @@ -1,81 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_instr_realign_ports: - -.. list-table:: **instr_realign module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``flush_i`` - - in - - Fetch flush request - - CONTROLLER - - logic - - * - ``valid_i`` - - in - - 32-bit block is valid - - CACHE - - logic - - * - ``serving_unaligned_o`` - - out - - Instruction is unaligned - - FRONTEND - - logic - - * - ``address_i`` - - in - - 32-bit block address - - CACHE - - logic[CVA6Cfg.VLEN-1:0] - - * - ``data_i`` - - in - - 32-bit block - - CACHE - - logic[CVA6Cfg.FETCH_WIDTH-1:0] - - * - ``valid_o`` - - out - - instruction is valid - - FRONTEND - - logic[CVA6Cfg.INSTR_PER_FETCH-1:0] - - * - ``addr_o`` - - out - - Instruction address - - FRONTEND - - logic[CVA6Cfg.INSTR_PER_FETCH-1:0][CVA6Cfg.VLEN-1:0] - - * - ``instr_o`` - - out - - Instruction - - instr_scan&instr_queue - - logic[CVA6Cfg.INSTR_PER_FETCH-1:0][31:0] - - diff --git a/docs/04_cv32a65x/design/source/port_instr_scan.adoc b/docs/04_cv32a65x/design/source/port_instr_scan.adoc new file mode 100644 index 0000000000..799791820f --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_instr_scan.adoc @@ -0,0 +1,46 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_instr_scan_ports]] + +.*instr_scan module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`instr_i` | in | Instruction to be predecoded | instr_realign | logic[31:0] + +|`rvi_return_o` | out | Return instruction | FRONTEND | logic + +|`rvi_call_o` | out | JAL instruction | FRONTEND | logic + +|`rvi_branch_o` | out | Branch instruction | FRONTEND | logic + +|`rvi_jalr_o` | out | JALR instruction | FRONTEND | logic + +|`rvi_jump_o` | out | Unconditional jump instruction | FRONTEND | logic + +|`rvi_imm_o` | out | Instruction immediat | FRONTEND | logic[CVA6Cfg.VLEN-1:0] + +|`rvc_branch_o` | out | Branch compressed instruction | FRONTEND | logic + +|`rvc_jump_o` | out | Unconditional jump compressed instruction | FRONTEND | logic + +|`rvc_jr_o` | out | JR compressed instruction | FRONTEND | logic + +|`rvc_return_o` | out | Return compressed instruction | FRONTEND | logic + +|`rvc_jalr_o` | out | JALR compressed instruction | FRONTEND | logic + +|`rvc_call_o` | out | JAL compressed instruction | FRONTEND | logic + +|`rvc_imm_o` | out | Instruction compressed immediat | FRONTEND | logic[CVA6Cfg.VLEN-1:0] + +|=== + diff --git a/docs/04_cv32a65x/design/source/port_instr_scan.rst b/docs/04_cv32a65x/design/source/port_instr_scan.rst deleted file mode 100644 index dbc877777e..0000000000 --- a/docs/04_cv32a65x/design/source/port_instr_scan.rst +++ /dev/null @@ -1,105 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_instr_scan_ports: - -.. list-table:: **instr_scan module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``instr_i`` - - in - - Instruction to be predecoded - - instr_realign - - logic[31:0] - - * - ``rvi_return_o`` - - out - - Return instruction - - FRONTEND - - logic - - * - ``rvi_call_o`` - - out - - JAL instruction - - FRONTEND - - logic - - * - ``rvi_branch_o`` - - out - - Branch instruction - - FRONTEND - - logic - - * - ``rvi_jalr_o`` - - out - - JALR instruction - - FRONTEND - - logic - - * - ``rvi_jump_o`` - - out - - Unconditional jump instruction - - FRONTEND - - logic - - * - ``rvi_imm_o`` - - out - - Instruction immediat - - FRONTEND - - logic[CVA6Cfg.VLEN-1:0] - - * - ``rvc_branch_o`` - - out - - Branch compressed instruction - - FRONTEND - - logic - - * - ``rvc_jump_o`` - - out - - Unconditional jump compressed instruction - - FRONTEND - - logic - - * - ``rvc_jr_o`` - - out - - JR compressed instruction - - FRONTEND - - logic - - * - ``rvc_return_o`` - - out - - Return compressed instruction - - FRONTEND - - logic - - * - ``rvc_jalr_o`` - - out - - JALR compressed instruction - - FRONTEND - - logic - - * - ``rvc_call_o`` - - out - - JAL compressed instruction - - FRONTEND - - logic - - * - ``rvc_imm_o`` - - out - - Instruction compressed immediat - - FRONTEND - - logic[CVA6Cfg.VLEN-1:0] - - diff --git a/docs/04_cv32a65x/design/source/port_issue_read_operands.adoc b/docs/04_cv32a65x/design/source/port_issue_read_operands.adoc new file mode 100644 index 0000000000..1311ff9c22 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_issue_read_operands.adoc @@ -0,0 +1,136 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_issue_read_operands_ports]] + +.*issue_read_operands module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`flush_i` | in | Flush | CONTROLLER | logic + +|`issue_instr_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0] + +|`orig_instr_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0][31:0] + +|`issue_instr_valid_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`issue_ack_o` | out | Issue stage acknowledge | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`rs1_o` | out | rs1 operand address | scoreboard | logic[CVA6Cfg.NrIssuePorts-1:0][REG_ADDR_SIZE-1:0] + +|`rs1_i` | in | rs1 operand | scoreboard | logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] + +|`rs1_valid_i` | in | rs1 operand is valid | scoreboard | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`rs2_o` | out | rs2 operand address | scoreboard | logic[CVA6Cfg.NrIssuePorts-1:0][REG_ADDR_SIZE-1:0] + +|`rs2_i` | in | rs2 operand | scoreboard | logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] + +|`rs2_valid_i` | in | rs2 operand is valid | scoreboard | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`rs3_o` | out | rs3 operand address | scoreboard | logic[CVA6Cfg.NrIssuePorts-1:0][REG_ADDR_SIZE-1:0] + +|`rs3_i` | in | rs3 operand | scoreboard | rs3_len_t[CVA6Cfg.NrIssuePorts-1:0] + +|`rs3_valid_i` | in | rs3 operand is valid | scoreboard | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`rd_clobber_gpr_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | fu_t[2**REG_ADDR_SIZE-1:0] + +|`rd_clobber_fpr_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | fu_t[2**REG_ADDR_SIZE-1:0] + +|`fu_data_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | fu_data_t[CVA6Cfg.NrIssuePorts-1:0] + +|`rs1_forwarding_o` | out | Unregistered version of fu_data_o.operanda | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] + +|`rs2_forwarding_o` | out | Unregistered version of fu_data_o.operandb | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] + +|`pc_o` | out | Instruction pc | TO_BE_COMPLETED | logic[CVA6Cfg.VLEN-1:0] + +|`is_compressed_instr_o` | out | Is compressed instruction | TO_BE_COMPLETED | logic + +|`flu_ready_i` | in | Fixed Latency Unit ready to accept new request | TO_BE_COMPLETED | logic + +|`alu_valid_o` | out | ALU output is valid | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`branch_valid_o` | out | Branch instruction is valid | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`branch_predict_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | branchpredict_sbe_t + +|`lsu_ready_i` | in | Load Store Unit is ready | TO_BE_COMPLETED | logic + +|`lsu_valid_o` | out | Load Store Unit result is valid | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`mult_valid_o` | out | Mult result is valid | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`alu2_valid_o` | out | ALU output is valid | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`csr_valid_o` | out | CSR result is valid | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`cvxif_valid_o` | out | CVXIF result is valid | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`cvxif_ready_i` | in | CVXIF is ready | TO_BE_COMPLETED | logic + +|`cvxif_off_instr_o` | out | CVXIF offloaded instruction | TO_BE_COMPLETED | logic[31:0] + +|`hart_id_i` | in | CVA6 Hart ID | SUBSYSTEM | logic[CVA6Cfg.XLEN-1:0] + +|`x_issue_ready_i` | in | none | none | logic + +|`x_issue_resp_i` | in | none | none | x_issue_resp_t + +|`x_issue_valid_o` | out | none | none | logic + +|`x_issue_req_o` | out | none | none | x_issue_req_t + +|`x_register_ready_i` | in | none | none | logic + +|`x_register_valid_o` | out | none | none | logic + +|`x_register_o` | out | none | none | x_register_t + +|`x_commit_valid_o` | out | none | none | logic + +|`x_commit_o` | out | none | none | x_commit_t + +|`x_transaction_accepted_o` | out | none | none | logic + +|`x_transaction_rejected_o` | out | none | none | logic + +|`x_issue_writeback_o` | out | none | none | logic + +|`x_id_o` | out | none | none | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`waddr_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrCommitPorts-1:0][4:0] + +|`wdata_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] + +|`we_gpr_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrCommitPorts-1:0] + +|`stall_issue_o` | out | Stall signal, we do not want to fetch any more entries | TO_BE_COMPLETED | logic + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As EnableAccelerator = 0,:: +* `stall_i` input is tied to 0 +As RVH = False,:: +* `tinst_o` output is tied to 0 +As RVF = 0,:: +* `fpu_ready_i` input is tied to 0 +* `fpu_valid_o` output is tied to 0 +* `fpu_fmt_o` output is tied to 0 +* `fpu_rm_o` output is tied to 0 +* `we_fpr_i` input is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_issue_read_operands.rst b/docs/04_cv32a65x/design/source/port_issue_read_operands.rst deleted file mode 100644 index 946bdf1b8d..0000000000 --- a/docs/04_cv32a65x/design/source/port_issue_read_operands.rst +++ /dev/null @@ -1,267 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_issue_read_operands_ports: - -.. list-table:: **issue_read_operands module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``flush_i`` - - in - - Flush - - CONTROLLER - - logic - - * - ``issue_instr_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0] - - * - ``orig_instr_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0][31:0] - - * - ``issue_instr_valid_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``issue_ack_o`` - - out - - Issue stage acknowledge - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``rs1_o`` - - out - - rs1 operand address - - scoreboard - - logic[CVA6Cfg.NrIssuePorts-1:0][REG_ADDR_SIZE-1:0] - - * - ``rs1_i`` - - in - - rs1 operand - - scoreboard - - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] - - * - ``rs1_valid_i`` - - in - - rs1 operand is valid - - scoreboard - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``rs2_o`` - - out - - rs2 operand address - - scoreboard - - logic[CVA6Cfg.NrIssuePorts-1:0][REG_ADDR_SIZE-1:0] - - * - ``rs2_i`` - - in - - rs2 operand - - scoreboard - - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] - - * - ``rs2_valid_i`` - - in - - rs2 operand is valid - - scoreboard - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``rs3_o`` - - out - - rs3 operand address - - scoreboard - - logic[CVA6Cfg.NrIssuePorts-1:0][REG_ADDR_SIZE-1:0] - - * - ``rs3_i`` - - in - - rs3 operand - - scoreboard - - rs3_len_t[CVA6Cfg.NrIssuePorts-1:0] - - * - ``rs3_valid_i`` - - in - - rs3 operand is valid - - scoreboard - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``rd_clobber_gpr_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - fu_t[2**REG_ADDR_SIZE-1:0] - - * - ``rd_clobber_fpr_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - fu_t[2**REG_ADDR_SIZE-1:0] - - * - ``fu_data_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - fu_data_t[CVA6Cfg.NrIssuePorts-1:0] - - * - ``rs1_forwarding_o`` - - out - - Unregistered version of fu_data_o.operanda - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] - - * - ``rs2_forwarding_o`` - - out - - Unregistered version of fu_data_o.operandb - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] - - * - ``pc_o`` - - out - - Instruction pc - - TO_BE_COMPLETED - - logic[CVA6Cfg.VLEN-1:0] - - * - ``is_compressed_instr_o`` - - out - - Is compressed instruction - - TO_BE_COMPLETED - - logic - - * - ``flu_ready_i`` - - in - - Fixed Latency Unit ready to accept new request - - TO_BE_COMPLETED - - logic - - * - ``alu_valid_o`` - - out - - ALU output is valid - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``branch_valid_o`` - - out - - Branch instruction is valid - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``branch_predict_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - branchpredict_sbe_t - - * - ``lsu_ready_i`` - - in - - Load Store Unit is ready - - TO_BE_COMPLETED - - logic - - * - ``lsu_valid_o`` - - out - - Load Store Unit result is valid - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``mult_valid_o`` - - out - - Mult result is valid - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``alu2_valid_o`` - - out - - ALU output is valid - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``csr_valid_o`` - - out - - CSR result is valid - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``cvxif_valid_o`` - - out - - CVXIF result is valid - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``cvxif_ready_i`` - - in - - CVXIF is ready - - TO_BE_COMPLETED - - logic - - * - ``cvxif_off_instr_o`` - - out - - CVXIF offloaded instruction - - TO_BE_COMPLETED - - logic[31:0] - - * - ``waddr_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrCommitPorts-1:0][4:0] - - * - ``wdata_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] - - * - ``we_gpr_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``stall_issue_o`` - - out - - Stall signal, we do not want to fetch any more entries - - TO_BE_COMPLETED - - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As EnableAccelerator = 0, -| ``stall_i`` input is tied to 0 -| As RVH = False, -| ``tinst_o`` output is tied to 0 -| As RVF = 0, -| ``fpu_ready_i`` input is tied to 0 -| ``fpu_valid_o`` output is tied to 0 -| ``fpu_fmt_o`` output is tied to 0 -| ``fpu_rm_o`` output is tied to 0 -| ``we_fpr_i`` input is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_issue_stage.adoc b/docs/04_cv32a65x/design/source/port_issue_stage.adoc new file mode 100644 index 0000000000..fcb044082b --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_issue_stage.adoc @@ -0,0 +1,140 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_issue_stage_ports]] + +.*issue_stage module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`flush_unissued_instr_i` | in | TO_BE_COMPLETED | CONTROLLER | logic + +|`flush_i` | in | TO_BE_COMPLETED | CONTROLLER | logic + +|`decoded_instr_i` | in | Handshake's data with decode stage | ID_STAGE | scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0] + +|`orig_instr_i` | in | instruction value | ID_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0][31:0] + +|`decoded_instr_valid_i` | in | Handshake's valid with decode stage | ID_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`is_ctrl_flow_i` | in | Is instruction a control flow instruction | ID_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`decoded_instr_ack_o` | out | Handshake's acknowlege with decode stage | ID_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`rs1_forwarding_o` | out | rs1 forwarding | EX_STAGE | [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] + +|`rs2_forwarding_o` | out | rs2 forwarding | EX_STAGE | [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] + +|`fu_data_o` | out | FU data useful to execute instruction | EX_STAGE | fu_data_t[CVA6Cfg.NrIssuePorts-1:0] + +|`pc_o` | out | Program Counter | EX_STAGE | logic[CVA6Cfg.VLEN-1:0] + +|`is_compressed_instr_o` | out | Is compressed instruction | EX_STAGE | logic + +|`flu_ready_i` | in | Fixed Latency Unit is ready | EX_STAGE | logic + +|`alu_valid_o` | out | ALU FU is valid | EX_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`resolve_branch_i` | in | Signaling that we resolved the branch | EX_STAGE | logic + +|`lsu_ready_i` | in | Load store unit FU is ready | EX_STAGE | logic + +|`lsu_valid_o` | out | Load store unit FU is valid | EX_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`branch_valid_o` | out | Branch unit is valid | EX_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`branch_predict_o` | out | Information of branch prediction | EX_STAGE | branchpredict_sbe_t + +|`mult_valid_o` | out | Mult FU is valid | EX_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`alu2_valid_o` | out | ALU2 FU is valid | EX_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`csr_valid_o` | out | CSR is valid | EX_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`xfu_valid_o` | out | CVXIF FU is valid | EX_STAGE | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`xfu_ready_i` | in | CVXIF is FU ready | EX_STAGE | logic + +|`x_off_instr_o` | out | CVXIF offloader instruction value | EX_STAGE | logic[31:0] + +|`hart_id_i` | in | CVA6 Hart ID | SUBSYSTEM | logic[CVA6Cfg.XLEN-1:0] + +|`x_issue_ready_i` | in | none | none | logic + +|`x_issue_resp_i` | in | none | none | x_issue_resp_t + +|`x_issue_valid_o` | out | none | none | logic + +|`x_issue_req_o` | out | none | none | x_issue_req_t + +|`x_register_ready_i` | in | none | none | logic + +|`x_register_valid_o` | out | none | none | logic + +|`x_register_o` | out | none | none | x_register_t + +|`x_commit_valid_o` | out | none | none | logic + +|`x_commit_o` | out | none | none | x_commit_t + +|`x_transaction_rejected_o` | out | CVXIF Transaction rejected -> instruction is illegal | EX_STAGE | logic + +|`trans_id_i` | in | Transaction ID | EX_STAGE | logic[CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] + +|`resolved_branch_i` | in | The branch engine uses the write back from the ALU | EX_STAGE | bp_resolve_t + +|`wbdata_i` | in | TO_BE_COMPLETED | EX_STAGE | logic[CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.XLEN-1:0] + +|`ex_ex_i` | in | exception from execute stage or CVXIF | EX_STAGE | exception_t[CVA6Cfg.NrWbPorts-1:0] + +|`wt_valid_i` | in | TO_BE_COMPLETED | EX_STAGE | logic[CVA6Cfg.NrWbPorts-1:0] + +|`x_we_i` | in | CVXIF write enable | EX_STAGE | logic + +|`x_rd_i` | in | CVXIF destination register | ISSUE_STAGE | logic[4:0] + +|`waddr_i` | in | TO_BE_COMPLETED | EX_STAGE | logic[CVA6Cfg.NrCommitPorts-1:0][4:0] + +|`wdata_i` | in | TO_BE_COMPLETED | EX_STAGE | logic[CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] + +|`we_gpr_i` | in | GPR write enable | EX_STAGE | logic[CVA6Cfg.NrCommitPorts-1:0] + +|`commit_instr_o` | out | Instructions to commit | COMMIT_STAGE | scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] + +|`commit_drop_o` | out | Instruction is cancelled | COMMIT_STAGE | logic[CVA6Cfg.NrCommitPorts-1:0] + +|`commit_ack_i` | in | Commit acknowledge | COMMIT_STAGE | logic[CVA6Cfg.NrCommitPorts-1:0] + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As PerfCounterEn = 0,:: +* `sb_full_o` output is tied to 0 +* `stall_issue_o` output is tied to 0 +As EnableAccelerator = 0,:: +* `stall_i` input is tied to 0 +* `issue_instr_o` output is tied to 0 +* `issue_instr_hs_o` output is tied to 0 +As RVH = False,:: +* `tinst_o` output is tied to 0 +As RVF = 0,:: +* `fpu_ready_i` input is tied to 0 +* `fpu_valid_o` output is tied to 0 +* `fpu_fmt_o` output is tied to 0 +* `fpu_rm_o` output is tied to 0 +* `we_fpr_i` input is tied to 0 +As IsRVFI = 0,:: +* `rvfi_issue_pointer_o` output is tied to 0 +* `rvfi_commit_pointer_o` output is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_issue_stage.rst b/docs/04_cv32a65x/design/source/port_issue_stage.rst deleted file mode 100644 index 7e5b9b27e2..0000000000 --- a/docs/04_cv32a65x/design/source/port_issue_stage.rst +++ /dev/null @@ -1,275 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_issue_stage_ports: - -.. list-table:: **issue_stage module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``flush_unissued_instr_i`` - - in - - TO_BE_COMPLETED - - CONTROLLER - - logic - - * - ``flush_i`` - - in - - TO_BE_COMPLETED - - CONTROLLER - - logic - - * - ``decoded_instr_i`` - - in - - Handshake's data with decode stage - - ID_STAGE - - scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0] - - * - ``orig_instr_i`` - - in - - instruction value - - ID_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0][31:0] - - * - ``decoded_instr_valid_i`` - - in - - Handshake's valid with decode stage - - ID_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``is_ctrl_flow_i`` - - in - - Is instruction a control flow instruction - - ID_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``decoded_instr_ack_o`` - - out - - Handshake's acknowlege with decode stage - - ID_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``rs1_forwarding_o`` - - out - - rs1 forwarding - - EX_STAGE - - [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] - - * - ``rs2_forwarding_o`` - - out - - rs2 forwarding - - EX_STAGE - - [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] - - * - ``fu_data_o`` - - out - - FU data useful to execute instruction - - EX_STAGE - - fu_data_t[CVA6Cfg.NrIssuePorts-1:0] - - * - ``pc_o`` - - out - - Program Counter - - EX_STAGE - - logic[CVA6Cfg.VLEN-1:0] - - * - ``is_compressed_instr_o`` - - out - - Is compressed instruction - - EX_STAGE - - logic - - * - ``flu_ready_i`` - - in - - Fixed Latency Unit is ready - - EX_STAGE - - logic - - * - ``alu_valid_o`` - - out - - ALU FU is valid - - EX_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``resolve_branch_i`` - - in - - Signaling that we resolved the branch - - EX_STAGE - - logic - - * - ``lsu_ready_i`` - - in - - Load store unit FU is ready - - EX_STAGE - - logic - - * - ``lsu_valid_o`` - - out - - Load store unit FU is valid - - EX_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``branch_valid_o`` - - out - - Branch unit is valid - - EX_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``branch_predict_o`` - - out - - Information of branch prediction - - EX_STAGE - - branchpredict_sbe_t - - * - ``mult_valid_o`` - - out - - Mult FU is valid - - EX_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``alu2_valid_o`` - - out - - ALU2 FU is valid - - EX_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``csr_valid_o`` - - out - - CSR is valid - - EX_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``x_issue_valid_o`` - - out - - CVXIF FU is valid - - EX_STAGE - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``x_issue_ready_i`` - - in - - CVXIF is FU ready - - EX_STAGE - - logic - - * - ``x_off_instr_o`` - - out - - CVXIF offloader instruction value - - EX_STAGE - - logic[31:0] - - * - ``trans_id_i`` - - in - - Transaction ID - - EX_STAGE - - logic[CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``resolved_branch_i`` - - in - - The branch engine uses the write back from the ALU - - EX_STAGE - - bp_resolve_t - - * - ``wbdata_i`` - - in - - TO_BE_COMPLETED - - EX_STAGE - - logic[CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.XLEN-1:0] - - * - ``ex_ex_i`` - - in - - exception from execute stage or CVXIF - - EX_STAGE - - exception_t[CVA6Cfg.NrWbPorts-1:0] - - * - ``wt_valid_i`` - - in - - TO_BE_COMPLETED - - EX_STAGE - - logic[CVA6Cfg.NrWbPorts-1:0] - - * - ``x_we_i`` - - in - - CVXIF write enable - - EX_STAGE - - logic - - * - ``waddr_i`` - - in - - TO_BE_COMPLETED - - EX_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0][4:0] - - * - ``wdata_i`` - - in - - TO_BE_COMPLETED - - EX_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] - - * - ``we_gpr_i`` - - in - - GPR write enable - - EX_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``commit_instr_o`` - - out - - Instructions to commit - - COMMIT_STAGE - - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] - - * - ``commit_drop_o`` - - out - - Instruction is cancelled - - COMMIT_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``commit_ack_i`` - - in - - Commit acknowledge - - COMMIT_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0] - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As PerfCounterEn = 0, -| ``sb_full_o`` output is tied to 0 -| ``stall_issue_o`` output is tied to 0 -| As EnableAccelerator = 0, -| ``stall_i`` input is tied to 0 -| ``issue_instr_o`` output is tied to 0 -| ``issue_instr_hs_o`` output is tied to 0 -| As RVH = False, -| ``tinst_o`` output is tied to 0 -| As RVF = 0, -| ``fpu_ready_i`` input is tied to 0 -| ``fpu_valid_o`` output is tied to 0 -| ``fpu_fmt_o`` output is tied to 0 -| ``fpu_rm_o`` output is tied to 0 -| ``we_fpr_i`` input is tied to 0 -| As IsRVFI = 0, -| ``rvfi_issue_pointer_o`` output is tied to 0 -| ``rvfi_commit_pointer_o`` output is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_load_store_unit.adoc b/docs/04_cv32a65x/design/source/port_load_store_unit.adoc new file mode 100644 index 0000000000..7fa01ad7a0 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_load_store_unit.adoc @@ -0,0 +1,115 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_load_store_unit_ports]] + +.*load_store_unit module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`flush_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`stall_st_pending_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`no_st_pending_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`fu_data_i` | in | FU data needed to execute instruction | ISSUE_STAGE | fu_data_t + +|`lsu_ready_o` | out | Load Store Unit is ready | ISSUE_STAGE | logic + +|`lsu_valid_i` | in | Load Store Unit instruction is valid | ISSUE_STAGE | logic + +|`load_trans_id_o` | out | Load transaction ID | ISSUE_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`load_result_o` | out | Load result | ISSUE_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`load_valid_o` | out | Load result is valid | ISSUE_STAGE | logic + +|`load_exception_o` | out | Load exception | ISSUE_STAGE | exception_t + +|`store_trans_id_o` | out | Store transaction ID | ISSUE_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`store_result_o` | out | Store result | ISSUE_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`store_valid_o` | out | Store result is valid | ISSUE_STAGE | logic + +|`store_exception_o` | out | Store exception | ISSUE_STAGE | exception_t + +|`commit_i` | in | Commit the first pending store | TO_BE_COMPLETED | logic + +|`commit_ready_o` | out | Commit queue is ready to accept another commit request | TO_BE_COMPLETED | logic + +|`commit_tran_id_i` | in | Commit transaction ID | TO_BE_COMPLETED | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`icache_areq_i` | in | Instruction cache input request | CACHES | icache_arsp_t + +|`icache_areq_o` | out | Instruction cache output request | CACHES | icache_areq_t + +|`dcache_req_ports_i` | in | Data cache request output | CACHES | dcache_req_o_t[2:0] + +|`dcache_req_ports_o` | out | Data cache request input | CACHES | dcache_req_i_t[2:0] + +|`dcache_wbuffer_empty_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`dcache_wbuffer_not_ni_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`pmpcfg_i` | in | PMP configuration | CSR_REGFILE | riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries:0] + +|`pmpaddr_i` | in | PMP address | CSR_REGFILE | logic[CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As RVA = False,:: +* `amo_valid_commit_i` input is tied to 0 +* `amo_req_o` output is tied to 0 +* `amo_resp_i` input is tied to 0 +As RVH = False,:: +* `tinst_i` input is tied to 0 +* `enable_g_translation_i` input is tied to 0 +* `en_ld_st_g_translation_i` input is tied to 0 +* `v_i` input is tied to 0 +* `ld_st_v_i` input is tied to 0 +* `csr_hs_ld_st_inst_o` output is tied to 0 +* `vs_sum_i` input is tied to 0 +* `vmxr_i` input is tied to 0 +* `vsatp_ppn_i` input is tied to 0 +* `vs_asid_i` input is tied to 0 +* `hgatp_ppn_i` input is tied to 0 +* `vmid_i` input is tied to 0 +* `vmid_to_be_flushed_i` input is tied to 0 +* `gpaddr_to_be_flushed_i` input is tied to 0 +* `flush_tlb_vvma_i` input is tied to 0 +* `flush_tlb_gvma_i` input is tied to 0 +As RVS = False,:: +* `enable_translation_i` input is tied to 0 +* `en_ld_st_translation_i` input is tied to 0 +* `sum_i` input is tied to 0 +* `mxr_i` input is tied to 0 +* `satp_ppn_i` input is tied to 0 +* `asid_i` input is tied to 0 +* `asid_to_be_flushed_i` input is tied to 0 +* `vaddr_to_be_flushed_i` input is tied to 0 +As PRIV = MachineOnly,:: +* `priv_lvl_i` input is tied to MachineMode +* `ld_st_priv_lvl_i` input is tied to MAchineMode +As MMUPresent = 0,:: +* `flush_tlb_i` input is tied to 0 +As PerfCounterEn = 0,:: +* `itlb_miss_o` output is tied to 0 +* `dtlb_miss_o` output is tied to 0 +As IsRVFI = 0,:: +* `rvfi_lsu_ctrl_o` output is tied to 0 +* `rvfi_mem_paddr_o` output is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_load_store_unit.rst b/docs/04_cv32a65x/design/source/port_load_store_unit.rst deleted file mode 100644 index 8f3c1fe798..0000000000 --- a/docs/04_cv32a65x/design/source/port_load_store_unit.rst +++ /dev/null @@ -1,226 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_load_store_unit_ports: - -.. list-table:: **load_store_unit module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``flush_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``stall_st_pending_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``no_st_pending_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``fu_data_i`` - - in - - FU data needed to execute instruction - - ISSUE_STAGE - - fu_data_t - - * - ``lsu_ready_o`` - - out - - Load Store Unit is ready - - ISSUE_STAGE - - logic - - * - ``lsu_valid_i`` - - in - - Load Store Unit instruction is valid - - ISSUE_STAGE - - logic - - * - ``load_trans_id_o`` - - out - - Load transaction ID - - ISSUE_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``load_result_o`` - - out - - Load result - - ISSUE_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``load_valid_o`` - - out - - Load result is valid - - ISSUE_STAGE - - logic - - * - ``load_exception_o`` - - out - - Load exception - - ISSUE_STAGE - - exception_t - - * - ``store_trans_id_o`` - - out - - Store transaction ID - - ISSUE_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``store_result_o`` - - out - - Store result - - ISSUE_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``store_valid_o`` - - out - - Store result is valid - - ISSUE_STAGE - - logic - - * - ``store_exception_o`` - - out - - Store exception - - ISSUE_STAGE - - exception_t - - * - ``commit_i`` - - in - - Commit the first pending store - - TO_BE_COMPLETED - - logic - - * - ``commit_ready_o`` - - out - - Commit queue is ready to accept another commit request - - TO_BE_COMPLETED - - logic - - * - ``commit_tran_id_i`` - - in - - Commit transaction ID - - TO_BE_COMPLETED - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``icache_areq_i`` - - in - - Instruction cache input request - - CACHES - - icache_arsp_t - - * - ``icache_areq_o`` - - out - - Instruction cache output request - - CACHES - - icache_areq_t - - * - ``dcache_req_ports_i`` - - in - - Data cache request output - - CACHES - - dcache_req_o_t[2:0] - - * - ``dcache_req_ports_o`` - - out - - Data cache request input - - CACHES - - dcache_req_i_t[2:0] - - * - ``dcache_wbuffer_empty_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``dcache_wbuffer_not_ni_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``pmpcfg_i`` - - in - - PMP configuration - - CSR_REGFILE - - riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries:0] - - * - ``pmpaddr_i`` - - in - - PMP address - - CSR_REGFILE - - logic[CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As RVA = False, -| ``amo_valid_commit_i`` input is tied to 0 -| ``amo_req_o`` output is tied to 0 -| ``amo_resp_i`` input is tied to 0 -| As RVH = False, -| ``tinst_i`` input is tied to 0 -| ``enable_g_translation_i`` input is tied to 0 -| ``en_ld_st_g_translation_i`` input is tied to 0 -| ``v_i`` input is tied to 0 -| ``ld_st_v_i`` input is tied to 0 -| ``csr_hs_ld_st_inst_o`` output is tied to 0 -| ``vs_sum_i`` input is tied to 0 -| ``vmxr_i`` input is tied to 0 -| ``vsatp_ppn_i`` input is tied to 0 -| ``vs_asid_i`` input is tied to 0 -| ``hgatp_ppn_i`` input is tied to 0 -| ``vmid_i`` input is tied to 0 -| ``vmid_to_be_flushed_i`` input is tied to 0 -| ``gpaddr_to_be_flushed_i`` input is tied to 0 -| ``flush_tlb_vvma_i`` input is tied to 0 -| ``flush_tlb_gvma_i`` input is tied to 0 -| As RVS = False, -| ``enable_translation_i`` input is tied to 0 -| ``en_ld_st_translation_i`` input is tied to 0 -| ``sum_i`` input is tied to 0 -| ``mxr_i`` input is tied to 0 -| ``satp_ppn_i`` input is tied to 0 -| ``asid_i`` input is tied to 0 -| ``asid_to_be_flushed_i`` input is tied to 0 -| ``vaddr_to_be_flushed_i`` input is tied to 0 -| As PRIV = MachineOnly, -| ``priv_lvl_i`` input is tied to MachineMode -| ``ld_st_priv_lvl_i`` input is tied to MAchineMode -| As MMUPresent = 0, -| ``flush_tlb_i`` input is tied to 0 -| As PerfCounterEn = 0, -| ``itlb_miss_o`` output is tied to 0 -| ``dtlb_miss_o`` output is tied to 0 -| As IsRVFI = 0, -| ``rvfi_lsu_ctrl_o`` output is tied to 0 -| ``rvfi_mem_paddr_o`` output is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_load_unit.adoc b/docs/04_cv32a65x/design/source/port_load_unit.adoc new file mode 100644 index 0000000000..e594181d3e --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_load_unit.adoc @@ -0,0 +1,70 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_load_unit_ports]] + +.*load_unit module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`flush_i` | in | Flush signal | CONTROLLER | logic + +|`valid_i` | in | Load request is valid | LSU_BYPASS | logic + +|`lsu_ctrl_i` | in | Load request input | LSU_BYPASS | lsu_ctrl_t + +|`pop_ld_o` | out | Pop the load request from the LSU bypass FIFO | LSU_BYPASS | logic + +|`valid_o` | out | Load unit result is valid | ISSUE_STAGE | logic + +|`trans_id_o` | out | Load transaction ID | ISSUE_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`result_o` | out | Load result | ISSUE_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`ex_o` | out | Load exception | ISSUE_STAGE | exception_t + +|`translation_req_o` | out | Request address translation | MMU | logic + +|`vaddr_o` | out | Virtual address | MMU | logic[CVA6Cfg.VLEN-1:0] + +|`paddr_i` | in | Physical address | MMU | logic[CVA6Cfg.PLEN-1:0] + +|`ex_i` | in | Excepted which appears before load | MMU | exception_t + +|`page_offset_o` | out | Page offset for address checking | STORE_UNIT | logic[11:0] + +|`page_offset_matches_i` | in | Indicates if the page offset matches a store unit entry | STORE_UNIT | logic + +|`store_buffer_empty_i` | in | Store buffer is empty | STORE_UNIT | logic + +|`commit_tran_id_i` | in | Transaction ID of the committing instruction | COMMIT_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`req_port_i` | in | Data cache request out | CACHES | dcache_req_o_t + +|`req_port_o` | out | Data cache request in | CACHES | dcache_req_i_t + +|`dcache_wbuffer_not_ni_i` | in | Presence of non-idempotent operations in the D$ write buffer | CACHES | logic + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As RVH = False,:: +* `tinst_o` output is tied to 0 +* `hs_ld_st_inst_o` output is tied to 0 +* `hlvx_inst_o` output is tied to 0 +For any HW configuration,:: +* `dtlb_hit_i` input is tied to 1 +As MMUPresent = 0,:: +* `dtlb_ppn_i` input is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_load_unit.rst b/docs/04_cv32a65x/design/source/port_load_unit.rst deleted file mode 100644 index 99a2ff7d13..0000000000 --- a/docs/04_cv32a65x/design/source/port_load_unit.rst +++ /dev/null @@ -1,157 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_load_unit_ports: - -.. list-table:: **load_unit module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``flush_i`` - - in - - Flush signal - - CONTROLLER - - logic - - * - ``valid_i`` - - in - - Load request is valid - - LSU_BYPASS - - logic - - * - ``lsu_ctrl_i`` - - in - - Load request input - - LSU_BYPASS - - lsu_ctrl_t - - * - ``pop_ld_o`` - - out - - Pop the load request from the LSU bypass FIFO - - LSU_BYPASS - - logic - - * - ``valid_o`` - - out - - Load unit result is valid - - ISSUE_STAGE - - logic - - * - ``trans_id_o`` - - out - - Load transaction ID - - ISSUE_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``result_o`` - - out - - Load result - - ISSUE_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``ex_o`` - - out - - Load exception - - ISSUE_STAGE - - exception_t - - * - ``translation_req_o`` - - out - - Request address translation - - MMU - - logic - - * - ``vaddr_o`` - - out - - Virtual address - - MMU - - logic[CVA6Cfg.VLEN-1:0] - - * - ``paddr_i`` - - in - - Physical address - - MMU - - logic[CVA6Cfg.PLEN-1:0] - - * - ``ex_i`` - - in - - Excepted which appears before load - - MMU - - exception_t - - * - ``page_offset_o`` - - out - - Page offset for address checking - - STORE_UNIT - - logic[11:0] - - * - ``page_offset_matches_i`` - - in - - Indicates if the page offset matches a store unit entry - - STORE_UNIT - - logic - - * - ``store_buffer_empty_i`` - - in - - Store buffer is empty - - STORE_UNIT - - logic - - * - ``commit_tran_id_i`` - - in - - Transaction ID of the committing instruction - - COMMIT_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``req_port_i`` - - in - - Data cache request out - - CACHES - - dcache_req_o_t - - * - ``req_port_o`` - - out - - Data cache request in - - CACHES - - dcache_req_i_t - - * - ``dcache_wbuffer_not_ni_i`` - - in - - Presence of non-idempotent operations in the D$ write buffer - - CACHES - - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As RVH = False, -| ``tinst_o`` output is tied to 0 -| ``hs_ld_st_inst_o`` output is tied to 0 -| ``hlvx_inst_o`` output is tied to 0 -| For any HW configuration, -| ``dtlb_hit_i`` input is tied to 1 -| As MMUPresent = 0, -| ``dtlb_ppn_i`` input is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_lsu_bypass.adoc b/docs/04_cv32a65x/design/source/port_lsu_bypass.adoc new file mode 100644 index 0000000000..540af4878b --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_lsu_bypass.adoc @@ -0,0 +1,36 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_lsu_bypass_ports]] + +.*lsu_bypass module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`flush_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`lsu_req_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | lsu_ctrl_t + +|`lsu_req_valid_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`pop_ld_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`pop_st_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`lsu_ctrl_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | lsu_ctrl_t + +|`ready_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|=== + diff --git a/docs/04_cv32a65x/design/source/port_lsu_bypass.rst b/docs/04_cv32a65x/design/source/port_lsu_bypass.rst deleted file mode 100644 index 8eac0f7ab4..0000000000 --- a/docs/04_cv32a65x/design/source/port_lsu_bypass.rst +++ /dev/null @@ -1,75 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_lsu_bypass_ports: - -.. list-table:: **lsu_bypass module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``flush_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``lsu_req_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - lsu_ctrl_t - - * - ``lsu_req_valid_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``pop_ld_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``pop_st_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``lsu_ctrl_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - lsu_ctrl_t - - * - ``ready_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - diff --git a/docs/04_cv32a65x/design/source/port_mult.adoc b/docs/04_cv32a65x/design/source/port_mult.adoc new file mode 100644 index 0000000000..90af4c8bfa --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_mult.adoc @@ -0,0 +1,36 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_mult_ports]] + +.*mult module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`flush_i` | in | Flush | CONTROLLER | logic + +|`fu_data_i` | in | FU data needed to execute instruction | ISSUE_STAGE | fu_data_t + +|`mult_valid_i` | in | Mult instruction is valid | ISSUE_STAGE | logic + +|`result_o` | out | Mult result | ISSUE_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`mult_valid_o` | out | Mult result is valid | ISSUE_STAGE | logic + +|`mult_ready_o` | out | Mutl is ready | ISSUE_STAGE | logic + +|`mult_trans_id_o` | out | Mult transaction ID | ISSUE_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|=== + diff --git a/docs/04_cv32a65x/design/source/port_mult.rst b/docs/04_cv32a65x/design/source/port_mult.rst deleted file mode 100644 index 41e342d72f..0000000000 --- a/docs/04_cv32a65x/design/source/port_mult.rst +++ /dev/null @@ -1,75 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_mult_ports: - -.. list-table:: **mult module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``flush_i`` - - in - - Flush - - CONTROLLER - - logic - - * - ``fu_data_i`` - - in - - FU data needed to execute instruction - - ISSUE_STAGE - - fu_data_t - - * - ``mult_valid_i`` - - in - - Mult instruction is valid - - ISSUE_STAGE - - logic - - * - ``result_o`` - - out - - Mult result - - ISSUE_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``mult_valid_o`` - - out - - Mult result is valid - - ISSUE_STAGE - - logic - - * - ``mult_ready_o`` - - out - - Mutl is ready - - ISSUE_STAGE - - logic - - * - ``mult_trans_id_o`` - - out - - Mult transaction ID - - ISSUE_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - diff --git a/docs/04_cv32a65x/design/source/port_multiplier.adoc b/docs/04_cv32a65x/design/source/port_multiplier.adoc new file mode 100644 index 0000000000..b759d487bd --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_multiplier.adoc @@ -0,0 +1,40 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_multiplier_ports]] + +.*multiplier module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`trans_id_i` | in | Multiplier transaction ID | Mult | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`mult_valid_i` | in | Multiplier instruction is valid | Mult | logic + +|`operation_i` | in | Multiplier operation | Mult | fu_op + +|`operand_a_i` | in | A operand | Mult | logic[CVA6Cfg.XLEN-1:0] + +|`operand_b_i` | in | B operand | Mult | logic[CVA6Cfg.XLEN-1:0] + +|`result_o` | out | Multiplier result | Mult | logic[CVA6Cfg.XLEN-1:0] + +|`mult_valid_o` | out | Mutliplier result is valid | Mult | logic + +|`mult_ready_o` | out | Multiplier FU is ready | Mult | logic + +|`mult_trans_id_o` | out | Multiplier transaction ID | Mult | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|=== + diff --git a/docs/04_cv32a65x/design/source/port_multiplier.rst b/docs/04_cv32a65x/design/source/port_multiplier.rst deleted file mode 100644 index 5dfca691c0..0000000000 --- a/docs/04_cv32a65x/design/source/port_multiplier.rst +++ /dev/null @@ -1,87 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_multiplier_ports: - -.. list-table:: **multiplier module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``trans_id_i`` - - in - - Multiplier transaction ID - - Mult - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``mult_valid_i`` - - in - - Multiplier instruction is valid - - Mult - - logic - - * - ``operation_i`` - - in - - Multiplier operation - - Mult - - fu_op - - * - ``operand_a_i`` - - in - - A operand - - Mult - - logic[CVA6Cfg.XLEN-1:0] - - * - ``operand_b_i`` - - in - - B operand - - Mult - - logic[CVA6Cfg.XLEN-1:0] - - * - ``result_o`` - - out - - Multiplier result - - Mult - - logic[CVA6Cfg.XLEN-1:0] - - * - ``mult_valid_o`` - - out - - Mutliplier result is valid - - Mult - - logic - - * - ``mult_ready_o`` - - out - - Multiplier FU is ready - - Mult - - logic - - * - ``mult_trans_id_o`` - - out - - Multiplier transaction ID - - Mult - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - diff --git a/docs/04_cv32a65x/design/source/port_ras.adoc b/docs/04_cv32a65x/design/source/port_ras.adoc new file mode 100644 index 0000000000..8e195dc53f --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_ras.adoc @@ -0,0 +1,34 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_ras_ports]] + +.*ras module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`push_i` | in | Push address in RAS | FRONTEND | logic + +|`pop_i` | in | Pop address from RAS | FRONTEND | logic + +|`data_i` | in | Data to be pushed | FRONTEND | logic[CVA6Cfg.VLEN-1:0] + +|`data_o` | out | Popped data | FRONTEND | ras_t + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +For any HW configuration,:: +* `flush_bp_i` input is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_ras.rst b/docs/04_cv32a65x/design/source/port_ras.rst deleted file mode 100644 index f0bdb4d401..0000000000 --- a/docs/04_cv32a65x/design/source/port_ras.rst +++ /dev/null @@ -1,61 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_ras_ports: - -.. list-table:: **ras module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``push_i`` - - in - - Push address in RAS - - FRONTEND - - logic - - * - ``pop_i`` - - in - - Pop address from RAS - - FRONTEND - - logic - - * - ``data_i`` - - in - - Data to be pushed - - FRONTEND - - logic[CVA6Cfg.VLEN-1:0] - - * - ``data_o`` - - out - - Popped data - - FRONTEND - - ras_t - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| For any HW configuration, -| ``flush_bp_i`` input is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_scoreboard.adoc b/docs/04_cv32a65x/design/source/port_scoreboard.adoc new file mode 100644 index 0000000000..ee4870f11f --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_scoreboard.adoc @@ -0,0 +1,97 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_scoreboard_ports]] + +.*scoreboard module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`sb_full_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`flush_unissued_instr_i` | in | Flush only un-issued instructions | TO_BE_COMPLETED | logic + +|`flush_i` | in | Flush whole scoreboard | TO_BE_COMPLETED | logic + +|`rd_clobber_gpr_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | ariane_pkg::fu_t[2**ariane_pkg::REG_ADDR_SIZE-1:0] + +|`rd_clobber_fpr_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | ariane_pkg::fu_t[2**ariane_pkg::REG_ADDR_SIZE-1:0] + +|`x_transaction_accepted_i` | in | none | none | logic + +|`x_issue_writeback_i` | in | none | none | logic + +|`x_id_i` | in | none | none | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`rs1_i` | in | rs1 operand address | issue_read_operands | logic[CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] + +|`rs1_o` | out | rs1 operand | issue_read_operands | logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] + +|`rs1_valid_o` | out | rs1 operand is valid | issue_read_operands | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`rs2_i` | in | rs2 operand address | issue_read_operands | logic[CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] + +|`rs2_o` | out | rs2 operand | issue_read_operands | logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] + +|`rs2_valid_o` | out | rs2 operand is valid | issue_read_operands | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`rs3_i` | in | rs3 operand address | issue_read_operands | logic[CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] + +|`rs3_o` | out | rs3 operand | issue_read_operands | rs3_len_t[CVA6Cfg.NrIssuePorts-1:0] + +|`rs3_valid_o` | out | rs3 operand is valid | issue_read_operands | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`commit_instr_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] + +|`commit_drop_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrCommitPorts-1:0] + +|`commit_ack_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrCommitPorts-1:0] + +|`decoded_instr_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0] + +|`orig_instr_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0][31:0] + +|`decoded_instr_valid_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`decoded_instr_ack_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`orig_instr_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0][31:0] + +|`issue_instr_valid_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`issue_ack_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic[CVA6Cfg.NrIssuePorts-1:0] + +|`resolved_branch_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | bp_resolve_t + +|`trans_id_i` | in | Transaction ID at which to write the result back | TO_BE_COMPLETED | logic[CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] + +|`wbdata_i` | in | Results to write back | TO_BE_COMPLETED | logic[CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.XLEN-1:0] + +|`ex_i` | in | Exception from a functional unit (e.g.: ld/st exception) | TO_BE_COMPLETED | exception_t[CVA6Cfg.NrWbPorts-1:0] + +|`wt_valid_i` | in | Indicates valid results | TO_BE_COMPLETED | logic[CVA6Cfg.NrWbPorts-1:0] + +|`x_we_i` | in | Cvxif we for writeback | TO_BE_COMPLETED | logic + +|`x_rd_i` | in | CVXIF destination register | ISSUE_STAGE | logic[4:0] + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As EnableAccelerator = 0,:: +* `issue_instr_o` output is tied to 0 +As IsRVFI = 0,:: +* `rvfi_issue_pointer_o` output is tied to 0 +* `rvfi_commit_pointer_o` output is tied to 0 + diff --git a/docs/04_cv32a65x/design/source/port_scoreboard.rst b/docs/04_cv32a65x/design/source/port_scoreboard.rst deleted file mode 100644 index ad5afa9757..0000000000 --- a/docs/04_cv32a65x/design/source/port_scoreboard.rst +++ /dev/null @@ -1,220 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_scoreboard_ports: - -.. list-table:: **scoreboard module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``sb_full_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``flush_unissued_instr_i`` - - in - - Flush only un-issued instructions - - TO_BE_COMPLETED - - logic - - * - ``flush_i`` - - in - - Flush whole scoreboard - - TO_BE_COMPLETED - - logic - - * - ``rd_clobber_gpr_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - ariane_pkg::fu_t[2**ariane_pkg::REG_ADDR_SIZE-1:0] - - * - ``rd_clobber_fpr_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - ariane_pkg::fu_t[2**ariane_pkg::REG_ADDR_SIZE-1:0] - - * - ``rs1_i`` - - in - - rs1 operand address - - issue_read_operands - - logic[CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] - - * - ``rs1_o`` - - out - - rs1 operand - - issue_read_operands - - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] - - * - ``rs1_valid_o`` - - out - - rs1 operand is valid - - issue_read_operands - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``rs2_i`` - - in - - rs2 operand address - - issue_read_operands - - logic[CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] - - * - ``rs2_o`` - - out - - rs2 operand - - issue_read_operands - - logic[CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] - - * - ``rs2_valid_o`` - - out - - rs2 operand is valid - - issue_read_operands - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``rs3_i`` - - in - - rs3 operand address - - issue_read_operands - - logic[CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] - - * - ``rs3_o`` - - out - - rs3 operand - - issue_read_operands - - rs3_len_t[CVA6Cfg.NrIssuePorts-1:0] - - * - ``rs3_valid_o`` - - out - - rs3 operand is valid - - issue_read_operands - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``commit_instr_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] - - * - ``commit_drop_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``commit_ack_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``decoded_instr_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - scoreboard_entry_t[CVA6Cfg.NrIssuePorts-1:0] - - * - ``orig_instr_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0][31:0] - - * - ``decoded_instr_valid_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``decoded_instr_ack_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``orig_instr_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0][31:0] - - * - ``issue_instr_valid_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``issue_ack_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrIssuePorts-1:0] - - * - ``resolved_branch_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - bp_resolve_t - - * - ``trans_id_i`` - - in - - Transaction ID at which to write the result back - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``wbdata_i`` - - in - - Results to write back - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.XLEN-1:0] - - * - ``ex_i`` - - in - - Exception from a functional unit (e.g.: ld/st exception) - - TO_BE_COMPLETED - - exception_t[CVA6Cfg.NrWbPorts-1:0] - - * - ``wt_valid_i`` - - in - - Indicates valid results - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrWbPorts-1:0] - - * - ``x_we_i`` - - in - - Cvxif we for writeback - - TO_BE_COMPLETED - - logic - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As EnableAccelerator = 0, -| ``issue_instr_o`` output is tied to 0 -| As IsRVFI = 0, -| ``rvfi_issue_pointer_o`` output is tied to 0 -| ``rvfi_commit_pointer_o`` output is tied to 0 - diff --git a/docs/04_cv32a65x/design/source/port_scoreboard.rst.ori b/docs/04_cv32a65x/design/source/port_scoreboard.rst.ori deleted file mode 100644 index ebd3fc64ef..0000000000 --- a/docs/04_cv32a65x/design/source/port_scoreboard.rst.ori +++ /dev/null @@ -1,229 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_scoreboard_ports: - -.. list-table:: scoreboard module IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - Connection - - Type - - * - ``clk_i`` - - in - - Clock - - TO_BE_COMPLETED - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - TO_BE_COMPLETED - - logic - - * - ``sb_full_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``flush_unissued_instr_i`` - - in - - flush only un-issued instructions - - TO_BE_COMPLETED - - logic - - * - ``flush_i`` - - in - - flush whole scoreboard - - TO_BE_COMPLETED - - logic - - * - ``unresolved_branch_i`` - - in - - we have an unresolved branch - - TO_BE_COMPLETED - - logic - - * - ``rd_clobber_gpr_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - ariane_pkg::fu_t[2**ariane_pkg::REG_ADDR_SIZE-1:0] - - * - ``rd_clobber_fpr_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - ariane_pkg::fu_t[2**ariane_pkg::REG_ADDR_SIZE-1:0] - - * - ``rs1_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[ariane_pkg::REG_ADDR_SIZE-1:0] - - * - ``rs1_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - riscv::xlen_t - - * - ``rs1_valid_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``rs2_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[ariane_pkg::REG_ADDR_SIZE-1:0] - - * - ``rs2_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - riscv::xlen_t - - * - ``rs2_valid_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``rs3_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[ariane_pkg::REG_ADDR_SIZE-1:0] - - * - ``rs3_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - rs3_len_t - - * - ``rs3_valid_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``commit_instr_o`` - - out - - TO_BE_COMPLETED - - COMMIT_STAGE - - ariane_pkg::scoreboard_entry_t[CVA6Cfg.NrCommitPorts-1:0] - - * - ``commit_ack_i`` - - in - - Advance the commit pointer when acknowledge - - COMMIT_STAGE - - logic[CVA6Cfg.NrCommitPorts-1:0] - - * - ``decoded_instr_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - ariane_pkg::scoreboard_entry_t - - * - ``orig_instr_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[31:0] - - * - ``decoded_instr_valid_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``decoded_instr_ack_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``issue_instr_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - ariane_pkg::scoreboard_entry_t - - * - ``orig_instr_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[31:0] - - * - ``issue_instr_valid_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``issue_ack_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``resolved_branch_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - ariane_pkg::bp_resolve_t - - * - ``trans_id_i`` - - in - - transaction ID at which to write the result back - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrWbPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] - - * - ``wbdata_i`` - - in - - write data in - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrWbPorts-1:0][riscv::XLEN-1:0] - - * - ``ex_i`` - - in - - exception from a functional unit (e.g.: ld/st exception) - - TO_BE_COMPLETED - - ariane_pkg::exception_t[CVA6Cfg.NrWbPorts-1:0] - - * - ``wt_valid_i`` - - in - - data in is valid - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrWbPorts-1:0] - - * - ``x_we_i`` - - in - - cvxif we for writeback - - TO_BE_COMPLETED - - logic - - * - ``rvfi_issue_pointer_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[ariane_pkg::TRANS_ID_BITS-1:0] - - * - ``rvfi_commit_pointer_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic[CVA6Cfg.NrCommitPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] diff --git a/docs/04_cv32a65x/design/source/port_serdiv.adoc b/docs/04_cv32a65x/design/source/port_serdiv.adoc new file mode 100644 index 0000000000..8c17be5cb2 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_serdiv.adoc @@ -0,0 +1,44 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_serdiv_ports]] + +.*serdiv module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`id_i` | in | Serdiv translation ID | Mult | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`op_a_i` | in | A operand | Mult | logic[WIDTH-1:0] + +|`op_b_i` | in | B operand | Mult | logic[WIDTH-1:0] + +|`rem` | in | Serdiv operation | Mult | logic[1:0]opcode_i,//0:udiv,2:urem,1:div,3: + +|`in_vld_i` | in | Serdiv instruction is valid | Mult | logic + +|`in_rdy_o` | out | Serdiv FU is ready | Mult | logic + +|`flush_i` | in | Flush | CONTROLLER | logic + +|`out_vld_o` | out | Serdiv result is valid | Mult | logic + +|`out_rdy_i` | in | Serdiv is ready | Mult | logic + +|`id_o` | out | Serdiv transaction ID | Mult | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`res_o` | out | Serdiv result | Mult | logic[WIDTH-1:0] + +|=== + diff --git a/docs/04_cv32a65x/design/source/port_serdiv.rst b/docs/04_cv32a65x/design/source/port_serdiv.rst deleted file mode 100644 index 467df2704a..0000000000 --- a/docs/04_cv32a65x/design/source/port_serdiv.rst +++ /dev/null @@ -1,99 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_serdiv_ports: - -.. list-table:: **serdiv module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``id_i`` - - in - - Serdiv translation ID - - Mult - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``op_a_i`` - - in - - A operand - - Mult - - logic[WIDTH-1:0] - - * - ``op_b_i`` - - in - - B operand - - Mult - - logic[WIDTH-1:0] - - * - ``rem`` - - in - - Serdiv operation - - Mult - - logic[1:0]opcode_i,//0:udiv,2:urem,1:div,3: - - * - ``in_vld_i`` - - in - - Serdiv instruction is valid - - Mult - - logic - - * - ``in_rdy_o`` - - out - - Serdiv FU is ready - - Mult - - logic - - * - ``flush_i`` - - in - - Flush - - CONTROLLER - - logic - - * - ``out_vld_o`` - - out - - Serdiv result is valid - - Mult - - logic - - * - ``out_rdy_i`` - - in - - Serdiv is ready - - Mult - - logic - - * - ``id_o`` - - out - - Serdiv transaction ID - - Mult - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``res_o`` - - out - - Serdiv result - - Mult - - logic[WIDTH-1:0] - - diff --git a/docs/04_cv32a65x/design/source/port_store_unit.adoc b/docs/04_cv32a65x/design/source/port_store_unit.adoc new file mode 100644 index 0000000000..35151db588 --- /dev/null +++ b/docs/04_cv32a65x/design/source/port_store_unit.adoc @@ -0,0 +1,78 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[_CVA6_store_unit_ports]] + +.*store_unit module* IO ports +|=== +|Signal | IO | Description | connexion | Type + +|`clk_i` | in | Subsystem Clock | SUBSYSTEM | logic + +|`rst_ni` | in | Asynchronous reset active low | SUBSYSTEM | logic + +|`flush_i` | in | Flush | CONTROLLER | logic + +|`stall_st_pending_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`no_st_pending_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`store_buffer_empty_o` | out | Store buffer is empty | TO_BE_COMPLETED | logic + +|`valid_i` | in | Store instruction is valid | ISSUE_STAGE | logic + +|`lsu_ctrl_i` | in | Data input | ISSUE_STAGE | lsu_ctrl_t + +|`pop_st_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`commit_i` | in | Instruction commit | TO_BE_COMPLETED | logic + +|`commit_ready_o` | out | TO_BE_COMPLETED | TO_BE_COMPLETED | logic + +|`valid_o` | out | Store result is valid | ISSUE_STAGE | logic + +|`trans_id_o` | out | Transaction ID | ISSUE_STAGE | logic[CVA6Cfg.TRANS_ID_BITS-1:0] + +|`result_o` | out | Store result | ISSUE_STAGE | logic[CVA6Cfg.XLEN-1:0] + +|`ex_o` | out | Store exception output | TO_BE_COMPLETED | exception_t + +|`translation_req_o` | out | Address translation request | TO_BE_COMPLETED | logic + +|`vaddr_o` | out | Virtual address | TO_BE_COMPLETED | logic[CVA6Cfg.VLEN-1:0] + +|`paddr_i` | in | Physical address | TO_BE_COMPLETED | logic[CVA6Cfg.PLEN-1:0] + +|`ex_i` | in | Exception raised before store | TO_BE_COMPLETED | exception_t + +|`page_offset_i` | in | Address to be checked | load_unit | logic[11:0] + +|`page_offset_matches_o` | out | Address check result | load_unit | logic + +|`req_port_i` | in | Data cache request | CACHES | dcache_req_o_t + +|`req_port_o` | out | Data cache response | CACHES | dcache_req_i_t + +|=== +Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below + +As RVA = False,:: +* `amo_valid_commit_i` input is tied to 0 +* `amo_req_o` output is tied to 0 +* `amo_resp_i` input is tied to 0 +As IsRVFI = 0,:: +* `rvfi_mem_paddr_o` output is tied to 0 +As RVH = False,:: +* `tinst_o` output is tied to 0 +* `hs_ld_st_inst_o` output is tied to 0 +* `hlvx_inst_o` output is tied to 0 +For any HW configuration,:: +* `dtlb_hit_i` input is tied to 1 + diff --git a/docs/04_cv32a65x/design/source/port_store_unit.rst b/docs/04_cv32a65x/design/source/port_store_unit.rst deleted file mode 100644 index eda5a1058b..0000000000 --- a/docs/04_cv32a65x/design/source/port_store_unit.rst +++ /dev/null @@ -1,173 +0,0 @@ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -.. _CVA6_store_unit_ports: - -.. list-table:: **store_unit module** IO ports - :header-rows: 1 - - * - Signal - - IO - - Description - - connexion - - Type - - * - ``clk_i`` - - in - - Subsystem Clock - - SUBSYSTEM - - logic - - * - ``rst_ni`` - - in - - Asynchronous reset active low - - SUBSYSTEM - - logic - - * - ``flush_i`` - - in - - Flush - - CONTROLLER - - logic - - * - ``stall_st_pending_i`` - - in - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``no_st_pending_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``store_buffer_empty_o`` - - out - - Store buffer is empty - - TO_BE_COMPLETED - - logic - - * - ``valid_i`` - - in - - Store instruction is valid - - ISSUE_STAGE - - logic - - * - ``lsu_ctrl_i`` - - in - - Data input - - ISSUE_STAGE - - lsu_ctrl_t - - * - ``pop_st_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``commit_i`` - - in - - Instruction commit - - TO_BE_COMPLETED - - logic - - * - ``commit_ready_o`` - - out - - TO_BE_COMPLETED - - TO_BE_COMPLETED - - logic - - * - ``valid_o`` - - out - - Store result is valid - - ISSUE_STAGE - - logic - - * - ``trans_id_o`` - - out - - Transaction ID - - ISSUE_STAGE - - logic[CVA6Cfg.TRANS_ID_BITS-1:0] - - * - ``result_o`` - - out - - Store result - - ISSUE_STAGE - - logic[CVA6Cfg.XLEN-1:0] - - * - ``ex_o`` - - out - - Store exception output - - TO_BE_COMPLETED - - exception_t - - * - ``translation_req_o`` - - out - - Address translation request - - TO_BE_COMPLETED - - logic - - * - ``vaddr_o`` - - out - - Virtual address - - TO_BE_COMPLETED - - logic[CVA6Cfg.VLEN-1:0] - - * - ``paddr_i`` - - in - - Physical address - - TO_BE_COMPLETED - - logic[CVA6Cfg.PLEN-1:0] - - * - ``ex_i`` - - in - - Exception raised before store - - TO_BE_COMPLETED - - exception_t - - * - ``page_offset_i`` - - in - - Address to be checked - - load_unit - - logic[11:0] - - * - ``page_offset_matches_o`` - - out - - Address check result - - load_unit - - logic - - * - ``req_port_i`` - - in - - Data cache request - - CACHES - - dcache_req_o_t - - * - ``req_port_o`` - - out - - Data cache response - - CACHES - - dcache_req_i_t - -Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below - -| As RVA = False, -| ``amo_valid_commit_i`` input is tied to 0 -| ``amo_req_o`` output is tied to 0 -| ``amo_resp_i`` input is tied to 0 -| As IsRVFI = 0, -| ``rvfi_mem_paddr_o`` output is tied to 0 -| As RVH = False, -| ``tinst_o`` output is tied to 0 -| ``hs_ld_st_inst_o`` output is tied to 0 -| ``hlvx_inst_o`` output is tied to 0 -| For any HW configuration, -| ``dtlb_hit_i`` input is tied to 1 - diff --git a/docs/04_cv32a65x/index.rst b/docs/04_cv32a65x/index.rst index 71e91ee8e5..ad7e6d23a7 100644 --- a/docs/04_cv32a65x/index.rst +++ b/docs/04_cv32a65x/index.rst @@ -6,4 +6,4 @@ CV32A65X documentation riscv/unpriv.rst riscv/priv.rst - design/source/index.rst + design/design.rst diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..d8b87bbcdb --- /dev/null +++ b/docs/README.md @@ -0,0 +1,26 @@ +# CVA6 documentation + +CVA6 documentation is published as a Read the Docs documentation. +It can be generated by running `make html` in this directory. + +## Configuration-specific manuals + +For each supported target (e.g. `cv32a65x`), there are two manuals included in the main documentation: a tailored RISC-V instruction set manual, and a design documentation. +These documents are generated as HTML files, are committed to the repository, and are included when generating the main documentation. + +### Instruction set manual + +Instruction set manuals (privileged & unprivileged) are based on the official RISC-V Instruction Set Manual repository. +Some parts are stripped down or annotated to only include what's relevant for each specific configuration. + +These manuals can be generated with: `make -C 04_cv32a65x/riscv priv-html unpriv-html`. +Replace `04_cv32a65x` with the desired target. + +### Design documentation + +Design documentation describes the internal architecture of the CVA6 processor. + +It can be generated with: `make -C 04_cv32a65x/design design-html`. + +Some of the files used in this documentation (`port_*.adoc`) are directly generated from the RTL. +They can be updated by running `python3 scripts/spec_builder.py`. diff --git a/docs/riscv-isa/src/config_define.adoc b/docs/common/config_define.adoc similarity index 100% rename from docs/riscv-isa/src/config_define.adoc rename to docs/common/config_define.adoc diff --git a/docs/conf.py b/docs/conf.py index 4c7c11135b..0454f4fbcb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -37,7 +37,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '*.yaml', '*.xml', +exclude_patterns = ['_build', '**/build', 'Thumbs.db', '.DS_Store', '*.yaml', '*.xml', 'csr-from-ip-xact/**/*_csr.md', 'csr-ip-xact/**/cva6_csr.*'] diff --git a/docs/design/build.mk b/docs/design/build.mk new file mode 100644 index 0000000000..6a90d2ef1f --- /dev/null +++ b/docs/design/build.mk @@ -0,0 +1,38 @@ +# Copyright 2024 Thales DIS France SAS +# Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); +# you may not use this file except in compliance with the License. +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +# You may obtain a copy of the License at https://solderpad.org/licenses/ +# +# Original Author: Jean-Roch COULON - Thales + +ifeq ($(CONFIG),) +$(error CONFIG must be defined) +endif + +# Path of current file, intended to be included by a configuration subfolder +design_dir := $(dir $(lastword $(MAKEFILE_LIST))) + +all: design-pdf design-html + +setup: + mkdir -p build + pwd + echo $(design_dir) + cp -r $(design_dir)/design-manual/* build + cp -r $(design_dir)/../../config/gen_from_riscv_config/$(CONFIG)/* build/source + cp -r $(design_dir)/../riscv-isa/riscv-isa-manual/docs-resources build + cp ../config/config.adoc build/source + cp $(design_dir)/../common/*.adoc build/source + cp -rf source build + +design-pdf: setup + cd build; make SKIP_DOCKER=true build/design.pdf + cp ./build/build/design.pdf design-$(CONFIG).pdf + +design-html: setup + cd build; make SKIP_DOCKER=true build/design.html + cp ./build/build/design.html design-$(CONFIG).html + +clean: + rm -rf build diff --git a/docs/design/design-manual/Makefile b/docs/design/design-manual/Makefile new file mode 100644 index 0000000000..e3bc3cbe1e --- /dev/null +++ b/docs/design/design-manual/Makefile @@ -0,0 +1,122 @@ +# Makefile for RISC-V ISA Manuals +# +# This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 +# International License. To view a copy of this license, visit +# http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to +# Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. +# +# SPDX-License-Identifier: CC-BY-SA-4.0 +# +# Description: +# +# This Makefile is designed to automate the process of building and packaging +# the documentation for RISC-V ISA Manuals. It supports multiple build targets +# for generating documentation in various formats (PDF, HTML, EPUB). +# +# Building with a preinstalled docker container is recommended. +# Install by running: +# +# docker pull riscvintl/riscv-docs-base-container-image:latest +# + +DOCS := design + +DATE ?= $(shell date +%Y-%m-%d) +DOCKER_IMG := riscvintl/riscv-docs-base-container-image:latest +ifneq ($(SKIP_DOCKER),true) + DOCKER_CMD = \ + docker run --rm -v ${PWD}/$@.workdir:/build -w /build \ + ${DOCKER_IMG} \ + /bin/sh -c + DOCKER_QUOTE := " +else + DOCKER_CMD = \ + cd $@.workdir && +endif + +WORKDIR_SETUP = \ + rm -rf $@.workdir && \ + mkdir -p $@.workdir && \ + cp -r source docs-resources $@.workdir + +WORKDIR_TEARDOWN = \ + mv $@.workdir/$@ $@ && \ + rm -rf $@.workdir + +SRC_DIR := source +BUILD_DIR := build + +DOCS_PDF := $(addprefix $(BUILD_DIR)/, $(addsuffix .pdf, $(DOCS))) +DOCS_HTML := $(addprefix $(BUILD_DIR)/, $(addsuffix .html, $(DOCS))) +DOCS_EPUB := $(addprefix $(BUILD_DIR)/, $(addsuffix .epub, $(DOCS))) + +ENV := LANG=C.utf8 +XTRA_ADOC_OPTS := +ASCIIDOCTOR_PDF := $(ENV) asciidoctor-pdf +ASCIIDOCTOR_HTML := $(ENV) asciidoctor +ASCIIDOCTOR_EPUB := $(ENV) asciidoctor-epub3 +OPTIONS := --trace \ + -a compress \ + -a mathematical-format=svg \ + -a pdf-fontsdir=docs-resources/fonts \ + -a pdf-theme=docs-resources/themes/riscv-pdf.yml \ + $(XTRA_ADOC_OPTS) \ + -D build \ + --failure-level=WARN \ + -a attribute-missing=warn +REQUIRES := + +.PHONY: all build clean build-container build-no-container build-docs build-pdf build-html build-epub + +all: build + +build-docs: $(DOCS_PDF) $(DOCS_HTML) $(DOCS_EPUB) +build-pdf: $(DOCS_PDF) +build-html: $(DOCS_HTML) +build-epub: $(DOCS_EPUB) + +ALL_SRCS := $(shell git ls-files $(SRC_DIR)) + +$(BUILD_DIR)/%.pdf: $(SRC_DIR)/%.adoc $(ALL_SRCS) + $(WORKDIR_SETUP) + $(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_PDF) $(OPTIONS) $(REQUIRES) $< $(DOCKER_QUOTE) + $(WORKDIR_TEARDOWN) + +$(BUILD_DIR)/%.html: $(SRC_DIR)/%.adoc $(ALL_SRCS) + $(WORKDIR_SETUP) + $(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_HTML) $(OPTIONS) $(REQUIRES) $< $(DOCKER_QUOTE) + $(WORKDIR_TEARDOWN) + +$(BUILD_DIR)/%.epub: $(SRC_DIR)/%.adoc $(ALL_SRCS) + $(WORKDIR_SETUP) + $(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_EPUB) $(OPTIONS) $(REQUIRES) $< $(DOCKER_QUOTE) + $(WORKDIR_TEARDOWN) + +build: + @echo "Checking if Docker is available..." + @if command -v docker >/dev/null 2>&1 ; then \ + echo "Docker is available, building inside Docker container..."; \ + $(MAKE) build-container; \ + else \ + echo "Docker is not available, building without Docker..."; \ + $(MAKE) build-no-container; \ + fi + +build-container: + @echo "Starting build inside Docker container..." + $(MAKE) build-docs + @echo "Build completed successfully inside Docker container." + +build-no-container: + @echo "Starting build..." + $(MAKE) SKIP_DOCKER=true build-docs + @echo "Build completed successfully." + +# Update docker image to latest +docker-pull-latest: + docker pull ${DOCKER_IMG} + +clean: + @echo "Cleaning up generated files..." + rm -rf $(BUILD_DIR) + @echo "Cleanup completed." diff --git a/docs/04_cv32a65x/design/source/AXI.rst b/docs/design/design-manual/source/AXI.adoc similarity index 86% rename from docs/04_cv32a65x/design/source/AXI.rst rename to docs/design/design-manual/source/AXI.adoc index 595f64397f..e8bf7b80d9 100644 --- a/docs/04_cv32a65x/design/source/AXI.rst +++ b/docs/design/design-manual/source/AXI.adoc @@ -1,4 +1,4 @@ -.. +//// Copyright 2023 Thales DIS France SAS Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -6,5 +6,7 @@ You may obtain a copy of the License at https://solderpad.org/licenses/ Original Author: Jean-Roch COULON - Thales +//// +[[axi]] -.. include:: ../../../01_cva6_user/AXI_Interface.rst +include::AXI_Interface.adoc[] diff --git a/docs/design/design-manual/source/AXI_Interface.adoc b/docs/design/design-manual/source/AXI_Interface.adoc new file mode 100644 index 0000000000..1da1cf31c0 --- /dev/null +++ b/docs/design/design-manual/source/AXI_Interface.adoc @@ -0,0 +1,895 @@ +//// + Copyright (c) 2023 OpenHW Group + Copyright (c) 2023 Thales + + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Original Author: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com) +//// + +[[cva6_axi]] +AXI +~~~ + +[[cva6_axi-introduction]] +Introduction +^^^^^^^^^^^^ +In this chapter, we describe in detail the restriction that apply to the supported features. + +In order to understand how the AXI memory interface behaves in CVA6, it is necessary to read the AMBA AXI and ACE Protocol Specification (https://developer.arm.com/documentation/ihi0022/hc) and this chapter. + +_Applicability of this chapter to configurations:_ + +[cols=",",options="header",] +|============================= +|Configuration |Implementation +|CV32A60AX |AXI included +|CV32A60X |AXI included +|============================= + +[[about-the-axi4-protocol]] +About the AXI4 protocol ++++++++++++++++++++++++ + +The AMBA AXI protocol supports high-performance, high-frequency system designs for communication between Manager and Subordinate components. + +The AXI protocol features are: + +* It is suitable for high-bandwidth and low-latency designs. +* High-frequency operation is provided, without using complex bridges. +* The protocol meets the interface requirements of a wide range of components. +* It is suitable for memory controllers with high initial access latency. +* Flexibility in the implementation of interconnect architectures is provided. +* It is backward-compatible with AHB and APB interfaces. + +The key features of the AXI protocol are: + +* Separate address/control and data phases. +* Support for unaligned data transfers, using byte strobes. +* Uses burst-based transactions with only the start address issued. +* Separate read and write data channels, that can provide low-cost Direct Memory Access (DMA). +* Support for issuing multiple outstanding addresses. +* Support for out-of-order transaction completion. +* Permits easy addition of register stages to provide timing closure. + +The present specification is based on: https://developer.arm.com/documentation/ihi0022/hc + + +[[axi4-and-cva6]] +AXI4 and CVA6 ++++++++++++++ + +The AXI bus protocol is used with the CVA6 processor as a memory interface. Since the processor is the one that initiates the connection with the memory, it will have a manager interface to send requests to the subordinate, which will be the memory. + +Features supported by CVA6 are the ones in the AMBA AXI4 specification and the Atomic Operation feature from AXI5. With restriction that apply to some features. + +This doesn’t mean that all the full set of signals available on an AXI interface are supported by the CVA6. Nevertheless, all required AXI signals are implemented. + +Supported AXI4 features are defined in AXI Protocol Specification sections: A3, A4, A5, A6 and A7. + +Supported AXI5 feature are defined in AXI Protocol Specification section: E1.1. + + +[[signal-description-section-a2]] +Signal Description (Section A2) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This section introduces the AXI memory interface signals of CVA6. Most of the signals are supported by CVA6, the tables summarizing the signals identify the exceptions. + +In the following tables, the *Src* column tells whether the signal is driven by Manager ou Subordinate. + +The AXI required and optional signals, and the default signals values that apply when an optional signal is not implemented are defined in AXI Protocol Specification section A9.3. + +[[global-signals-section-a2.1]] +Global signals (Section A2.1) ++++++++++++++++++++++++++++++ + +Table 2.1 shows the global AXI memory interface signals. + +[width="100%",cols="20%,20%,60%",options="header",] +|========================================================== +|*Signal* |*Src* |*Description* +|*ACLK* |Clock source a| +[verse] +-- +Global clock signal. Synchronous signals are sampled on the +rising edge of the global clock. +-- + +|*WDATA* |Reset source a| +[verse] +-- +Global reset signal. This signal is active-LOW. +-- + +|========================================================== + +[[write-address-channel-signals-section-a2.2]] +Write address channel signals (Section A2.2) +++++++++++++++++++++++++++++++++++++++++++++ + +Table 2.2 shows the AXI memory interface write address channel signals. Unless the description indicates otherwise, a signal can take any parameter if is supported. + +[width="100%",cols="15%,15%,15%,55%",options="header",] +|===================================================================== +|*Signal* |*Src* |*Support* |*Description* +|*AWID* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Identification tag for a write transaction. +CVA6 gives the id depending on the type of transaction. +See transaction_identifiers_label. +-- + +|*AWADDR* |M |Yes a| +[verse] +-- +The address of the first transfer in a write transaction. +-- + +|*AWLEN* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Length, the exact number of data transfers in a write +transaction. This information determines the number of +data transfers associated with the address. +All write transactions performed by CVA6 are of length 1. +(AWLEN = 0b00000000) +-- + +|*AWSIZE* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Size, the number of bytes in each data transfer in a write +transaction +See address_structure_label. +-- + +|*AWBURST* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Burst type, indicates how address changes between each +transfer in a write transaction. +All write transactions performed by CVA6 are of burst type +INCR. (AWBURST = 0b01) +-- + +|*AWLOCK* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Provides information about the atomic characteristics of a +write transaction. +-- + +|*AWCACHE* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Indicates how a write transaction is required to progress +through a system. +The subordinate is always of type Normal Non-cacheable Non-bufferable. +(AWCACHE = 0b0010) +-- + +|*AWPROT* |M |Yes a| +[verse] +-- +Protection attributes of a write transaction: +privilege, security level, and access type. +The value of AWPROT is always 0b000. +-- + +|*AWQOS* |M a| +[verse] +-- +No +(optional) +-- + + a| +[verse] +-- +Quality of Service identifier for a write transaction. +AWQOS = 0b0000 +-- + +|*AWREGION* |M a| +[verse] +-- +No +(optional) +-- + + a| +[verse] +-- +Region indicator for a write transaction. +AWREGION = 0b0000 +-- + +|*AWUSER* |M a| +[verse] +-- +No +(optional) +-- + + a| +[verse] +-- +User-defined extension for the write address channel. +AWUSER = 0b00 +-- + +|*AWATOP* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +AWATOP indicates the Properties of the Atomic Operation +used for a write transaction. +See atomic_transactions_label. +-- + +|*AWVALID* |M |Yes a| +[verse] +-- +Indicates that the write address channel signals are valid. +-- + +|*AWREADY* |S |Yes a| +[verse] +-- +Indicates that a transfer on the write address channel +can be accepted. +-- + +|===================================================================== + +[[write-data-channel-signals-section-a2.3]] +Write data channel signals (Section A2.3) ++++++++++++++++++++++++++++++++++++++++++ + +Table 2.3 shows the AXI write data channel signals. Unless the description indicates otherwise, a signal can take any parameter if is supported. + +[width="100%",cols="15%,15%,15%,55%",options="header",] +|========================================================== +|*Signal* |*Src* |*Support* |*Description* +|*WDATA* |M |Yes a| +[verse] +-- +Write data. +-- + +|*WSTRB* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Write strobes, indicate which byte lanes hold valid data +See data_read_and_write_structure_label. +-- + +|*WLAST* |M |Yes a| +[verse] +-- +Indicates whether this is the last data transfer in a write +transaction. +-- + +|*WUSER* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +User-defined extension for the write data channel. +-- + +|*WVALID* |M |Yes a| +[verse] +-- +Indicates that the write data channel signals are valid. +-- + +|*WREADY* |S |Yes a| +[verse] +-- +Indicates that a transfer on the write data channel can be +accepted. +-- + +|========================================================== + +[[write-response-channel-signals-section-a2.4]] +Write Response Channel signals (Section A2.4) ++++++++++++++++++++++++++++++++++++++++++++++ + +Table 2.4 shows the AXI write response channel signals. Unless the description indicates otherwise, a signal can take any parameter if is supported. + +[width="100%",cols="15%,15%,15%,55%",options="header",] +|============================================================= +|*Signal* |*Src* |*Support* |*Description* +|*BID* |S a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Identification tag for a write response. +CVA6 gives the id depending on the type of transaction. +See transaction_identifiers_label. +-- + +|*BRESP* |S |Yes a| +[verse] +-- +Write response, indicates the status of a write transaction. +See read_and_write_response_structure_label. +-- + +|*BUSER* |S a| +[verse] +-- +No +(optional) +-- + + a| +[verse] +-- +User-defined extension for the write response channel. +Not supported. +-- + +|*BVALID* |S |Yes a| +[verse] +-- +Indicates that the write response channel signals are valid. +-- + +|*BREADY* |M |Yes a| +[verse] +-- +Indicates that a transfer on the write response channel can be +accepted. +-- + +|============================================================= + +[[read-address-channel-signals-section-a2.5]] +Read address channel signals (Section A2.5) ++++++++++++++++++++++++++++++++++++++++++++ + +Table 2.5 shows the AXI read address channel signals. Unless the description indicates otherwise, a signal can take any parameter if is supported. + + +[width="100%",cols="15%,15%,15%,55%",options="header",] +|================================================================ +|*Signal* |*Src* |*Support* |*Description* +|*ARID* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Identification tag for a read transaction. +CVA6 gives the id depending on the type of transaction. +See transaction_identifiers_label. +-- + +|*ARADDR* |M a| +[verse] +-- +Yes +-- + + a| +[verse] +-- +The address of the first transfer in a read transaction. +-- + +|*ARLEN* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Length, the exact number of data transfers in a read +transaction. This information determines the number of data +transfers associated with the address. +All read transactions performed by CVA6 have a length equal to 0, +ICACHE_LINE_WIDTH/64 or DCACHE_LINE_WIDTH/64. +-- + +|*ARSIZE* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Size, the number of bytes in each data transfer in a read +transaction +See address_structure_label. +-- + +|*ARBURST* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Burst type, indicates how address changes between each +transfer in a read transaction. +All Read transactions performed by CVA6 are of burst type INCR. +(ARBURST = 0b01) +-- + +|*ARLOCK* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Provides information about the atomic characteristics of +a read transaction. +-- + +|*ARCACHE* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Indicates how a read transaction is required to progress +through a system. +The memory is always of type Normal Non-cacheable Non-bufferable. +(ARCACHE = 0b0010) +-- + +|*ARPROT* |M a| +[verse] +-- +Yes +-- + + a| +[verse] +-- +Protection attributes of a read transaction: +privilege, security level, and access type. +The value of ARPROT is always 0b000. +-- + +|*ARQOS* |M a| +[verse] +-- +No +(optional) +-- + + a| +[verse] +-- +Quality of Service identifier for a read transaction. +ARQOS= 0b00 +-- + +|*ARREGION* |M a| +[verse] +-- +No +(optional) +-- + + a| +[verse] +-- +Region indicator for a read transaction. +ARREGION= 0b00 +-- + +|*ARUSER* |M a| +[verse] +-- +No +(optional) +-- + + a| +[verse] +-- +User-defined extension for the read address channel. +ARUSER= 0b00 +-- + +|*ARVALID* |M a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Indicates that the read address channel signals are valid. +-- + +|*ARREADY* |S a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +Indicates that a transfer on the read address channel can be +accepted. +-- + +|================================================================ + +[[read-data-channel-signals-section-a2.6]] +Read data channel signals (Section A2.6) +++++++++++++++++++++++++++++++++++++++++ + +Table 2.6 shows the AXI read data channel signals. Unless the description indicates otherwise, a signal can take any parameter if is supported. + + +[width="100%",cols="15%,15%,15%,55%",options="header",] +|================================================================== +|*Signal* |*Src* |*Support* |*Description* +|*RID* |S a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +The ID tag of the read data transfer. +CVA6 gives the id depending on the type of transaction. +See transaction_identifiers_label. +-- + +|*RDATA* |S |Yes a| +[verse] +-- +Read data. +-- + +|*RLAST* |S |Yes a| +[verse] +-- +Indicates whether this is the last data transfer in a read +transaction. +-- + +|*RUSER* |S a| +[verse] +-- +Yes +(optional) +-- + + a| +[verse] +-- +User-defined extension for the read data channel. +Not supported. +-- + +|*RVALID* |S |Yes a| +[verse] +-- +Indicates that the read data channel signals are valid. +-- + +|*RREADY* |M |Yes a| +[verse] +-- +Indicates that a transfer on the read data channel can be accepted. +-- + +|================================================================== + +[[single-interface-requirements-transaction-structure-section-a3.4]] +Single Interface Requirements: Transaction structure (Section A3.4) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This section describes the structure of transactions. The following sections define the address, data, and response +structures + +[[address_structure_label]] +Address structure (Section A3.4.1) +++++++++++++++++++++++++++++++++++ + +The AXI protocol is burst-based. The Manager begins each burst by driving control information and the address of the first byte in the transaction to the Subordinate. As the burst progresses, the Subordinate must calculate the addresses of subsequent transfers in the burst. + +*Burst length* + +The burst length is specified by: + +* `ARLEN[7:0]`, for read transfers +* `AWLEN[7:0]`, for write transfers + +The burst length for AXI4 is defined as: `Burst_Length = AxLEN[3:0] + 1`. + +CVA6 has some limitation governing the use of bursts: + +* _All read transactions performed by CVA6 are of burst length equal to 0, ICACHE_LINE_WIDTH/64 or DCACHE_LINE_WIDTH/64._ +* _All write transactions performed by CVA6 are of burst length equal to 1._ + +*Burst size* + +The maximum number of bytes to transfer in each data transfer, or beat, in a burst, is specified by: + +* `ARSIZE[2:0]`, for read transfers +* `AWSIZE[2:0]`, for write transfers + +_The maximum value can be taking by AxSIZE is log2(AXI DATA WIDTH/8) (8 bytes by transfer)._ +_If(RV32) AWSIZE < 3 (The maximum store size is 4 bytes)_ + +*Burst type* + +The AXI protocol defines three burst types: + +* *FIXED* +* *INCR* +* *WRAP* + +The burst type is specified by: + +* `ARBURST[1:0]`, for read transfers +* `AWBURST[1:0]`, for write transfers + +_All transactions performed by CVA6 are of burst type INCR. (AxBURST = 0b01)_ + +[[data_read_and_write_structure_label]] +Data read and write structure: (Section A3.4.4) ++++++++++++++++++++++++++++++++++++++++++++++++ + +*Write strobes* + +The `WSTRB[n:0]` signals when HIGH, specify the byte lanes of the data bus that contain valid information. There is one write strobe +for each 8 bits of the write data bus, therefore `WSTRB[n]` corresponds to `WDATA[(8n)+7: (8n)]`. + +_Write Strobe width is equal to (AXI_DATA_WIDTH/8) (n = (AXI_DATA_WIDTH/8)-1)._ + +_The size of transactions performed by cva6 is equal to the number of data byte lanes containing valid information._ +_This means 1, 2, 4, ... or (AXI_DATA_WIDTH/8) byte lanes containing valid information._ +_CVA6 doesn't perform unaligned memory acces, therefore the WSTRB take only combination of aligned access_ +_If(RV32) WSTRB < 255 (Since AWSIZE lower than 3, so the data bus cannot have more than 4 valid byte lanes)_ + +*Unaligned transfers* + +For any burst that is made up of data transfers wider than 1 byte, the first bytes accessed might be unaligned with the natural +address boundary. For example, a 32-bit data packet that starts at a byte address of 0x1002 is not aligned to the natural 32-bit +transfer size. + +_CVA6 does not perform Unaligned transfers._ + +[[read_and_write_response_structure_label]] +Read and write response structure (Section A3.4.5) +++++++++++++++++++++++++++++++++++++++++++++++++++ + +The AXI protocol provides response signaling for both read and write transactions: + +* For read transactions, the response information from the Subordinate is signaled on the read data channel. +* For write transactions, the response information is signaled on the write response channel. + +CVA6 does not consider the responses sent by the memory except in the exclusive Access ( `XRESP[1:0]` = 0b01 ). + +[[transaction-attributes-memory-types-section-a4]] +Transaction Attributes: Memory types (Section A4) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This section describes the attributes that determine how a transaction should be treated by the AXI subordinate that is connected to the CVA6. + +`AxCACHE` always takeq 0b0010. The subordinate should be a Normal Non-cacheable Non-bufferable. + +The required behavior for Normal Non-cacheable Non-bufferable memory is: + +* The write response must be obtained from the final destination. +* Read data must be obtained from the final destination. +* Transactions are modifiable. +* Writes can be merged. + +[[transaction_identifiers_label]] +Transaction Identifiers (Section A5) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The AXI protocol includes AXI ID transaction identifiers. A Manager can use these to identify separate transactions that must be returned in order. + +The CVA6 identify each type of transaction with a specific ID: + +* For read transaction, id can be 0 or 1. (0 for instruction fetch and 1 for data) +* For write transaction, id = 1. +* For Atomic operation, id = 3. This ID must be sent in the write channels and also in the read channel if the transaction performed requires response data. +* For Exclusive transaction, id = 3. + +[[axi-ordering-model-section-a6]] +AXI Ordering Model (Section A6) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +[[axi-ordering-model-overview-section-a6.1]] +AXI ordering model overview (Section A6.1) +++++++++++++++++++++++++++++++++++++++++++ + +The AXI ordering model is based on the use of the transaction identifier, which is signaled on `ARID` or `AWID`. + +Transaction requests on the same channel, with the same ID and destination are guaranteed to remain in order. + +Transaction responses with the same ID are returned in the same order as the requests were issued. + +Write transaction requests, with the same destination are guaranteed to remain in order. Because all write transaction performed by CVA6 have the same ID. + +CVA6 can perform multiple outstanding write address transactions. + +CVA6 cannot perform a Read transaction and a Write one at the same time. Therefore there no ordering problems between Read and write transactions. + +The ordering model does not give any ordering guarantees between: + +* Transactions from different Managers +* Read Transactions with different IDs +* Transactions to different Memory locations + +If the CVA6 requires ordering between transactions that have no ordering guarantee, the Manager must wait to receive a response to the first transaction before issuing the second transaction. + +[[memory-locations-and-peripheral-regions-section-a6.2]] +Memory locations and Peripheral regions (Section A6.2) +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The address map in AMBA is made up of Memory locations and Peripheral regions. But the AXI is associated to the memory interface of CVA6. + +A Memory location has all of the following properties: + +* A read of a byte from a Memory location returns the last value that was written to that byte location. +* A write to a byte of a Memory location updates the value at that location to a new value that is obtained by a subsequent read of that location. +* Reading or writing to a Memory location has no side-effects on any other Memory location. +* Observation guarantees for Memory are given for each location. +* The size of a Memory location is equal to the single-copy atomicity size for that component. + +[[transactions-and-ordering-section-a6.3]] +Transactions and ordering (Section A6.3) +++++++++++++++++++++++++++++++++++++++++ + +A transaction is a read or a write to one or more address locations. The locations are determined by AxADDR and any relevant qualifiers such as the Non-secure bit in `AxPROT`. + +* Ordering guarantees are given only between accesses to the same Memory location or Peripheral region. +* A transaction to a Peripheral region must be entirely contained within that region. +* A transaction that spans multiple Memory locations has multiple ordering guarantees. + +Transaction performed by CVA6 is of type Normal, because `AxCACHE[1]` is asserted. + +Normal transactions are used to access Memory locations and are not expected to be used to access Peripheral regions. + +A Normal access to a Peripheral region must complete in a protocol-compliant manner, but the result is IMPLEMENTATION DEFINED. + +A write transaction performed by CVA6 is Non-bufferable (It is not possible to send an early response before the transaction reach the final destination), because `AxCACHE[0]` is deasserted. + +[[ordered-write-observation-section-a6.8]] +Ordered write observation (Section A6.8) +++++++++++++++++++++++++++++++++++++++++ + +To improve compatibility with interface protocols that support a different ordering model, a Subordinate interface can give stronger ordering guarantees for write transactions. A stronger ordering guarantee is known as Ordered Write Observation. + +_The CVA6 AXI interface exhibits Ordered Write Observation, so the Ordered_Write_Observation property is True._ + +An interface that exhibits Ordered Write Observation gives guarantees for write transactions that are not dependent on the destination or address: + +* A write W1 is guaranteed to be observed by a write W2, where W2 is issued after W1, from the same Manager, with the same ID. + +[[atomic_transactions_label]] +Atomic transactions (Section E1.1) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +AMBA 5 introduces Atomic transactions, which perform more than just a single access and have an operation that is associated with the transaction. Atomic transactions enable sending the operation to the data, permitting the operation to be performed closer to where the data is located. Atomic transactions are suited to situations where the data is located a significant distance from the agent that must perform the operation. + +_If(RVA) AWATOP = 0 (If AMO instructions are not supported, CVA6 cannot perform Atomic transaction)_ + +_CVA6 supports just the AtomicLoad and AtomicSwap transaction. So `AWATOP[5:4]` can be 00, 10 or 11._ + +_CVA6 performs only little-endian operation. So `AWATOP[3]` = 0._ + +_For AtomicLoad, CVA6 supports all arithmetic operations encoded on the lower-order `AWATOP[2:0]` signals._ + +[[cva6-constraints]] +CVA6 Constraints +^^^^^^^^^^^^^^^^ + +This section describes cross-cases between several features that are not supported by CVA6. + +* ARID = 0 && ARSIZE = log(AXI_DATA_WIDTH/8), CVA6 always requests max number of words in case of read transaction with ID 0 (instruction fetch) +* if(RV32) ARSIZE != 3 && ARLEN = 0 && ARID = 1, the maximum load instruction size is 4 bytes +* if(!RVA) AxLOCK = 0, if AMO instructions are not supported, CVA6 cannot perform exclusive transaction +* if(RVA) AxLOCK = 1 => AxSIZE > 1, CVA6 doesn't perform exclusive transaction with size lower than 4 bytes diff --git a/docs/design/design-manual/source/CSRs.adoc b/docs/design/design-manual/source/CSRs.adoc new file mode 100644 index 0000000000..7c1c0b7b64 --- /dev/null +++ b/docs/design/design-manual/source/CSRs.adoc @@ -0,0 +1,3 @@ +[[csrs]] + +include::csr/csr.adoc[] \ No newline at end of file diff --git a/docs/04_cv32a65x/design/source/csr_list.rst b/docs/design/design-manual/source/CVXIF.adoc similarity index 85% rename from docs/04_cv32a65x/design/source/csr_list.rst rename to docs/design/design-manual/source/CVXIF.adoc index 07373e9c5f..359125ad06 100644 --- a/docs/04_cv32a65x/design/source/csr_list.rst +++ b/docs/design/design-manual/source/CVXIF.adoc @@ -1,4 +1,4 @@ -.. +//// Copyright 2023 Thales DIS France SAS Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -6,6 +6,8 @@ You may obtain a copy of the License at https://solderpad.org/licenses/ Original Author: Jean-Roch COULON - Thales +//// +[[cvxif]] -.. include:: ../../../csr-from-ip-xact/cv32a60x/csr_list.rst +include::CVX_Interface_Coprocessor.adoc[] diff --git a/docs/design/design-manual/source/CVX_Interface_Coprocessor.adoc b/docs/design/design-manual/source/CVX_Interface_Coprocessor.adoc new file mode 100644 index 0000000000..4290a1372e --- /dev/null +++ b/docs/design/design-manual/source/CVX_Interface_Coprocessor.adoc @@ -0,0 +1,294 @@ +[[cva6_cvx_interface_coprocessor]] +CV-X-IF Interface and Coprocessor +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The CV-X-IF interface of CVA6 allows to extend its supported instruction +set with external coprocessors. + +_Applicability of this chapter to configurations:_ + +[cols=",",options="header",] +|============================= +|Configuration |Implementation +|CV32A60AX |CV-X-IF included +|CV32A60X |CV-X-IF included +|CV64A6_MMU |CV-X-IF included +|============================= + +[[cv-x-if-interface-specification]] +CV-X-IF interface specification +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +[[description]] +Description ++++++++++++ + +This design specification presents global functionalities of +Core-V-eXtension-Interface (XIF, CVXIF, CV-X-IF, X-interface) in the CVA6 core. + + +[source,sourceCode,text] +---- +The CORE-V X-Interface is a RISC-V eXtension interface that provides a +generalized framework suitable to implement custom coprocessors and ISA +extensions for existing RISC-V processors. + +--core-v-xif Readme, https://github.com/openhwgroup/core-v-xif +---- + +The specification of the CV-X-IF bus protocol can be found at [CV-X-IF]. + +CV-X-IF aims to: + +* Create interfaces to connect a coprocessor to the CVA6 to execute instructions. +* Offload CVA6 illegal instrutions to the coprocessor to be executed. +* Get the results of offloaded instructions from the coprocessor so they are written back into the CVA6 register file. +* Add standard RISC-V instructions unsupported by CVA6 or custom instructions and implement them in a coprocessor. +* Kill offloaded instructions to allow speculative execution in the coprocessor. (Unsupported in CVA6 yet) +* Connect the coprocessor to memory via the CVA6 Load and Store Unit. (Unsupported in CVA6 yet) + +The coprocessor operates like another functional unit so it is connected +to the CVA6 in the execute stage. + +Only the 3 mandatory interfaces from the CV-X-IF specification (issue, commit and result +) have been implemented. +Compressed interface, Memory Interface and Memory result interface are not yet +implemented in the CVA6. + +[[supported-parameters]] +Supported Parameters +++++++++++++++++++++ + +The following table presents CVXIF parameters supported by CVA6. + +[cols=",,",options="header",] +|============================================= +|Signal |Value |Description +|*X_NUM_RS* |int: 2 or 3 (configurable) a| +[verse] +-- +Number of register file read ports that can +be used by the eXtension interface +-- + + | +|*X_ID_WIDTH* |int: 3 a| +[verse] +-- +Identification width for the eXtension +interface +-- + + | +|*X_MEM_WIDTH* |n/a (feature not supported) a| +[verse] +-- +Memory access width for loads/stores via the +eXtension interface +-- + + | +|*X_RFR_WIDTH* |int: `XLEN` (32 or 64) a| +[verse] +-- +Register file read access width for the +eXtension interface +-- + + | +|*X_RFW_WIDTH* |int: `XLEN` (32 or 64) a| +[verse] +-- +Register file write access width for the +eXtension interface +-- + + | +|*X_MISA* |logic[31:0]: 0x0000_0000 a| +[verse] +-- +MISA extensions implemented on the eXtension +interface +-- + + | +|============================================= + +[[cv-x-if-enabling]] +CV-X-IF Enabling +++++++++++++++++ + +CV-X-IF can be enabled or disabled via the `CVA6ConfigCvxifEn` parameter in the SystemVerilog source code. + +[[illegal-instruction-decoding]] +Illegal instruction decoding +++++++++++++++++++++++++++++ + +The CVA6 decoder module detects illegal instructions for the CVA6, prepares exception field +with relevant information (exception code "ILLEGAL INSTRUCTION", instruction value). + +The exception valid flag is raised in CVA6 decoder when CV-X-IF is disabled. Otherwise +it is not raised at this stage because the decision belongs to the coprocessor +after the offload process. + +[[rs3-support]] +RS3 support ++++++++++++ + +The number of source registers used by the CV-X-IF coprocessor is configurable with 2 or +3 source registers. + +If CV-X-IF is enabled and configured with 3 source registers, +a third read port is added to the CVA6 general purpose register file. + +[[description-of-interface-connections-between-cva6-and-coprocessor]] +Description of interface connections between CVA6 and Coprocessor ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In CVA6 execute stage, there is a new functional unit dedicated to drive the CV-X-IF interfaces. +Here is _how_ and _to what_ CV-X-IF interfaces are connected to the CVA6. + +* Issue interface:: + ** Request;; + *** [verse] + -- + Operands are connected to `issue_req.rs` signals + -- + *** [verse] + -- + Scoreboard transaction id is connected to `issue_req.id` signal. + Therefore scoreboard ids and offloaded instruction ids are linked + together (equal in this implementation). It allows the CVA6 to do out + of order execution with the coprocessor in the same way as other + functional units. + -- + *** [verse] + -- + Undecoded instruction is connected to `issue_req.instruction` + -- + *** [verse] + -- + Valid signal for CVXIF functional unit is connected to + `issue_req.valid` + -- + *** [verse] + -- + All `issue_req.rs_valid` signals are set to 1. The validity of source + registers is assured by the validity of valid signal sent from issue stage. + -- + ** Response;; + *** [verse] + -- + If `issue_resp.accept` is set during a transaction (i.e. issue valid + and ready are set), the offloaded instruction is accepted by the coprocessor + and a result transaction will happen. + -- + *** [verse] + -- + If `issue_resp.accept` is not set during a transaction, the offloaded + instruction is illegal and an illegal instruction exception will be + raised as soon as no result transaction are written on the writeback bus. + -- +* Commit interface:: + ** [verse] + -- + Valid signal of commit interface is connected to the valid signal of + issue interface. + -- + ** [verse] + -- + Id signal of commit interface is connected to issue interface id signal + (i.e. scoreboard id). + -- + ** [verse] + -- + Killing of offload instruction is never set. (Unsupported feature) + -- + ** [verse] + -- + Therefore all accepted offloaded instructions are commited to their + execution and no killing of instruction is possible in this implementation. + -- +* Result interface:: + ** Request;; + *** [verse] + -- + Ready signal of result interface is always set as CVA6 is always ready + to take a result from coprocessor for an accepted offloaded instruction. + -- + ** Response;; + *** [verse] + -- + Result response is directly connected to writeback bus of the CV-X-IF + functionnal unit. + -- + *** [verse] + -- + Valid signal of result interface is connected to valid signal of + writeback bus. + -- + *** [verse] + -- + Id signal of result interface is connected to scoreboard id of + writeback bus. + -- + *** [verse] + -- + Write enable signal of result interface is connected to a dedicated CV-X-IF WE + signal in CVA6 which signals scoreboard if a writeback should happen + or not to the CVA6 register file. + -- + *** [verse] + -- + `exccode` and `exc` signal of result interface are connected to exception + signals of writeback bus. Exception from coprocessor does not write + the `tval` field in exception signal of writeback bus. + -- + *** [verse] + -- + Three registers are added to hold illegal instruction information in + case a result transaction and a non-accepted issue transaction happen + in the same cycle. Result transactions will be written to the writeback + bus in this case having priority over the non-accepted instruction due + to being linked to an older offloaded instruction. Once the writeback + bus is free, an illegal instruction exception will be raised thanks to + information held in these three registers. + -- + +[[coprocessor-recommendations-for-use-with-cva6s-cv-x-if]] +Coprocessor recommendations for use with CVA6's CV-X-IF +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +CVA6 supports all coprocessors supporting the CV-X-IF specification with the exception of : + +* Coprocessor requiring the Memory interface and Memory result interface (not implemented in CVA6 yet).:: + ** All memory transaction should happen via the Issue interface, i.e. Load into CVA6 register file + then initialize an issue transaction. +* Coprocessor requiring the Compressed interface (not implemented in CVA6 yet).:: + ** RISC-V Compressed extension (RVC) is already implemented in CVA6 User Space for custom compressed instruction + is not big enough to have RVC and a custom compressed extension. +* Stateful coprocessors.:: + ** CVA6 will commit on the Commit interface all its issue transactions. Speculation + informations are only kept in the CVA6 and speculation process is only done in CVA6. + The coprocessor shall be stateless otherwise it will not be able to revert its state if CVA6 kills an + in-flight instruction (in case of mispredict or flush). + +[[how-to-use-cva6-without-cv-x-if-interface]] +How to use CVA6 without CV-X-IF interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Select a configuration with `CVA6ConfigCvxifEn` parameter disabled or change it for your configuration. + +Never let the CV-X-IF interface unconnected with the `CVA6ConfigCvxifEn` parameter enabled. + +[[how-to-design-a-coprocessor-for-the-cv-x-if-interface]] +How to design a coprocessor for the CV-X-IF interface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +_The team is looking for a contributor to write this section._ + +[[how-to-program-a-cv-x-if-coprocessor]] +How to program a CV-X-IF coprocessor +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +_The team is looking for a contributor to write this section._ diff --git a/docs/design/design-manual/source/Traps_Interrupts_Exceptions.adoc b/docs/design/design-manual/source/Traps_Interrupts_Exceptions.adoc new file mode 100644 index 0000000000..078e02584e --- /dev/null +++ b/docs/design/design-manual/source/Traps_Interrupts_Exceptions.adoc @@ -0,0 +1,129 @@ +[[traps-interrupts-exceptions]] +Traps, Interrupts, Exceptions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Traps are composed of interrupts and exceptions. +Interrupts are asynchronous events whereas exceptions are synchronous ones. +On one hand, interrupts are occuring independently of the instructions +(mainly raised by peripherals or debug module). +On the other hand, an instruction may raise exceptions synchronously. + +[[raising-traps]] +Raising Traps +^^^^^^^^^^^^^ + +When a trap is raised, the behaviour of the CVA6 core depends on +several CSRs and some CSRs are modified. + +[[configuration-csrs]] +Configuration CSRs +++++++++++++++++++ + +CSRs having an effect on the core behaviour when a trap occurs are: + +* `mstatus` and `sstatus`: several fields control the core behaviour like interrupt enable (`MIE`, `SIE`) +* `mtvec` and `stvec`: specifies the address of trap handler. +* `medeleg`: specifies which exceptions can be handled by a lower privileged mode (S-mode) +* `mideleg`: specifies which interrupts can be handled by a lower privileged mode (S-mode) + +[[modified-csrs]] +Modified CSRs ++++++++++++++ + +CSRs (or fields) updated by the core when a trap occurs are: + +* `mstatus` or `sstatus`: several fields are updated like previous privilege mode (`MPP`, `SPP`), previous interrupt enabled (`MPIE`, SPIE``) +* `mepc` or `sepc`: updated with the virtual address of the interrupted instruction or the instruction raising the exception. +* `mcause` or `scause`: updated with a code indicating the event causing the trap. +* `mtval` or `stval`: updated with exception specific information like the faulting virtual address + +[[supported-exceptions]] +Supported exceptions +++++++++++++++++++++ + +The following exceptions are supported by the CVA6: + +* instruction address misaligned +** control flow instruction with misaligned target + +* instruction access fault +** access to PMP region without execute permissions + +* illegal instruction: +** unimplemented CSRs +** unsupported extensions + +* breakpoint (`EBREAK`) + +* load address misaligned: +** `LH` at 2n+1 address +** `LW` at 4n+1, 4n+2, 4n+3 address + +* load access fault +** access to PMP region without read permissions + +* store/AMO address misaligned +** `SH` at 2n+1 address +** `SW` at 4n+1, 4n+2, 4n+3 address + +* store/AMO access fault +** access to PMP region without write permissions + +* environment call (`ECALL`) from U-mode + +* environment call (`ECALL`) from S-mode + +* environment call (`ECALL`) from M-mode + +* instruction page fault + +* load page fault +** access to effective address without read permissions + +* store/AMO page fault +** access to effective address without write permissions + +* debug request (custom) via debug interface + +Note: all exceptions are supported except the ones linked to the hypervisor extension + +[[trap-return]] +Trap return +^^^^^^^^^^^ + +Trap handler ends with trap return instruction (`MRET`, `SRET`). The behaviour of the CVA6 core depends on several CSRs. + +[[configuration-csrs-1]] +Configuration CSRs +++++++++++++++++++ + +CSRs having an effect on the core behaviour when returning from a trap are: + +* `mstatus`: several fields control the core behaviour like previous privilege mode (`MPP`, `SPP`), previous interrupt enabled (`MPIE`, `SPIE`) + +[[modified-csrs-1]] +Modified CSRs ++++++++++++++ + +CSRs (or fields) updated by the core when returning from a trap are: + +* `mstatus`: several fields are updated like interrupt enable (`MIE`, `SIE`), modify privilege (`MPRV`) + +[[interrupts]] +Interrupts +^^^^^^^^^^ + +* external interrupt: `irq_i` signal +* software interrupt (inter-processor interrupt): `ipi_i` signal +* timer interrupt: `time_irq_i` signal +* debug interrupt: `debug_req_i` signal + +These signals are level sensitive. It means the interrupt is raised until it is cleared. + +The exception code field (`mcause` CSR) depends on the interrupt source. + +[[wait-for-interrupt]] +Wait for Interrupt +^^^^^^^^^^^^^^^^^^ + +* CVA6 implementation: `WFI` stalls the core. The instruction is not available in U-mode (raise illegal instruction exception). Such exception is also raised when `TW=1` in `mstatus`. diff --git a/docs/04_cv32a65x/design/source/architecture.rst b/docs/design/design-manual/source/architecture.adoc similarity index 57% rename from docs/04_cv32a65x/design/source/architecture.rst rename to docs/design/design-manual/source/architecture.adoc index 8ddd680a17..7de7ea334a 100644 --- a/docs/04_cv32a65x/design/source/architecture.rst +++ b/docs/design/design-manual/source/architecture.adoc @@ -1,4 +1,4 @@ -.. +//// Copyright 2022 Thales DIS design services SAS Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -6,42 +6,29 @@ You may obtain a copy of the License at https://solderpad.org/licenses/ Original Author: Jean-Roch COULON - Thales +//// - - +[[architecture-and-modules]] Architecture and Modules -======================== +------------------------ -The CV32A65X is fully synthesizable. It has been designed mainly for ASIC designs, but FPGA synthesis is supported as well. +The {ohg-config} is fully synthesizable. It has been designed mainly for ASIC designs, but FPGA synthesis is supported as well. For ASIC synthesis, the whole design is completely synchronous and uses positive-edge triggered flip-flops. The core occupies an area of about 80 kGE. The clock frequency can be more than 1GHz depending of technology. -The CV32A65X subsystem is composed of 8 modules. - -.. figure:: ../images/subsystems.png - :name: CV32A6 v0.1.0 modules - :align: center - :alt: +The {ohg-config} subsystem is composed of 8 modules. - CV32A65X modules +image:subsystems.png[{ohg-config} modules] Connections between modules are illustrated in the following block diagram. FRONTEND, DECODE, ISSUE, EXECUTE, COMMIT and CONTROLLER are part of the pipeline. And CACHES implements the instruction and data caches and CSRFILE contains registers. -.. figure:: ../images/CV32A65X_subsystems.png - :name: CV32A65X subsystem - :align: center - :alt: - - CV32A65X pipeline and modules - -.. toctree:: - :hidden: +image:{ohg-config}_subsystems.png[{ohg-config} pipeline and modules] - cv32a6_frontend - cva6_id_stage - cva6_issue_stage - cv32a6_execute - cva6_commit_stage - cva6_controller - cva6_csr_regfile - cva6_caches +include::cv32a6_frontend.adoc[] +include::cva6_id_stage.adoc[] +include::cva6_issue_stage.adoc[] +include::cv32a6_execute.adoc[] +include::cva6_commit_stage.adoc[] +include::cva6_controller.adoc[] +include::cva6_csr_regfile.adoc[] +include::cva6_caches.adoc[] diff --git a/docs/04_cv32a65x/design/source/cv32a6_execute.rst b/docs/design/design-manual/source/cv32a6_execute.adoc similarity index 75% rename from docs/04_cv32a65x/design/source/cv32a6_execute.rst rename to docs/design/design-manual/source/cv32a6_execute.adoc index 57d4899342..55f98719cf 100644 --- a/docs/04_cv32a65x/design/source/cv32a6_execute.rst +++ b/docs/design/design-manual/source/cv32a6_execute.adoc @@ -1,12 +1,11 @@ -.. _CVA6_EX_STAGE: +[[CVA6_EX_STAGE]] -############### EX_STAGE Module -############### +~~~~~~~~~~~~~~~ -*********** +[[ex_stage-description]] Description -*********** +^^^^^^^^^^^ The EX_STAGE module is a logical stage which implements the execute stage. It encapsulates the following functional units: ALU, Branch Unit, CSR buffer, Mult, load and store and CVXIF. @@ -16,89 +15,73 @@ The module is connected to: * ID_STAGE module provides scoreboard entry. * -.. include:: port_ex_stage.rst - -************* +[[ex_stage-functionality]] Functionality -************* +^^^^^^^^^^^^^ TO BE COMPLETED -********** +[[ex_stage-submodules]] Submodules -********** - -.. figure:: ../images/ex_stage_modules.png - :name: EX_STAGE submodules - :align: center - :alt: - - EX_STAGE submodules +^^^^^^^^^^ +image:ex_stage_modules.png[EX_STAGE submodules] +[[alu]] alu -=== ++++ The arithmetic logic unit (ALU) is a small piece of hardware which performs 32 and 64-bit arithmetic and bitwise operations: subtraction, addition, shifts, comparisons... It always completes its operation in a single cycle. -.. include:: port_alu.rst - +include::port_alu.adoc[] +[[branch_unit]] branch_unit -=========== ++++++++++++ The branch unit module manages all kinds of control flow changes i.e.: conditional and unconditional jumps. It calculates the target address and decides whether to take the branch or not. It also decides if a branch was mis-predicted or not and reports corrective actions to the pipeline stages. -.. include:: port_branch_unit.rst - +include::port_branch_unit.adoc[] +[[csr_buffer]] CSR_buffer -========== +++++++++++ The CSR buffer module stores the CSR address at which the instruction is going to read/write. As the CSR instruction alters the processor architectural state, this instruction has to be buffered until the commit stage decides to execute the instruction. -.. include:: port_csr_buffer.rst - +include::port_csr_buffer.adoc[] +[[mult]] mult -==== +++++ The multiplier module supports the division and multiplication operations. -.. figure:: ../images/mult_modules.png - :name: mult submodules - :align: center - :alt: - - mult submodules +image:mult_modules.png[mult submodules] -.. include:: port_mult.rst +include::port_mult.adoc[] - ----------- -multiplier ----------- +[[multiplier]] +====== multiplier Multiplication is performed in two cycles and is fully pipelined. -.. include:: port_multiplier.rst - +include::port_multiplier.adoc[] ------- -serdiv ------- +[[serdiv]] +====== serdiv The division is a simple serial divider which needs 64 cycles in the worst case. -.. include:: port_serdiv.rst - +include::port_serdiv.adoc[] +[[load_store_unit-lsu]] load_store_unit (LSU) -===================== ++++++++++++++++++++++ The load store module interfaces with the data cache (D$) to manage the load and store operations. @@ -106,19 +89,12 @@ The LSU does not handle misaligned accesses. Misaligned accesses are double word accesses which are not aligned to a 64-bit boundary, word accesses which are not aligned to a 32-bit boundary and half word accesses which are not aligned on 16-bit boundary. If the LSU encounters a misaligned load or store, it throws a misaligned exception. -.. figure:: ../images/load_store_unit_modules.png - :name: load_store_unit submodules - :align: center - :alt: - - load_store_unit submodules +image:load_store_unit_modules.png[load_store_unit submodules] -.. include:: port_load_store_unit.rst +include::port_load_store_unit.adoc[] - ----------- -store_unit ----------- +[[store_unit]] +====== store_unit The store_unit module manages the data store operations. @@ -132,12 +108,10 @@ When commit buffer is not empty, the buffer automatically tries to write the old Furthermore, the store_unit module provides information to the load_unit to know if an outstanding store matches addresses with a load. -.. include:: port_store_unit.rst - +include::port_store_unit.adoc[] ---------- -load_unit ---------- +[[load_unit]] +====== load_unit The load unit module manages the data load operations. @@ -156,27 +130,21 @@ If the load request address is non-idempotent, it stalls until the write buffer It also stalls until the incoming load instruction is the next instruction to be committed. When the D$ allows the read of the data, the data is sent to the load unit and the load instruction can be committed (4). -.. figure:: ../images/schema_fsm_load_control.png - :align: center +image:schema_fsm_load_control.png[Load unit's interactions] - Load unit's interactions +include::port_load_unit.adoc[] -.. include:: port_load_unit.rst - - ----------- -lsu_bypass ----------- +[[lsu_bypass]] +====== lsu_bypass The LSU bypass is a FIFO which keeps instructions from the issue stage when the store unit or the load unit are not available immediately. -.. include:: port_lsu_bypass.rst - +include::port_lsu_bypass.adoc[] +[[cvxif_fu]] CVXIF_fu -======== +++++++++ TO BE COMPLETED -.. include:: port_cvxif_fu.rst - +include::port_cvxif_fu.adoc[] diff --git a/docs/04_cv32a65x/design/source/cv32a6_frontend.rst b/docs/design/design-manual/source/cv32a6_frontend.adoc similarity index 55% rename from docs/04_cv32a65x/design/source/cv32a6_frontend.rst rename to docs/design/design-manual/source/cv32a6_frontend.adoc index f647a618a2..1012c7cb50 100644 --- a/docs/04_cv32a65x/design/source/cv32a6_frontend.rst +++ b/docs/design/design-manual/source/cv32a6_frontend.adoc @@ -1,4 +1,4 @@ -.. +//// Copyright 2021 Thales DIS design services SAS Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -6,14 +6,16 @@ You may obtain a copy of the License at https://solderpad.org/licenses/ Original Author: Jean-Roch COULON - Thales +//// -.. _CV32A6_FRONTEND: +[[CV32A6_FRONTEND]] FRONTEND Module -=============== +~~~~~~~~~~~~~~~ +[[frontend-description]] Description ------------ +^^^^^^^^^^^ The FRONTEND module implements two first stages of the cva6 pipeline, PC gen and Fetch stages. @@ -29,74 +31,75 @@ The module is connected to: * CACHES module provides fethed instructions to FRONTEND. * DECODE module receives instructions from FRONTEND. * CONTROLLER module can order to flush and to halt FRONTEND PC gen stage -* EXECUTE, CONTROLLER, CSR and COMMIT modules trigger PC jumping due to a branch misprediction, an exception, a return from an exception, a debug entry or a pipeline flush. - They provides the PC next value. +* EXECUTE, CONTROLLER, CSR and COMMIT modules trigger PC jumping due to +a branch misprediction, an exception, a return from an exception, a +debug entry or a pipeline flush. They provides the PC next value. * CSR module states about debug mode. -.. include:: port_frontend.rst +include::port_frontend.adoc[] +[[frontend-functionality]] Functionality -------------- - - +^^^^^^^^^^^^^ +[[pc-generation-stage]] PC Generation stage -~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^ PC gen generates the next program counter. The next PC can originate from the following sources (listed in order of precedence): -* **Reset state:** At reset, the PC is assigned to the boot address. - -* **Branch Prediction:** The fetched instruction is predecoded by the instr_scan submodule. - When the instruction is a control flow, three cases are considered: - - 1. When the instruction is a JALR which corresponds to a return (rs1 = x1 or rs1 = x5). - RAS provides next PC as a prediction. - - 2. When the instruction is a JALR which **does not** correspond to a return. - If BTB (Branch Target Buffer) returns a valid address, then BTB predicts next PC. - Else JALR is not considered as a control flow instruction, which will generate a mispredict. - - 3. When the instruction is a conditional branch. - If BHT (Branch History table) returns a valid address, then BHT predicts next PC. - Else the prediction depends on the PC relative jump offset sign: if sign is negative the prediction is taken, otherwise the prediction is not taken. - - Then the PC gen informs the Fetch stage that it performed a prediction on the PC. - -* **Default:** The next 32-bit block is fetched. - PC Gen fetches word boundary 32-bits block from CACHES module. And the fetch stage identifies the instructions from the 32-bits blocks. - -* **Mispredict:** Misprediction are feedbacked by EX_STAGE module. - In any case we need to correct our action and start fetching from the correct address. - -* **Replay instruction fetch:** When the instruction queue is full, the instr_queue submodule asks the fetch replay and provides the address to be replayed. - -* **Return from environment call:** When CSR requests a return from an environment call, next PC takes the value of the PC of the instruction after the one pointed to by the mepc CSR. - -* **Exception/Interrupt:** If an exception is triggered by CSR_REGISTER, next PC takes the value of the trap vector base address CSR. - -* **Pipeline starting fetching from COMMIT PC:** When the commit stage is halted by a WFI instruction or when the pipeline has been flushed due to CSR change, next PC takes the value of the PC coming from the COMMIT submodule. - As CSR instructions do not exist in a compressed form, PC is unconditionally incremented by 4. - -.. user and supervisor modes are not supported by CV32A65X - The trap vector base address can be different depending on whether the exception traps to S-Mode or M-Mode (user mode exceptions are currently not supported). - It is the purpose of the CSR Unit to figure out where to trap to and present the correct address to PC Gen. - -.. Debug feature is not supported by CV32A65X - * **Debug:** Debug has the highest order of precedence as it can interrupt any control flow requests. It also the only source of control flow change which can actually happen simultaneously to any other of the forced control flow changes. - The debug jump is requested by CSR. - The address to be jumped into is HW coded. - +* *Reset state:* At reset, the PC is assigned to the boot address. + +* *Branch Prediction:* The fetched instruction is predecoded by the +instr_scan submodule. When the instruction is a control flow, three +cases are considered: ++ +________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ +1. When the instruction is a JALR which corresponds to a return (rs1 = x1 or rs1 = x5). +RAS provides next PC as a prediction. +2. When the instruction is a JALR which *does not* correspond to areturn. +If BTB (Branch Target Buffer) returns a valid address, then BTBpredicts next PC. +Else JALR is not considered as a control flow instruction, which will generate a mispredict. +3. When the instruction is a conditional branch. +If BHT (Branch History table) returns a valid address, then BHT predicts next PC. +Else the prediction depends on the PC relative jump offset sign: if sign is negative the prediction is taken, otherwise the prediction is not taken. +________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ ++ +Then the PC gen informs the Fetch stage that it performed a prediction on the PC. + +* *Default:* The next 32-bit block is fetched. +PC Gen fetches word boundary 32-bits block from CACHES module. And the fetch stage identifies the instructions from the 32-bits blocks. + +* *Mispredict:* Misprediction are feedbacked by EX_STAGE module. +In any case we need to correct our action and start fetching from the correct address. + +* *Replay instruction fetch:* When the instruction queue is full, the instr_queue submodule asks the fetch replay and provides the address to be replayed. + +* *Return from environment call:* When CSR requests a return from an environment call, next PC takes the value of the PC of the instruction after the one pointed to by the mepc CSR. + +* *Exception/Interrupt:* If an exception is triggered by CSR_REGISTER, next PC takes the value of the trap vector base address CSR. +ifdef::RVS-true,RVU-true[] +The trap vector base address can be different depending on whether the exception traps to S-Mode or M-Mode. +It is the purpose of the CSR Unit to figure out where to trap to and present the correct address to PC Gen. +endif::[] + +* *Pipeline starting fetching from COMMIT PC:* When the commit stage is halted by a WFI instruction or when the pipeline has been flushed due to CSR change, next PC takes the value of the PC coming from the COMMIT submodule. +As CSR instructions do not exist in a compressed form, PC is unconditionally incremented by 4. + +ifeval::[{DebugEn} == true] +* *Debug:* Debug has the highest order of precedence as it can interrupt any control flow requests. It also the only source of control flow change which can actually happen simultaneously to any other of the forced control flow changes. +The debug jump is requested by CSR. +The address to be jumped into is HW coded. +endif::[] All program counters are logical addressed. +ifeval::[{MmuPresent} == true] +If the logical to physical mapping changes, a ``fence.vm`` instruction should be used to flush the pipeline and TLBs. +endif::[] -.. MMU is not supported in CV32A65X - If the logical to physical mapping changes, a ``fence.vm`` instruction should be used to flush the pipeline *and TLBs (MMU is not enabled in CV32A6 v0.1.0)*. - - - +[[fetch-stage]] Fetch Stage -~~~~~~~~~~~ +^^^^^^^^^^^ Fetch stage controls the CACHE module by a handshaking protocol. Fetched data is a 32-bit block with a word-aligned address. @@ -104,44 +107,38 @@ A granted fetch is processed by the instr_realign submodule to produce instructi Then instructions are pushed into an internal instruction FIFO called instruction queue (instr_queue submodule). This submodule stores the instructions and sends them to the DECODE module. -.. TO_BE_COMPLETED MMU also feedback an exception, but not present in 65X +// TO_BE_COMPLETED MMU also feedback an exception, but not present in 65X Memory can feedback potential exceptions which can be bus errors, invalid accesses or instruction page faults. The FRONTEND transmits the exception from CACHES to DECODE. +[[submodules]] Submodules ----------- - -.. figure:: ../images/frontend_modules.png - :name: FRONTEND submodules - :align: center +^^^^^^^^^^ - FRONTEND submodules +image:frontend_modules.png[FRONTEND submodules] -.. figure:: ../images/ZoominFrontend.png - :name: frontend-schematic - :align: center - - FRONTEND submodule interconnections +image:ZoominFrontend.png[FRONTEND submodule interconnections] +[[instr_realign-submodule]] Instr_realign submodule -~~~~~~~~~~~~~~~~~~~~~~~ ++++++++++++++++++++++++ The 32-bit aligned block coming from the CACHE module enters the instr_realign submodule. This submodule extracts the instructions from the 32-bit blocks. It is possible to fetch up to two instructions per cycle when C extension is used. An not-compressed instruction can be misaligned on the block size, interleaved with two cache blocks. In that case, two cache accesses are needed to get the whole instruction. -The instr_realign submodule provides at maximum two instructions per cycle when compressed extensionis enabled, else one instruction per cycle. +The instr_realign submodule provides at maximum two instructions per cycle when compressed extension is enabled, else one instruction per cycle. Incomplete instruction is stored in instr_realign submodule until its second half is fetched. -.. include:: port_instr_realign.rst - +include::port_instr_realign.adoc[] +[[instr_queue-submodule]] Instr_queue submodule -~~~~~~~~~~~~~~~~~~~~~ ++++++++++++++++++++++ The instr_queue receives mutliple instructions from instr_realign submodule to create a valid stream of instructions to be decoded (by DECODE), to be issued (by ISSUE) and executed (by EXECUTE). FRONTEND pushes in FIFO to store the instructions and related information needed in case of mispredict or exception: instructions, instruction control flow type, exception, exception address and predicted address. @@ -152,11 +149,11 @@ If the instruction queue is full, a replay request is sent to inform the fetch m The instruction queue can be flushed by CONTROLLER. -.. include:: port_instr_queue.rst - +include::port_instr_queue.adoc[] +[[instr_scan-submodule]] instr_scan submodule -~~~~~~~~~~~~~~~~~~~~ +++++++++++++++++++++ As compressed extension is enabled, two instr_scan are instantiated to handle up to two instructions per cycle. @@ -164,64 +161,56 @@ Each instr_scan submodule pre-decodes the fetched instructions coming from the i The instr_scan submodule is a flox controler which provides the intruction type: branch, jump, return, jalr, imm, call or others. These outputs are used by the branch prediction feature. -.. include:: port_instr_scan.rst - +include::port_instr_scan.adoc[] +[[bht-branch-history-table-submodule]] BHT (Branch History Table) submodule -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - +++++++++++++++++++++++++++++++++++++ BHT is implemented as a memory which is composed of **BHTDepth configuration parameter** entries. The lower address bits of the virtual address point to the memory entry. When a branch instruction is resolved by the EX_STAGE module, the branch PC and the taken (or not taken) status information is stored in the Branch History Table. -.. TO_BE_COMPLETED: Specify the behaviour when BHT is saturated +// TO_BE_COMPLETED: Specify the behaviour when BHT is saturated The Branch History Table is a table of two-bit saturating counters that takes the virtual address of the current fetched instruction by the CACHE. It states whether the current branch request should be taken or not. The two bit counter is updated by the successive execution of the instructions as shown in the following figure. -.. figure:: ../images/bht.png - :name: BHT saturation - :align: center - :alt: - - BHT saturation +image:bht.png[BHT saturation] -.. TODO: if debug enable, The BHT is not updated if processor is in debug mode. +// TODO: if debug enable, The BHT is not updated if processor is in debug mode. When a branch instruction is pre-decoded by instr_scan submodule, the BHT valids whether the PC address is in the BHT and provides the taken or not prediction. The BHT is never flushed. -.. include:: port_bht.rst +include::port_bht.adoc[] +[[btb-branch-target-buffer-submodule]] BTB (Branch Target Buffer) submodule -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - +++++++++++++++++++++++++++++++++++++ BTB is implemented as an array which is composed of **BTBDepth configuration parameter** entries. The lower address bits of the virtual address point to the memory entry. When an JALR instruction is found mispredicted by the EX_STAGE module, the JALR PC and the target address are stored into the BTB. -.. TODO: Specify the behaviour when BTB is saturated +// TODO: Specify the behaviour when BTB is saturated -.. TODO: when debug enabled, The BTB is not updated if processor is in debug mode. +// TODO: when debug enabled, The BTB is not updated if processor is in debug mode. When a JALR instruction is pre-decoded by instr_scan submodule, the BTB informs whether the input PC address is in the BTB. In this case, the BTB provides the predicted target address. The BTB is never flushed. +include::port_btb.adoc[] -.. include:: port_btb.rst - - +[[ras-return-address-stack-submodule]] RAS (Return Address Stack) submodule -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - +++++++++++++++++++++++++++++++++++++ RAS is implemented as a LIFO which is composed of **RASDepth configuration parameter** entries. @@ -232,5 +221,4 @@ If the predicted return address is wrong due for instance to speculation or RAS The RAS is never flushed. -.. include:: port_ras.rst - +include::port_ras.adoc[] diff --git a/docs/design/design-manual/source/cv32a6_glossary.adoc b/docs/design/design-manual/source/cv32a6_glossary.adoc new file mode 100644 index 0000000000..d0f0906e2d --- /dev/null +++ b/docs/design/design-manual/source/cv32a6_glossary.adoc @@ -0,0 +1,65 @@ +[[CV32A6_GLOSSARY]] +[[glossary]] +Glossary +-------- + +* *ALU*: Arithmetic/Logic Unit +* *APU*: Application Processing Unit +* *ASIC*: Application-Specific Integrated Circuit +* *AXI*: Advanced eXtensible Interface +* *BHT*: Branch History Table +* *BTB*: Branch Target Buffer +* *Byte*: 8-bit data item +* *CPU*: Central Processing Unit, processor +* *CSR*: Control and Status Register +* *Custom extension*: Non-Standard extension to the RISC-V base +instruction set (RISC-V Instruction Set Manual, Volume I: User-Level +ISA) +* *CVA6*: Core-V Application class processor with a 6 stage pipeline +* *D$*: Data Cache +* *DPI*: Direct Programming Interface +* *EX* or *EXE*: Instruction Execute +* *FPGA*: Field Programmable Gate Array +* *FPU*: Floating Point Unit +* *Halfword*: 16-bit data item +* *Halfword aligned address*: An address is halfword aligned if it is +divisible by 2 +* *I$*: Instruction Cache +* *ID*: Instruction Decode +* *IF*: Instruction Fetch +* *ISA*: Instruction Set Architecture +* *KGE*: Kilo Gate Equivalents (NAND2) +* *LSU*: Load Store Unit +* *M-Mode*: Machine Mode (RISC-V Instruction Set Manual, Volume II: +Privileged Architecture) +* *MMU*: Memory Management Unit +* *NC*: Not Cacheable +* *OBI*: Open Bus Interface +* *OoO*: Out Of Order +* *PC*: Program Counter +* *PMP*: Physical memory protection (RISC-V Instruction Set Manual, +Volume II: Privileged Architecture) +* *PTW*: Page Table Walker +* *PULP platform*: Parallel Ultra Low Power Platform +() +* *RAS*: Return Address Stack +* *RV32C*: RISC-V Compressed (C extension) +* *RV32F*: RISC-V Floating Point (F extension) +* *S-Mode*: Supervisor Mode (RISC-V Instruction Set Manual, Volume II: +Privileged Architecture) +* *SIMD*: Single Instruction/Multiple Data +* *Standard extension*: Standard extension to the RISC-V base +instruction set (RISC-V Instruction Set Manual, Volume I: User-Level +ISA) +* *TLB*: Translation Lookaside Buffer +* *U-Mode*: User Mode (RISC-V Instruction Set Manual, Volume II: +Privileged Architecture) +* *VLEN*: Virtual address length +* *WARL*: Write Any Values, Reads Legal Values +* *WB*: Write Back of instruction results +* *WLRL*: Write/Read Only Legal Values +* *Word*: 32-bit data item +* *Word aligned address*: An address is word aligned if it is divisible +by 4 +* *WPRI*: Reserved Writes Preserve Values, Reads Ignore Values +* *XLEN*: RISC-V processor data length diff --git a/docs/04_cv32a65x/design/source/cva6_caches.rst b/docs/design/design-manual/source/cva6_caches.adoc similarity index 68% rename from docs/04_cv32a65x/design/source/cva6_caches.rst rename to docs/design/design-manual/source/cva6_caches.adoc index 21e1d7fec8..1e9fcb2b9d 100644 --- a/docs/04_cv32a65x/design/source/cva6_caches.rst +++ b/docs/design/design-manual/source/cva6_caches.adoc @@ -1,4 +1,4 @@ -.. +//// Copyright 2024 Thales DIS France SAS Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); you may not use this file except in compliance with the License. @@ -6,36 +6,33 @@ You may obtain a copy of the License at https://solderpad.org/licenses/ Original Author: Jean-Roch COULON - Thales +//// -.. _CVA6_CACHES: - +[[CVA6_CACHES]] CACHES Module -============= +~~~~~~~~~~~~~ +[[caches-description]] Description ------------ +^^^^^^^^^^^ -The CACHES module implements an instruction cache, a data cache and an AXI adapter. +The CACHES module implements an instruction cache, a data cache and an +AXI adapter. The module is connected to: * TO_BE_COMPLETED -.. include:: port_cva6_hpdcache_subsystem.rst - +include::port_cva6_hpdcache_subsystem.adoc[] +[[caches-functionality]] Functionality -------------- +^^^^^^^^^^^^^ TO BE COMPLETED - +[[caches-submodules]] Submodules ----------- - -.. figure:: ../images/caches.png - :name: CACHES submodules - :align: center - :alt: +^^^^^^^^^^ - CACHES submodules +image:caches.png[CACHES submodules] diff --git a/docs/design/design-manual/source/cva6_commit_stage.adoc b/docs/design/design-manual/source/cva6_commit_stage.adoc new file mode 100644 index 0000000000..99611f2ce9 --- /dev/null +++ b/docs/design/design-manual/source/cva6_commit_stage.adoc @@ -0,0 +1,42 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[CVA6_COMMIT_STAGE]] +COMMIT_STAGE Module +~~~~~~~~~~~~~~~~~~~ + +[[commit_stage-description]] +Description +^^^^^^^^^^^ + +The COMMIT_STAGE module implements the commit stage, which is the last +stage in the processor’s pipeline. For the instructions for which the +execution is completed, it updates the architectural state: writing CSR +registers, committing stores and writing back data to the register file. +The commit stage controls the stalling and the flushing of the +processor. + +The commit stage also manages the exceptions. An exception can occur +during the first four pipeline stages (PCgen cannot generate an +exception) or happen in commit stage, coming from the CSR_REGFILE or +from an interrupt. Exceptions are precise: they are considered during +the commit only and associated with the related instruction. + +The module is connected to: + +* TO BE COMPLETED + +include::port_commit_stage.adoc[] + +[[commit_stage-functionality]] +Functionality +^^^^^^^^^^^^^ + +TO BE COMPLETED diff --git a/docs/04_cv32a65x/design/source/cva6_controller.rst b/docs/design/design-manual/source/cva6_controller.adoc similarity index 76% rename from docs/04_cv32a65x/design/source/cva6_controller.rst rename to docs/design/design-manual/source/cva6_controller.adoc index 468970856e..6be2f70285 100644 --- a/docs/04_cv32a65x/design/source/cva6_controller.rst +++ b/docs/design/design-manual/source/cva6_controller.adoc @@ -1,4 +1,4 @@ -.. +//// Copyright 2024 Thales DIS France SAS Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); you may not use this file except in compliance with the License. @@ -6,14 +6,15 @@ You may obtain a copy of the License at https://solderpad.org/licenses/ Original Author: Jean-Roch COULON - Thales +//// -.. _CVA6_CONTROLLER: - +[[CVA6_CONTROLLER]] CONTROLLER Module -================= +~~~~~~~~~~~~~~~~~ +[[controller-description]] Description ------------ +^^^^^^^^^^^ The CONTROLLER module implements ... TO BE COMPLETED @@ -21,10 +22,10 @@ The module is connected to: * TO BE COMPLETED -.. include:: port_controller.rst +include::port_controller.adoc[] +[[controller-functionality]] Functionality -------------- +^^^^^^^^^^^^^ TO BE COMPLETED - diff --git a/docs/04_cv32a65x/design/source/cva6_csr_regfile.rst b/docs/design/design-manual/source/cva6_csr_regfile.adoc similarity index 76% rename from docs/04_cv32a65x/design/source/cva6_csr_regfile.rst rename to docs/design/design-manual/source/cva6_csr_regfile.adoc index bdc6b35487..a79bd9bf93 100644 --- a/docs/04_cv32a65x/design/source/cva6_csr_regfile.rst +++ b/docs/design/design-manual/source/cva6_csr_regfile.adoc @@ -1,4 +1,4 @@ -.. +//// Copyright 2024 Thales DIS France SAS Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); you may not use this file except in compliance with the License. @@ -6,14 +6,15 @@ You may obtain a copy of the License at https://solderpad.org/licenses/ Original Author: Jean-Roch COULON - Thales +//// -.. _CVA6_CSR_REGFILE: - +[[CVA6_CSR_REGFILE]] CSR_REGFILE Module -================== +~~~~~~~~~~~~~~~~~~ +[[csr_regfile-description]] Description ------------ +^^^^^^^^^^^ The CSR_REGFILE module implements ... TO BE COMPLETED @@ -21,9 +22,10 @@ The module is connected to: * TO BE COMPLETED -.. include:: port_csr_regfile.rst +include::port_csr_regfile.adoc[] +[[csr_regfile-functionality]] Functionality -------------- +^^^^^^^^^^^^^ TO BE COMPLETED diff --git a/docs/04_cv32a65x/design/source/cva6_id_stage.rst b/docs/design/design-manual/source/cva6_id_stage.adoc similarity index 52% rename from docs/04_cv32a65x/design/source/cva6_id_stage.rst rename to docs/design/design-manual/source/cva6_id_stage.adoc index faa3c579ea..0527ef6a94 100644 --- a/docs/04_cv32a65x/design/source/cva6_id_stage.rst +++ b/docs/design/design-manual/source/cva6_id_stage.adoc @@ -1,4 +1,4 @@ -.. +//// Copyright 2024 Thales DIS France SAS Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); you may not use this file except in compliance with the License. @@ -6,74 +6,74 @@ You may obtain a copy of the License at https://solderpad.org/licenses/ Original Author: Jean-Roch COULON - Thales - -.. _CVA6_ID_STAGE: - +//// + +[[CVA6_ID_STAGE]] ID_STAGE Module -=============== +~~~~~~~~~~~~~~~ +[[id_stage-description]] Description ------------ +^^^^^^^^^^^ -The ID_STAGE module implements the decode stage of the pipeline. -Its main purpose is to decode RISC-V instructions coming from FRONTEND module -(fetch stage) and send them to the ISSUE_STAGE module (issue stage). +The ID_STAGE module implements the decode stage of the pipeline. Its +main purpose is to decode RISC-V instructions coming from FRONTEND +module (fetch stage) and send them to the ISSUE_STAGE module (issue +stage). The compressed_decoder module checks whether the incoming instruction is -compressed and output the corresponding uncompressed instruction. -Then the decoder module decodes the instruction and send it to the -issue stage. - +compressed and output the corresponding uncompressed instruction. Then +the decoder module decodes the instruction and send it to the issue +stage. The module is connected to: * CONTROLLER module can flush ID_STAGE decode stage * FRONTEND module sends instrution to ID_STAGE module * ISSUE module receives the decoded instruction from ID_STAGE module -* CSR_REGFILE module sends status information about privilege mode, traps, extension support. - -.. include:: port_id_stage.rst - +* CSR_REGFILE module sends status information about privilege mode, +traps, extension support. +include::port_id_stage.adoc[] +[[id_stage-functionality]] Functionality -------------- +^^^^^^^^^^^^^ TO BE COMPLETED - +[[id_stage-submodules]] Submodules ----------- - -.. figure:: ../images/id_stage_modules.png - :name: ID_STAGE submodules - :align: center - :alt: - - ID_STAGE submodules +^^^^^^^^^^ +image:id_stage_modules.png[ID_STAGE submodules] +[[compressed_decoder]] Compressed_decoder -~~~~~~~~~~~~~~~~~~ +++++++++++++++++++ The compressed_decoder module decompresses all the compressed -instructions taking a 16-bit compressed instruction and expanding it -to its 32-bit equivalent. -All compressed instructions have a 32-bit equivalent. +instructions taking a 16-bit compressed instruction and expanding it to +its 32-bit equivalent. All compressed instructions have a 32-bit +equivalent. -.. include:: port_compressed_decoder.rst +include::port_compressed_decoder.adoc[] +[[decoder]] Decoder -~~~~~~~ - -The decoder module takes the output of compressed_decoder module and decodes it. -It transforms the instruction to the most fundamental control structure in pipeline, a scoreboard entry. ++++++++ -The scoreboard entry contains an exception entry which is composed of a valid field, a cause and a value called TVAL. -As TVALEn configuration parameter is zero, the TVAL field is not implemented. +The decoder module takes the output of compressed_decoder module and +decodes it. It transforms the instruction to the most fundamental +control structure in pipeline, a scoreboard entry. -A potential illegal instruction exception can be detected during decoding. -If no exception has happened previously in fetch stage, the decoder will valid the exception and add the cause and tval value to the scoreboard entry. +The scoreboard entry contains an exception entry which is composed of a +valid field, a cause and a value called TVAL. As TVALEn configuration +parameter is zero, the TVAL field is not implemented. -.. include:: port_decoder.rst +A potential illegal instruction exception can be detected during +decoding. If no exception has happened previously in fetch stage, the +decoder will valid the exception and add the cause and tval value to the +scoreboard entry. +include::port_decoder.adoc[] diff --git a/docs/design/design-manual/source/cva6_issue_stage.adoc b/docs/design/design-manual/source/cva6_issue_stage.adoc new file mode 100644 index 0000000000..6e2889d1df --- /dev/null +++ b/docs/design/design-manual/source/cva6_issue_stage.adoc @@ -0,0 +1,65 @@ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[CVA6_ISSUE_STAGE]] +ISSUE_STAGE Module +~~~~~~~~~~~~~~~~~~ + +[[issue_stage-description]] +Description +^^^^^^^^^^^ + +The execution can be roughly divided into four parts: issue(1), read +operands(2), execute(3) and write-back(4). The ISSUE_STAGE module +handles step one, two and four. The ISSUE_STAGE module receives the +decoded instructions and issues them to the various functional units. + +A data structure called scoreboard is used to keep track of data related +to the issue instruction: which functional unit and which destination +register they are. The scoreboard handle the write-back data received +from the COMMIT_STAGE module. + +Furthermore it contains the CPU’s register file. + +The module is connected to: + +* TO BE COMPLETED + +include::port_issue_stage.adoc[] + +[[issue_stage-functionality]] +Functionality +^^^^^^^^^^^^^ + +TO BE COMPLETED + +[[issue_stage-submodules]] +Submodules +^^^^^^^^^^ + +image:issue_stage_modules.png[ISSUE_STAGE submodules] + +[[scoreboard]] +Scoreboard +++++++++++ + +The scoreboard contains a FIFO to store the decoded instructions. Issued +instruction is pushed to the FIFO if it is not full. It indicates which +registers are going to be clobbered by a previously issued instruction. + +include::port_scoreboard.adoc[] + +[[issue_read_operands]] +Issue_read_operands ++++++++++++++++++++ + +TO BE COMPLETED + +include::port_issue_read_operands.adoc[] diff --git a/docs/design/design-manual/source/design.adoc b/docs/design/design-manual/source/design.adoc new file mode 100644 index 0000000000..1fdb50d401 --- /dev/null +++ b/docs/design/design-manual/source/design.adoc @@ -0,0 +1,40 @@ +//// + Copyright (c) 2022 Thales + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +include::config.adoc[] +include::config_define.adoc[] + +[[DesignDocument]] += Design Documentation for {ohg-config} architecture +:description: Design documentation for {ohg-config} +:company: THALES +:doctype: book +:sectnums: +:sectnumlevels: 5 +:toc: left +:toclevels: 4 +:table-caption: Table +:figure-caption: Figure +:xrefstyle: short +:imagesdir: images +:example-caption: Example +:listing-caption: Listing +:chapter-refsig: Chapter +:section-refsig: Section +:appendix-refsig: Appendix +:data-uri: + +Editor: *Jean Roch Coulon* + +include::intro.adoc[] +include::subsystem.adoc[] +include::functionality.adoc[] +include::architecture.adoc[] +include::cv32a6_glossary.adoc[] diff --git a/docs/04_cv32a65x/design/source/functionality.rst b/docs/design/design-manual/source/functionality.adoc similarity index 70% rename from docs/04_cv32a65x/design/source/functionality.rst rename to docs/design/design-manual/source/functionality.adoc index 71198e13ee..b4bd673f42 100644 --- a/docs/04_cv32a65x/design/source/functionality.rst +++ b/docs/design/design-manual/source/functionality.adoc @@ -1,4 +1,4 @@ -.. +//// Copyright 2023 Thales DIS France SAS Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -6,17 +6,14 @@ You may obtain a copy of the License at https://solderpad.org/licenses/ Original Author: Jean-Roch COULON - Thales +//// - - +[[functionality]] Functionality -============= - -.. toctree:: - :maxdepth: 1 +------------- - instructions - traps - CSRs - AXI - CVXIF +include::instructions.adoc[] +include::traps.adoc[] +include::CSRs.adoc[] +include::AXI.adoc[] +include::CVXIF.adoc[] diff --git a/docs/04_cv32a65x/design/images/CVA6_subsystems.png b/docs/design/design-manual/source/images/CVA6_subsystems.png similarity index 100% rename from docs/04_cv32a65x/design/images/CVA6_subsystems.png rename to docs/design/design-manual/source/images/CVA6_subsystems.png diff --git a/docs/04_cv32a65x/design/images/LZC.png b/docs/design/design-manual/source/images/LZC.png similarity index 100% rename from docs/04_cv32a65x/design/images/LZC.png rename to docs/design/design-manual/source/images/LZC.png diff --git a/docs/04_cv32a65x/design/images/RR.png b/docs/design/design-manual/source/images/RR.png similarity index 100% rename from docs/04_cv32a65x/design/images/RR.png rename to docs/design/design-manual/source/images/RR.png diff --git a/docs/04_cv32a65x/design/images/ZoominFrontend.png b/docs/design/design-manual/source/images/ZoominFrontend.png similarity index 100% rename from docs/04_cv32a65x/design/images/ZoominFrontend.png rename to docs/design/design-manual/source/images/ZoominFrontend.png diff --git a/docs/04_cv32a65x/design/images/ariane_overview.drawio.png b/docs/design/design-manual/source/images/ariane_overview.drawio.png similarity index 100% rename from docs/04_cv32a65x/design/images/ariane_overview.drawio.png rename to docs/design/design-manual/source/images/ariane_overview.drawio.png diff --git a/docs/04_cv32a65x/design/images/ariane_overview.png b/docs/design/design-manual/source/images/ariane_overview.png similarity index 100% rename from docs/04_cv32a65x/design/images/ariane_overview.png rename to docs/design/design-manual/source/images/ariane_overview.png diff --git a/docs/04_cv32a65x/design/images/bht.png b/docs/design/design-manual/source/images/bht.png similarity index 100% rename from docs/04_cv32a65x/design/images/bht.png rename to docs/design/design-manual/source/images/bht.png diff --git a/docs/04_cv32a65x/design/images/caches.png b/docs/design/design-manual/source/images/caches.png similarity index 100% rename from docs/04_cv32a65x/design/images/caches.png rename to docs/design/design-manual/source/images/caches.png diff --git a/docs/04_cv32a65x/design/images/cva6_tlb_entry.png b/docs/design/design-manual/source/images/cva6_tlb_entry.png similarity index 100% rename from docs/04_cv32a65x/design/images/cva6_tlb_entry.png rename to docs/design/design-manual/source/images/cva6_tlb_entry.png diff --git a/docs/04_cv32a65x/design/images/cva6_tlb_hit.png b/docs/design/design-manual/source/images/cva6_tlb_hit.png similarity index 100% rename from docs/04_cv32a65x/design/images/cva6_tlb_hit.png rename to docs/design/design-manual/source/images/cva6_tlb_hit.png diff --git a/docs/04_cv32a65x/design/images/ex_stage_modules.png b/docs/design/design-manual/source/images/ex_stage_modules.png similarity index 100% rename from docs/04_cv32a65x/design/images/ex_stage_modules.png rename to docs/design/design-manual/source/images/ex_stage_modules.png diff --git a/docs/04_cv32a65x/design/images/frontend_modules.png b/docs/design/design-manual/source/images/frontend_modules.png similarity index 100% rename from docs/04_cv32a65x/design/images/frontend_modules.png rename to docs/design/design-manual/source/images/frontend_modules.png diff --git a/docs/04_cv32a65x/design/images/id_stage_modules.png b/docs/design/design-manual/source/images/id_stage_modules.png similarity index 100% rename from docs/04_cv32a65x/design/images/id_stage_modules.png rename to docs/design/design-manual/source/images/id_stage_modules.png diff --git a/docs/04_cv32a65x/design/images/in_out_tlb.png b/docs/design/design-manual/source/images/in_out_tlb.png similarity index 100% rename from docs/04_cv32a65x/design/images/in_out_tlb.png rename to docs/design/design-manual/source/images/in_out_tlb.png diff --git a/docs/04_cv32a65x/design/images/issue_stage_modules.png b/docs/design/design-manual/source/images/issue_stage_modules.png similarity index 100% rename from docs/04_cv32a65x/design/images/issue_stage_modules.png rename to docs/design/design-manual/source/images/issue_stage_modules.png diff --git a/docs/04_cv32a65x/design/images/load_store_unit_modules.png b/docs/design/design-manual/source/images/load_store_unit_modules.png similarity index 100% rename from docs/04_cv32a65x/design/images/load_store_unit_modules.png rename to docs/design/design-manual/source/images/load_store_unit_modules.png diff --git a/docs/04_cv32a65x/design/images/mmu_control_flow.png b/docs/design/design-manual/source/images/mmu_control_flow.png similarity index 100% rename from docs/04_cv32a65x/design/images/mmu_control_flow.png rename to docs/design/design-manual/source/images/mmu_control_flow.png diff --git a/docs/04_cv32a65x/design/images/mmu_in_out.png b/docs/design/design-manual/source/images/mmu_in_out.png similarity index 100% rename from docs/04_cv32a65x/design/images/mmu_in_out.png rename to docs/design/design-manual/source/images/mmu_in_out.png diff --git a/docs/04_cv32a65x/design/images/mmu_major_blocks.png b/docs/design/design-manual/source/images/mmu_major_blocks.png similarity index 100% rename from docs/04_cv32a65x/design/images/mmu_major_blocks.png rename to docs/design/design-manual/source/images/mmu_major_blocks.png diff --git a/docs/04_cv32a65x/design/images/mult_modules.png b/docs/design/design-manual/source/images/mult_modules.png similarity index 100% rename from docs/04_cv32a65x/design/images/mult_modules.png rename to docs/design/design-manual/source/images/mult_modules.png diff --git a/docs/04_cv32a65x/design/images/openhw-landscape.svg b/docs/design/design-manual/source/images/openhw-landscape.svg similarity index 100% rename from docs/04_cv32a65x/design/images/openhw-landscape.svg rename to docs/design/design-manual/source/images/openhw-landscape.svg diff --git a/docs/04_cv32a65x/design/images/plru_tree_indexing.png b/docs/design/design-manual/source/images/plru_tree_indexing.png similarity index 100% rename from docs/04_cv32a65x/design/images/plru_tree_indexing.png rename to docs/design/design-manual/source/images/plru_tree_indexing.png diff --git a/docs/04_cv32a65x/design/images/ptw_dptw.png b/docs/design/design-manual/source/images/ptw_dptw.png similarity index 100% rename from docs/04_cv32a65x/design/images/ptw_dptw.png rename to docs/design/design-manual/source/images/ptw_dptw.png diff --git a/docs/04_cv32a65x/design/images/ptw_dptw_s.png b/docs/design/design-manual/source/images/ptw_dptw_s.png similarity index 100% rename from docs/04_cv32a65x/design/images/ptw_dptw_s.png rename to docs/design/design-manual/source/images/ptw_dptw_s.png diff --git a/docs/04_cv32a65x/design/images/ptw_idle.png b/docs/design/design-manual/source/images/ptw_idle.png similarity index 100% rename from docs/04_cv32a65x/design/images/ptw_idle.png rename to docs/design/design-manual/source/images/ptw_idle.png diff --git a/docs/04_cv32a65x/design/images/ptw_in_out.png b/docs/design/design-manual/source/images/ptw_in_out.png similarity index 100% rename from docs/04_cv32a65x/design/images/ptw_in_out.png rename to docs/design/design-manual/source/images/ptw_in_out.png diff --git a/docs/04_cv32a65x/design/images/ptw_iptw.png b/docs/design/design-manual/source/images/ptw_iptw.png similarity index 100% rename from docs/04_cv32a65x/design/images/ptw_iptw.png rename to docs/design/design-manual/source/images/ptw_iptw.png diff --git a/docs/04_cv32a65x/design/images/ptw_mis_sup.png b/docs/design/design-manual/source/images/ptw_mis_sup.png similarity index 100% rename from docs/04_cv32a65x/design/images/ptw_mis_sup.png rename to docs/design/design-manual/source/images/ptw_mis_sup.png diff --git a/docs/04_cv32a65x/design/images/ptw_nlvl.png b/docs/design/design-manual/source/images/ptw_nlvl.png similarity index 100% rename from docs/04_cv32a65x/design/images/ptw_nlvl.png rename to docs/design/design-manual/source/images/ptw_nlvl.png diff --git a/docs/04_cv32a65x/design/images/ptw_pte_1.png b/docs/design/design-manual/source/images/ptw_pte_1.png similarity index 100% rename from docs/04_cv32a65x/design/images/ptw_pte_1.png rename to docs/design/design-manual/source/images/ptw_pte_1.png diff --git a/docs/04_cv32a65x/design/images/ptw_pte_flowchart.png b/docs/design/design-manual/source/images/ptw_pte_flowchart.png similarity index 100% rename from docs/04_cv32a65x/design/images/ptw_pte_flowchart.png rename to docs/design/design-manual/source/images/ptw_pte_flowchart.png diff --git a/docs/04_cv32a65x/design/images/ptw_state_diagram.png b/docs/design/design-manual/source/images/ptw_state_diagram.png similarity index 100% rename from docs/04_cv32a65x/design/images/ptw_state_diagram.png rename to docs/design/design-manual/source/images/ptw_state_diagram.png diff --git a/docs/04_cv32a65x/design/images/replacement_entry.png b/docs/design/design-manual/source/images/replacement_entry.png similarity index 100% rename from docs/04_cv32a65x/design/images/replacement_entry.png rename to docs/design/design-manual/source/images/replacement_entry.png diff --git a/docs/04_cv32a65x/design/images/schema_fsm_load_control.png b/docs/design/design-manual/source/images/schema_fsm_load_control.png similarity index 100% rename from docs/04_cv32a65x/design/images/schema_fsm_load_control.png rename to docs/design/design-manual/source/images/schema_fsm_load_control.png diff --git a/docs/04_cv32a65x/design/images/sfence_vaddr_asid.png b/docs/design/design-manual/source/images/sfence_vaddr_asid.png similarity index 100% rename from docs/04_cv32a65x/design/images/sfence_vaddr_asid.png rename to docs/design/design-manual/source/images/sfence_vaddr_asid.png diff --git a/docs/04_cv32a65x/design/images/sfence_vaddr_x0.png b/docs/design/design-manual/source/images/sfence_vaddr_x0.png similarity index 100% rename from docs/04_cv32a65x/design/images/sfence_vaddr_x0.png rename to docs/design/design-manual/source/images/sfence_vaddr_x0.png diff --git a/docs/04_cv32a65x/design/images/sfence_x0_asid.png b/docs/design/design-manual/source/images/sfence_x0_asid.png similarity index 100% rename from docs/04_cv32a65x/design/images/sfence_x0_asid.png rename to docs/design/design-manual/source/images/sfence_x0_asid.png diff --git a/docs/04_cv32a65x/design/images/sfence_x0_x0.png b/docs/design/design-manual/source/images/sfence_x0_x0.png similarity index 100% rename from docs/04_cv32a65x/design/images/sfence_x0_x0.png rename to docs/design/design-manual/source/images/sfence_x0_x0.png diff --git a/docs/04_cv32a65x/design/images/shared_tlb.png b/docs/design/design-manual/source/images/shared_tlb.png similarity index 100% rename from docs/04_cv32a65x/design/images/shared_tlb.png rename to docs/design/design-manual/source/images/shared_tlb.png diff --git a/docs/04_cv32a65x/design/images/shared_tlb_in_out.png b/docs/design/design-manual/source/images/shared_tlb_in_out.png similarity index 100% rename from docs/04_cv32a65x/design/images/shared_tlb_in_out.png rename to docs/design/design-manual/source/images/shared_tlb_in_out.png diff --git a/docs/04_cv32a65x/design/images/shared_tlb_set.png b/docs/design/design-manual/source/images/shared_tlb_set.png similarity index 100% rename from docs/04_cv32a65x/design/images/shared_tlb_set.png rename to docs/design/design-manual/source/images/shared_tlb_set.png diff --git a/docs/04_cv32a65x/design/images/subsystems.png b/docs/design/design-manual/source/images/subsystems.png similarity index 100% rename from docs/04_cv32a65x/design/images/subsystems.png rename to docs/design/design-manual/source/images/subsystems.png diff --git a/docs/04_cv32a65x/design/images/update_tree.png b/docs/design/design-manual/source/images/update_tree.png similarity index 100% rename from docs/04_cv32a65x/design/images/update_tree.png rename to docs/design/design-manual/source/images/update_tree.png diff --git a/docs/design/design-manual/source/instructions.adoc b/docs/design/design-manual/source/instructions.adoc new file mode 100644 index 0000000000..d7e0e5ba96 --- /dev/null +++ b/docs/design/design-manual/source/instructions.adoc @@ -0,0 +1,19 @@ +//// + Copyright 2023 Thales DIS France SAS + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[instructions]] +Instructions +~~~~~~~~~~~~ + +The next subchapter lists the extensions implemented in {ohg-config}. By +configuration, we can enable/disable the extensions. {ohg-config} supports +the extensions described in the next subchapters. + +include::isa/isa.adoc[] diff --git a/docs/design/design-manual/source/intro.adoc b/docs/design/design-manual/source/intro.adoc new file mode 100644 index 0000000000..927a69af1a --- /dev/null +++ b/docs/design/design-manual/source/intro.adoc @@ -0,0 +1,120 @@ +//// + Copyright 2022 Thales DIS design services SAS + Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +[[introduction]] +Introduction +------------ + +The OpenHW Group uses https://semver.org/[semantic versioning] to +describe the release status of its IP. This document describes the +{ohg-config} configuration version of CVA6. This intends to be the first +formal release of CVA6. + +CVA6 is a 6-stage in-order and single issue processor core which +implements the RISC-V instruction set. CVA6 can be configured as a 32- +or 64-bit core (RV32 or RV64), called CV32A6 or CV64A6. + +The objective of this document is to provide enough information to allow +the RTL modification (by designers) and the RTL verification (by +verificators). This document is not dedicated to CVA6 users looking for +information to develop software like instructions or registers. + +The CVA6 architecture is illustrated in the following figure. + +image:ariane_overview.drawio.png[CVA6 Architecture] + +[[license]] +License +~~~~~~~ + +[verse] +-- +Copyright 2022 Thales +Copyright 2018 ETH Zürich and University of Bologna +SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file except in compliance with the License, or, at your option, the Apache License version 2.0. You may obtain a copy of the License at https://solderpad.org/licenses/SHL-2.1/. +Unless required by applicable law or agreed to in writing, any work 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. +-- + +[[standards-compliance]] +Standards Compliance +~~~~~~~~~~~~~~~~~~~~ + +To ease the reading, the reference to these specifications can be +implicit in the requirements below. For the sake of precision, the +requirements identify the versions of RISC-V extensions from these +specifications. + +* *[CVA6req]* “CVA6 requirement specification”, +https://github.com/openhwgroup/cva6/blob/master/docs/specifications/cva6_requirement_specification.rst, +HASH#767c465. +* *[RVunpriv]* “The RISC-V Instruction Set Manual, Volume I: User-Level +ISA, Document Version 20191213”, Editors Andrew Waterman and Krste +Asanović, RISC-V Foundation, December 13, 2019. +* *[RVpriv]* “The RISC-V Instruction Set Manual, Volume II: Privileged +Architecture, Document Version 20211203”, Editors Andrew Waterman, Krste +Asanović and John Hauser, RISC-V Foundation, December 4, 2021. +* *[RVdbg]* “RISC-V External Debug Support, Document Version 0.13.2”, +Editors Tim Newsome and Megan Wachs, RISC-V Foundation, March 22, 2019. +* *[RVcompat]* “RISC-V Architectural Compatibility Test Framework”, +https://github.com/riscv-non-isa/riscv-arch-test. +* *[AXI]* AXI Specification, +https://developer.arm.com/documentation/ihi0022/hc. +* *[CV-X-IF]* Placeholder for the CV-X-IF coprocessor interface +currently prepared at OpenHW Group; current version in +https://docs.openhwgroup.org/projects/openhw-group-core-v-xif/. +* *[OpenPiton]* “OpenPiton Microarchitecture Specification”, Princeton +University, +https://parallel.princeton.edu/openpiton/docs/micro_arch.pdf. + +CV32A6 is a standards-compliant 32-bit processor fully compliant with +RISC-V specifications: [RVunpriv], [RVpriv] and [RVdbg] and passes +[RVcompat] compatibility tests, as requested by [GEN-10] in [CVA6req]. + +[[documentation-framework]] +Documentation framework +~~~~~~~~~~~~~~~~~~~~~~~ + +The framework of this document is inspired by the Common Criteria. The +Common Criteria for Information Technology Security Evaluation (referred +to as Common Criteria or CC) is an international standard (ISO/IEC +15408) for computer security certification. + +Description of the framework: + +* Processor is split into module corresponding to the main modules of +the design +* Modules can contain several modules +* Each module is described in a chapter, which contains the following +subchapters: _Description_, _Functionalities_, _Architecture and +Modules_ and _Registers_ (if any) +* The subchapter _Description_ describes the main features of the +submodule, the interconnections between the current module and the +others and the inputs/outputs interface. +* The subchapter _Functionality_ lists in details the module +functionalities. Please avoid using the RTL signal names to explain the +functionalities. +* The subchapter _Architecture and Modules_ provides a drawing to +present the module hierarchy, then the functionalities covered by the +module +* The subchapter _Registers_ specifies the module registers if any + +[[contributors]] +Contributors +~~~~~~~~~~~~ + +[verse] +-- +Jean-Roch Coulon - Thales +Ayoub Jalali (mailto:ayoub.jalali@external.thalesgroup.com[ayoub.jalali@external.thalesgroup.com]) +Alae Eddine Ezzejjari (mailto:alae-eddine.ez-zejjari@external.thalesgroup.com[alae-eddine.ez-zejjari@external.thalesgroup.com]) +-- + +*[TO BE COMPLETED]* diff --git a/docs/design/design-manual/source/mmu.adoc b/docs/design/design-manual/source/mmu.adoc new file mode 100644 index 0000000000..204fac8232 --- /dev/null +++ b/docs/design/design-manual/source/mmu.adoc @@ -0,0 +1,1258 @@ +[[CVA6_MMU]] +[[memory-management-unit]] +Memory Management Unit +---------------------- + +The Memory Management Unit (MMU) SV32 module is a crucial component in +the RISC-V-based processor, serving as the backbone for virtual memory +management and address translation. + +image:mmu_in_out.png[*Figure 1:* Inputs and Outputs of CVA6 +MMU SV32,scaledwidth=70.0%] + +At its core, the MMU SV32 plays a pivotal role in translating virtual +addresses into their corresponding physical counterparts. This +translation process is paramount for providing memory protection, +isolation, and efficient memory management in modern computer systems. +Importantly, it handles both instruction and data accesses, ensuring a +seamless interaction between the processor and virtual memory. Within +the MMU, several major blocks play pivotal roles in this address +translation process. These includes: + +* Instruction TLB (ITLB) +* Data TLB (DTLB) +* Shared TLB +* Page Table Walker (PTW) + +image:mmu_major_blocks.png[*Figure 2:* Major Blocks in CVA6 +MMU SV32,scaledwidth=60.0%] + +The MMU SV32 manages privilege levels and access control, enforcing +permissions for user and supervisor modes while handling access +exceptions. It employs Translation Lookaside Buffers (TLBs) for +efficient address translation, reducing the need for page table access. +TLB hits yield quick translations, but on misses, the shared TLB is +consulted, and if necessary, the Page Table Walker (PTW) performs page +table walks, updating TLBs and managing exceptions during the process. + +In addition to these functionalities, the MMU SV32 seamlessly integrates +support for Physical Memory Protection (PMP), enabling it to enforce +access permissions and memory protection configurations as specified by +the PMP settings. This additional layer of security and control enhances +the management of memory accesses + +The MMU SV32 maintains interfaces with the instruction cache (ICache) +and the load-store unit (LSU). It receives virtual addresses from these +components and proceeds to translate them into physical addresses, a +fundamental task for ensuring proper program execution and memory +access. + +[cols=",,,,",options="header",] +|======================================================================= +|Signal |IO |Connection Type |Type |Description +|`clk_i` |in |Subsystem |logic |Subsystem Clock + +|`rst_ni` |in |Subsystem |logic |Asynchronous reset active low + +|`flush_i` |in |Controller |logic |Sfence Committed + +|`enable_translation_i` |in |CSR RegFile |logic |Indicate address +translation request for instruction + +|`en_ld_st_translation_i` |in |CSR RegFile |logic |Indicate address +translation request for load or store + +|`icache_areq_i` |in |Cache Subsystem |icache_arsp_t |Icache Response + +|`icache_areq_o` |out |Cache Subsystem |icache_areq_t |Icache Request + +|`misaligned_ex_i` |in |Load Store Unit |exception_t |Indicate +misaligned exception + +|`lsu_req_i` |in |Load Store Unit |logic |Request address translation + +|`lsu_vaddr_i` |in |Load Store Unit |logic [riscv::VLEN-1:0] |Virtual +Address In + +|`lsu_is_store_i` |in |Store Unit |logic |Translation is requested by a +store + +|`lsu_dtlb_hit_o` |out |Store / Load Unit |logic |Indicate a DTLB hit + +|`lsu_dtlb_ppn_o` |out |Load Unit |logic [riscv::PPNW-1:0] |Send PNN to +LSU + +|`lsu_valid_o` |out |Load Store Unit |logic |Indicate a valid +translation + +|`lsu_paddr_o` |out |Store / Load Unit |logic [riscv::PLEN-1:0] +|Translated Address + +|`lsu_exception_o` |out |Store / Load Unit |exception_t |Address +Translation threw an exception + +|`priv_lvl_i` |in |CSR RegFile |riscv::priv_lvl_t |Privilege level for +instruction fetch interface + +|`ld_st_priv_lvl_i` |in |CSR RegFile |riscv::priv_lvl_t |Privilege Level +for Data Interface + +|`sum_i` |in |CSR RegFile |logic |Supervisor User Memory Access bit in +xSTATUS CSR register + +|`mxr_i` |in |CSR RegFile |logic |Make Executable Readable bit in +xSTATUS CSR register + +|`satp_ppn_I` |in |CSR RegFile |logic [riscv::PPNW-1:0] |PPN of top +level page table from SATP register + +|`asid_i` |in |CSR RegFile |logic [ASID_WIDTH-1:0] |ASID to for the +lookup + +|`asid_to_be_flushed` |in |Execute Stage |logic [ASID_WIDTH-1:0] |ASID +of the entry to be flushed. + +|`vaddr_to_be_flushed_i` |in |Execute Stage |logic [riscv::VLEN-1:0] +|Virtual address of the entry to be flushed. + +|`flush_tlb_i` |in |Controller |logic |SFENCE.VMA committed + +|`itlb_miss_o` |out |Performance Counter |logic |Indicate an ITLB miss + +|`dtlb_miss_o` |out |Performance Counter |logic |Indicate a DTLB miss + +|`req_port_i` |in |Cache Subsystem |dcache_req_o_t |D Cache Data +Requests + +|`req_port_o` |out |Cache Subsystem |dcache_req_i_t |D Cache Data +Response + +|`pmpcfg_i` |in |CSR RegFile |riscv::pmpcfg_t [15:0] |PMP configurations + +|`pmpaddr_i` |in |CSR RegFile |logic [15:0][riscv::PLEN-3:0] |PMP +Address +|======================================================================= + +[cols=",,",options="header",] +|=============================================================== +|Signal |Type |Description +|`fetch_valid` |logic |Address Translation Valid +|`fetch_paddr` |logic [riscv::PLEN-1:0] |Physical Address In +|`fetch_exception` |exception_t |Exception occurred during fetch +|=============================================================== + +[cols=",,",options="header",] +|=========================================================== +|Signal |Type |Description +|`fetch_req` |logic |Address Translation Request +|`fetch_vaddr` |logic [riscv::VLEN-1:0] |Virtual Address out +|=========================================================== + +[cols=",,",options="header",] +|======================================================================= +|Signal |Type |Description +|`cause` |riscv::xlen_t |Cause of exception + +|`tval` |riscv::xlen_t |Additional information of causing exception +(e.g. instruction causing it), address of LD/ST fault + +|`valid` |logic |Indicate that exception is valid +|======================================================================= + +[cols=",,",options="header",] +|==================================================================== +|Signal |Type |Description +|`locked` |logic |Lock this configuration +|`reserved` |logic[1:0] |Reserved bits in pmpcfg CSR +|`addr_mode` |pmp_addr_mode_t |Addressing Modes: OFF, TOR, NA4, NAPOT +|`access_type` |pmpcfg_access_t |None, read, write, execute +|==================================================================== + +image:mmu_control_flow.png[*Figure 3:* Control Flow in CVA6 +MMU SV32,scaledwidth=95.0%] + +Two potential exception sources exist: + +* Hardware Page Table Walker (HPTW) throwing an exception, signifying a +page fault exception. +* Access error due to insufficient permissions of PMP, known as an +access exception. + +The IF stage initiates a request to retrieve memory content at a +specific virtual address. When the MMU is disabled, the instruction +fetch request is directly passed to the I$ without modifications. + +If virtual memory translation is enabled for instruction fetches, the +following operations are performed in the instruction interface: + +* Compatibility of requested virtual address with selected page based +address translation scheme is checked. +* For 4K page translation, the module determines the fetch physical +address by combining the physical page number (PPN) from ITLB content +and the offset from the virtual address. +* In the case of Mega page translation, if the ITLB indicates a 4M page, +the VPN0 from the fetch virtual address is written to the PPN0 of the +fetch physical address to ensure alignment for superpage translation. +* If the Instruction TLB (ITLB) lookup hits, the fetch valid signal +(which indicates a valid physical address) is activated in response to +the input fetch request. Memory region accessibility is checked from the +perspective of the fetch operation, potentially triggering a page fault +exception in case of an access error or insufficient PMP permission. +* In case of an ITLB miss, if the page table walker (PTW) is active +(only active if there is a shared TLB miss) and handling instruction +fetches, the fetch valid signal is determined based on PTW errors or +access exceptions. + +If the fetch physical address doesn't match any execute region, an +Instruction Access Fault is raised. When not translating, PMPs are +immediately checked against the physical address for access +verification. + +If address translation is enabled for load or store, and no misaligned +exception has occurred, the following operations are performed in the +data interface: + +* Initially, translation is assumed to be invalid, signified by the MMU +to LSU. +* The translated physical address is formed by combining the PPN from +the Page Table Entry (PTE) and the offset from the virtual address +requiring translation. This send one cycle later due to the additional +bank of registers which delayed the MMU’s answer. The PPN from the PTE +is also shared separately with LSU in the same cycle as the hit. +* In the case of superpage translation, as in SV32, known as the 4M +page, PPN0 of the translated physical address and the separately shared +PPN are updated with the VPN0 of the virtual address. + +If a Data TLB (DTLB) hit occurs, it indicates a valid translation, and +various fault checks are performed depending on whether it's a load or +store request. + +* For store requests, if the page is not writable, the dirty flag isn't +set, or privileges are violated, it results in a page fault +corresponding to the store access. If PMPs are also violated, it leads +to an access fault corresponding to the store access. Page faults take +precedence over access faults. +* For load requests, a page fault is triggered if there are insufficient +access privileges. PMPs are checked again during load access, resulting +in an access fault corresponding to load access if PMPs are violated. + +In case of a DTLB miss, potential exceptions are monitored during the +page table walk. If the PTW indicates a page fault, the corresponding +page fault related to the requested type is signaled. If the PTW +indicates an access exception, the load access fault is indicated +through address translation because the page table walker can only throw +load access faults. + +When address translation is not enabled, the physical address is +immediately checked against Physical Memory Protections (PMPs). If there +is a request from LSU, no misaligned exception, and PMPs are violated, +it results in an access fault corresponding to the request being +indicated. + +[[translation-lookaside-buffer]] +Translation Lookaside Buffer +---------------------------- + +Page tables are accessed for translating virtual memory addresses to +physical memory addresses. This translation needs to be carried out for +every load and store instruction and also for every instruction fetch. +Since page tables are resident in physical memory, accessing these +tables in all these situations has a significant impact on performance. +Page table accesses occur in patterns that are closely related in time. +Furthermore, the spatial and temporal locality of data accesses or +instruction fetches mean that the same page is referenced repeatedly. +Taking advantage of these access patterns the processor keeps the +information of recent address translations, to enable fast retrieval, in +a small cache called the Translation Lookaside Buffer (TLB) or an +address-translation cache. + +The CVA6 TLB is structured as a fully associative cache, where the +virtual address that needs to be translated is compared against all the +individual TLB entries. Given a virtual address, the processor examines +the TLB (TLB lookup) to determine if the virtual page number (VPN) of +the page being accessed is in the TLB. When a TLB entry is found (TLB +hit), the TLB returns the corresponding physical page number (PPN) which +is used to calculate the target physical address. If no TLB entry is +found (TLB miss) the processor has to read individual page table entries +from memory (Table walk). In CVA6 table walking is supported by +dedicated hardware. Once the processor finishes the table walk it has +the Physical Page Number (PPN) corresponding to the Virtual Page Number +(VPN) That needs to be translated. The processor adds an entry for this +address translation to the TLB so future translations of that virtual +address will happen quickly through the TLB. During the table walk the +processor may find out that the corresponding physical page is not +resident in memory. At this stage a page table exception (Page Fault) is +generated which gets handled by the operating system. The operating +system places the appropriate page in memory, updates the appropriate +page tables and returns execution to the instruction which generated the +exception. + +The inputs and output signals of the TLB are shown in the following two +figures. + +image:in_out_tlb.png[*Figure 4:* Inputs and Outputs of CVA6 +TLB,scaledwidth=65.0%] + +[cols=",,,,",options="header",] +|======================================================================= +|Signal |IO |connection |Type |Description +|`clk_i` |in |SUBSYSTEM |logic |Subsystem Clock + +|`rst_ni` |in |SUBSYSTEM |logic |Asynchronous reset active low + +|`flush_i` |in |Controller |logic |Asynchronous reset active low + +|`update_i` |in |Shared TLB |tlb_update_sv32_t |Updated tag and content +of TLB + +|`lu_access_i` |in |Cache Subsystem |logic |Signal indicating a lookup +access is being requested + +|`lu_asid_i` |in |CSR RegFile |logic[ASID_WIDTH-1:0] |ASID (Address +Space Identifier) for the lookup + +|`lu_vaddr_i` |in |Cache Subsystem |logic[riscv::VLEN-1:0] |Virtual +address for the lookup + +|`lu_content_o` |out |MMU SV32 |riscv::pte_sv32_t |Output for the +content of the TLB entry + +|`asid_to_be_flushed_i` |in |Execute Stage |logic[ASID_WIDTH-1:0] |ASID +of the entry to be flushed + +|`vaddr_to_be_flushed_i` |in |Execute Stage |logic[riscv::VLEN-1:0] +|Virtual address of the entry to be flushed + +|`lu_is_4M_o` |out |MMU SV32 |logic |Output indicating whether the TLB +entry corresponds to a 4MB page + +|`lu_hit_o` |out |MMU SV32 |logic |Output indicating whether the lookup +resulted in a hit or miss +|======================================================================= + +[cols=",,",options="header",] +|======================================================================= +|Signal |Type |Description +|`valid` |logic |Indicates whether the TLB update entry is valid or not + +|`is_4M` |logic |Indicates if the TLB entry corresponds to a 4MB page + +|`vpn` |logic[19:0] |Virtual Page Number (VPN) used for updating the +TLB, consisting of 20 bits + +|`asid` |logic[8:0] |Address Space Identifier (ASID) used for updating +the TLB, with a length of 9 bits for Sv32 MMU + +|`content` |riscv::pte_sv32_t |Content of the TLB update entry, defined +by the structure +|======================================================================= + +[cols=",,",options="header",] +|======================================================================= +|Signal |Type |Description +|`ppn` |logic[21:0] |22 bit Physical Page Number (PPN) + +|`rsw` |logic[1:0] |Reserved for use by supervisor software + +|`d` |logic a| +[verse] +-- +Dirty bit indicating whether the page has been modified (dirty) or not +0: Page is clean i.e., has not been written +1: Page is dirty i.e., has been written +-- + +|`a` |logic a| +[verse] +-- +Accessed bit indicating whether the page has been accessed +0: Virtual page has not been accessed since the last time A bit was cleared +1: Virtual page has been read, written, or fetched from since the last time the A bit was cleared +-- + +|`g` |logic a| +[verse] +-- +Global bit marking a page as part of a global address space valid for all ASIDs +0: Translation is valid for specific ASID +1: Translation is valid for all ASIDs +-- + +|`u` |logic a| +[verse] +-- +User bit indicating privilege level of the page +0: Page is not accessible in user mode but in supervisor mode +1: Page is accessible in user mode but not in supervisor mode +-- + +|`x` |logic a| +[verse] +-- +Execute bit which allows execution of code from the page +0: Code execution is not allowed +1: Code execution is permitted +-- + +|`w` |logic a| +[verse] +-- +Write bit allows the page to be written +0: Write operations are not allowed +1: Write operations are permitted +-- + +|`r` |logic a| +[verse] +-- +Read bit allows read access to the page +0: Read operations are not allowed +1: Read operations are permitted +-- + +|`v` |logic a| +[verse] +-- +Valid bit indicating the page table entry is valid +0: Page is invalid i.e. page is not in DRAM, translation is not valid +1: Page is valid i.e. page resides in the DRAM, translation is valid +-- + +|======================================================================= + +The number of TLB entries can be changed via a design parameter. In +32-bit configurations of CVA6 only 2 TLB entries are instantiated. Each +TLB entry is made up of two fields: Tag and Content. The Tag field holds +the virtual page number (VPN1, VPN0), ASID, page size (is_4M) along with +a valid bit (VALID) indicating that the entry is valid. The SV32 virtual +page number, which is supported by CV32A6X, is further split into two +separate virtual page numbers VPN1 and VPN0. The Content field contains +two physical page numbers (PPN1, PPN0) along with a number of bits which +specify various attributes of the physical page. Note that the V bit in +the Content field is the V bit which is present in the page table in +memory. It is copied from the page table, as is, and the VALID bit in +the Tag is set based on its value.The TLB entry fields are shown in +*Figure 2*. + +image:cva6_tlb_entry.png[*Figure 5:* Fields in CVA6 TLB +entry,scaledwidth=80.0%] + +The CVA6 TLB implements the following three functions: + +* *Translation:* This function implements the address lookup and match +logic. +* *Update and Flush:* This function implements the update and flush +logic. +* *Pseudo Least Recently Used Replacement Policy:* This function +implements the replacement policy for TLB entries. + +This function takes in the virtual address and certain other fields, +examines the TLB to determine if the virtual page number of the page +being accessed is in the TLB or not. If a TLB entry is found (TLB hit), +the TLB returns the corresponding physical page number (PPN) which is +then used to calculate the target physical address. The following checks +are done as part of this lookup function to find a match in the TLB: + +* *Validity Check:* For a TLB hit, the associated TLB entry must be +valid . +* *ASID and Global Flag Check:* The TLB entry's ASID must match the +given ASID (ASID associated with the Virtual address). If the TLB +entry’s Global bit (G) bit is set then this check is not done. This +ensures that the translation is either specific to the provided ASID or +it is globally applicable. +* *Level 1 VPN match:* SV32 implements a two-level page table. As such +the virtual address is broken up into three parts which are the virtual +page number 1, virtual page number 0 and displacement. So the condition +that is checked next is that the virtual page number 1 of the virtual +address matches the virtual page number 1(VPN1) of the TLB entry. +* *Level 0 VPN match or 4-Mega Page:* The last condition to be checked, +for a TLB hit, is that the virtual page number 0 of the virtual address +matches the virtual page number 0 of the TLB entry (VPN0). This match is +ignored if the is_4M bit in the Tag is set which implies a super 4M +page. + +All the conditions listed above are checked against every TLB entry. If +there is a TLB hit then the corresponding bit in the hit array is set. +*Figure 3* Illustrates the TLB hit/miss process listed above. + +image:cva6_tlb_hit.png[*Figure 6:* Block diagram of CVA6 TLB +hit or miss,scaledwidth=75.0%] + +The SFENCE.VMA instruction can be used with certain specific source +register specifiers (rs1 & rs2) to flush a specific TLB entry, some set +of TLB entries or all TLB entries. Like all instructions this action +only takes place when the SFENCE.VMA instruction is committed (shown via +the commit_sfence signal in the following figures.) The behavior of the +instruction is as follows: + +* *If rs1 is not equal to x0 and rs2 is not equal to x0:* Invalidate all +TLB entries which contain leaf page table entries corresponding to the +virtual address in rs1 (shown below as Virtual Address to be flushed) +and that match the address space identifier as specified by integer +register rs2 (shown below as asid_to_be_flushed_i), except for entries +containing global mappings. This is referred to as the “SFENCE.VMA vaddr +asid” case. + +image:sfence_vaddr_asid.png[*Figure 7:* Invalidate TLB entry +if ASID and virtual address match,scaledwidth=75.0%] + +* *If rs1 is equal to x0 and rs2 is equal to x0:* Invalidate all TLB +entries for all address spaces. This is referred to as the "SFENCE.VMA +x0 x0" case. + +image:sfence_x0_x0.png[*Figure 8:* Invalidate all TLB entries +if both source register specifiers are x0,scaledwidth=62.0%] + +* *If rs1 is not equal to x0 and rs2 is equal to x0:* invalidate all TLB +entries that contain leaf page table entries corresponding to the +virtual address in rs1, for all address spaces. This is referred to as +the “SFENCE.VMA vaddr x0” case. + +image:sfence_vaddr_x0.png[*Figure 9:* Invalidate TLB entry +with matching virtual address for all address spaces,scaledwidth=75.0%] + +* *If rs1 is equal to x0 and rs2 is not equal to x0:* Invalidate all TLB +entries matching the address space identified by integer register rs2, +except for entries containing global mappings. This is referred to as +the “SFENCE.VMA 0 asid” case. + +image:sfence_x0_asid.png[*Figure 10:* Invalidate TLB entry for +matching ASIDs,scaledwidth=75.0%] + +When a TLB valid update request is signaled by the shared TLB, and the +replacement policy select the update of a specific TLB entry, the +corresponding entry's tag is updated with the new tag, and its +associated content is refreshed with the information from the update +request. This ensures that the TLB entry accurately reflects the new +translation information. + +Cache replacement algorithms are used to determine which TLB entry +should be replaced, because it is not likely to be used in the near +future. The Pseudo-Least-Recently-Used (PLRU) is a cache entry +replacement algorithm, derived from Least-Recently-Used (LRU) cache +entry replacement algorithm, used by the TLB. Instead of precisely +tracking recent usage as the LRU algorithm does, PLRU employs an +approximate measure to determine which entry in the cache has not been +recently used and as such can be replaced. + +CVA6 implements the PLRU algorithm via the Tree-PLRU method which +implements a binary tree. The TLB entries are the leaf nodes of the +tree. Each internal node, of the tree, consists of a single bit, +referred to as the state bit or plru bit, indicating which subtree +contains the (pseudo) least recently used entry (the PLRU); 0 for the +left hand tree and 1 for the right hand tree. Following this traversal, +the leaf node reached, corresponds to the PLRU entry which can be +replaced. Having accessed an entry (so as to replace it) we need to +promote that entry to be the Most Recently Used (MRU) entry. This is +done by updating the value of each node along the access path to point +away from that entry. If the accessed entry is a right child i.e., its +parent node value is 1, it is set to 0, and if the parent is the left +child of its parent (the grandparent of the accessed node) then its node +value is set to 1 and so on all the way up to the root node. + +The PLRU binary tree is implemented as an array of node values. Nodes +are organized in the array based on levels, with those from lower levels +appearing before higher ones. Furthermore those on the left side of a +node appear before those on the right side of a node. The figure below +shows a tree and the corresponding array. + +image:plru_tree_indexing.png[*Figure 11:* PLRU Tree +Indexing,scaledwidth=60.0%] + +For n-way associative, we require n - 1 internal nodes in the tree. With +those nodes, two operations need to be performed efficiently. + +* Promote the accessed entry to be MRU +* Identify which entry to replace (i.e. the PLRU entry) + +For a TLB entry which is accessed, the following steps are taken to make +it the MRU: + +1. Iterate through each level of the binary tree. +2. Calculate the index of the leftmost child within the current level. +Let us call that index the index base. +3. Calculate the shift amount to identify the relevant node based on +the level and TLB entry index. +4. Calculate the new value that the node should have in order to make +the accessed entry the Most Recently Used (MRU). The new value of the +root node is the opposite of the TLB entry index, MSB at the root node, +MSB - 1 at node at next level and so on. +5. Assign this new value to the relevant node, ensuring that the hit +entry becomes the MRU within the binary tree structure. + +At level 0, no bit of the TLB entry’s index determines the offset from +the index base because it’s a root node. At level 1, MSB of entry’s +index determines the amount of offset from index base at that level. At +level 2, the first two bits of the entry's index from MSB side determine +the offset from the index base because there are 4 nodes at the level 2 +and so on. + +image:update_tree.png[*Figure 12:* Promote Entry to be +MRU,scaledwidth=82.0%] + +In the above figure entry at index 5, is accessed. To make it MRU entry, +every node along the access path should point away from it. Entry 5 is a +right child, therefore, its parent plru bit set to 0, its parent is a +left child, its grand parent’s plru bit set to 1, and great +grandparent’s plru bit set to 0. + +Every TLB entry is checked for the replacement entry. The following +steps are taken: + +1. Iterate through each level of the binary tree. +2. Calculate the index of the leftmost child within the current level. +Let us call that index the index base. +3. Calculate the shift amount to identify the relevant node based on +the level and TLB entry index. +4. If the corresponding bit of the entry's index matches the value of +the node being traversed at the current level, keep the replacement +signal high for that entry; otherwise, set the replacement signal to +low. + +image:replacement_entry.png[*Figure 13:* Possible path +traverse for entry selection for replacement,scaledwidth=65.0%] + +Figure shows every possible path that traverses to find out the PLRU +entry. If the plru bit at each level matches with the corresponding bit +of the entry's index, that’s the next entry to replace. Below Table +shows the entry selection for replacement. + +[width="81%",cols="35%,27%,38%",] +|================================================ +|*Path Traverse* |*PLRU Bits* |*Entry to replace* +a| +0 -> 1 -> 3:: + * + + a| +___ +000 +___ + +---------------+:: + 001 + + a| +_ +0 +_ + +----------------------+:: + 1 + +a| +0 -> 1 -> 4:: + * + + a| +___ +010 +___ + +---------------+:: + 011 + + a| +_ +2 +_ + +----------------------+:: + 3 + +a| +0 -> 2 -> 5:: + * + + a| +___ +100 +___ + +---------------+:: + 101 + + a| +_ +4 +_ + +----------------------+:: + 5 + +a| +0 -> 2 -> 6:: + * + + a| +___ +110 +___ + +---------------+:: + 111 + + a| +_ +6 +_ + +----------------------+:: + 7 + +|================================================ + +[[shared-translation-lookaside-buffer]] +Shared Translation Lookaside Buffer +----------------------------------- + +The CVA6 shared TLB is structured as a 2-way associative cache, where +the virtual address requiring translation is compared with the set +indicated by the virtual page number. The shared TLB is looked up in +case of an Instruction TLB (ITLB) or data TLB (DTLB) miss, signaled by +these TLBs. If the entry is found in the shared TLB set, the respective +TLB, whose translation is being requested, is updated. If the entry is +not found in the shared TLB, then the processor has to perform a page +table walk. Once the processor obtains a PPN corresponding to the VPN, +the shared TLB is updated with this information. If the physical page is +not found in the page table, it results in a page fault, which is +handled by the operating system. The operating system will then place +the corresponding physical page in memory. + +The inputs and output signals of the shared TLB are shown in the +following two figures. + +image:shared_tlb_in_out.png[*Figure 14:* Inputs and outputs of +CVA6 shared TLB,scaledwidth=60.0%] + +[cols=",,,,",options="header",] +|======================================================================= +|Signal |IO |Connection |Type |Description +|`clk_i` |in |Subsystem |logic |Subsystem Clock + +|`rst_ni` |in |Subsystem |logic |Asynchronous reset active low + +|`flush_i` |in |Controller |logic |TLB flush request + +|`enable_translation_i` |in |CSR Regfile |logic |CSRs indicate to enable +Sv32 + +|`en_ld_st_translation_i` |in |CSR Regfile |logic |Enable virtual memory +translation for load/stores + +|`asid_i` |in |CSR Regfile |logic |ASID for the lookup + +|`itlb_access_i` |in |Cache Subsystem |logic |Signal indicating a lookup +access in ITLB is being requested. + +|`itlb_hit_i` |in |ITLB |logic |Signal indicating an ITLB hit + +|`itlb_vaddr_i` |in |Cache Subsystem |logic[31:0] |Virtual address +lookup in ITLB + +|`dtlb_access_i` |in |Load/Store Unit |logic |Signal indicating a lookup +access in DTLB is being requested. + +|`dtlb_hit_i` |in |DTLB |logic |Signal indicating a DTLB hit + +|`dtlb_vaddr_i` |in |Load/Store Unit |logic[31:0] |Virtual address +lookup in DTLB + +|`itlb_update_o` |out |ITLB |tlb_update_sv32_t |Tag and content to +update ITLB + +|`dtlb_update_o` |out |DTLB |tlb_update_sv32_t |Tag and content to +update DTLB + +|`itlb_miss_o` |out |Performance Counter |logic |Signal indicating an +ITLB miss + +|`dtlb_miss_o` |out |Performance Counter |logic |Signal indicating a +DTLB miss + +|`shared_tlb_access_o` |out |PTW |logic |Signal indicating a lookup +access in shared TLB is being requested + +|`shared_tlb_hit_o` |out |PTW |logic |Signal indicating a shared TLB hit + +|`shared_tlb_vadd_o` |out |PTW |logic[31:0] |Virtual address lookup in +shared TLB + +|`itlb_req_o` |out |PTW |logic |ITLB Request Output + +|`shared_tlb_update_i` |in |PTW |tlb_update_sv32_t |Updated tag and +content of shared TLB +|======================================================================= + +[cols=",,",options="header",] +|======================================================================= +|Signal |Type |Description +|`is_4M` |logic |Indicates if the shared TLB entry corresponds to a 4MB +page. + +|`vpn1` |logic[9:0] |Virtual Page Number (VPN) represents the index of +PTE in the page table level 1. + +|`vpn0` |logic[9:0] |Virtual Page Number (VPN) represents the index of +PTE in the page table level 0. + +|`asid` |logic |Address Space Identifier (ASID) used to identify +different address spaces +|======================================================================= + +Shared TLB is 2-way associative, with a depth of 64. A single entry in +the set contains the valid bit, tag and the content. The Tag segment +stores details such as the virtual page number (VPN1, VPN0), ASID, and +page size (is_4M). The Content field contains two physical page numbers +(PPN1, PPN0) along with a number of bits which specify various +attributes of the physical page. + +image:shared_tlb.png[*Figure 15:* CVA6 Shared TLB +Structure,scaledwidth=60.0%] + +The implementation of a shared TLB in CVA6 is described in the following +sections: + +* *ITLB and DTLB Miss:* Prepare a shared TLB lookup if the entry is not +found in ITLB or DTLB. +* *Tag Comparison:* Look up the provided virtual address in the shared +TLB. +* *Update and Flush:* Flush the shared TLB or update it. +* *Replacement Policies:* First non-valid entry and random replacement +policy. + +Consider a scenario where an entry is found in the ITLB or DTLB. In this +case, there is no need to perform a lookup in the shared TLB since the +entry has already been found. Next, there are two scenarios: an ITLB +miss or a DTLB miss. + +To identify an ITLB miss, the following conditions need to be fulfilled: + +* Address translation must be enabled. +* There must be an access request to the ITLB. +* The ITLB should indicate an ITLB miss. +* There should be no access request to the DTLB. + +During an ITLB miss, access is granted to read the tag and content of +the shared TLB from their respective sram. The address for reading the +tag and content of the shared TLB entry is calculated using the virtual +address for which translation is not found in the ITLB. The ITLB miss is +also explicitly indicated by the shared TLB. A request for shared TLB +access is initiated. + +To identify the DTLB miss, the following conditions need to be +fulfilled: + +* Address translation for load and stores must be enabled. +* There must be an access request to the DTLB. +* The DTLB should indicate a DTLB miss. + +In the case of a DTLB miss, the same logic is employed as described for +an ITLB miss. + +Shared TLB lookup for a hit occurs under the same conditions as +described for the TLB modules used as ITLB and DTLB. However, there are +some distinctions. In both the ITLB and DTLB, the virtual address +requiring translation is compared against all TLB entries. In contrast, +the shared TLB only compares the tag and content of the set indicated by +the provided virtual page number. The index of the set is extracted from +VPN0 of the requested virtual address. Given that the shared TLB is +2-way associative, each set contains two entries. Consequently, both of +these entries are compared. Below figure illustrates how the set is +opted for the lookup. + +image:shared_tlb_set.png[*Figure 16:* Set opted for lookup in +shared TLB,scaledwidth=60.0%] + +Differing from the ITLB and DTLB, a specific virtual address or +addressing space cannot be flushed in the shared TLB. When SFENCE.VMA is +committed, all entries in the shared TLB are invalidated. (Cases of +SFENCE.VMA should also be added in shared TLB) + +When the Page Table Walker signals a valid update request, the shared +TLB is updated by selecting an entry through the replacement policy and +marking it as valid. This also triggers the writing of the new tag and +content to the respective SRAM. + +In CVA6's shared TLB, two replacement policies are employed for +replacements based on a specific condition. These replacement policies +select the entry within the set indicated by the virtual page number. +The two policies are: + +* First non-valid encounter replacement policy +* Random replacement policy + +First replacement policy failed if all ways are valid. Therefore, a +random replacement policy is opted for. + +The module implemented in CVA6 to find the first non-valid entry in the +shared TLB is the Leading Zero Counter (LZC). It takes three parameters +as input: + +1. *WIDTH:* The width of the input vector. +2. *MODE:* Mode selection - 0 for trailing zero, 1 for leading zero. +3. *CNT WIDTH:* Width of the output signal containing the zero count. + +The input signal is the vector to be counted, and the output represents +the count of trailing/leading zeros. If all bits in the input vector are +zero, it will also be indicated. + +When initializing the module, the width of the input vector is set to +the number of shared TLB ways. The trailing zero counter mode is +selected. The vector of valid bits is set as the input vector, but with +negation. This is because we want the index of the first non-valid +entry, and LZC returns the count of trailing zeros, which actually +corresponds to the index of the first occurrence of 1 from the least +significant bit (LSB). if there is at least one non-valid entry, that +entry is opted for the replacement, and If not then this is signaled by +LZC. + +image:LZC.png[*Figure 17:* Replacement of First invalid +entry.,scaledwidth=60.0%] + +If all ways are valid, a random replacement policy is employed for the +replacement process. The Linear Feedback Shift Register (LFSR) is +utilized to select the replacement entry randomly. LFSR is commonly used +in generating sequences of pseudo-random numbers. When the enable signal +is active, the current state of the LFSR undergoes a transformation. +Specifically, the state is shifted right by one bit, and the result is +combined with a predetermined masking pattern. This masking pattern is +derived from the predefined “Masks” array, introducing a non-linear +behavior to the sequence generation of the LFSR. The masking process +involves XOR operations between the shifted state bits and specific +pattern bits, contributing to the complexity and unpredictability of the +generated sequence. + +image:RR.png[*Figure 18:* Entry selection for replacement +using LFSR,scaledwidth=95.0%] + +[[page-table-walker]] +Page Table Walker +----------------- + +The "CVA6 Page Table Walker (PTW) for MMU Sv32" is a hardware module +developed for the CV32A6 processor architecture, designed to facilitate +the translation of virtual addresses into physical addresses, a crucial +task in memory access management. + +image:ptw_in_out.png[*Figure 19:* Input and Outputs of Page +Table Walker,scaledwidth=60.0%] + +The PTW module operates through various states, each with its specific +function, such as handling memory access requests, validating page table +entries, and responding to errors. + +Key features of this PTW module include support for two levels of page +tables (LVL1 and LVL2) in the Sv32 standard, accommodating instruction +and data page table walks. It rigorously validates and verifies page +table entries (PTEs) to ensure translation accuracy and adherence to +access permissions. This module seamlessly integrates with the CV32A6 +processor's memory management unit (MMU), which governs memory access +control. It also takes into account global mapping, access flags, and +privilege levels during the translation process, ensuring that memory +access adheres to the processor's security and privilege settings. + +In addition to its translation capabilities, the PTW module is equipped +to detect and manage errors, including page-fault exceptions and access +exceptions, contributing to the robustness of the memory access system. +It works harmoniously with physical memory protection (PMP) +configurations, a critical aspect of modern processors' memory security. +Moreover, the module efficiently processes virtual addresses, generating +corresponding physical addresses, all while maintaining speculative +translation, a feature essential for preserving processor performance +during memory access operations. + +[cols=",,,,",options="header",] +|======================================================================= +|Signal |IO |Connection |Type |Description +|`clk_i` |in |Subsystem |logic |Subsystem Clock + +|`rst_ni` |in |Subsystem |logic |Asynchronous reset active low + +|`flush_i` |in |Controller |logic |Sfence Committed + +|`ptw_active_o` |out |MMU |logic |Output signal indicating whether the +Page Table Walker (PTW) is currently active + +|`walking_instr_o` |out |MMU |logic |Indicating it's an instruction page +table walk or not + +|`ptw_error_o` |out |MMU |logic |Output signal indicating that an error +occurred during PTW operation + +|`ptw_access_exception_o` |out |MMU |logic |Output signal indicating +that a PMP (Physical Memory Protection) access exception occurred during +PTW operation. + +|`lsu_is_store_i` |in |Store Unit |logic |Input signal indicating +whether the translation was triggered by a store operation. + +|`req_port_i` |in |Cache Subsystem |dcache_req_o_t |D Cache Data +Requests + +|`req_port_o` |out |Cache Subsystem / Perf Counter |dcache_req_u_t |D +Cache Data Response + +|`shared_tlb_update_o` |out |Shared TLB |tlb_update_sv32_t |Updated tag +and content of shared TLB + +|`update_vaddr_o` |out |MMU |logic[riscv::VLEN-1:0] |Updated VADDR from +shared TLB + +|`asid_i` |in |CSR RegFile |logic[ASID_WIDTH-1:0] |ASID for the lookup + +|`shared_tlb_access_i` |in |Shared TLB |logic |Access request of shared +TLB + +|`shared_tlb_hit_i` |in |Shared TLB |logic |Indicate shared TLB hit + +|`shared_tlb_vaddr_i` |in |Shared TLB |logic[riscv::VLEN-1:0] |Virtual +Address from shared TLB + +|`itlb_req_i` |in |Shared TLB |logic |Indicate request to ITLB + +|`satp_ppn_i` |in |CSR RegFile |logic[riscv::PPNW-1:0] |PPN of top level +page table from SATP register + +|`mxr_i` |in |CSR RegFile |logic |Make Executable Readable bit in +xSTATUS CSR register + +|`shared_tlb_miss_o` |out |OPEN |logic |Indicate a shared TLB miss + +|`pmpcfg_i` |in |CSR RegFile |riscv::pmpcfg_t[15:0] |PMP configuration + +|`pmpaddr_i` |in |CSR RegFile |logic[15:0][riscv::PLEN-3:0] |PMP Address + +|`bad_paddr_o` |out |MMU |logic[riscv::PLEN-1:0] |Bad Physical Address +in case of access exception +|======================================================================= + +[cols=",,",options="header",] +|======================================================================= +|Signal |Type |Description +|`address_index` |logic [DCACHE_INDEX_WIDTH-1:0] |Index of the Dcache +Line + +|`address_tag` |logic [DCACHE_TAG_WIDTH-1:0] |Tag of the Dcache Line + +|`data_wdata` |riscv::xlen_t |Data to write in the Dcache + +|`data_wuser` |logic [DCACHE_USER_WIDTH-1:0] |data_wuser + +|`data_req` |logic |Data Request + +|`data_we` |logic |Data Write enabled + +|`data_be` |logic [(riscv::XLEN/8)-1:0] |Data Byte enable + +|`data_size` |logic [1:0] |Size of data + +|`data_id` |logic [DCACHE_TID_WIDTH-1:0] |Data ID + +|`kill_req` |logic |Kill the D cache request + +|`tag_valid` |logic |Indicate that teh tag is valid +|======================================================================= + +[cols=",,",options="header",] +|======================================================================= +|Signal |Type |Description +|`data_gnt` |logic |Grant of data is given in response to the data +request + +|`data_rvalid` |logic |Indicate that data is valid which is sent by D +cache + +|`data_rid` |logic [DCACHE_TID_WIDTH-1:0] |Requested data ID + +|`data_rdata` |riscv::xlen_t |Data from D cache + +|`data_ruser` |logic [DCACHE_USER_WIDTH-1:0] |Requested data user +|======================================================================= + +Page Table Walker is implemented as a finite state machine. It listens +to shared TLB for incoming translation requests. If there is a shared +TLB miss, it saves the virtual address and starts the page table walk. +Page table walker transition between 7 states in CVA6. + +* *IDLE:* The initial state where the PTW is awaiting a trigger, often a +Shared TLB miss, to initiate a memory access request. +* *WAIT_GRANT:* Request memory access and wait for data grant +* *PTE_LOOKUP:* Once granted access, the PTW examines the valid Page +Table Entry (PTE), checking attributes to determine the appropriate +course of action. +* *PROPOGATE_ERROR:* If the PTE is invalid, this state handles the +propagation of an error, often leading to a page-fault exception due to +non-compliance with access conditions +* *PROPOGATE_ACCESS_ERROR:* Propagate access fault if access is not +allowed from a PMP perspective +* *WAIT_RVALID:* After processing a PTE, the PTW waits for a valid data +signal, indicating that relevant data is ready for further processing. +* *LATENCY:* Introduces a delay to account for synchronization or timing +requirements between states. + +image:ptw_state_diagram.png[*Figure 20:* State Machine Diagram +of CVA6 PTW,scaledwidth=95.0%] + +In the IDLE state of the Page Table Walker (PTW) finite state machine, +the system awaits a trigger to initiate the page table walk process. +This trigger is often prompted by a Shared Translation Lookaside Buffer +(TLB) miss, indicating that the required translation is not present in +the shared TLB cache. The PTW's behavior in this state is explained as +follows: + +1. The top-most page table is selected for the page table walk. In the +case of SV32, which implements a two-level page table, the level 1 page +table is chosen. +2. In the IDLE state, translations are assumed to be invalid in all +addressing spaces. +3. The signal indicating the instruction page table walk is set to 0. +4. A conditional check is performed: if there is a shared TLB access +request and the entry is not found in the shared TLB (indicating a +shared TLB miss), the following steps are executed: +a. The address of the desired Page Table Entry within the level 1 page +table is calculated by multiplying the Physical Page Number (PPN) of the +level 1 page table from the SATP register by the page size (4kB). This +result is then added to the product of the Virtual Page Number (VPN1), +and the size of a page table entry(4 bytes). + +image:ptw_idle.png[*Figure 21:* Address of Desired PTE at +Level 1,scaledwidth=68.0%] + +In the *WAIT_GRANT* state of the Page Table Walker's finite state +machine, a data request is sent to retrieve memory information. It waits +for a data grant signal from the Dcache controller, remaining in this +state until granted. Once granted, it activates a tag valid signal, +marking data validity. The state then transitions to "PTE_LOOKUP" for +page table entry lookup. + +In the *PTE_LOOKUP* state of the Page Table Walker (PTW) finite state +machine, the PTW performs the actual lookup and evaluation of the page +table entry (PTE) based on the virtual address translation. The behavior +and operations performed in this state are detailed as follows: + +1. The state waits for a valid signal indicating that the data from the +memory subsystem, specifically the page table entry, is available for +processing. +2. Upon receiving the valid signal, the PTW proceeds with examining the +retrieved page table entry to determine its properties and validity. +3. The state checks if the global mapping bit in the PTE is set, and if +so, sets the global mapping signal to indicate that the translation +applies globally across all address spaces. +4. The state distinguishes between two cases: Invalid PTE and Valid +PTE. +a. If the valid bit of the PTE is not set, or if the PTE has reserved +RWX field encodings, it signifies an Invalid PTE. In such cases, the +state transitions to the "PROPAGATE_ERROR" state, indicating a +page-fault exception due to an invalid translation. + +image:ptw_pte_1.png[*Figure 22:* Invalid PTE and reserved RWX +encoding leads to page fault,scaledwidth=70.0%] + +1. Within the Valid PTE scenario, the state performs further checks +based on whether the translation is intended for instruction fetching or +data access: +a. For instruction page table walk, if the page is not executable +(pte.x is not set) or not marked as accessible (pte.a is not set), the +state transitions to the "PROPAGATE_ERROR" state. + +image:ptw_iptw.png[*Figure 23:* For Instruction Page Table +Walk,scaledwidth=70.0%] + +image:ptw_dptw.png[*Figure 24:* Data Access Page Table +Walk,scaledwidth=70.0%] + +image:ptw_dptw_s.png[*Figure 25:* Data Access Page Table Walk, +Store requested,scaledwidth=70.0%] + +1. The state also checks for potential misalignment issues in the +translation: If the current page table level is the first level (LVL1) +and if the PPN0 of in PTE is not zero, it indicates a misaligned +superpage, leading to a transition to the "PROPAGATE_ERROR" state. + +image:ptw_mis_sup.png[*Figure 26:* Misaligned Superpage +Check,scaledwidth=70.0%] + +1. If the PTE is valid but the page is neither readable nor executable, +the PTW recognizes the PTE as a pointer to the next level of the page +table, indicating that additional translation information can be found +in the referenced page table at a lower level. +2. If the current page table level is the first level (LVL1), the PTW +proceeds to switch to the second level (LVL2) page table, updating the +next level pointer and calculating the address for the next page table +entry using the Physical Page Number from the PTE and the index of the +level 2 page table from virtual address. + +image:ptw_nlvl.png[*Figure 27:* Address of desired PTE at next +level of Page Table,scaledwidth=70.0%] + +1. The state then transitions to the "WAIT_GRANT" state, indicating +that the PTW is awaiting the grant signal to proceed with requesting the +next level page table entry. +2. If the current level is already the second level (LVL2), an error is +flagged, and the state transitions to the "PROPAGATE_ERROR" state, +signifying an unexpected situation where the PTW is already at the last +level page table. +3. If the translation access is found to be restricted by the Physical +Memory Protection (PMP) settings (allow_access is false), the state +updates the shared TLB update signal to indicate that the TLB entry +should not be updated. Additionally, the saved address for the page +table walk is restored to its previous value, and the state transitions +to the "PROPAGATE_ACCESS_ERROR" state. +4. Lastly, if the data request for the page table entry was granted, +the state indicates to the cache subsystem that the tag associated with +the data is now valid. + +image:ptw_pte_flowchart.png[*Figure 28:* Flow Chart of PTE +LOOKUP State] + +This state indicates a detected error in the page table walk process, +and an error signal is asserted to indicate the Page Table Walker's +error condition, triggering a transition to the "LATENCY" state for +error signal propagation. + +This state indicates a detected access error in the page table walk +process, and an access error signal is asserted to indicate the Page +Table Walker's access error condition, triggering a transition to the +"LATENCY" state for access error signal propagation. + +This state waits until it gets the "read valid" signal, and when it +does, it's ready to start a new page table walk. + +The LATENCY state introduces a latency period to allow for necessary +system actions or signals to stabilize. After the latency period, the +FSM transitions back to the IDLE state, indicating that the system is +prepared for a new translation request. + +The first step when a flush is triggered is to check whether the Page +Table Entry (PTE) lookup process is currently in progress. If the PTW +(Page Table Walker) module is indeed in the middle of a PTE lookup +operation, the code then proceeds to evaluate a specific aspect of this +operation. + +* *Check for Data Validity (rvalid):* Within the PTE lookup operation, +it's important to ensure that the data being used for the translation is +valid. In other words, the code checks whether the "rvalid" signal +(which likely indicates the validity of the data) is not active. If the +data is not yet valid, it implies that the PTW module is waiting for the +data to become valid before completing the lookup. In such a case, the +code takes appropriate action to wait for the data to become valid +before proceeding further. +* *Check for Waiting on Grant:* The second condition the code checks for +during a flush scenario is whether the PTW module is currently waiting +for a "grant." This "grant" signal is typically used to indicate +permission or authorization to proceed with an operation. If the PTW +module is indeed in a state of waiting for this grant signal, it implies +that it requires authorization before continuing its task. ++ +__________________________________________________________________________________________________________________________________________________________________________________________________ +** *Waiting for Grant:* If the PTW module is in a state of waiting for +the grant signal, the code ensures that it continues to wait for the +grant signal to be asserted before proceeding further. +__________________________________________________________________________________________________________________________________________________________________________________________________ +* *Return to Idle State if Neither Condition is Met:* After evaluating +the above two conditions, the code determines whether either of these +conditions is true. If neither of these conditions applies, it suggests +that the PTW module can return to its idle state, indicating that it can +continue normal operations without any dependencies on the flush +condition. diff --git a/docs/04_cv32a65x/design/source/subsystem.rst b/docs/design/design-manual/source/subsystem.adoc similarity index 57% rename from docs/04_cv32a65x/design/source/subsystem.rst rename to docs/design/design-manual/source/subsystem.adoc index 4f507d71bc..a28862511e 100644 --- a/docs/04_cv32a65x/design/source/subsystem.rst +++ b/docs/design/design-manual/source/subsystem.adoc @@ -1,4 +1,4 @@ -.. +//// Copyright 2022 Thales DIS design services SAS Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -6,25 +6,30 @@ You may obtain a copy of the License at https://solderpad.org/licenses/ Original Author: Jean-Roch COULON - Thales +//// - - +[[subsystem]] Subsystem -========= +--------- +[[global-functionality]] Global functionality --------------------- +~~~~~~~~~~~~~~~~~~~~ -The CVA6 is a subsystem composed of the modules and protocol interfaces as illustrated -The processor is a Harvard-based modern architecture. -Instructions are issued in-order through the DECODE stage and executed out-of-order but committed in-order. -The processor is Single issue, that means that at maximum one instruction per cycle can be issued to the EXECUTE stage. +The CVA6 is a subsystem composed of the modules and protocol interfaces +as illustrated The processor is a Harvard-based modern architecture. +Instructions are issued in-order through the DECODE stage and executed +out-of-order but committed in-order. The processor is Single issue, that +means that at maximum one instruction per cycle can be issued to the +EXECUTE stage. -The CVA6 implements a 6-stage pipeline composed of PC Generation, Instruction Fetch, Instruction Decode, Issue stage, Execute stage and Commit stage. -At least 6 cycles are needed to execute one instruction. +The CVA6 implements a 6-stage pipeline composed of PC Generation, +Instruction Fetch, Instruction Decode, Issue stage, Execute stage and +Commit stage. At least 6 cycles are needed to execute one instruction. +[[connection-with-other-sub-systems]] Connection with other sub-systems ---------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The submodule is connected to : @@ -33,16 +38,14 @@ The submodule is connected to : * TRACER provides support for verification * TRAP provides traps inputs - +[[parameter-configuration]] Parameter configuration ------------------------ - - -.. include:: parameters_cv32a65x.rst - +~~~~~~~~~~~~~~~~~~~~~~~ +include::parameters.adoc[] +[[io-ports]] IO ports --------- +~~~~~~~~ -.. include:: port_cva6.rst +include::port_cva6.adoc[] diff --git a/docs/04_cv32a65x/design/source/CVXIF.rst b/docs/design/design-manual/source/traps.adoc similarity index 84% rename from docs/04_cv32a65x/design/source/CVXIF.rst rename to docs/design/design-manual/source/traps.adoc index 94dc7e4f16..fd6f42ef43 100644 --- a/docs/04_cv32a65x/design/source/CVXIF.rst +++ b/docs/design/design-manual/source/traps.adoc @@ -1,4 +1,4 @@ -.. +//// Copyright 2023 Thales DIS France SAS Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -6,6 +6,10 @@ You may obtain a copy of the License at https://solderpad.org/licenses/ Original Author: Jean-Roch COULON - Thales +//// + +[[traps]] + +include::Traps_Interrupts_Exceptions.adoc[] -.. include:: ../../../01_cva6_user/CVX_Interface_Coprocessor.rst diff --git a/docs/index.rst b/docs/index.rst index 5ab692133d..ce38770a99 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -56,7 +56,7 @@ The target audience of this document is current and existing members of the Open The :doc:`CVA6 Design Document <03_cva6_design/index>` describes in detail the **CVA6**, the code base that can be used to compile/synthesize a specific core instance (e.g. cv32a65x). -The :doc:`CV32A65X Design Document <04_cv32a65x/design/source/index>` describes in detail the **CV32A65X**, a specific core based on the CVA6 and the first production quality 32-bit application processor derived from the CVA6. +The :doc:`CV32A65X Design Document <04_cv32a65x/design/design>` describes in detail the **CV32A65X**, a specific core based on the CVA6 and the first production quality 32-bit application processor derived from the CVA6. The primary audience for this documentation are design and verification engineers working to bring the CV32A65X to TRL-5. The :doc:`CVA6 APU <05_cva6_apu/index>` describes an Application Processor Unit built around the CVA6. diff --git a/docs/riscv-isa/build.mk b/docs/riscv-isa/build.mk index 5828ee4271..c03f3a5486 100644 --- a/docs/riscv-isa/build.mk +++ b/docs/riscv-isa/build.mk @@ -19,7 +19,8 @@ setup: mkdir -p build/riscv-isa-manual cp -r $(riscv-isa_dir)/riscv-isa-manual/* build/riscv-isa-manual cp -r $(riscv-isa_dir)/src build/riscv-isa-manual - cp -r src build/riscv-isa-manual + cp -r $(riscv-isa_dir)/../common/*.adoc build/riscv-isa-manual/src + cp ../config/config.adoc build/riscv-isa-manual/src priv-pdf: setup cd build/riscv-isa-manual; make SKIP_DOCKER=true build/riscv-privileged.pdf diff --git a/docs/scripts/parameters_extractor.py b/docs/scripts/parameters_extractor.py index 03a692cb45..2f1952c670 100644 --- a/docs/scripts/parameters_extractor.py +++ b/docs/scripts/parameters_extractor.py @@ -79,3 +79,29 @@ def writeout_parameter_table(fileout, parameters, module): fout.write(f" * - {name}\n") fout.write(f" - {parameters[name].description}\n") fout.write(f" - {parameters[name].value}\n") + +def writeout_parameter_table_adoc(fileout, parameters, module): + + with open(fileout, "w") as fout: + fout.write("////\n") + fout.write(" Copyright 2024 Thales DIS France SAS\n") + fout.write( + ' Licensed under the Solderpad Hardware License, Version 2.1 (the "License");\n' + ) + fout.write( + " you may not use this file except in compliance with the License.\n" + ) + fout.write(" SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1\n") + fout.write( + " You may obtain a copy of the License at https://solderpad.org/licenses/\n\n" + ) + fout.write(" Original Author: Jean-Roch COULON - Thales\n") + fout.write("////\n\n") + + fout.write(f"[[{module}_PARAMETERS]]\n\n") + fout.write(f".{module} parameter configuration\n") + fout.write("|===\n") + fout.write("|Name | description | description\n\n") + for name in parameters: + fout.write(f"|{name} | {parameters[name].description} | {parameters[name].value}\n") + fout.write("|===\n") diff --git a/docs/scripts/spec_builder.py b/docs/scripts/spec_builder.py index edf103582c..2f4f72cf89 100755 --- a/docs/scripts/spec_builder.py +++ b/docs/scripts/spec_builder.py @@ -10,26 +10,128 @@ #!/usr/bin/python3 import re +import sys from classes import Parameter from classes import PortIO from define_blacklist import define_blacklist from parameters_extractor import parameters_extractor from parameters_extractor import writeout_parameter_table +from parameters_extractor import writeout_parameter_table_adoc +HEADER_RST = """\ +.. + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales + +""" + +HEADER_ADOC = """\ +//// + Copyright 2024 Thales DIS France SAS + Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); + you may not use this file except in compliance with the License. + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + You may obtain a copy of the License at https://solderpad.org/licenses/ + + Original Author: Jean-Roch COULON - Thales +//// + +""" + +def print_to_rst(pathout, target, module, ports, comments): + fileout = f"{pathout}/port_{module}.rst" + print("Output file " + fileout) + + with open(fileout, "w", encoding="utf-8") as fout: + fout.write(HEADER_RST) + fout.write(f".. _CVA6_{module}_ports:\n\n") + fout.write(f".. list-table:: **{module} module** IO ports\n") + fout.write(" :header-rows: 1\n") + fout.write("\n") + fout.write(" * - Signal\n") + fout.write(" - IO\n") + fout.write(" - Description\n") + fout.write(" - connexion\n") + fout.write(" - Type\n") + for i, port in enumerate(ports): + fout.write("\n") + fout.write(f" * - ``{port.name}``\n") + fout.write(f" - {port.direction}\n") + fout.write(f" - {port.description}\n") + fout.write(f" - {port.connexion}\n") + fout.write(f" - {port.data_type}\n") + fout.write("\n") + if len(comments) != 0: + fout.write( + f"Due to {target} configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below\n" + ) + fout.write("\n") + for comment in comments: + fout.write(f"| {comment[0]},\n| {comment[1]}\n") + fout.write("\n") + +def print_to_adoc(pathout, target, module, ports, comments): + fileout = f"{pathout}/port_{module}.adoc" + print("Output file " + fileout) + + # format comments + for comment in comments: + for i in range(len(comment)): + comment[i] = comment[i].replace('``', '`') + comment[i] = comment[i].replace('|', '*') + + with open(fileout, "w", encoding="utf-8") as fout: + fout.write(HEADER_ADOC) + + fout.write(f"[[_CVA6_{module}_ports]]\n\n") + + fout.write(f".*{module} module* IO ports\n") + fout.write("|===\n") + fout.write("|Signal | IO | Description | connexion | Type\n\n") + + for port in ports: + fout.write(f"|`{port.name}` | {port.direction} | {port.description} | {port.connexion} | {port.data_type}\n\n") + fout.write("|===\n") + + if len(comments) != 0: + fout.write( + f"Due to {target} configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below\n\n" + ) + for comment in comments: + fout.write(f"{comment[0]},::\n* {comment[1]}\n") + fout.write("\n") def main(): PATH = "04_cv32a65x" + generate_file_type = "adoc" [spec_number, target] = PATH.split("_") print(spec_number, target) + + # Parameters parameters = parameters_extractor(spec_number, target) pathout = f"./{spec_number}_{target}/design/source" - fileout = f"{pathout}/parameters_{target}.rst" - writeout_parameter_table(fileout, parameters, target) + if generate_file_type in ['rst']: + fileout = f"{pathout}/parameters_{target}.rst" + writeout_parameter_table(fileout, parameters, target) + elif generate_file_type in ['adoc']: + pathout = f"./{spec_number}_{target}/design/source" + fileout = f"{pathout}/parameters.adoc" + writeout_parameter_table_adoc(fileout, parameters, target) + else: + raise Exception("Format de sortie %s non pris en charge"%generate_file_type) + + # User_cfg export_user_cfg_doc("01_cva6_user/user_cfg_doc.rst", parameters) + # Ports file = [] file.append("../core/cva6.sv") file.append("../core/frontend/frontend.sv") @@ -68,9 +170,7 @@ def main(): comments = [] a = re.match(r".*\/(.*).sv", filein) module = a.group(1) - fileout = f"{pathout}/port_{module}.rst" print("Input file " + filein) - print("Output file " + fileout) ports = [] with open(filein, "r", encoding="utf-8") as fin: description = "none" @@ -126,49 +226,16 @@ def main(): description = "none" connexion = "none" - with open(fileout, "w", encoding="utf-8") as fout: - fout.write(HEADER) - fout.write(f".. _CVA6_{module}_ports:\n\n") - fout.write(f".. list-table:: **{module} module** IO ports\n") - fout.write(" :header-rows: 1\n") - fout.write("\n") - fout.write(" * - Signal\n") - fout.write(" - IO\n") - fout.write(" - Description\n") - fout.write(" - connexion\n") - fout.write(" - Type\n") - for i, port in enumerate(ports): - fout.write("\n") - fout.write(f" * - ``{port.name}``\n") - fout.write(f" - {port.direction}\n") - fout.write(f" - {port.description}\n") - fout.write(f" - {port.connexion}\n") - fout.write(f" - {port.data_type}\n") - fout.write("\n") - if len(comments) != 0: - fout.write( - f"Due to {target} configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below\n" - ) - fout.write("\n") - for comment in comments: - fout.write(f"| {comment[0]},\n| {comment[1]}\n") - fout.write("\n") - -HEADER = """\ -.. - Copyright 2024 Thales DIS France SAS - Licensed under the Solderpad Hardware License, Version 2.1 (the "License"); - you may not use this file except in compliance with the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 - You may obtain a copy of the License at https://solderpad.org/licenses/ - - Original Author: Jean-Roch COULON - Thales - -""" + if generate_file_type in ['rst']: + print_to_rst(pathout, target, module, ports, comments) + elif generate_file_type in ['adoc']: + print_to_adoc(pathout, target, module, ports, comments) + else: + raise Exception("Format de sortie %s non pris en charge"%generate_file_type) def export_user_cfg_doc(out_path, params): with open(out_path, "w", encoding="utf-8") as f: - f.write(HEADER) + f.write(HEADER_RST) f.write("""\ .. _cva6_user_cfg_doc: From b438a8ba8ece76a11cf253c5ad6413e0aa9884ef Mon Sep 17 00:00:00 2001 From: AbdessamiiOukalrazqou <163409352+AbdessamiiOukalrazqou@users.noreply.github.com> Date: Thu, 25 Jul 2024 20:07:45 +0200 Subject: [PATCH 037/183] [gen_from_riscv_config] Improve the tool to support debug spec (#2398) --- .../scripts/libs/csr_updater.py | 35 +++++++++++-------- .../scripts/libs/utils.py | 9 +++-- .../scripts/riscv_config_gen.py | 13 ++++--- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/config/gen_from_riscv_config/scripts/libs/csr_updater.py b/config/gen_from_riscv_config/scripts/libs/csr_updater.py index af76b67b28..2a5077d577 100644 --- a/config/gen_from_riscv_config/scripts/libs/csr_updater.py +++ b/config/gen_from_riscv_config/scripts/libs/csr_updater.py @@ -22,25 +22,30 @@ def csr_recursive_update(original_dict, csr_update): original_dict[key] = value -def csr_formatter(srcfile, customfile, modifile): +def csr_formatter(srcfile, customfile, debugfile, modifile): # Read original dictionary from YAML source file with open(srcfile, "r", encoding="utf-8") as file: original_dict = yaml.safe_load(file) with open(customfile, "r", encoding="utf-8") as file: custom_dict = yaml.safe_load(file) - - isa_data = original_dict.copy() - isa_data["hart0"].update(custom_dict["hart0"]) - updated_values = {} + debug_dict = {} + riscv_config_data = original_dict.copy() + if debugfile is not None: + with open(debugfile, "r", encoding="utf-8") as file: + debug_dict = yaml.safe_load(file) + if debug_dict["hart0"]["debug_mode"]: + riscv_config_data["hart0"].update(debug_dict["hart0"]) + riscv_config_data["hart0"].update(custom_dict["hart0"]) + update_dict = {} if modifile is not None: with open(modifile, "r", encoding="utf-8") as file: - updated_values = yaml.safe_load(file) - + update_dict = yaml.safe_load(file) + print(riscv_config_data["hart0"]) # Update original_dict with values from updated_values recursively - csr_recursive_update(isa_data["hart0"], updated_values) + csr_recursive_update(riscv_config_data["hart0"], update_dict) # Identify and remove keys within the range specified for each register keys_to_remove = [] - for key, value in updated_values.items(): + for key, value in update_dict.items(): if "range" in value: range_value = value["range"] pattern = rf"{key}(\d+)" @@ -51,7 +56,7 @@ def csr_formatter(srcfile, customfile, modifile): if index >= range_value: keys_to_remove.append(k) # Remove excluded keys based on the condition - exclude_data = updated_values.get("exclude") + exclude_data = update_dict.get("exclude") if exclude_data: exclude_key = exclude_data.get("key") sub_key = exclude_data.get("sub_key") @@ -71,12 +76,12 @@ def remove_keys_recursive(dictionary): for k in keys_to_remove: dictionary.pop(k) - remove_keys_recursive(isa_data["hart0"]) - remove_keys_recursive(isa_data["hart0"]) + remove_keys_recursive(riscv_config_data["hart0"]) + remove_keys_recursive(riscv_config_data["hart0"]) # Remove keys from original_dict for k in keys_to_remove: - isa_data["hart0"].pop(k, None) + riscv_config_data["hart0"].pop(k, None) # Remove keys from original_dict for k in keys_to_remove: - isa_data.pop(k, None) - return isa_data["hart0"] + riscv_config_data.pop(k, None) + return riscv_config_data["hart0"] diff --git a/config/gen_from_riscv_config/scripts/libs/utils.py b/config/gen_from_riscv_config/scripts/libs/utils.py index 0a620462b2..738bdd5a92 100644 --- a/config/gen_from_riscv_config/scripts/libs/utils.py +++ b/config/gen_from_riscv_config/scripts/libs/utils.py @@ -14,7 +14,7 @@ # # Original Author: Oukalrazqou Abdessamii -""" Module is used to gather all utils and function to generate the csr and isa documents""" +"""Module is used to gather all utils and function to generate the csr and isa documents""" import io import os @@ -942,9 +942,10 @@ def returnMdRegDesc(self, name, address, resetValue, desc, access): class CsrParser: """parse CSR RISC-V config yaml file""" - def __init__(self, srcFile, customFile, target, modiFile=None): + def __init__(self, srcFile, customFile, debugfile, target, modiFile=None): self.srcFile = srcFile self.customFile = customFile + self.debugfile = debugfile self.modiFile = modiFile self.target = target @@ -1256,7 +1257,9 @@ def returnDocument(self): size = int( data["hart0"].get("supported_xlen", "")[0] ) # depends on architecture - data = csr_formatter(self.srcFile, self.customFile, self.modiFile) + data = csr_formatter( + self.srcFile, self.customFile, self.debugfile, self.modiFile + ) Registers = factorizer(data) d = DocumentClass(docName) m = MemoryMapClass(docName) diff --git a/config/gen_from_riscv_config/scripts/riscv_config_gen.py b/config/gen_from_riscv_config/scripts/riscv_config_gen.py index fd18c2afaf..ea5a58e555 100644 --- a/config/gen_from_riscv_config/scripts/riscv_config_gen.py +++ b/config/gen_from_riscv_config/scripts/riscv_config_gen.py @@ -13,15 +13,17 @@ # limitations under the License. # # Original Author: Oukalrazqou Abdessamii -""" Module is used to factorize multiples registers with the same name to - a specific format of registers """ +"""Module is used to factorize multiples registers with the same name to +a specific format of registers""" import argparse from libs.utils import CsrParser from libs.utils import IsaParser +from libs.utils import SpikeParser from libs.utils import IsaGenerator from libs.utils import CsrGenerator +from libs.utils import SpikeGenerator from libs.utils import RstAddressBlock from libs.utils import AdocAddressBlock from libs.utils import MdAddressBlock @@ -29,11 +31,12 @@ from libs.utils import InstadocBlock from libs.utils import InstmdBlock + if __name__ == "__main__": parser = argparse.ArgumentParser(description="GEN From RISC-V Config") parser.add_argument("-s", "--srcFile", help="isa_gen yaml input file") parser.add_argument("-c", "--customFile", help=" custom_gen yaml input file") - parser.add_argument("-d", "--destDir", help="write generated file to dir") + parser.add_argument("-d", "--debugFile", help=" debug_gen yaml input file") parser.add_argument("-m", "--modif", help="ISA /CSR Formatter if exist") parser.add_argument("-i", "--temp", help="Full ISA /SPIKETemplate") parser.add_argument("-t", "--target", help="Specifiy Config Name") @@ -65,7 +68,9 @@ spike_generator = SpikeGenerator(args.target, args.temp, args.modif) spike_generator.generateSpike(document) else: - e = CsrParser(args.srcFile, args.customFile, args.target, args.modif) + e = CsrParser( + args.srcFile, args.customFile, args.debugFile, args.target, args.modif + ) document = e.returnDocument() generator = CsrGenerator(args.target) generator.generateCSR(C_AddressBlock, document) From 96b050852598786d8aeb9877ebf9783aed7352a1 Mon Sep 17 00:00:00 2001 From: Zbigniew Chamski <107464696+zchamski@users.noreply.github.com> Date: Thu, 25 Jul 2024 22:06:51 +0200 Subject: [PATCH 038/183] [riscv-config] Update PMP definitions in cv32q65x spec (#2401) --- .../scripts/libs/utils.py | 10 +- .../cv32a65x/generated/isa_gen.yaml | 1020 +++++++++++++++-- .../riscv-config/cv32a65x/spec/isa_spec.yaml | 550 ++++++--- 3 files changed, 1307 insertions(+), 273 deletions(-) diff --git a/config/gen_from_riscv_config/scripts/libs/utils.py b/config/gen_from_riscv_config/scripts/libs/utils.py index 738bdd5a92..4a26398721 100644 --- a/config/gen_from_riscv_config/scripts/libs/utils.py +++ b/config/gen_from_riscv_config/scripts/libs/utils.py @@ -454,11 +454,7 @@ def returnAsString(self): field.name.upper(), field.fieldreset, field.fieldaccess, - ( - Render.bitmask(field.andMask, field.orMask) - if field.andMask and field.orMask - else field.bitlegal - ), + field.bitlegal, ] _line.append(field.fieldDesc) reg_table.append(_line) @@ -1015,9 +1011,11 @@ def returnRegister( if matches: expr_type = str(matches.group(2)) if expr_type == "bitmask": - # legal_value is left at default, cf. Render.bitmask(). andMask = str(matches.group(4)) orMask = str(matches.group(5)) + legal_value = Render.bitmask( + andMask, orMask + ) elif expr_type == "in": if matches.group(3).find(",") >= 0: # list ==> set of values diff --git a/config/riscv-config/cv32a65x/generated/isa_gen.yaml b/config/riscv-config/cv32a65x/generated/isa_gen.yaml index 0b3ea13925..65104d3881 100644 --- a/config/riscv-config/cv32a65x/generated/isa_gen.yaml +++ b/config/riscv-config/cv32a65x/generated/isa_gen.yaml @@ -2241,7 +2241,7 @@ hart0: warl: dependency_fields: [] legal: - - pmp0cfg[7:0] in [0x00:0xFF] + - pmp0cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged description: pmp configuration bits @@ -2255,7 +2255,7 @@ hart0: warl: dependency_fields: [] legal: - - pmp1cfg[7:0] in [0x00:0xFF] + - pmp1cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged description: pmp configuration bits @@ -2269,7 +2269,7 @@ hart0: warl: dependency_fields: [] legal: - - pmp2cfg[7:0] in [0x00:0xFF] + - pmp2cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged description: pmp configuration bits @@ -2283,7 +2283,7 @@ hart0: warl: dependency_fields: [] legal: - - pmp3cfg[7:0] in [0x00:0xFF] + - pmp3cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged description: pmp configuration bits @@ -2311,7 +2311,7 @@ hart0: warl: dependency_fields: [] legal: - - pmp4cfg[7:0] in [0x00:0xFF] + - pmp4cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged description: pmp configuration bits @@ -2325,7 +2325,7 @@ hart0: warl: dependency_fields: [] legal: - - pmp5cfg[7:0] in [0x00:0xFF] + - pmp5cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged description: pmp configuration bits @@ -2339,7 +2339,7 @@ hart0: warl: dependency_fields: [] legal: - - pmp6cfg[7:0] in [0x00:0xFF] + - pmp6cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged description: pmp configuration bits @@ -2353,7 +2353,7 @@ hart0: warl: dependency_fields: [] legal: - - pmp7cfg[7:0] in [0x00:0xFF] + - pmp7cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged description: pmp configuration bits @@ -2378,12 +2378,7 @@ hart0: pmp8cfg: implemented: true type: - warl: - dependency_fields: [] - legal: - - pmp8cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + ro_constant: 0x0 description: pmp configuration bits shadow: shadow_type: rw @@ -2392,12 +2387,7 @@ hart0: pmp9cfg: implemented: true type: - warl: - dependency_fields: [] - legal: - - pmp9cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + ro_constant: 0x0 description: pmp configuration bits shadow: shadow_type: rw @@ -2406,12 +2396,7 @@ hart0: pmp10cfg: implemented: true type: - warl: - dependency_fields: [] - legal: - - pmp10cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + ro_constant: 0x0 description: pmp configuration bits shadow: shadow_type: rw @@ -2420,12 +2405,7 @@ hart0: pmp11cfg: implemented: true type: - warl: - dependency_fields: [] - legal: - - pmp11cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + ro_constant: 0x0 description: pmp configuration bits shadow: shadow_type: rw @@ -2448,12 +2428,7 @@ hart0: pmp12cfg: implemented: true type: - warl: - dependency_fields: [] - legal: - - pmp12cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + ro_constant: 0x0 description: pmp configuration bits shadow: shadow_type: rw @@ -2462,12 +2437,7 @@ hart0: pmp13cfg: implemented: true type: - warl: - dependency_fields: [] - legal: - - pmp13cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + ro_constant: 0x0 description: pmp configuration bits shadow: shadow_type: rw @@ -2476,12 +2446,7 @@ hart0: pmp14cfg: implemented: true type: - warl: - dependency_fields: [] - legal: - - pmp14cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + ro_constant: 0x0 description: pmp configuration bits shadow: shadow_type: rw @@ -2490,12 +2455,7 @@ hart0: pmp15cfg: implemented: true type: - warl: - dependency_fields: [] - legal: - - pmp15cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + ro_constant: 0x0 description: pmp configuration bits shadow: shadow_type: rw @@ -2514,7 +2474,48 @@ hart0: priv_mode: M pmpcfg4: rv32: - accessible: false + accessible: true + pmp16cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp17cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp18cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp19cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp16cfg + - pmp17cfg + - pmp18cfg + - pmp19cfg rv64: accessible: false reset-val: 0 @@ -2523,7 +2524,48 @@ hart0: priv_mode: M pmpcfg5: rv32: - accessible: false + accessible: true + pmp20cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp21cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp22cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp23cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp20cfg + - pmp21cfg + - pmp22cfg + - pmp23cfg rv64: accessible: false reset-val: 0 @@ -2532,7 +2574,48 @@ hart0: priv_mode: M pmpcfg6: rv32: - accessible: false + accessible: true + pmp24cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp25cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp26cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp27cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp24cfg + - pmp25cfg + - pmp26cfg + - pmp27cfg rv64: accessible: false reset-val: 0 @@ -2541,7 +2624,48 @@ hart0: priv_mode: M pmpcfg7: rv32: - accessible: false + accessible: true + pmp28cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp29cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp30cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp31cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp28cfg + - pmp29cfg + - pmp30cfg + - pmp31cfg rv64: accessible: false reset-val: 0 @@ -2550,7 +2674,48 @@ hart0: priv_mode: M pmpcfg8: rv32: - accessible: false + accessible: true + pmp32cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp33cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp34cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp35cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp32cfg + - pmp33cfg + - pmp34cfg + - pmp35cfg rv64: accessible: false reset-val: 0 @@ -2559,7 +2724,48 @@ hart0: priv_mode: M pmpcfg9: rv32: - accessible: false + accessible: true + pmp36cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp37cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp38cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp39cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp36cfg + - pmp37cfg + - pmp38cfg + - pmp39cfg rv64: accessible: false reset-val: 0 @@ -2568,7 +2774,48 @@ hart0: priv_mode: M pmpcfg10: rv32: - accessible: false + accessible: true + pmp40cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp41cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp42cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp43cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp40cfg + - pmp41cfg + - pmp42cfg + - pmp43cfg rv64: accessible: false reset-val: 0 @@ -2577,7 +2824,48 @@ hart0: priv_mode: M pmpcfg11: rv32: - accessible: false + accessible: true + pmp44cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp45cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp46cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp47cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp44cfg + - pmp45cfg + - pmp46cfg + - pmp47cfg rv64: accessible: false reset-val: 0 @@ -2586,7 +2874,48 @@ hart0: priv_mode: M pmpcfg12: rv32: - accessible: false + accessible: true + pmp48cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp49cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp50cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp51cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp48cfg + - pmp49cfg + - pmp50cfg + - pmp51cfg rv64: accessible: false reset-val: 0 @@ -2595,7 +2924,48 @@ hart0: priv_mode: M pmpcfg13: rv32: - accessible: false + accessible: true + pmp52cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp53cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp54cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp55cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp52cfg + - pmp53cfg + - pmp54cfg + - pmp55cfg rv64: accessible: false reset-val: 0 @@ -2604,7 +2974,48 @@ hart0: priv_mode: M pmpcfg14: rv32: - accessible: false + accessible: true + pmp56cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp57cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp58cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp59cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp56cfg + - pmp57cfg + - pmp58cfg + - pmp59cfg rv64: accessible: false reset-val: 0 @@ -2613,7 +3024,48 @@ hart0: priv_mode: M pmpcfg15: rv32: - accessible: false + accessible: true + pmp60cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 7 + lsb: 0 + pmp61cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 15 + lsb: 8 + pmp62cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 23 + lsb: 16 + pmp63cfg: + implemented: true + type: + ro_constant: 0x0 + description: pmp configuration bits + shadow: + shadow_type: rw + msb: 31 + lsb: 24 + fields: + - pmp60cfg + - pmp61cfg + - pmp62cfg + - pmp63cfg rv64: accessible: false reset-val: 0 @@ -3004,7 +3456,14 @@ hart0: priv_mode: M pmpaddr16: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3013,7 +3472,14 @@ hart0: priv_mode: M pmpaddr17: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3022,7 +3488,14 @@ hart0: priv_mode: M pmpaddr18: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3031,7 +3504,14 @@ hart0: priv_mode: M pmpaddr19: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3040,7 +3520,14 @@ hart0: priv_mode: M pmpaddr20: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3049,7 +3536,14 @@ hart0: priv_mode: M pmpaddr21: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3058,7 +3552,14 @@ hart0: priv_mode: M pmpaddr22: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3067,7 +3568,14 @@ hart0: priv_mode: M pmpaddr23: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3076,7 +3584,14 @@ hart0: priv_mode: M pmpaddr24: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3085,7 +3600,14 @@ hart0: priv_mode: M pmpaddr25: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3094,7 +3616,14 @@ hart0: priv_mode: M pmpaddr26: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3103,7 +3632,14 @@ hart0: priv_mode: M pmpaddr27: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3112,7 +3648,14 @@ hart0: priv_mode: M pmpaddr28: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3121,7 +3664,14 @@ hart0: priv_mode: M pmpaddr29: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3130,7 +3680,14 @@ hart0: priv_mode: M pmpaddr30: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3139,7 +3696,14 @@ hart0: priv_mode: M pmpaddr31: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3148,7 +3712,14 @@ hart0: priv_mode: M pmpaddr32: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3157,7 +3728,14 @@ hart0: priv_mode: M pmpaddr33: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3166,7 +3744,14 @@ hart0: priv_mode: M pmpaddr34: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3175,7 +3760,14 @@ hart0: priv_mode: M pmpaddr35: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3184,7 +3776,14 @@ hart0: priv_mode: M pmpaddr36: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3193,7 +3792,14 @@ hart0: priv_mode: M pmpaddr37: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3202,7 +3808,14 @@ hart0: priv_mode: M pmpaddr38: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3211,7 +3824,14 @@ hart0: priv_mode: M pmpaddr39: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3220,7 +3840,14 @@ hart0: priv_mode: M pmpaddr40: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3229,7 +3856,14 @@ hart0: priv_mode: M pmpaddr41: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3238,7 +3872,14 @@ hart0: priv_mode: M pmpaddr42: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3247,7 +3888,14 @@ hart0: priv_mode: M pmpaddr43: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3256,7 +3904,14 @@ hart0: priv_mode: M pmpaddr44: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3265,7 +3920,14 @@ hart0: priv_mode: M pmpaddr45: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3274,7 +3936,14 @@ hart0: priv_mode: M pmpaddr46: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3283,7 +3952,14 @@ hart0: priv_mode: M pmpaddr47: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3292,7 +3968,14 @@ hart0: priv_mode: M pmpaddr48: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3301,7 +3984,14 @@ hart0: priv_mode: M pmpaddr49: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3310,7 +4000,14 @@ hart0: priv_mode: M pmpaddr50: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3319,7 +4016,14 @@ hart0: priv_mode: M pmpaddr51: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3328,7 +4032,14 @@ hart0: priv_mode: M pmpaddr52: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3337,7 +4048,14 @@ hart0: priv_mode: M pmpaddr53: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3346,7 +4064,14 @@ hart0: priv_mode: M pmpaddr54: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3355,7 +4080,14 @@ hart0: priv_mode: M pmpaddr55: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3364,7 +4096,14 @@ hart0: priv_mode: M pmpaddr56: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3373,7 +4112,14 @@ hart0: priv_mode: M pmpaddr57: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3382,7 +4128,14 @@ hart0: priv_mode: M pmpaddr58: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3391,7 +4144,14 @@ hart0: priv_mode: M pmpaddr59: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3400,7 +4160,14 @@ hart0: priv_mode: M pmpaddr60: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3409,7 +4176,14 @@ hart0: priv_mode: M pmpaddr61: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3418,7 +4192,14 @@ hart0: priv_mode: M pmpaddr62: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 @@ -3427,7 +4208,14 @@ hart0: priv_mode: M pmpaddr63: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 + fields: [] + shadow: + shadow_type: rw + msb: 31 + lsb: 0 rv64: accessible: false reset-val: 0 diff --git a/config/riscv-config/cv32a65x/spec/isa_spec.yaml b/config/riscv-config/cv32a65x/spec/isa_spec.yaml index 9b25133aaa..2044cdca4e 100644 --- a/config/riscv-config/cv32a65x/spec/isa_spec.yaml +++ b/config/riscv-config/cv32a65x/spec/isa_spec.yaml @@ -998,34 +998,34 @@ hart0: &hart0 warl: dependency_fields: [] legal: - - pmp0cfg[7:0] in [0x00:0xFF] + - pmp0cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged pmp1cfg: implemented: true - type: + type: warl: dependency_fields: [] legal: - - pmp1cfg[7:0] in [0x00:0xFF] + - pmp1cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged pmp2cfg: implemented: true - type: + type: warl: dependency_fields: [] legal: - - pmp2cfg[7:0] in [0x00:0xFF] + - pmp2cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged pmp3cfg: implemented: true - type: + type: warl: dependency_fields: [] legal: - - pmp3cfg[7:0] in [0x00:0xFF] + - pmp3cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged rv64: @@ -1036,38 +1036,38 @@ hart0: &hart0 accessible: true pmp4cfg: implemented: true - type: + type: warl: dependency_fields: [] legal: - - pmp4cfg[7:0] in [0x00:0xFF] + - pmp4cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged pmp5cfg: implemented: true - type: + type: warl: dependency_fields: [] legal: - - pmp5cfg[7:0] in [0x00:0xFF] + - pmp5cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged pmp6cfg: implemented: true - type: + type: warl: dependency_fields: [] legal: - - pmp6cfg[7:0] in [0x00:0xFF] + - pmp6cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged pmp7cfg: implemented: true - type: + type: warl: dependency_fields: [] legal: - - pmp7cfg[7:0] in [0x00:0xFF] + - pmp7cfg[7:0] bitmask [0x8f, 0x0] wr_illegal: - unchanged rv64: @@ -1078,40 +1078,20 @@ hart0: &hart0 accessible: true pmp8cfg: implemented: true - type: - warl: - dependency_fields: [] - legal: - - pmp8cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + type: + ro_constant: 0x0 pmp9cfg: implemented: true - type: - warl: - dependency_fields: [] - legal: - - pmp9cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + type: + ro_constant: 0x0 pmp10cfg: implemented: true - type: - warl: - dependency_fields: [] - legal: - - pmp10cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + type: + ro_constant: 0x0 pmp11cfg: implemented: true - type: - warl: - dependency_fields: [] - legal: - - pmp11cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 @@ -1120,119 +1100,291 @@ hart0: &hart0 accessible: true pmp12cfg: implemented: true - type: - warl: - dependency_fields: [] - legal: - - pmp12cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + type: + ro_constant: 0x0 pmp13cfg: implemented: true - type: - warl: - dependency_fields: [] - legal: - - pmp13cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + type: + ro_constant: 0x0 pmp14cfg: implemented: true - type: - warl: - dependency_fields: [] - legal: - - pmp14cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + type: + ro_constant: 0x0 pmp15cfg: implemented: true - type: - warl: - dependency_fields: [] - legal: - - pmp15cfg[7:0] in [0x00:0xFF] - wr_illegal: - - unchanged + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpcfg4: rv32: - accessible: false + accessible: true + pmp16cfg: + implemented: true + type: + ro_constant: 0x0 + pmp17cfg: + implemented: true + type: + ro_constant: 0x0 + pmp18cfg: + implemented: true + type: + ro_constant: 0x0 + pmp19cfg: + implemented: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpcfg5: rv32: - accessible: false + accessible: true + pmp20cfg: + implemented: true + type: + ro_constant: 0x0 + pmp21cfg: + implemented: true + type: + ro_constant: 0x0 + pmp22cfg: + implemented: true + type: + ro_constant: 0x0 + pmp23cfg: + implemented: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpcfg6: rv32: - accessible: false + accessible: true + pmp24cfg: + implemented: true + type: + ro_constant: 0x0 + pmp25cfg: + implemented: true + type: + ro_constant: 0x0 + pmp26cfg: + implemented: true + type: + ro_constant: 0x0 + pmp27cfg: + implemented: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpcfg7: rv32: - accessible: false + accessible: true + pmp28cfg: + implemented: true + type: + ro_constant: 0x0 + pmp29cfg: + implemented: true + type: + ro_constant: 0x0 + pmp30cfg: + implemented: true + type: + ro_constant: 0x0 + pmp31cfg: + implemented: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpcfg8: rv32: - accessible: false + accessible: true + pmp32cfg: + implemented: true + type: + ro_constant: 0x0 + pmp33cfg: + implemented: true + type: + ro_constant: 0x0 + pmp34cfg: + implemented: true + type: + ro_constant: 0x0 + pmp35cfg: + implemented: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpcfg9: rv32: - accessible: false + accessible: true + pmp36cfg: + implemented: true + type: + ro_constant: 0x0 + pmp37cfg: + implemented: true + type: + ro_constant: 0x0 + pmp38cfg: + implemented: true + type: + ro_constant: 0x0 + pmp39cfg: + implemented: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpcfg10: rv32: - accessible: false + accessible: true + pmp40cfg: + implemented: true + type: + ro_constant: 0x0 + pmp41cfg: + implemented: true + type: + ro_constant: 0x0 + pmp42cfg: + implemented: true + type: + ro_constant: 0x0 + pmp43cfg: + implemented: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpcfg11: rv32: - accessible: false + accessible: true + pmp44cfg: + implemented: true + type: + ro_constant: 0x0 + pmp45cfg: + implemented: true + type: + ro_constant: 0x0 + pmp46cfg: + implemented: true + type: + ro_constant: 0x0 + pmp47cfg: + implemented: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpcfg12: rv32: - accessible: false + accessible: true + pmp48cfg: + implemented: true + type: + ro_constant: 0x0 + pmp49cfg: + implemented: true + type: + ro_constant: 0x0 + pmp50cfg: + implemented: true + type: + ro_constant: 0x0 + pmp51cfg: + implemented: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpcfg13: rv32: - accessible: false + accessible: true + pmp52cfg: + implemented: true + type: + ro_constant: 0x0 + pmp53cfg: + implemented: true + type: + ro_constant: 0x0 + pmp54cfg: + implemented: true + type: + ro_constant: 0x0 + pmp55cfg: + implemented: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpcfg14: rv32: - accessible: false + accessible: true + pmp56cfg: + implemented: true + type: + ro_constant: 0x0 + pmp57cfg: + implemented: true + type: + ro_constant: 0x0 + pmp58cfg: + implemented: true + type: + ro_constant: 0x0 + pmp59cfg: + implemented: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpcfg15: rv32: - accessible: false + accessible: true + pmp60cfg: + implemented: true + type: + ro_constant: 0x0 + pmp61cfg: + implemented: true + type: + ro_constant: 0x0 + pmp62cfg: + implemented: true + type: + ro_constant: 0x0 + pmp63cfg: + implemented: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 mcycle: rv32: accessible: true - type: + type: warl: dependency_fields: [] legal: @@ -1245,7 +1397,7 @@ hart0: &hart0 minstret: rv32: accessible: true - type: + type: warl: dependency_fields: [] legal: @@ -1258,7 +1410,7 @@ hart0: &hart0 mcycleh: rv32: accessible: true - type: + type: warl: dependency_fields: [] legal: @@ -1271,7 +1423,7 @@ hart0: &hart0 minstreth: rv32: accessible: true - type: + type: warl: dependency_fields: [] legal: @@ -1284,7 +1436,7 @@ hart0: &hart0 pmpaddr0: rv32: accessible: true - type: + type: warl: dependency_fields: [] legal: @@ -1297,7 +1449,7 @@ hart0: &hart0 pmpaddr1: rv32: accessible: true - type: + type: warl: dependency_fields: [] legal: @@ -1310,7 +1462,7 @@ hart0: &hart0 pmpaddr2: rv32: accessible: true - type: + type: warl: dependency_fields: [] legal: @@ -1323,7 +1475,7 @@ hart0: &hart0 pmpaddr3: rv32: accessible: true - type: + type: warl: dependency_fields: [] legal: @@ -1336,7 +1488,7 @@ hart0: &hart0 pmpaddr4: rv32: accessible: true - type: + type: warl: dependency_fields: [] legal: @@ -1349,7 +1501,7 @@ hart0: &hart0 pmpaddr5: rv32: accessible: true - type: + type: warl: dependency_fields: [] legal: @@ -1362,7 +1514,7 @@ hart0: &hart0 pmpaddr6: rv32: accessible: true - type: + type: warl: dependency_fields: [] legal: @@ -1375,7 +1527,7 @@ hart0: &hart0 pmpaddr7: rv32: accessible: true - type: + type: warl: dependency_fields: [] legal: @@ -1388,7 +1540,7 @@ hart0: &hart0 pmpaddr8: rv32: accessible: true - type: + type: ro_constant: 0x0 rv64: accessible: false @@ -1396,7 +1548,7 @@ hart0: &hart0 pmpaddr9: rv32: accessible: true - type: + type: ro_constant: 0x0 rv64: accessible: false @@ -1404,7 +1556,7 @@ hart0: &hart0 pmpaddr10: rv32: accessible: true - type: + type: ro_constant: 0x0 rv64: accessible: false @@ -1412,7 +1564,7 @@ hart0: &hart0 pmpaddr11: rv32: accessible: true - type: + type: ro_constant: 0x0 rv64: accessible: false @@ -1420,7 +1572,7 @@ hart0: &hart0 pmpaddr12: rv32: accessible: true - type: + type: ro_constant: 0x0 rv64: accessible: false @@ -1428,7 +1580,7 @@ hart0: &hart0 pmpaddr13: rv32: accessible: true - type: + type: ro_constant: 0x0 rv64: accessible: false @@ -1436,7 +1588,7 @@ hart0: &hart0 pmpaddr14: rv32: accessible: true - type: + type: ro_constant: 0x0 rv64: accessible: false @@ -1444,296 +1596,392 @@ hart0: &hart0 pmpaddr15: rv32: accessible: true - type: + type: ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr16: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr17: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr18: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr19: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr20: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr21: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr22: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr23: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr24: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr25: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr26: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr27: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr28: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr29: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr30: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr31: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr32: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr33: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr34: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr35: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr36: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr37: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr38: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr39: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr40: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr41: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr42: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr43: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr44: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr45: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr46: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr47: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr48: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr49: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr50: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr51: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr52: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr53: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr54: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr55: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr56: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr57: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr58: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr59: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr60: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr61: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr62: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 pmpaddr63: rv32: - accessible: false + accessible: true + type: + ro_constant: 0x0 rv64: accessible: false reset-val: 0 From 211af02e5e8600e9a5aabfc024ad83f801ca12b4 Mon Sep 17 00:00:00 2001 From: Guillaume Chauvon <94678394+Gchauvon@users.noreply.github.com> Date: Fri, 26 Jul 2024 14:58:18 +0200 Subject: [PATCH 039/183] Separate RAW and WAW process to fix CVXIF with Superscalar (#2395) --- .../cvxif_example/compressed_instr_decoder.sv | 13 +- .../cvxif_example_coprocessor.sv | 3 + core/cvxif_example/instr_decoder.sv | 26 +-- core/cvxif_issue_register_commit_if_driver.sv | 38 ++--- core/include/build_config_pkg.sv | 2 +- core/issue_read_operands.sv | 128 +++++++------- spyglass/reference_summary.rpt | 161 +++++++++--------- 7 files changed, 194 insertions(+), 177 deletions(-) diff --git a/core/cvxif_example/compressed_instr_decoder.sv b/core/cvxif_example/compressed_instr_decoder.sv index 861f05d5be..de2fbb391c 100644 --- a/core/cvxif_example/compressed_instr_decoder.sv +++ b/core/cvxif_example/compressed_instr_decoder.sv @@ -7,13 +7,12 @@ // // Original Author: Guillaume Chauvon -module compressed_instr_decoder - import cvxif_instr_pkg::*; -#( - parameter int NbInstr = 1, - parameter copro_compressed_resp_t CoproInstr [NbInstr] = {0}, - parameter type x_compressed_req_t = logic, - parameter type x_compressed_resp_t = logic +module compressed_instr_decoder #( + parameter type copro_compressed_resp_t = logic, + parameter int NbInstr = 1, + parameter copro_compressed_resp_t CoproInstr [NbInstr] = {0}, + parameter type x_compressed_req_t = logic, + parameter type x_compressed_resp_t = logic ) ( input logic clk_i, input logic rst_ni, diff --git a/core/cvxif_example/cvxif_example_coprocessor.sv b/core/cvxif_example/cvxif_example_coprocessor.sv index 6b30e5d833..8cc1b15558 100644 --- a/core/cvxif_example/cvxif_example_coprocessor.sv +++ b/core/cvxif_example/cvxif_example_coprocessor.sv @@ -71,6 +71,7 @@ module cvxif_example_coprocessor assign register_valid = cvxif_req_i.register_valid; compressed_instr_decoder #( + .copro_compressed_resp_t(cvxif_instr_pkg::copro_compressed_resp_t), .NbInstr(cvxif_instr_pkg::NbCompInstr), .CoproInstr(cvxif_instr_pkg::CoproCompInstr), .x_compressed_req_t(x_compressed_req_t), @@ -85,6 +86,8 @@ module cvxif_example_coprocessor ); instr_decoder #( + .copro_issue_resp_t (cvxif_instr_pkg::copro_issue_resp_t), + .opcode_t (cvxif_instr_pkg::opcode_t), .NbInstr (cvxif_instr_pkg::NbInstr), .CoproInstr(cvxif_instr_pkg::CoproInstr), .NrRgprPorts(NrRgprPorts), diff --git a/core/cvxif_example/instr_decoder.sv b/core/cvxif_example/instr_decoder.sv index 6f271695f2..8e952b6dfe 100644 --- a/core/cvxif_example/instr_decoder.sv +++ b/core/cvxif_example/instr_decoder.sv @@ -7,18 +7,18 @@ // // Original Author: Guillaume Chauvon -module instr_decoder - import cvxif_instr_pkg::*; -#( - parameter int NbInstr = 1, - parameter copro_issue_resp_t CoproInstr [NbInstr] = {0}, - parameter int unsigned NrRgprPorts = 2, - parameter type hartid_t = logic, - parameter type id_t = logic, - parameter type x_issue_req_t = logic, - parameter type x_issue_resp_t = logic, - parameter type x_register_t = logic, - parameter type registers_t = logic +module instr_decoder #( + parameter type copro_issue_resp_t = logic, + parameter type opcode_t = logic, + parameter int NbInstr = 1, + parameter copro_issue_resp_t CoproInstr [NbInstr] = {0}, + parameter int unsigned NrRgprPorts = 2, + parameter type hartid_t = logic, + parameter type id_t = logic, + parameter type x_issue_req_t = logic, + parameter type x_issue_resp_t = logic, + parameter type x_register_t = logic, + parameter type registers_t = logic ) ( input logic clk_i, input logic rst_ni, @@ -53,7 +53,7 @@ module instr_decoder issue_resp_o.writeback = '0; issue_resp_o.register_read = '0; registers_o = '0; - opcode_o = ILLEGAL; + opcode_o = opcode_t'(0); // == ILLEGAL see cvxif_instr_pkg.sv hartid_o = '0; id_o = '0; rd_o = '0; diff --git a/core/cvxif_issue_register_commit_if_driver.sv b/core/cvxif_issue_register_commit_if_driver.sv index e550d773d1..2b6ab540d0 100644 --- a/core/cvxif_issue_register_commit_if_driver.sv +++ b/core/cvxif_issue_register_commit_if_driver.sv @@ -15,29 +15,29 @@ module cvxif_issue_register_commit_if_driver #( parameter type x_commit_t = logic ) ( // CVA6 inputs - input logic clk_i, - input logic rst_ni, - input logic flush_i, - input logic [ CVA6Cfg.XLEN-1:0] hart_id_i, + input logic clk_i, + input logic rst_ni, + input logic flush_i, + input logic [CVA6Cfg.XLEN-1:0] hart_id_i, // CVXIF Issue interface - input logic issue_ready_i, - input x_issue_resp_t issue_resp_i, - output logic issue_valid_o, - output x_issue_req_t issue_req_o, + input logic issue_ready_i, + input x_issue_resp_t issue_resp_i, + output logic issue_valid_o, + output x_issue_req_t issue_req_o, // CVXIF Register interface - input logic register_ready_i, - output logic register_valid_o, - output x_register_t register_o, + input logic register_ready_i, + output logic register_valid_o, + output x_register_t register_o, // CVXIF Commit interface - output logic commit_valid_o, - output x_commit_t commit_o, + output logic commit_valid_o, + output x_commit_t commit_o, // IRO in/out - input logic valid_i, - input logic [ 31:0] x_off_instr_i, - input logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_i, - input logic [ CVA6Cfg.NrRgprPorts-1:0][CVA6Cfg.XLEN-1:0] register_i, - input logic [ CVA6Cfg.NrRgprPorts-1:0] rs_valid_i, - output logic cvxif_busy_o + input logic valid_i, + input logic [31:0] x_off_instr_i, + input logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_i, + input [(CVA6Cfg.NrRgprPorts/CVA6Cfg.NrIssuePorts)-1:0][CVA6Cfg.XLEN-1:0] register_i, + input logic [(CVA6Cfg.NrRgprPorts/CVA6Cfg.NrIssuePorts)-1:0] rs_valid_i, + output logic cvxif_busy_o ); // X_ISSUE_REGISTER_SPLIT = 0 : Issue and register transactions are synchrone // Mandatory assignement diff --git a/core/include/build_config_pkg.sv b/core/include/build_config_pkg.sv index 1da077eba5..53ab116c6d 100644 --- a/core/include/build_config_pkg.sv +++ b/core/include/build_config_pkg.sv @@ -167,7 +167,7 @@ package build_config_pkg; cfg.VpnLen = VpnLen; cfg.PtLevels = PtLevels; - cfg.X_NUM_RS = cfg.NrRgprPorts; + cfg.X_NUM_RS = cfg.NrRgprPorts / cfg.NrIssuePorts; cfg.X_ID_WIDTH = cfg.TRANS_ID_BITS; cfg.X_RFR_WIDTH = cfg.XLEN; cfg.X_RFW_WIDTH = cfg.XLEN; diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index 7a37030bf1..9a2ca7a964 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -149,9 +149,10 @@ module issue_read_operands logic none, load, store, alu, alu2, ctrl_flow, mult, csr, fpu, fpu_vec, cvxif, accel; } fus_busy_t; - logic [CVA6Cfg.NrIssuePorts-1:0] stall, stall_rs1, stall_rs2, stall_rs3; + logic [CVA6Cfg.NrIssuePorts-1:0] stall_raw, stall_waw, stall_rs1, stall_rs2, stall_rs3; logic [CVA6Cfg.NrIssuePorts-1:0] fu_busy; // functional unit is busy fus_busy_t [CVA6Cfg.NrIssuePorts-1:0] fus_busy; // which functional units are considered busy + logic [CVA6Cfg.NrIssuePorts-1:0] issue_ack; // operands coming from regfile logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] operand_a_regfile, operand_b_regfile; // third operand from fp regfile or gp regfile if NR_RGPR_PORTS == 3 @@ -185,10 +186,10 @@ module issue_read_operands assign orig_instr = riscv::instruction_t'(orig_instr_i[0]); // CVXIF Signals - logic cvxif_busy; + logic cvxif_req_allowed; logic x_transaction_rejected; - logic [CVA6Cfg.NrRgprPorts-1:0] rs_valid; - logic [CVA6Cfg.NrRgprPorts-1:0][CVA6Cfg.XLEN-1:0] rs; + logic [OPERANDS_PER_INSTR-1:0] rs_valid; + logic [OPERANDS_PER_INSTR-1:0][CVA6Cfg.XLEN-1:0] rs; cvxif_issue_register_commit_if_driver #( .CVA6Cfg (CVA6Cfg), @@ -215,7 +216,7 @@ module issue_read_operands .x_trans_id_i (issue_instr_i[0].trans_id), .register_i (rs), .rs_valid_i (rs_valid), - .cvxif_busy_o (cvxif_busy) + .cvxif_busy_o () ); if (OPERANDS_PER_INSTR == 3) begin assign rs_valid = {~stall_rs3[0], ~stall_rs2[0], ~stall_rs1[0]}; @@ -226,7 +227,9 @@ module issue_read_operands end // TODO check only for 1st instruction ?? - assign cvxif_instruction_valid = (!issue_instr_i[0].ex.valid && issue_instr_valid_i[0] && (issue_instr_i[0].fu == CVXIF)); + // Allow a cvxif transaction if we WaW condition are ok. + assign cvxif_req_allowed = (issue_instr_i[0].fu == CVXIF) && !stall_waw[0]; + assign cvxif_instruction_valid = !issue_instr_i[0].ex.valid && issue_instr_valid_i[0] && cvxif_req_allowed; assign x_transaction_accepted_o = x_issue_valid_o && x_issue_ready_i && x_issue_resp_i.accept; assign x_transaction_rejected = x_issue_valid_o && x_issue_ready_i && ~x_issue_resp_i.accept; assign x_issue_writeback_o = x_issue_resp_i.writeback; @@ -251,7 +254,7 @@ module issue_read_operands assign alu2_valid_o = alu2_valid_q; assign cvxif_valid_o = CVA6Cfg.CvxifEn ? cvxif_valid_q : '0; assign cvxif_off_instr_o = CVA6Cfg.CvxifEn ? cvxif_off_instr_q : '0; - assign stall_issue_o = stall[0]; + assign stall_issue_o = stall_raw[0]; assign tinst_o = CVA6Cfg.RVH ? tinst_q : '0; // --------------- // Issue Stage @@ -259,7 +262,10 @@ module issue_read_operands always_comb begin : structural_hazards fus_busy = '0; - + // CVXIF is always ready to try a new transaction on 1st issue port + // If a transaction is already pending then we stall until the transaction is done.(issue_ack_o[0] = 0) + // Since we can not have two CVXIF instruction on 1st issue port, CVXIF is always ready for the pending instruction. + fus_busy[0].cvxif = 1'b0; if (!flu_ready_i) begin fus_busy[0].alu = 1'b1; fus_busy[0].ctrl_flow = 1'b1; @@ -286,15 +292,13 @@ module issue_read_operands fus_busy[0].store = 1'b1; end - if (cvxif_busy) begin - fus_busy[0].cvxif = 1'b1; - end - if (CVA6Cfg.SuperscalarEn) begin fus_busy[1] = fus_busy[0]; // Never issue CSR instruction on second issue port. fus_busy[1].csr = 1'b1; + // Never issue CVXIF instruction on second issue port. + fus_busy[1].cvxif = 1'b1; unique case (issue_instr_i[0].fu) NONE: fus_busy[1].none = 1'b1; @@ -346,7 +350,7 @@ module issue_read_operands fus_busy[1].load = 1'b1; fus_busy[1].store = 1'b1; end - CVXIF: fus_busy[1].cvxif = 1'b1; + CVXIF: ; endcase end end @@ -390,7 +394,7 @@ module issue_read_operands // check that all operands are available, otherwise stall // forward corresponding register always_comb begin : operands_available - stall = '{default: stall_i}; + stall_raw = '{default: stall_i}; stall_rs1 = '{default: stall_i}; stall_rs2 = '{default: stall_i}; stall_rs3 = '{default: stall_i}; @@ -426,7 +430,7 @@ module issue_read_operands (CVA6Cfg.RVS && issue_instr_i[i].op == SFENCE_VMA)))) begin forward_rs1[i] = 1'b1; end else begin // the operand is not available -> stall - stall[i] = 1'b1; + stall_raw[i] = 1'b1; stall_rs1[i] = 1'b1; end end @@ -445,7 +449,7 @@ module issue_read_operands (CVA6Cfg.RVS && issue_instr_i[i].op == SFENCE_VMA)))) begin forward_rs2[i] = 1'b1; end else begin // the operand is not available -> stall - stall[i] = 1'b1; + stall_raw[i] = 1'b1; stall_rs2[i] = 1'b1; end end @@ -456,12 +460,12 @@ module issue_read_operands )) ? rd_clobber_fpr_i[issue_instr_i[i].result[REG_ADDR_SIZE-1:0]] != NONE : 0) || ((CVA6Cfg.CvxifEn && OPERANDS_PER_INSTR == 3 && x_issue_valid_o && x_issue_resp_i.accept && x_issue_resp_i.register_read[2]) && - rd_clobber_gpr_i[issue_instr_i[i].result] != NONE)) begin + rd_clobber_gpr_i[issue_instr_i[i].result[REG_ADDR_SIZE-1:0]] != NONE)) begin // if the operand is available, forward it. CSRs don't write to/from FPR so no need to check if (rs3_valid_i[i]) begin forward_rs3[i] = 1'b1; end else begin // the operand is not available -> stall - stall[i] = 1'b1; + stall_raw[i] = 1'b1; stall_rs3[i] = 1'b1; end end @@ -473,7 +477,7 @@ module issue_read_operands ) == is_rd_fpr( issue_instr_i[0].op ))) && issue_instr_i[1].rs1 == issue_instr_i[0].rd && issue_instr_i[1].rs1 != '0) begin - stall[1] = 1'b1; + stall_raw[1] = 1'b1; end if ((!CVA6Cfg.FpPresent || (is_rs2_fpr( @@ -481,7 +485,7 @@ module issue_read_operands ) == is_rd_fpr( issue_instr_i[0].op ))) && issue_instr_i[1].rs2 == issue_instr_i[0].rd && issue_instr_i[1].rs2 != '0) begin - stall[1] = 1'b1; + stall_raw[1] = 1'b1; end // Only check clobbered gpr for OFFLOADED instruction @@ -492,7 +496,7 @@ module issue_read_operands ) && issue_instr_i[0].rd == issue_instr_i[1].result[REG_ADDR_SIZE-1:0] : issue_instr_i[1].op == OFFLOAD && OPERANDS_PER_INSTR == 3 ? issue_instr_i[0].rd == issue_instr_i[1].result[REG_ADDR_SIZE-1:0] : 1'b0) begin - stall[1] = 1'b1; + stall_raw[1] = 1'b1; end end end @@ -664,43 +668,51 @@ module issue_read_operands end end + + always_comb begin : gen_check_waw_dependencies + stall_waw = '1; + for (int unsigned i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin + if (issue_instr_valid_i[i] && !fu_busy[i]) begin + // ----------------------------------------- + // WAW - Write After Write Dependency Check + // ----------------------------------------- + // no other instruction has the same destination register -> issue the instruction + if ((CVA6Cfg.FpPresent && ariane_pkg::is_rd_fpr( + issue_instr_i[i].op + )) ? (rd_clobber_fpr_i[issue_instr_i[i].rd] == NONE) : + (rd_clobber_gpr_i[issue_instr_i[i].rd] == NONE)) begin + stall_waw[i] = 1'b0; + end + // or check that the target destination register will be written in this cycle by the + // commit stage + for (int unsigned c = 0; c < CVA6Cfg.NrCommitPorts; c++) begin + if ((CVA6Cfg.FpPresent && ariane_pkg::is_rd_fpr( + issue_instr_i[i].op + )) ? (we_fpr_i[c] && waddr_i[c] == issue_instr_i[i].rd[4:0]) : + (we_gpr_i[c] && waddr_i[c] == issue_instr_i[i].rd[4:0])) begin + stall_waw[i] = 1'b0; + end + end + if (i > 0) begin + if ((issue_instr_i[i].rd[4:0] == issue_instr_i[i-1].rd[4:0]) && (issue_instr_i[i].rd[4:0] != '0)) begin + stall_waw[i] = 1'b1; + end + end + end + end + end // We can issue an instruction if we do not detect that any other instruction is writing the same // destination register. // We also need to check if there is an unresolved branch in the scoreboard. always_comb begin : issue_scoreboard for (int unsigned i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin // default assignment - issue_ack_o[i] = 1'b0; - // check that we didn't stall, that the instruction we got is valid + issue_ack[i] = 1'b0; + // check that the instruction we got is valid // and that the functional unit we need is not busy if (issue_instr_valid_i[i] && !fu_busy[i]) begin - // check that the corresponding functional unit is not busy - if (!stall[i]) begin - // ----------------------------------------- - // WAW - Write After Write Dependency Check - // ----------------------------------------- - // no other instruction has the same destination register -> issue the instruction - if ((CVA6Cfg.FpPresent && ariane_pkg::is_rd_fpr( - issue_instr_i[i].op - )) ? (rd_clobber_fpr_i[issue_instr_i[i].rd] == NONE) : - (rd_clobber_gpr_i[issue_instr_i[i].rd] == NONE)) begin - issue_ack_o[i] = 1'b1; - end - // or check that the target destination register will be written in this cycle by the - // commit stage - for (int unsigned c = 0; c < CVA6Cfg.NrCommitPorts; c++) begin - if ((CVA6Cfg.FpPresent && ariane_pkg::is_rd_fpr( - issue_instr_i[i].op - )) ? (we_fpr_i[c] && waddr_i[c] == issue_instr_i[i].rd[4:0]) : - (we_gpr_i[c] && waddr_i[c] == issue_instr_i[i].rd[4:0])) begin - issue_ack_o[i] = 1'b1; - end - end - if (i > 0) begin - if ((issue_instr_i[i].rd[4:0] == issue_instr_i[i-1].rd[4:0]) && (issue_instr_i[i].rd[4:0] != '0)) begin - issue_ack_o[i] = 1'b0; - end - end + if (!stall_raw[i] && !stall_waw[i]) begin + issue_ack[i] = 1'b1; end // we can also issue the instruction under the following two circumstances: // we can do this even if we are stalled or no functional unit is ready (as we don't need one) @@ -708,23 +720,25 @@ module issue_read_operands // need any functional unit or if an exception occurred previous to the execute stage. // 1. we already got an exception if (issue_instr_i[i].ex.valid) begin - issue_ack_o[i] = 1'b1; + issue_ack[i] = 1'b1; end // 2. it is an instruction which does not need any functional unit if (issue_instr_i[i].fu == NONE) begin - issue_ack_o[i] = 1'b1; - end - if (issue_instr_i[i].fu == CVXIF) begin - issue_ack_o[i] = (x_transaction_accepted_o || x_transaction_rejected); + issue_ack[i] = 1'b1; end end end if (CVA6Cfg.SuperscalarEn) begin - if (!issue_ack_o[0]) begin - issue_ack_o[1] = 1'b0; + if (!issue_ack[0]) begin + issue_ack[1] = 1'b0; end end + issue_ack_o = issue_ack; + // Do not acknoledge the issued instruction if transaction is not completed. + if (issue_instr_i[0].fu == CVXIF && !(x_transaction_accepted_o || x_transaction_rejected)) begin + issue_ack_o[0] = 1'b0; + end end // ---------------------- diff --git a/spyglass/reference_summary.rpt b/spyglass/reference_summary.rpt index 8988519e4b..84153fe53e 100644 --- a/spyglass/reference_summary.rpt +++ b/spyglass/reference_summary.rpt @@ -3,9 +3,9 @@ # # This file has been generated by SpyGlass: # Report Name : summary -# Report Created by: akassimi -# Report Created on: Tue Jul 16 15:53:46 2024 -# Working Directory: /home/akassimi/rhel8/cva6_synthesis/cva6/spyglass +# Report Created by: runner_riscv-public +# Report Created on: Fri Jul 26 00:36:54 2024 +# Working Directory: /gitlab-runner/runner_riscv-public/builds/yD5zmwgi3/0/riscv-ci/cva6/spyglass # SpyGlass Version : SpyGlass_vS-2021.09-SP2-3 # Policy Name : SpyGlass(SpyGlass_vS-2021.09-SP2-03) # erc(SpyGlass_vS-2021.09-SP2-03) @@ -17,9 +17,9 @@ # starc(SpyGlass_vS-2021.09-SP2-03) # starc2005(SpyGlass_vS-2021.09-SP2-03) # -# Total Number of Generated Messages : 1501 +# Total Number of Generated Messages : 1521 # Number of Waived Messages : 2 -# Number of Reported Messages : 1499 +# Number of Reported Messages : 1519 # Number of Overlimit Messages : 0 # # @@ -31,102 +31,103 @@ SUMMARY REPORT: ############### BuiltIn -> RuleGroup=Blackbox Resolution ############### +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Severity Rule Name Count Short Help +Severity Rule Name Count Short Help =============================================================================== -WARNING WarnAnalyzeBBox 1 Reports black boxes in the design with - Warn severity. +WARNING WarnAnalyzeBBox 1 Reports black boxes in the design with + Warn severity. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ############### BuiltIn -> RuleGroup=Command-line read ############### +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Severity Rule Name Count Short Help +Severity Rule Name Count Short Help =============================================================================== -INFO HdlLibDuCheck_03 1 Reports that 'hdllibdu' is not required - if no precompiled design unit is used - in current run. +INFO HdlLibDuCheck_03 1 Reports that 'hdllibdu' is not required + if no precompiled design unit is used + in current run. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ############### BuiltIn -> RuleGroup=Design Read ############### +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Severity Rule Name Count Short Help +Severity Rule Name Count Short Help =============================================================================== -WARNING SYNTH_12605 5 Used Priority/Unique Type case/if - statement but all the conditions are - not covered -WARNING SYNTH_12608 1 The logic of the always block - mismatches with the type of Always - Block -WARNING SYNTH_12611 2 Property blocks will be ignored for - synthesis -WARNING SYNTH_5064 37 Non-synthesizable statements are - ignored for synthesis. -WARNING SYNTH_5143 11 Initial block is ignored for synthesis -WARNING SYNTH_89 4 Initial Assignment at Declaration is - ignored by synthesis. -WARNING WRN_1024 3 Signed argument is passed to $signed - system function call, or unsigned - argument passed to $unsigned system - function call. -INFO DetectTopDesignUnits 1 Identify the top-level design units in - user design. -INFO ElabSummary 1 Generates Elaborated design units - Summary data +WARNING SYNTH_12605 5 Used Priority/Unique Type case/if + statement but all the conditions are + not covered +WARNING SYNTH_12608 1 The logic of the always block + mismatches with the type of Always + Block +WARNING SYNTH_12611 2 Property blocks will be ignored for + synthesis +WARNING SYNTH_5064 38 Non-synthesizable statements are + ignored for synthesis. +WARNING SYNTH_5143 11 Initial block is ignored for synthesis +WARNING SYNTH_89 4 Initial Assignment at Declaration is + ignored by synthesis. +WARNING WRN_1024 3 Signed argument is passed to $signed + system function call, or unsigned + argument passed to $unsigned system + function call. +WARNING WRN_27 1 Bit-select should not be out-of-range. +INFO DetectTopDesignUnits 1 Identify the top-level design units in + user design. +INFO ElabSummary 1 Generates Elaborated design units + Summary data +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ############### Non-BuiltIn -> Goal=lint/lint_rtl ############### +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -Severity Rule Name Count Short Help +Severity Rule Name Count Short Help =============================================================================== -ERROR InferLatch 2 Latch inferred -ERROR UndrivenInTerm-ML 3 Undriven but loaded input terminal of - an instance detected -ERROR W123 11 A signal or variable has been read but - is not set -ERROR W416 1 Width of return type and return value - of a function should be same (Verilog) - Range of return type and return value - of a function should be same (VHDL) -WARNING FlopEConst 19 Flip-flop enable pin is permanently - disabled or enabled -WARNING ParamWidthMismatch-ML 1 Parameter width does not match with the - value assigned -WARNING STARC05-1.3.1.3 1 Asynchronous reset/preset signals must - not be used as non-reset/preset or - synchronous reset/preset signals -WARNING STARC05-2.1.3.1 2 Bit-width of function arguments must - match bit-width of the corresponding - function inputs. -WARNING STARC05-2.1.4.5 1 Bit-wise operators must be used instead - of logic operators in multi-bit - operations. -WARNING STARC05-2.1.5.3 1 Conditional expressions should evaluate - to a scalar. -WARNING STARC05-2.2.3.3 14 Do not assign over the same signal in - an always construct for sequential - circuits -WARNING W224 1 Multi-bit expression found when one-bit - expression expected -WARNING W240 323 An input has been declared but is not - read -WARNING W263 4 A case expression width does not match - case select expression width -WARNING W287b 32 Output port of an instance is not - connected -WARNING W415a 526 Signal may be multiply assigned (beside - initialization) in the same scope. -WARNING W480 3 Loop index is not of type integer -WARNING W486 2 Shift overflow - some bits may be lost -WARNING W528 483 A signal or variable is set but never - read -INFO W240 1 An input has been declared but is not - read -INFO W528 1 A signal or variable is set but never - read +ERROR InferLatch 2 Latch inferred +ERROR UndrivenInTerm-ML 3 Undriven but loaded input terminal of + an instance detected +ERROR W123 11 A signal or variable has been read but + is not set +ERROR W416 1 Width of return type and return value + of a function should be same (Verilog) + Range of return type and return value + of a function should be same (VHDL) +WARNING FlopEConst 19 Flip-flop enable pin is permanently + disabled or enabled +WARNING ParamWidthMismatch-ML 1 Parameter width does not match with the + value assigned +WARNING STARC05-1.3.1.3 1 Asynchronous reset/preset signals must + not be used as non-reset/preset or + synchronous reset/preset signals +WARNING STARC05-2.1.3.1 2 Bit-width of function arguments must + match bit-width of the corresponding + function inputs. +WARNING STARC05-2.1.4.5 1 Bit-wise operators must be used instead + of logic operators in multi-bit + operations. +WARNING STARC05-2.1.5.3 1 Conditional expressions should evaluate + to a scalar. +WARNING STARC05-2.2.3.3 14 Do not assign over the same signal in + an always construct for sequential + circuits +WARNING W224 1 Multi-bit expression found when one-bit + expression expected +WARNING W240 322 An input has been declared but is not + read +WARNING W263 4 A case expression width does not match + case select expression width +WARNING W287b 36 Output port of an instance is not + connected +WARNING W415a 537 Signal may be multiply assigned (beside + initialization) in the same scope. +WARNING W480 3 Loop index is not of type integer +WARNING W486 2 Shift overflow - some bits may be lost +WARNING W528 487 A signal or variable is set but never + read +INFO W240 1 An input has been declared but is not + read +INFO W528 1 A signal or variable is set but never + read +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ From 934823d89c47a9c682374836d9c060546c5fcd81 Mon Sep 17 00:00:00 2001 From: valentinThomazic Date: Fri, 26 Jul 2024 13:04:40 +0000 Subject: [PATCH 040/183] Add custom config in gitlab ci (#2405) --- .gitlab-ci.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c3878b8808..c1368e083d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,6 +25,10 @@ include: - project: '$CI_PROJECT_NAMESPACE/setup-ci' ref: '$SETUP_CI_CVV_BRANCH' file: 'cva6/core-v-verif-cva6.yml' + - local: '.gitlab-ci-custom.yml' + rules: + - exists: + - '.gitlab-ci-custom.yml' workflow: rules: @@ -34,6 +38,9 @@ workflow: - if: $CI_COMMIT_BRANCH == "master" variables: CI_KIND: regress + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + variables: + CI_KIND: regress - if: $CI_COMMIT_BRANCH =~ /.*_PR_.*/ variables: CI_KIND: dev From a4583a6e4d3a03b29153829da3ca6d8e4f2e3e20 Mon Sep 17 00:00:00 2001 From: AbdessamiiOukalrazqou <163409352+AbdessamiiOukalrazqou@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:25:54 +0200 Subject: [PATCH 041/183] [gen_from_riscv_config] improve readme file to support debug spec (#2406) --- config/gen_from_riscv_config/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config/gen_from_riscv_config/README.md b/config/gen_from_riscv_config/README.md index d13a2b6a57..2422c973e0 100644 --- a/config/gen_from_riscv_config/README.md +++ b/config/gen_from_riscv_config/README.md @@ -34,7 +34,7 @@ pip3 install -r requirements.txt ```bash #Generate Restructred-text documentation for Control and Status Registers (CSR) -python3 .py -s <../riscv-config/Config_Name/generated/isa_gen>.yaml -c <../riscv-config/Config_Name/generated/custom_gen>.yaml -m .yaml -t < Config_Name> +python3 .py -s <../riscv-config/Config_Name/generated/isa_gen>.yaml -c <../riscv-config/Config_Name/generated/custom_gen>.yaml -d <../riscv-config/Config_Name/generated/debug_gen>.yaml -m .yaml -t < Config_Name> #Generate Restructred-text documentation for ISA extensions python3 .py -s <../riscv-config/Config_Name/generated/isa_gen>.yaml -i .yaml -m .yaml -t < Config_Name> @@ -48,7 +48,7 @@ python3 .py -s <../riscv-config/Config_Name/generated/ ```bash #Generate the Restructred-text documentation for Control and Status Registers (CSR) -python3 scripts/riscv_config_gen.py -s ../riscv-config/cv32a65x/generated/isa_gen.yaml -c ../riscv-config/cv32a65x/generated/custom_gen.yaml -m updaters/cv32a65x/csr_updater.yaml -t cv32a65x +python3 scripts/riscv_config_gen.py -s ../riscv-config/cv32a65x/generated/isa_gen.yaml -c ../riscv-config/cv32a65x/generated/custom_gen.yaml -d ../riscv-config/cv32a65x/generated/debug_gen.yaml -m updaters/cv32a65x/csr_updater.yaml -t cv32a65x #Generate the Restructred-text documentation for ISA extensions python3 scripts/riscv_config_gen.py -s ../riscv-config/cv32a65x/generated/isa_gen.yaml -i templates/isa_template.yaml -m updaters/cv32a65x/isa_updater.yaml -t cv32a65x @@ -218,6 +218,8 @@ CSR/ISA Updater read RISC-CONFIG.yaml and update the registers so if you want to : - Exemple : + + Bootroom : true - Exemple : cores: From 22492027694b606489a9a4f4ea963eed6bdbcb5e Mon Sep 17 00:00:00 2001 From: slgth <166491525+slgth@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:27:42 +0200 Subject: [PATCH 042/183] docs: multiple fixes (#2409) --- .../cv32a65x/csr/csr.adoc | 89 +++++++++++++------ .../cv32a65x/csr/csr.rst | 22 ++--- docs/04_cv32a65x/design/design-cv32a65x.html | 8 +- .../04_cv32a65x/design/source/parameters.adoc | 2 +- .../design/source/port_ex_stage.adoc | 4 +- .../design/source/port_load_store_unit.adoc | 4 +- .../{riscv/src => config}/config.adoc | 0 ...{cv32a6_execute.adoc => cva6_execute.adoc} | 0 ...v32a6_frontend.adoc => cva6_frontend.adoc} | 12 +-- .../{cv32a6_glossary.adoc => glossary.adoc} | 1 - 10 files changed, 87 insertions(+), 55 deletions(-) rename docs/06_cv64a6_mmu/{riscv/src => config}/config.adoc (100%) rename docs/design/design-manual/source/{cv32a6_execute.adoc => cva6_execute.adoc} (100%) rename docs/design/design-manual/source/{cv32a6_frontend.adoc => cva6_frontend.adoc} (98%) rename docs/design/design-manual/source/{cv32a6_glossary.adoc => glossary.adoc} (99%) diff --git a/config/gen_from_riscv_config/cv32a65x/csr/csr.adoc b/config/gen_from_riscv_config/cv32a65x/csr/csr.adoc index e390932111..808f53c084 100644 --- a/config/gen_from_riscv_config/cv32a65x/csr/csr.adoc +++ b/config/gen_from_riscv_config/cv32a65x/csr/csr.adoc @@ -48,8 +48,10 @@ This allows to clearly represent read-write registers holding a single legal val |0x342| `<<_MCAUSE,MCAUSE>>`|MRW|The mcause register stores the information regarding the trap. |0x343| `<<_MTVAL,MTVAL>>`|MRW|The mtval is a warl register that holds the address of the instruction which caused the exception. |0x344| `<<_MIP,MIP>>`|MRW|The mip register is an MXLEN-bit read/write register containing information on pending interrupts. -|0x3a0-0x3a3| `<<_PMPCFG0-3,PMPCFG[0-3]>>`|MRW|PMP configuration register -|0x3b0-0x3bf| `<<_PMPADDR0-15,PMPADDR[0-15]>>`|MRW|Physical memory protection address register +|0x3a0-0x3a1| `<<_PMPCFG0-1,PMPCFG[0-1]>>`|MRW|PMP configuration register +|0x3a2-0x3af| `<<_PMPCFG2-15,PMPCFG[2-15]>>`|MRW|PMP configuration register +|0x3b0-0x3b7| `<<_PMPADDR0-7,PMPADDR[0-7]>>`|MRW|Physical memory protection address register +|0x3b8-0x3ef| `<<_PMPADDR8-63,PMPADDR[8-63]>>`|MRW|Physical memory protection address register |0x7c0| `<<_ICACHE,ICACHE>>`|MRW|the register controls the operation of the i-cache unit. |0x7c1| `<<_DCACHE,DCACHE>>`|MRW|the register controls the operation of the d-cache unit. |0xb00| `<<_MCYCLE,MCYCLE>>`|MRW|Counts the number of clock cycles executed from an arbitrary point in time. @@ -81,11 +83,11 @@ Description:: The mstatus register keeps track of and controls the hart's curren | 0 | UIE | 0x0 | ROCST | 0x0 | Stores the state of the user mode interrupts. | 1 | SIE | 0x0 | ROCST | 0x0 | Stores the state of the supervisor mode interrupts. | 2 | RESERVED_2 | 0x0 | WPRI | | *Reserved* -| 3 | MIE | 0x0 | WLRL | 0 - 1 | Stores the state of the machine mode interrupts. +| 3 | MIE | 0x0 | WLRL | 0x0 - 0x1 | Stores the state of the machine mode interrupts. | 4 | UPIE | 0x0 | ROCST | 0x0 | Stores the state of the user mode interrupts prior to the trap. | 5 | SPIE | 0x0 | ROCST | 0x0 | Stores the state of the supervisor mode interrupts prior to the trap. | 6 | UBE | 0x0 | ROCST | 0x0 | control the endianness of memory accesses other than instruction fetches for user mode -| 7 | MPIE | 0x0 | WLRL | 0 - 1 | Stores the state of the machine mode interrupts prior to the trap. +| 7 | MPIE | 0x0 | WLRL | 0x0 - 0x1 | Stores the state of the machine mode interrupts prior to the trap. | 8 | SPP | 0x0 | ROCST | 0x0 | Stores the previous priority mode for supervisor. | [10:9] | RESERVED_9 | 0x0 | WPRI | | *Reserved* | [12:11] | MPP | 0x3 | WARL | 0x3 | Stores the previous priority mode for machine. @@ -136,11 +138,11 @@ Description:: The mie register is an MXLEN-bit read/write register containing in | 4 | UTIE | 0x0 | ROCST | 0x0 | User Timer Interrupt enable. | 5 | STIE | 0x0 | ROCST | 0x0 | Supervisor Timer Interrupt enable. | 6 | VSTIE | 0x0 | ROCST | 0x0 | VS-level Timer Interrupt enable. -| 7 | MTIE | 0x0 | WLRL | 0 - 1 | Machine Timer Interrupt enable. +| 7 | MTIE | 0x0 | WLRL | 0x0 - 0x1 | Machine Timer Interrupt enable. | 8 | UEIE | 0x0 | ROCST | 0x0 | User External Interrupt enable. | 9 | SEIE | 0x0 | ROCST | 0x0 | Supervisor External Interrupt enable. | 10 | VSEIE | 0x0 | ROCST | 0x0 | VS-level External Interrupt enable. -| 11 | MEIE | 0x0 | WLRL | 0 - 1 | Machine External Interrupt enable. +| 11 | MEIE | 0x0 | WLRL | 0x0 - 0x1 | Machine External Interrupt enable. | 12 | SGEIE | 0x0 | ROCST | 0x0 | HS-level External Interrupt enable. | [31:13] | RESERVED_13 | 0x0 | WPRI | | *Reserved* |=== @@ -192,7 +194,7 @@ Description:: The mhpmevent is a MXLEN-bit event register which controls mhpmcou |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [31:0] | MHPMEVENT[I] | 0x00000000 | ROCST | 0x00000000 | The mhpmevent is a MXLEN-bit event register which controls mhpmcounter3. +| [31:0] | MHPMEVENT[I] | 0x00000000 | ROCST | 0x0 | The mhpmevent is a MXLEN-bit event register which controls mhpmcounter3. |=== [[_MSCRATCH]] @@ -234,7 +236,7 @@ Description:: The mcause register stores the information regarding the trap. |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [30:0] | EXCEPTION_CODE | 0x0 | WLRL | 0 - 15 | Encodes the exception code. +| [30:0] | EXCEPTION_CODE | 0x0 | WLRL | 0x0 - 0x8, 0xb | Encodes the exception code. | 31 | INTERRUPT | 0x0 | WLRL | 0x0 - 0x1 | Indicates whether the trap was due to an interrupt. |=== @@ -249,7 +251,7 @@ Description:: The mtval is a warl register that holds the address of the instruc |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [31:0] | MTVAL | 0x00000000 | ROCST | 0x00000000 | The mtval is a warl register that holds the address of the instruction which caused the exception. +| [31:0] | MTVAL | 0x00000000 | ROCST | 0x0 | The mtval is a warl register that holds the address of the instruction which caused the exception. |=== [[_MIP]] @@ -270,19 +272,19 @@ Description:: The mip register is an MXLEN-bit read/write register containing in | 4 | UTIP | 0x0 | ROCST | 0x0 | User Timer Interrupt Pending. | 5 | STIP | 0x0 | ROCST | 0x0 | Supervisor Timer Interrupt Pending. | 6 | VSTIP | 0x0 | ROCST | 0x0 | VS-level Timer Interrupt Pending. -| 7 | MTIP | 0x0 | ROVAR | 0x1 | Machine Timer Interrupt Pending. +| 7 | MTIP | 0x0 | ROVAR | 0x0 - 0x1 | Machine Timer Interrupt Pending. | 8 | UEIP | 0x0 | ROCST | 0x0 | User External Interrupt Pending. | 9 | SEIP | 0x0 | ROCST | 0x0 | Supervisor External Interrupt Pending. | 10 | VSEIP | 0x0 | ROCST | 0x0 | VS-level External Interrupt Pending. -| 11 | MEIP | 0x0 | ROVAR | 0x1 | Machine External Interrupt Pending. +| 11 | MEIP | 0x0 | ROVAR | 0x0 - 0x1 | Machine External Interrupt Pending. | 12 | SGEIP | 0x0 | ROCST | 0x0 | HS-level External Interrupt Pending. | [31:13] | RESERVED_13 | 0x0 | WPRI | | *Reserved* |=== -[[_PMPCFG0-3]] -===== PMPCFG[0-3] +[[_PMPCFG0-1]] +===== PMPCFG[0-1] -Address:: 0x3a0-0x3a3 +Address:: 0x3a0-0x3a1 Reset Value:: 0x00000000 Privilege:: MRW Description:: PMP configuration register @@ -290,16 +292,33 @@ Description:: PMP configuration register |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [7:0] | PMP[I*4 + 0]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits -| [15:8] | PMP[I*4 + 1]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits -| [23:16] | PMP[I*4 + 2]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits -| [31:24] | PMP[I*4 + 3]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits +| [7:0] | PMP[I*4 +0]CFG | 0x0 | WARL | masked: & 0x8f | 0x0 | pmp configuration bits +| [15:8] | PMP[I*4 +1]CFG | 0x0 | WARL | masked: & 0x8f | 0x0 | pmp configuration bits +| [23:16] | PMP[I*4 +2]CFG | 0x0 | WARL | masked: & 0x8f | 0x0 | pmp configuration bits +| [31:24] | PMP[I*4 +3]CFG | 0x0 | WARL | masked: & 0x8f | 0x0 | pmp configuration bits |=== -[[_PMPADDR0-15]] -===== PMPADDR[0-15] +[[_PMPCFG2-15]] +===== PMPCFG[2-15] -Address:: 0x3b0-0x3bf +Address:: 0x3a2-0x3af +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: PMP configuration register + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [7:0] | PMP[I*4 +0]CFG | 0x0 | ROCST | 0x0 | pmp configuration bits +| [15:8] | PMP[I*4 +1]CFG | 0x0 | ROCST | 0x0 | pmp configuration bits +| [23:16] | PMP[I*4 +2]CFG | 0x0 | ROCST | 0x0 | pmp configuration bits +| [31:24] | PMP[I*4 +3]CFG | 0x0 | ROCST | 0x0 | pmp configuration bits +|=== + +[[_PMPADDR0-7]] +===== PMPADDR[0-7] + +Address:: 0x3b0-0x3b7 Reset Value:: 0x00000000 Privilege:: MRW Description:: Physical memory protection address register @@ -310,6 +329,20 @@ Description:: Physical memory protection address register | [31:0] | PMPADDR[I] | 0x00000000 | WARL | 0x00000000 - 0xFFFFFFFF | Physical memory protection address register |=== +[[_PMPADDR8-63]] +===== PMPADDR[8-63] + +Address:: 0x3b8-0x3ef +Reset Value:: 0x00000000 +Privilege:: MRW +Description:: Physical memory protection address register + +|=== +| Bits | Field Name | Reset Value | Type | Legal Values | Description + +| [31:0] | PMPADDR[I] | 0x00000000 | ROCST | 0x0 | Physical memory protection address register +|=== + [[_ICACHE]] ===== ICACHE @@ -379,7 +412,7 @@ Description:: The mhpmcounter is a 64-bit counter. Returns lower 32 bits in RV32 |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [31:0] | MHPMCOUNTER[I] | 0x00000000 | ROCST | 0x00000000 | The mhpmcounter is a 64-bit counter. Returns lower 32 bits in RV32I mode. +| [31:0] | MHPMCOUNTER[I] | 0x00000000 | ROCST | 0x0 | The mhpmcounter is a 64-bit counter. Returns lower 32 bits in RV32I mode. |=== [[_MCYCLEH]] @@ -421,7 +454,7 @@ Description:: The mhpmcounterh returns the upper half word in RV32I systems. |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [31:0] | MHPMCOUNTER[I]H | 0x00000000 | ROCST | 0x00000000 | The mhpmcounterh returns the upper half word in RV32I systems. +| [31:0] | MHPMCOUNTER[I]H | 0x00000000 | ROCST | 0x0 | The mhpmcounterh returns the upper half word in RV32I systems. |=== [[_MVENDORID]] @@ -435,7 +468,7 @@ Description:: 32-bit read-only register providing the JEDEC manufacturer ID of t |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [31:0] | MVENDORID | 0x00000602 | ROCST | 0x00000602 | 32-bit read-only register providing the JEDEC manufacturer ID of the provider of the core. +| [31:0] | MVENDORID | 0x00000602 | ROCST | 0x602 | 32-bit read-only register providing the JEDEC manufacturer ID of the provider of the core. |=== [[_MARCHID]] @@ -449,7 +482,7 @@ Description:: MXLEN-bit read-only register encoding the base microarchitecture o |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [31:0] | MARCHID | 0x00000003 | ROCST | 0x00000003 | MXLEN-bit read-only register encoding the base microarchitecture of the hart. +| [31:0] | MARCHID | 0x00000003 | ROCST | 0x3 | MXLEN-bit read-only register encoding the base microarchitecture of the hart. |=== [[_MIMPID]] @@ -463,7 +496,7 @@ Description:: Provides a unique encoding of the version of the processor impleme |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [31:0] | MIMPID | 0x00000000 | ROCST | 0x00000000 | Provides a unique encoding of the version of the processor implementation. +| [31:0] | MIMPID | 0x00000000 | ROCST | 0x0 | Provides a unique encoding of the version of the processor implementation. |=== [[_MHARTID]] @@ -477,7 +510,7 @@ Description:: MXLEN-bit read-only register containing the integer ID of the hard |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [31:0] | MHARTID | 0x00000000 | ROCST | 0x00000000 | MXLEN-bit read-only register containing the integer ID of the hardware thread running the code. +| [31:0] | MHARTID | 0x00000000 | ROCST | 0x0 | MXLEN-bit read-only register containing the integer ID of the hardware thread running the code. |=== [[_MCONFIGPTR]] @@ -491,6 +524,6 @@ Description:: MXLEN-bit read-only register that holds the physical address of a |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [31:0] | MCONFIGPTR | 0x00000000 | ROCST | 0x00000000 | MXLEN-bit read-only register that holds the physical address of a configuration data structure. +| [31:0] | MCONFIGPTR | 0x00000000 | ROCST | 0x0 | MXLEN-bit read-only register that holds the physical address of a configuration data structure. |=== diff --git a/config/gen_from_riscv_config/cv32a65x/csr/csr.rst b/config/gen_from_riscv_config/cv32a65x/csr/csr.rst index 6083081e1c..7053c1f181 100644 --- a/config/gen_from_riscv_config/cv32a65x/csr/csr.rst +++ b/config/gen_from_riscv_config/cv32a65x/csr/csr.rst @@ -415,17 +415,17 @@ PMPCFG[0-1] :Privilege: MRW :Description: PMP configuration register -+---------+----------------+---------------+--------+----------------+------------------------+ -| Bits | Field Name | Reset Value | Type | Legal Values | Description | -+=========+================+===============+========+================+========================+ -| [7:0] | PMP[I*4 +0]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits | -+---------+----------------+---------------+--------+----------------+------------------------+ -| [15:8] | PMP[I*4 +1]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits | -+---------+----------------+---------------+--------+----------------+------------------------+ -| [23:16] | PMP[I*4 +2]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits | -+---------+----------------+---------------+--------+----------------+------------------------+ -| [31:24] | PMP[I*4 +3]CFG | 0x0 | WARL | 0x00 - 0xFF | pmp configuration bits | -+---------+----------------+---------------+--------+----------------+------------------------+ ++---------+----------------+---------------+--------+----------------------+------------------------+ +| Bits | Field Name | Reset Value | Type | Legal Values | Description | ++=========+================+===============+========+======================+========================+ +| [7:0] | PMP[I*4 +0]CFG | 0x0 | WARL | masked: & 0x8f | 0x0 | pmp configuration bits | ++---------+----------------+---------------+--------+----------------------+------------------------+ +| [15:8] | PMP[I*4 +1]CFG | 0x0 | WARL | masked: & 0x8f | 0x0 | pmp configuration bits | ++---------+----------------+---------------+--------+----------------------+------------------------+ +| [23:16] | PMP[I*4 +2]CFG | 0x0 | WARL | masked: & 0x8f | 0x0 | pmp configuration bits | ++---------+----------------+---------------+--------+----------------------+------------------------+ +| [31:24] | PMP[I*4 +3]CFG | 0x0 | WARL | masked: & 0x8f | 0x0 | pmp configuration bits | ++---------+----------------+---------------+--------+----------------------+------------------------+ .. .. _PMPCFG[2-15]::: diff --git a/docs/04_cv32a65x/design/design-cv32a65x.html b/docs/04_cv32a65x/design/design-cv32a65x.html index a191b6a607..82598ba3ae 100644 --- a/docs/04_cv32a65x/design/design-cv32a65x.html +++ b/docs/04_cv32a65x/design/design-cv32a65x.html @@ -1184,7 +1184,7 @@

2.3. Parameter configuration

WtDcacheWbufDepth

Write-through data cache write buffer depth

-

2

+

8

FetchUserEn

@@ -10630,14 +10630,14 @@
4.4.3.5. load_store_unit (LSU)

in

PMP configuration

CSR_REGFILE

-

riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries:0]

+

riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries-1:0]

pmpaddr_i

in

PMP address

CSR_REGFILE

-

logic[CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0]

+

logic[CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0]

@@ -12947,7 +12947,7 @@

5. Glossary

diff --git a/docs/04_cv32a65x/design/source/parameters.adoc b/docs/04_cv32a65x/design/source/parameters.adoc index 070d768175..bc6f728ba2 100644 --- a/docs/04_cv32a65x/design/source/parameters.adoc +++ b/docs/04_cv32a65x/design/source/parameters.adoc @@ -71,7 +71,7 @@ |DcacheSetAssoc | Data cache associativity (number of ways) | 2 |DcacheLineWidth | Data cache line width | 128 |DataUserEn | User field on data bus enable | 1 -|WtDcacheWbufDepth | Write-through data cache write buffer depth | 2 +|WtDcacheWbufDepth | Write-through data cache write buffer depth | 8 |FetchUserEn | User field on fetch bus enable | 1 |FetchUserWidth | Width of fetch user field | 32 |FpgaEn | Is FPGA optimization of CV32A6 | False diff --git a/docs/04_cv32a65x/design/source/port_ex_stage.adoc b/docs/04_cv32a65x/design/source/port_ex_stage.adoc index 8473147904..6a9f9290ec 100644 --- a/docs/04_cv32a65x/design/source/port_ex_stage.adoc +++ b/docs/04_cv32a65x/design/source/port_ex_stage.adoc @@ -126,9 +126,9 @@ |`dcache_wbuffer_not_ni_i` | in | TO_BE_COMPLETED | CACHE | logic -|`pmpcfg_i` | in | Report the PMP configuration | CSR_REGFILE | riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries:0] +|`pmpcfg_i` | in | Report the PMP configuration | CSR_REGFILE | riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries-1:0] -|`pmpaddr_i` | in | Report the PMP addresses | CSR_REGFILE | logic[CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] +|`pmpaddr_i` | in | Report the PMP addresses | CSR_REGFILE | logic[CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] |=== Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below diff --git a/docs/04_cv32a65x/design/source/port_load_store_unit.adoc b/docs/04_cv32a65x/design/source/port_load_store_unit.adoc index 7fa01ad7a0..bed4e9a0d9 100644 --- a/docs/04_cv32a65x/design/source/port_load_store_unit.adoc +++ b/docs/04_cv32a65x/design/source/port_load_store_unit.adoc @@ -64,9 +64,9 @@ |`dcache_wbuffer_not_ni_i` | in | TO_BE_COMPLETED | TO_BE_COMPLETED | logic -|`pmpcfg_i` | in | PMP configuration | CSR_REGFILE | riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries:0] +|`pmpcfg_i` | in | PMP configuration | CSR_REGFILE | riscv::pmpcfg_t[CVA6Cfg.NrPMPEntries-1:0] -|`pmpaddr_i` | in | PMP address | CSR_REGFILE | logic[CVA6Cfg.NrPMPEntries:0][CVA6Cfg.PLEN-3:0] +|`pmpaddr_i` | in | PMP address | CSR_REGFILE | logic[CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] |=== Due to cv32a65x configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below diff --git a/docs/06_cv64a6_mmu/riscv/src/config.adoc b/docs/06_cv64a6_mmu/config/config.adoc similarity index 100% rename from docs/06_cv64a6_mmu/riscv/src/config.adoc rename to docs/06_cv64a6_mmu/config/config.adoc diff --git a/docs/design/design-manual/source/cv32a6_execute.adoc b/docs/design/design-manual/source/cva6_execute.adoc similarity index 100% rename from docs/design/design-manual/source/cv32a6_execute.adoc rename to docs/design/design-manual/source/cva6_execute.adoc diff --git a/docs/design/design-manual/source/cv32a6_frontend.adoc b/docs/design/design-manual/source/cva6_frontend.adoc similarity index 98% rename from docs/design/design-manual/source/cv32a6_frontend.adoc rename to docs/design/design-manual/source/cva6_frontend.adoc index 1012c7cb50..c344c42c85 100644 --- a/docs/design/design-manual/source/cv32a6_frontend.adoc +++ b/docs/design/design-manual/source/cva6_frontend.adoc @@ -8,7 +8,7 @@ Original Author: Jean-Roch COULON - Thales //// -[[CV32A6_FRONTEND]] +[[CVA6_FRONTEND]] FRONTEND Module ~~~~~~~~~~~~~~~ @@ -60,17 +60,17 @@ RAS provides next PC as a prediction. 2. When the instruction is a JALR which *does not* correspond to areturn. If BTB (Branch Target Buffer) returns a valid address, then BTBpredicts next PC. Else JALR is not considered as a control flow instruction, which will generate a mispredict. -3. When the instruction is a conditional branch. -If BHT (Branch History table) returns a valid address, then BHT predicts next PC. +3. When the instruction is a conditional branch. +If BHT (Branch History table) returns a valid address, then BHT predicts next PC. Else the prediction depends on the PC relative jump offset sign: if sign is negative the prediction is taken, otherwise the prediction is not taken. ________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ + Then the PC gen informs the Fetch stage that it performed a prediction on the PC. -* *Default:* The next 32-bit block is fetched. +* *Default:* The next 32-bit block is fetched. PC Gen fetches word boundary 32-bits block from CACHES module. And the fetch stage identifies the instructions from the 32-bits blocks. -* *Mispredict:* Misprediction are feedbacked by EX_STAGE module. +* *Mispredict:* Misprediction are feedbacked by EX_STAGE module. In any case we need to correct our action and start fetching from the correct address. * *Replay instruction fetch:* When the instruction queue is full, the instr_queue submodule asks the fetch replay and provides the address to be replayed. @@ -83,7 +83,7 @@ The trap vector base address can be different depending on whether the exception It is the purpose of the CSR Unit to figure out where to trap to and present the correct address to PC Gen. endif::[] -* *Pipeline starting fetching from COMMIT PC:* When the commit stage is halted by a WFI instruction or when the pipeline has been flushed due to CSR change, next PC takes the value of the PC coming from the COMMIT submodule. +* *Pipeline starting fetching from COMMIT PC:* When the commit stage is halted by a WFI instruction or when the pipeline has been flushed due to CSR change, next PC takes the value of the PC coming from the COMMIT submodule. As CSR instructions do not exist in a compressed form, PC is unconditionally incremented by 4. ifeval::[{DebugEn} == true] diff --git a/docs/design/design-manual/source/cv32a6_glossary.adoc b/docs/design/design-manual/source/glossary.adoc similarity index 99% rename from docs/design/design-manual/source/cv32a6_glossary.adoc rename to docs/design/design-manual/source/glossary.adoc index d0f0906e2d..a484f9d3f8 100644 --- a/docs/design/design-manual/source/cv32a6_glossary.adoc +++ b/docs/design/design-manual/source/glossary.adoc @@ -1,4 +1,3 @@ -[[CV32A6_GLOSSARY]] [[glossary]] Glossary -------- From 6a649d65152124feb6b30950effb85bb5bdd2c2c Mon Sep 17 00:00:00 2001 From: slgth <166491525+slgth@users.noreply.github.com> Date: Fri, 26 Jul 2024 23:49:41 +0200 Subject: [PATCH 043/183] docs: more fixes (#2412) --- .../cv32a65x/csr/csr.adoc | 30 +- .../scripts/libs/utils.py | 34 ++- docs/04_cv32a65x/design/design-cv32a65x.html | 288 +++++++++++++----- 3 files changed, 249 insertions(+), 103 deletions(-) diff --git a/config/gen_from_riscv_config/cv32a65x/csr/csr.adoc b/config/gen_from_riscv_config/cv32a65x/csr/csr.adoc index 808f53c084..520b5cbbfe 100644 --- a/config/gen_from_riscv_config/cv32a65x/csr/csr.adoc +++ b/config/gen_from_riscv_config/cv32a65x/csr/csr.adoc @@ -82,14 +82,14 @@ Description:: The mstatus register keeps track of and controls the hart's curren | 0 | UIE | 0x0 | ROCST | 0x0 | Stores the state of the user mode interrupts. | 1 | SIE | 0x0 | ROCST | 0x0 | Stores the state of the supervisor mode interrupts. -| 2 | RESERVED_2 | 0x0 | WPRI | | *Reserved* +| 2 | RESERVED_2 | 0x0 | WPRI | | _Reserved_ | 3 | MIE | 0x0 | WLRL | 0x0 - 0x1 | Stores the state of the machine mode interrupts. | 4 | UPIE | 0x0 | ROCST | 0x0 | Stores the state of the user mode interrupts prior to the trap. | 5 | SPIE | 0x0 | ROCST | 0x0 | Stores the state of the supervisor mode interrupts prior to the trap. | 6 | UBE | 0x0 | ROCST | 0x0 | control the endianness of memory accesses other than instruction fetches for user mode | 7 | MPIE | 0x0 | WLRL | 0x0 - 0x1 | Stores the state of the machine mode interrupts prior to the trap. | 8 | SPP | 0x0 | ROCST | 0x0 | Stores the previous priority mode for supervisor. -| [10:9] | RESERVED_9 | 0x0 | WPRI | | *Reserved* +| [10:9] | RESERVED_9 | 0x0 | WPRI | | _Reserved_ | [12:11] | MPP | 0x3 | WARL | 0x3 | Stores the previous priority mode for machine. | [14:13] | FS | 0x0 | ROCST | 0x0 | Encodes the status of the floating-point unit, including the CSR fcsr and floating-point data registers. | [16:15] | XS | 0x0 | ROCST | 0x0 | Encodes the status of additional user-mode extensions and associated state. @@ -100,7 +100,7 @@ Description:: The mstatus register keeps track of and controls the hart's curren | 21 | TW | 0x0 | ROCST | 0x0 | Supports intercepting the WFI instruction. | 22 | TSR | 0x0 | ROCST | 0x0 | Supports intercepting the supervisor exception return instruction. | 23 | SPELP | 0x0 | ROCST | 0x0 | Supervisor mode previous expected-landing-pad (ELP) state. -| [30:24] | RESERVED_24 | 0x0 | WPRI | | *Reserved* +| [30:24] | RESERVED_24 | 0x0 | WPRI | | _Reserved_ | 31 | SD | 0x0 | ROCST | 0x0 | Read-only bit that summarizes whether either the FS field or XS field signals the presence of some dirty state. |=== @@ -116,7 +116,7 @@ Description:: misa is a read-write register reporting the ISA supported by the h | Bits | Field Name | Reset Value | Type | Legal Values | Description | [25:0] | EXTENSIONS | 0x1106 | ROCST | 0x1106 | Encodes the presence of the standard extensions, with a single bit per letter of the alphabet. -| [29:26] | RESERVED_26 | 0x0 | WPRI | | *Reserved* +| [29:26] | RESERVED_26 | 0x0 | WPRI | | _Reserved_ | [31:30] | MXL | 0x1 | WARL | 0x1 | Encodes the native base integer ISA width. |=== @@ -144,7 +144,7 @@ Description:: The mie register is an MXLEN-bit read/write register containing in | 10 | VSEIE | 0x0 | ROCST | 0x0 | VS-level External Interrupt enable. | 11 | MEIE | 0x0 | WLRL | 0x0 - 0x1 | Machine External Interrupt enable. | 12 | SGEIE | 0x0 | ROCST | 0x0 | HS-level External Interrupt enable. -| [31:13] | RESERVED_13 | 0x0 | WPRI | | *Reserved* +| [31:13] | RESERVED_13 | 0x0 | WPRI | | _Reserved_ |=== [[_MTVEC]] @@ -173,14 +173,14 @@ Description:: The mstatush register keeps track of and controls the hart’s cur |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [3:0] | RESERVED_0 | 0x0 | WPRI | | *Reserved* +| [3:0] | RESERVED_0 | 0x0 | WPRI | | _Reserved_ | 4 | SBE | 0x0 | ROCST | 0x0 | control the endianness of memory accesses other than instruction fetches for supervisor mode | 5 | MBE | 0x0 | ROCST | 0x0 | control the endianness of memory accesses other than instruction fetches for machine mode | 6 | GVA | 0x0 | ROCST | 0x0 | Stores the state of the supervisor mode interrupts. | 7 | MPV | 0x0 | ROCST | 0x0 | Stores the state of the user mode interrupts. -| 8 | RESERVED_8 | 0x0 | WPRI | | *Reserved* +| 8 | RESERVED_8 | 0x0 | WPRI | | _Reserved_ | 9 | MPELP | 0x0 | ROCST | 0x0 | Machine mode previous expected-landing-pad (ELP) state. -| [31:10] | RESERVED_10 | 0x0 | WPRI | | *Reserved* +| [31:10] | RESERVED_10 | 0x0 | WPRI | | _Reserved_ |=== [[_MHPMEVENT3-31]] @@ -278,7 +278,7 @@ Description:: The mip register is an MXLEN-bit read/write register containing in | 10 | VSEIP | 0x0 | ROCST | 0x0 | VS-level External Interrupt Pending. | 11 | MEIP | 0x0 | ROVAR | 0x0 - 0x1 | Machine External Interrupt Pending. | 12 | SGEIP | 0x0 | ROCST | 0x0 | HS-level External Interrupt Pending. -| [31:13] | RESERVED_13 | 0x0 | WPRI | | *Reserved* +| [31:13] | RESERVED_13 | 0x0 | WPRI | | _Reserved_ |=== [[_PMPCFG0-1]] @@ -292,10 +292,10 @@ Description:: PMP configuration register |=== | Bits | Field Name | Reset Value | Type | Legal Values | Description -| [7:0] | PMP[I*4 +0]CFG | 0x0 | WARL | masked: & 0x8f | 0x0 | pmp configuration bits -| [15:8] | PMP[I*4 +1]CFG | 0x0 | WARL | masked: & 0x8f | 0x0 | pmp configuration bits -| [23:16] | PMP[I*4 +2]CFG | 0x0 | WARL | masked: & 0x8f | 0x0 | pmp configuration bits -| [31:24] | PMP[I*4 +3]CFG | 0x0 | WARL | masked: & 0x8f | 0x0 | pmp configuration bits +| [7:0] | PMP[I*4 +0]CFG | 0x0 | WARL | masked: & 0x8f \| 0x0 | pmp configuration bits +| [15:8] | PMP[I*4 +1]CFG | 0x0 | WARL | masked: & 0x8f \| 0x0 | pmp configuration bits +| [23:16] | PMP[I*4 +2]CFG | 0x0 | WARL | masked: & 0x8f \| 0x0 | pmp configuration bits +| [31:24] | PMP[I*4 +3]CFG | 0x0 | WARL | masked: & 0x8f \| 0x0 | pmp configuration bits |=== [[_PMPCFG2-15]] @@ -355,7 +355,7 @@ Description:: the register controls the operation of the i-cache unit. | Bits | Field Name | Reset Value | Type | Legal Values | Description | 0 | ICACHE | 0x1 | RW | 0x1 | bit for cache-enable of instruction cache -| [31:1] | RESERVED_1 | 0x0 | WPRI | | *Reserved* +| [31:1] | RESERVED_1 | 0x0 | WPRI | | _Reserved_ |=== [[_DCACHE]] @@ -370,7 +370,7 @@ Description:: the register controls the operation of the d-cache unit. | Bits | Field Name | Reset Value | Type | Legal Values | Description | 0 | DCACHE | 0x1 | RW | 0x1 | bit for cache-enable of data cache -| [31:1] | RESERVED_1 | 0x0 | WPRI | | *Reserved* +| [31:1] | RESERVED_1 | 0x0 | WPRI | | _Reserved_ |=== [[_MCYCLE]] diff --git a/config/gen_from_riscv_config/scripts/libs/utils.py b/config/gen_from_riscv_config/scripts/libs/utils.py index 4a26398721..796a6057ce 100644 --- a/config/gen_from_riscv_config/scripts/libs/utils.py +++ b/config/gen_from_riscv_config/scripts/libs/utils.py @@ -552,7 +552,7 @@ def get_access_privilege(self, reg): return "RO" else: return "RW" - + def generate_label(self, name): return "_" + name.replace('[','').replace(']','').upper() @@ -573,24 +573,24 @@ def returnAsString(self): r += " SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1\n" r += " Author: Abdessamii Oukalrazqou\n" r += "////\n\n" - + r += "=== %s\n\n"%self.name r += "==== Conventions\n\n" - + r += "In the subsequent sections, register fields are labeled with one of the following abbreviations:\n\n" - + r += "* WPRI (Writes Preserve Values, Reads Ignore Values): read/write field reserved\n" r += "for future use. For forward compatibility, implementations that do not\n" r += "furnish these fields must make them read-only zero.\n" - + r += "* WLRL (Write/Read Only Legal Values): read/write CSR field that specifies\n" r += "behavior for only a subset of possible bit encodings, with other bit encodings\n" r += "reserved.\n" - + r += "* WARL (Write Any Values, Reads Legal Values): read/write CSR fields which are\n" r += "only defined for a subset of bit encodings, but allow any value to be written\n" r += "while guaranteeing to return a legal value whenever read.\n" - + r += "* ROCST (Read-Only Constant): A special case of WARL field which admits only one\n" r += "legal value, and therefore, behaves as a constant field that silently ignores\n" r += "writes.\n" @@ -598,12 +598,12 @@ def returnAsString(self): r += "* ROVAR (Read-Only Variable): A special case of WARL field which can take\n" r += "multiple legal values but cannot be modified by software and depends only on\n" r += "the architectural state of the hart.\n\n" - + r += "In particular, a register that is not internally divided\n" r += "into multiple fields can be considered as containing a single field of XLEN bits.\n" r += "This allows to clearly represent read-write registers holding a single legal value\n" r += "(typically zero).\n\n" - + r += "==== Register Summary\n\n" r += "|===\n" @@ -629,7 +629,7 @@ def returnAsString(self): # RO/RW privileges are encoded in register address. r += "Privilege:: %s\n"%(reg.access + self.get_access_privilege(reg)) r += "Description:: %s\n\n"%(reg.desc) - + reg_table = [] for field in reg.field: if field.bitWidth == 1: # only one bit -> no range needed @@ -658,10 +658,12 @@ def returnAsString(self): r += "| Bits | Field Name | Reset Value | Type | Legal Values | Description\n\n" for reg in reg_table: for col in reg: - r +="| %s "%col.replace('\n','') + if col == 'Reserved': + col = "_Reserved_" + r +="| %s "%col.replace('\n','').replace('|', '\|') r += "\n" r += "|===\n\n" - + return r class InstadocBlock(InstructionBlockClass): @@ -678,7 +680,7 @@ def returnAsString(self): InstrNameList = [reg.key for reg in self.Instructionlist] InstrDescrList = [reg.descr for reg in self.Instructionlist] InstrExtList = [reg.Extension_Name for reg in self.Instructionlist] - + r += "////\n" r += " Copyright (c) 2024 OpenHW Group\n" r += " Copyright (c) 2024 Thales\n" @@ -688,7 +690,7 @@ def returnAsString(self): r += "=== %s\n\n"%self.name r += "==== Instructions\n\n" - + r += "|===\n" r += "|Subset Name | Name | Description\n\n" for i, _ in enumerate(InstrNameList): @@ -696,7 +698,7 @@ def returnAsString(self): str(InstrNameList[i]), str(InstrDescrList[i]).replace('\n','')) r += "|===\n\n" - + for reg in self.Instructionlist: reg_table = [] if len(reg.Name) > 0: @@ -1106,7 +1108,7 @@ def returnRegister( legal = "" fieldaccess = "WPRI" bitWidth = int(item_[len(item_) - 1]) - int(item_[0]) + 1 - fieldDesc = "*Reserved*" + fieldDesc = "Reserved" bitlegal = legal fieldreset = hex( int(resetValue, 16) >> (bitlsb) & ((1 << ((bitWidth))) - 1) diff --git a/docs/04_cv32a65x/design/design-cv32a65x.html b/docs/04_cv32a65x/design/design-cv32a65x.html index 82598ba3ae..00c7521113 100644 --- a/docs/04_cv32a65x/design/design-cv32a65x.html +++ b/docs/04_cv32a65x/design/design-cv32a65x.html @@ -511,21 +511,23 @@

Design Documentation for CV32A65X architecture

  • 3.4.3.9. MCAUSE
  • 3.4.3.10. MTVAL
  • 3.4.3.11. MIP
  • -
  • 3.4.3.12. PMPCFG[0-3]
  • -
  • 3.4.3.13. PMPADDR[0-15]
  • -
  • 3.4.3.14. ICACHE
  • -
  • 3.4.3.15. DCACHE
  • -
  • 3.4.3.16. MCYCLE
  • -
  • 3.4.3.17. MINSTRET
  • -
  • 3.4.3.18. MHPMCOUNTER[3-31]
  • -
  • 3.4.3.19. MCYCLEH
  • -
  • 3.4.3.20. MINSTRETH
  • -
  • 3.4.3.21. MHPMCOUNTER[3-31]H
  • -
  • 3.4.3.22. MVENDORID
  • -
  • 3.4.3.23. MARCHID
  • -
  • 3.4.3.24. MIMPID
  • -
  • 3.4.3.25. MHARTID
  • -
  • 3.4.3.26. MCONFIGPTR
  • +
  • 3.4.3.12. PMPCFG[0-1]
  • +
  • 3.4.3.13. PMPCFG[2-15]
  • +
  • 3.4.3.14. PMPADDR[0-7]
  • +
  • 3.4.3.15. PMPADDR[8-63]
  • +
  • 3.4.3.16. ICACHE
  • +
  • 3.4.3.17. DCACHE
  • +
  • 3.4.3.18. MCYCLE
  • +
  • 3.4.3.19. MINSTRET
  • +
  • 3.4.3.20. MHPMCOUNTER[3-31]
  • +
  • 3.4.3.21. MCYCLEH
  • +
  • 3.4.3.22. MINSTRETH
  • +
  • 3.4.3.23. MHPMCOUNTER[3-31]H
  • +
  • 3.4.3.24. MVENDORID
  • +
  • 3.4.3.25. MARCHID
  • +
  • 3.4.3.26. MIMPID
  • +
  • 3.4.3.27. MHARTID
  • +
  • 3.4.3.28. MCONFIGPTR
  • @@ -3368,14 +3370,26 @@

    3.4.2. Register Summary

    The mip register is an MXLEN-bit read/write register containing information on pending interrupts.

    -

    0x3a0-0x3a3

    -

    PMPCFG[0-3]

    +

    0x3a0-0x3a1

    +

    PMPCFG[0-1]

    MRW

    PMP configuration register

    -

    0x3b0-0x3bf

    -

    PMPADDR[0-15]

    +

    0x3a2-0x3af

    +

    PMPCFG[2-15]

    +

    MRW

    +

    PMP configuration register

    + + +

    0x3b0-0x3b7

    +

    PMPADDR[0-7]

    +

    MRW

    +

    Physical memory protection address register

    + + +

    0x3b8-0x3ef

    +

    PMPADDR[8-63]

    MRW

    Physical memory protection address register

    @@ -3526,14 +3540,14 @@
    3.4.3.1. MSTATUS

    0x0

    WPRI

    -

    Reserved

    +

    Reserved

    3

    MIE

    0x0

    WLRL

    -

    0 - 1

    +

    0x0 - 0x1

    Stores the state of the machine mode interrupts.

    @@ -3565,7 +3579,7 @@
    3.4.3.1. MSTATUS

    MPIE

    0x0

    WLRL

    -

    0 - 1

    +

    0x0 - 0x1

    Stores the state of the machine mode interrupts prior to the trap.

    @@ -3582,7 +3596,7 @@
    3.4.3.1. MSTATUS

    0x0

    WPRI

    -

    Reserved

    +

    Reserved

    [12:11]

    @@ -3670,7 +3684,7 @@
    3.4.3.1. MSTATUS

    0x0

    WPRI

    -

    Reserved

    +

    Reserved

    31

    @@ -3739,7 +3753,7 @@
    3.4.3.2. MISA

    0x0

    WPRI

    -

    Reserved

    +

    Reserved

    [31:30]

    @@ -3855,7 +3869,7 @@
    3.4.3.3. MIE

    MTIE

    0x0

    WLRL

    -

    0 - 1

    +

    0x0 - 0x1

    Machine Timer Interrupt enable.

    @@ -3887,7 +3901,7 @@
    3.4.3.3. MIE

    MEIE

    0x0

    WLRL

    -

    0 - 1

    +

    0x0 - 0x1

    Machine External Interrupt enable.

    @@ -3904,7 +3918,7 @@
    3.4.3.3. MIE

    0x0

    WPRI

    -

    Reserved

    +

    Reserved

    @@ -4018,7 +4032,7 @@
    3.4.3.5. MSTATUSH

    0x0

    WPRI

    -

    Reserved

    +

    Reserved

    4

    @@ -4058,7 +4072,7 @@
    3.4.3.5. MSTATUSH

    0x0

    WPRI

    -

    Reserved

    +

    Reserved

    9

    @@ -4074,7 +4088,7 @@
    3.4.3.5. MSTATUSH

    0x0

    WPRI

    -

    Reserved

    +

    Reserved

    @@ -4126,7 +4140,7 @@
    3.4.3.6. MHPMEVENT[3-31]

    MHPMEVENT[I]

    0x00000000

    ROCST

    -

    0x00000000

    +

    0x0

    The mhpmevent is a MXLEN-bit event register which controls mhpmcounter3.

    @@ -4285,7 +4299,7 @@
    3.4.3.9. MCAUSE

    EXCEPTION_CODE

    0x0

    WLRL

    -

    0 - 15

    +

    0x0 - 0x8, 0xb

    Encodes the exception code.

    @@ -4346,7 +4360,7 @@
    3.4.3.10. MTVAL

    MTVAL

    0x00000000

    ROCST

    -

    0x00000000

    +

    0x0

    The mtval is a warl register that holds the address of the instruction which caused the exception.

    @@ -4455,7 +4469,7 @@
    3.4.3.11. MIP

    MTIP

    0x0

    ROVAR

    -

    0x1

    +

    0x0 - 0x1

    Machine Timer Interrupt Pending.

    @@ -4487,7 +4501,7 @@
    3.4.3.11. MIP

    MEIP

    0x0

    ROVAR

    -

    0x1

    +

    0x0 - 0x1

    Machine External Interrupt Pending.

    @@ -4504,18 +4518,18 @@
    3.4.3.11. MIP

    0x0

    WPRI

    -

    Reserved

    +

    Reserved

    -
    3.4.3.12. PMPCFG[0-3]
    +
    3.4.3.12. PMPCFG[0-1]
    Address
    -

    0x3a0-0x3a3

    +

    0x3a0-0x3a1

    Reset Value
    @@ -4553,46 +4567,123 @@
    3.4.3.12. PMPCFG[0-3]

    [7:0]

    -

    PMP[I*4 + 0]CFG

    +

    PMP[I*4 +0]CFG

    0x0

    WARL

    -

    0x00 - 0xFF

    +

    masked: & 0x8f | 0x0

    pmp configuration bits

    [15:8]

    -

    PMP[I*4 + 1]CFG

    +

    PMP[I*4 +1]CFG

    0x0

    WARL

    -

    0x00 - 0xFF

    +

    masked: & 0x8f | 0x0

    pmp configuration bits

    [23:16]

    -

    PMP[I*4 + 2]CFG

    +

    PMP[I*4 +2]CFG

    0x0

    WARL

    -

    0x00 - 0xFF

    +

    masked: & 0x8f | 0x0

    pmp configuration bits

    [31:24]

    -

    PMP[I*4 + 3]CFG

    +

    PMP[I*4 +3]CFG

    0x0

    WARL

    -

    0x00 - 0xFF

    +

    masked: & 0x8f | 0x0

    pmp configuration bits

    -
    3.4.3.13. PMPADDR[0-15]
    +
    3.4.3.13. PMPCFG[2-15]
    Address
    -

    0x3b0-0x3bf

    +

    0x3a2-0x3af

    +
    +
    Reset Value
    +
    +

    0x00000000

    +
    +
    Privilege
    +
    +

    MRW

    +
    +
    Description
    +
    +

    PMP configuration register

    +
    +
    +
    + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    BitsField NameReset ValueTypeLegal ValuesDescription

    [7:0]

    PMP[I*4 +0]CFG

    0x0

    ROCST

    0x0

    pmp configuration bits

    [15:8]

    PMP[I*4 +1]CFG

    0x0

    ROCST

    0x0

    pmp configuration bits

    [23:16]

    PMP[I*4 +2]CFG

    0x0

    ROCST

    0x0

    pmp configuration bits

    [31:24]

    PMP[I*4 +3]CFG

    0x0

    ROCST

    0x0

    pmp configuration bits

    +
    +
    +
    3.4.3.14. PMPADDR[0-7]
    +
    +
    +
    Address
    +
    +

    0x3b0-0x3b7

    Reset Value
    @@ -4640,7 +4731,60 @@
    3.4.3.13. PMPADDR[0-15]
    -
    3.4.3.14. ICACHE
    +
    3.4.3.15. PMPADDR[8-63]
    +
    +
    +
    Address
    +
    +

    0x3b8-0x3ef

    +
    +
    Reset Value
    +
    +

    0x00000000

    +
    +
    Privilege
    +
    +

    MRW

    +
    +
    Description
    +
    +

    Physical memory protection address register

    +
    +
    +
    + ++++++++ + + + + + + + + + + + + + + + + + + + + +
    BitsField NameReset ValueTypeLegal ValuesDescription

    [31:0]

    PMPADDR[I]

    0x00000000

    ROCST

    0x0

    Physical memory protection address register

    +
    +
    +
    3.4.3.16. ICACHE
    Address
    @@ -4695,13 +4839,13 @@
    3.4.3.14. ICACHE

    0x0

    WPRI

    -

    Reserved

    +

    Reserved

    -
    3.4.3.15. DCACHE
    +
    3.4.3.17. DCACHE
    Address
    @@ -4756,13 +4900,13 @@
    3.4.3.15. DCACHE

    0x0

    WPRI

    -

    Reserved

    +

    Reserved

    -
    3.4.3.16. MCYCLE
    +
    3.4.3.18. MCYCLE
    Address
    @@ -4815,7 +4959,7 @@
    3.4.3.16. MCYCLE
    -
    3.4.3.17. MINSTRET
    +
    3.4.3.19. MINSTRET
    Address
    @@ -4868,7 +5012,7 @@
    3.4.3.17. MINSTRET
    -
    3.4.3.18. MHPMCOUNTER[3-31]
    +
    3.4.3.20. MHPMCOUNTER[3-31]
    Address
    @@ -4914,14 +5058,14 @@
    3.4.3.18. MHPMCOUNTER[3-31]

    MHPMCOUNTER[I]

    0x00000000

    ROCST

    -

    0x00000000

    +

    0x0

    The mhpmcounter is a 64-bit counter. Returns lower 32 bits in RV32I mode.

    -
    3.4.3.19. MCYCLEH
    +
    3.4.3.21. MCYCLEH
    Address
    @@ -4974,7 +5118,7 @@
    3.4.3.19. MCYCLEH
    -
    3.4.3.20. MINSTRETH
    +
    3.4.3.22. MINSTRETH
    Address
    @@ -5027,7 +5171,7 @@
    3.4.3.20. MINSTRETH
    -
    3.4.3.21. MHPMCOUNTER[3-31]H
    +
    3.4.3.23. MHPMCOUNTER[3-31]H
    Address
    @@ -5073,14 +5217,14 @@
    3.4.3.21. MHPMCOUNTER[3-31]H

    MHPMCOUNTER[I]H

    0x00000000

    ROCST

    -

    0x00000000

    +

    0x0

    The mhpmcounterh returns the upper half word in RV32I systems.

    -
    3.4.3.22. MVENDORID
    +
    3.4.3.24. MVENDORID
    Address
    @@ -5126,14 +5270,14 @@
    3.4.3.22. MVENDORID

    MVENDORID

    0x00000602

    ROCST

    -

    0x00000602

    +

    0x602

    32-bit read-only register providing the JEDEC manufacturer ID of the provider of the core.

    -
    3.4.3.23. MARCHID
    +
    3.4.3.25. MARCHID
    Address
    @@ -5179,14 +5323,14 @@
    3.4.3.23. MARCHID

    MARCHID

    0x00000003

    ROCST

    -

    0x00000003

    +

    0x3

    MXLEN-bit read-only register encoding the base microarchitecture of the hart.

    -
    3.4.3.24. MIMPID
    +
    3.4.3.26. MIMPID
    Address
    @@ -5232,14 +5376,14 @@
    3.4.3.24. MIMPID

    MIMPID

    0x00000000

    ROCST

    -

    0x00000000

    +

    0x0

    Provides a unique encoding of the version of the processor implementation.

    -
    3.4.3.25. MHARTID
    +
    3.4.3.27. MHARTID
    Address
    @@ -5285,14 +5429,14 @@
    3.4.3.25. MHARTID

    MHARTID

    0x00000000

    ROCST

    -

    0x00000000

    +

    0x0

    MXLEN-bit read-only register containing the integer ID of the hardware thread running the code.

    -
    3.4.3.26. MCONFIGPTR
    +
    3.4.3.28. MCONFIGPTR
    Address
    @@ -5338,7 +5482,7 @@
    3.4.3.26. MCONFIGPTR

    MCONFIGPTR

    0x00000000

    ROCST

    -

    0x00000000

    +

    0x0

    MXLEN-bit read-only register that holds the physical address of a configuration data structure.

    @@ -12947,7 +13091,7 @@

    5. Glossary

    From 8dcdf8fb56069ab40a6b5591113fdc828fc8a86b Mon Sep 17 00:00:00 2001 From: Zbigniew Chamski <107464696+zchamski@users.noreply.github.com> Date: Fri, 26 Jul 2024 23:50:51 +0200 Subject: [PATCH 044/183] [riscv-config] Add memory map entry to platform schema and to CV32A65X platform spec. (#2411) --- .../cv32a65x/generated/platform_gen.yaml | 21 ++++++ .../cv32a65x/spec/platform_spec.yaml | 16 ++++- .../riscv_config/schemas/schema_platform.yaml | 66 +++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/config/riscv-config/cv32a65x/generated/platform_gen.yaml b/config/riscv-config/cv32a65x/generated/platform_gen.yaml index f6bd4ca837..3bcee8f92e 100644 --- a/config/riscv-config/cv32a65x/generated/platform_gen.yaml +++ b/config/riscv-config/cv32a65x/generated/platform_gen.yaml @@ -21,6 +21,27 @@ reset: mtime: implemented: true address: 0x20000 +memory_map: + - + memory_region: + name: bootrom + base_addr: 0x10000 + size: 0x10000 + description: System boot ROM + attributes: + read_only: true + cached: false + - + memory_region: + name: dram + base_addr: 0x80000000 + size: 0x40000000 + description: System (D)RAM + attributes: + executable: true + cached: true + non_idempotent: false + read_only: false mtimecmp: implemented: false mtval_condition_writes: diff --git a/config/riscv-config/cv32a65x/spec/platform_spec.yaml b/config/riscv-config/cv32a65x/spec/platform_spec.yaml index fd27af227c..36bee7f1d5 100644 --- a/config/riscv-config/cv32a65x/spec/platform_spec.yaml +++ b/config/riscv-config/cv32a65x/spec/platform_spec.yaml @@ -19,5 +19,19 @@ nmi: reset: label: reset_vector mtime: - implemented: True + implemented: true address: 0x20000 +memory_map: + - memory_region: + name: bootrom + base_addr: 0x10000 + size: 0x10000 + description: System boot ROM + attributes: + read_only: true + cached: false + - memory_region: + name: dram + base_addr: 0x80000000 + size: 0x40000000 + description: System (D)RAM diff --git a/vendor/riscv/riscv-config/riscv_config/schemas/schema_platform.yaml b/vendor/riscv/riscv-config/riscv_config/schemas/schema_platform.yaml index 3e7dddf623..c602e24d26 100644 --- a/vendor/riscv/riscv-config/riscv_config/schemas/schema_platform.yaml +++ b/vendor/riscv/riscv-config/riscv_config/schemas/schema_platform.yaml @@ -326,3 +326,69 @@ zicbo_cache_block_sz: check_with: cache_block_size default: implemented: False + +### +#memory_map +#-------- +# +# - **Description**: Memory map - list of memory regions with their attributes +# - **Constraints**: +# +# - All addresses must be non-negative (0 or higher) +# - All sizes must be non-negative (0 or higher) +# +# - **Examples**: +# +# .. code-block:: yaml +# +# memory_map: +# - memory_region: +# name: bootrom +# base_addr: 0x10000 +# size: 0x1000 +# description: System boot ROM +# attributes: +# read_only: True +# - memory_region: +# name: dram +# base_addr: 0x80000000 +# size: 0x40000000 +# description: Main memory + +memory_map: + type: list + schema: + type: dict + schema: + memory_region: + type: dict + schema: + description: + type: string + default: A homogeneous memory region + name: + type: string + required: True + base_addr: + type: integer + min: 0 + required: True + size: + type: integer + min: 0 + required: True + attributes: + type: dict + schema: + executable: + type: boolean + cached: + type: boolean + non_idempotent: + type: boolean + read_only: + type: boolean + default: { executable: True, cached: True, non_idempotent: False, read_only: False } + required: True + required: True + required: True From bed9a17880b253c01bfce0e15a44f8aa738d5ce1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 07:08:21 +0200 Subject: [PATCH 045/183] Bump verif/core-v-verif from `1e7f049` to `bd42aee` (#2418) --- verif/core-v-verif | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verif/core-v-verif b/verif/core-v-verif index 1e7f049744..bd42aeec16 160000 --- a/verif/core-v-verif +++ b/verif/core-v-verif @@ -1 +1 @@ -Subproject commit 1e7f049744c2d839267b0e4dfe2bb1d377676987 +Subproject commit bd42aeec1687e439d573fdcd360b98139d9304d4 From 4e9abb284cde6a8d0d1c504e4c880dc3ca7af0b8 Mon Sep 17 00:00:00 2001 From: Zbigniew Chamski <107464696+zchamski@users.noreply.github.com> Date: Tue, 30 Jul 2024 09:20:33 +0200 Subject: [PATCH 046/183] [cv32a65x] Remove unsupported Zifencei from riscv-config ISA string. (#2419) --- config/gen_from_riscv_config/cv32a65x/isa/isa.rst | 13 ------------- config/riscv-config/cv32a65x/generated/isa_gen.yaml | 2 +- config/riscv-config/cv32a65x/spec/isa_spec.yaml | 2 +- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/config/gen_from_riscv_config/cv32a65x/isa/isa.rst b/config/gen_from_riscv_config/cv32a65x/isa/isa.rst index 21bf0a004d..2d02548c4e 100644 --- a/config/gen_from_riscv_config/cv32a65x/isa/isa.rst +++ b/config/gen_from_riscv_config/cv32a65x/isa/isa.rst @@ -32,9 +32,6 @@ Instructions +---------------+-----------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Zicsr | RV32Zicsr Control and Status Register Instructions_ | All CSR instructions atomically read-modify-write a single CSR, whose CSR specifier is encoded in the 12-bit csr field of the instruction held in bits 31–20. The immediate forms use a 5-bit zero-extended immediate encoded in the rs1 field. | +---------------+-----------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Zifencei | RVZifencei Instruction Fetch Fence_ | FENCE.I instruction that provides explicit synchronization between writes to instruction memory and instruction fetches on the same hart. | -| | | Currently, this instruction is the only standard mechanism to ensure that stores visible to a hart will also be visible to it instruction fetches. | -+---------------+-----------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Zcb | RV32Zcb Code Size Reduction Instructions_ | Zcb belongs to the group of extensions called RISC-V Code Size Reduction Extension (Zc*). Zc* has become the superset of the Standard C extension adding more 16-bit instructions to the ISA. Zcb includes the 16-bit version of additional Integer (I), Multiply (M), and Bit-Manipulation (Zbb) Instructions. All the Zcb instructions require at least standard C extension support as a prerequisite, along with M and Zbb extensions for the 16-bit version of the respective instructions. | +---------------+-----------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Zba | RVZba Address generation instructions_ | The Zba instructions can be used to accelerate the generation of addresses that index into arrays of basic types (halfword, word, doubleword) using both unsigned word-sized and XLEN-sized indices: a shifted index is added to a base address. The shift and add instructions do a left shift of 1, 2, or 3 because these are commonly found in real-world code and because they can be implemented with a minimal amount of additional hardware beyond that of the simple adder. This avoids lengthening the critical path in implementations. While the shift and add instructions are limited to a maximum left shift of 3, the slli instruction (from the base ISA) can be used to perform similar shifts for indexing into arrays of wider elements. The slli.uw added in this extension can be used when the index is to be interpreted as an unsigned word. | @@ -243,16 +240,6 @@ RV32Zicsr Control and Status Register Instructions | CSRRCI | csrrci rd, csr, uimm[4:0] | t = CSRs[csr]; CSRs[csr] = t & ∼zext(uimm[4:0]); x[rd] = t | NONE | Attempts to access a non-existent CSR raise an illegal instruction exception. Attempts to access a CSR without appropriate privilege level or to write a read-only register also raise illegal instruction exceptions. | Reads the value of the CSR, zero-extends the value to 32 bits, and writes it to integer register rd. The zero-extends immediate value is treated as a bit mask that specifies bit positions to be cleared in the CSR. Any bit that is high in zero-extends immediate will cause the corresponding bit to be set in the CSR, if that CSR bit is writable. Other bits in the CSR are unaffected (though CSRs might have side effects when written). If the uimm[4:0] field is zero, then these instructions will not write to the CSR, and shall not cause any of the side effects that might otherwise occur on a CSR write. | Control and Status Register Operations | +--------+---------------------------+------------------------------------------------------------+------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------+ -RVZifencei Instruction Fetch Fence ----------------------------------- - - -+---------+----------+---------------------+------------------+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+ -| Name | Format | Pseudocode | Invalid_values | Exception_raised | Description | Op Name | -+=========+==========+=====================+==================+====================+==============================================================================================================================================================================================================================================================================================================================================================================================================================+========================+ -| FENCE.I | fence.i | Fence(Store, Fetch) | NONE | NONE | The FENCE.I instruction is used to synchronize the instruction and data streams. RISC-V does not guarantee that stores to instruction memory will be made visible to instruction fetches on the same RISC-V hart until a FENCE.I instruction is executed. A FENCE.I instruction only ensures that a subsequent instruction fetch on a RISC-V hart will see any previous data stores already visible to the same RISC-V hart. | Fetch Fence Operations | -+---------+----------+---------------------+------------------+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------+ - RV32Zcb Code Size Reduction Instructions ---------------------------------------- diff --git a/config/riscv-config/cv32a65x/generated/isa_gen.yaml b/config/riscv-config/cv32a65x/generated/isa_gen.yaml index 65104d3881..7d56fdd492 100644 --- a/config/riscv-config/cv32a65x/generated/isa_gen.yaml +++ b/config/riscv-config/cv32a65x/generated/isa_gen.yaml @@ -16,7 +16,7 @@ hart_ids: [0] hart0: - ISA: RV32IMCZicsr_Zicntr_Zifencei_Zcb_Zba_Zbb_Zbc_Zbs + ISA: RV32IMCZicsr_Zicntr_Zcb_Zba_Zbb_Zbc_Zbs User_Spec_Version: '2.3' supported_xlen: - 32 diff --git a/config/riscv-config/cv32a65x/spec/isa_spec.yaml b/config/riscv-config/cv32a65x/spec/isa_spec.yaml index 2044cdca4e..99b29ef927 100644 --- a/config/riscv-config/cv32a65x/spec/isa_spec.yaml +++ b/config/riscv-config/cv32a65x/spec/isa_spec.yaml @@ -16,7 +16,7 @@ hart_ids: [0] hart0: &hart0 - ISA: RV32IMCZicsr_Zicntr_Zifencei_Zcb_Zba_Zbb_Zbc_Zbs + ISA: RV32IMCZicsr_Zicntr_Zcb_Zba_Zbb_Zbc_Zbs User_Spec_Version: '2.3' supported_xlen: [32] physical_addr_sz: 32 From d4b62d737290400d064ede80512bdfe59f50b680 Mon Sep 17 00:00:00 2001 From: Asmaa Kassimi <163407779+Asmaa-Kassimi@users.noreply.github.com> Date: Tue, 30 Jul 2024 08:22:13 +0100 Subject: [PATCH 047/183] automate lint check process (#2414) --- .gitlab-ci/scripts/report_spyglass_lint.py | 30 ++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci/scripts/report_spyglass_lint.py b/.gitlab-ci/scripts/report_spyglass_lint.py index 2142a58423..24b7da9436 100644 --- a/.gitlab-ci/scripts/report_spyglass_lint.py +++ b/.gitlab-ci/scripts/report_spyglass_lint.py @@ -11,7 +11,7 @@ import re import sys - +import subprocess import report_builder as rb @@ -69,7 +69,7 @@ def compare_summaries(baseline_info, new_info): message = ( f"Count changed from {baseline_dict[key][0]} to {new_dict[key][0]}" ) - comparison_results.append((*key, *value, "PASS", message)) + comparison_results.append((*key, *value, "FAIL", message)) severity_order = {"ERROR": 1, "WARNING": 2, "INFO": 3} comparison_results.sort(key=lambda x: severity_order[x[0]]) @@ -97,6 +97,26 @@ def report_spyglass_lint(comparison_results): report.dump() +def run_diff(ref_file, new_file): + result = subprocess.run( + [ + "diff", + "-I", + r"#\s+Report Name\s+:\s*[^#]*#\s+Report Created by\s*:\s*[^#]*#\s+Report Created on\s*:\s*[^#]*#\s+Working Directory\s*:\s*[^#]*", + ref_file, + new_file, + ], + capture_output=True, + text=True, + ) + if result.stdout: + print("Found differences between reference and new summary") + return False + else: + print("No differences found between reference and new summary") + return True + + if __name__ == "__main__": if len(sys.argv) != 3: print("Usage: python script.py ") @@ -104,7 +124,13 @@ def report_spyglass_lint(comparison_results): summary_ref_results = sys.argv[1] summary_rpt = sys.argv[2] + no_diff = run_diff(summary_ref_results, summary_rpt) + baseline_info = extract_info(summary_ref_results) new_info = extract_info(summary_rpt) comparison_results = compare_summaries(baseline_info, new_info) report_spyglass_lint(comparison_results) + + if not no_diff: + print("Job failed due to differences in summaries") + sys.exit(1) From 6269f72b633a46c11abeb5054ea2cb28eb7ebb20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 15:09:37 +0200 Subject: [PATCH 048/183] Bump verif/core-v-verif from `bd42aee` to `e06bd57` (#2422) --- verif/core-v-verif | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verif/core-v-verif b/verif/core-v-verif index bd42aeec16..e06bd577f5 160000 --- a/verif/core-v-verif +++ b/verif/core-v-verif @@ -1 +1 @@ -Subproject commit bd42aeec1687e439d573fdcd360b98139d9304d4 +Subproject commit e06bd577f5db816015ec16a901e6e8f39cf7d640 From 81671e39fa30b6360e5e691044f022ad9fd2ff7e Mon Sep 17 00:00:00 2001 From: Guillaume Chauvon <94678394+Gchauvon@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:06:24 +0200 Subject: [PATCH 049/183] Fixes and Update CVXIF non regression tests, regression and TB (#2424) --- .gitlab-ci.yml | 18 +++++++ core/cvxif_example/copro_alu.sv | 29 ++++++----- .../cvxif_example_coprocessor.sv | 8 +-- core/cvxif_fu.sv | 4 +- core/issue_read_operands.sv | 43 +++++++++------ corev_apu/src/ariane.sv | 8 +++ spyglass/reference_summary.rpt | 16 +++--- .../custom_instructions_cvxif_1_0_0.rst | 34 +++--------- verif/regress/cvxif_verif_regression.sh | 52 +++++++++++++++++++ verif/regress/smoke-tests.sh | 2 - verif/tb/uvmt/cva6_tb_wrapper.sv | 29 +++-------- verif/tests/custom/cv_xif/cvxif_add_nop.S | 4 +- 12 files changed, 149 insertions(+), 98 deletions(-) create mode 100644 verif/regress/cvxif_verif_regression.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c1368e083d..6f9ecacbce 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -232,6 +232,24 @@ spyglass: - mv spyglass/sg_run_results/cva6_sg_reports/cva6_lint_lint_rtl artifacts/lint_reports - python3 .gitlab-ci/scripts/report_spyglass_lint.py spyglass/reference_summary.rpt artifacts/lint_reports/cva6_lint_lint_rtl/summary.rpt +cvxif-regression: + extends: + - .synthesis_test + variables: + DASHBOARD_JOB_TITLE: "CVXIF non-regression test $DV_SIMULATORS" + DASHBOARD_JOB_DESCRIPTION: "Short tests to challenge most CoreV-X-Interface in testharness" + DASHBOARD_SORT_INDEX: 5 + DASHBOARD_JOB_CATEGORY: "Basic" + COLLECT_SIMU_LOGS: 1 + parallel: + matrix: + - DV_SIMULATORS: + - "veri-testharness,spike" + - "vcs-testharness,spike" + script: + - bash verif/regress/cvxif_verif_regression.sh + - !reference [.simu_after_script] + asic-synthesis: extends: - .synthesis_test diff --git a/core/cvxif_example/copro_alu.sv b/core/cvxif_example/copro_alu.sv index cad4914610..672528454d 100644 --- a/core/cvxif_example/copro_alu.sv +++ b/core/cvxif_example/copro_alu.sv @@ -11,27 +11,28 @@ module copro_alu import cvxif_instr_pkg::*; #( parameter int unsigned NrRgprPorts = 2, + parameter int unsigned XLEN = 32, parameter type hartid_t = logic, parameter type id_t = logic, parameter type registers_t = logic ) ( - input logic clk_i, - input logic rst_ni, - input registers_t registers_i, - input opcode_t opcode_i, - input hartid_t hartid_i, - input id_t id_i, - input logic [ 4:0] rd_i, - output logic [31:0] result_o, // TODO parametrize to 64 bits - output hartid_t hartid_o, - output id_t id_o, - output logic [ 4:0] rd_o, - output logic valid_o, - output logic we_o + input logic clk_i, + input logic rst_ni, + input registers_t registers_i, + input opcode_t opcode_i, + input hartid_t hartid_i, + input id_t id_i, + input logic [ 4:0] rd_i, + output logic [XLEN-1:0] result_o, + output hartid_t hartid_o, + output id_t id_o, + output logic [ 4:0] rd_o, + output logic valid_o, + output logic we_o ); - logic [31:0] result_n, result_q; + logic [XLEN-1:0] result_n, result_q; hartid_t hartid_n, hartid_q; id_t id_n, id_q; logic valid_n, valid_q; diff --git a/core/cvxif_example/cvxif_example_coprocessor.sv b/core/cvxif_example/cvxif_example_coprocessor.sv index 8cc1b15558..614b17e850 100644 --- a/core/cvxif_example/cvxif_example_coprocessor.sv +++ b/core/cvxif_example/cvxif_example_coprocessor.sv @@ -12,6 +12,7 @@ module cvxif_example_coprocessor #( // CVXIF Types parameter int unsigned NrRgprPorts = 2, + parameter int unsigned XLEN = 32, parameter type readregflags_t = logic, parameter type writeregflags_t = logic, parameter type id_t = logic, @@ -25,7 +26,7 @@ module cvxif_example_coprocessor parameter type x_result_t = logic, parameter type cvxif_req_t = logic, parameter type cvxif_resp_t = logic, - localparam type registers_t = logic [NrRgprPorts-1:0][31:0] + localparam type registers_t = logic [NrRgprPorts-1:0][XLEN-1:0] ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low @@ -52,8 +53,8 @@ module cvxif_example_coprocessor hartid_t issue_hartid, hartid; id_t issue_id, id; logic [4:0] issue_rd, rd; - logic [31:0] result; - logic we; + logic [XLEN-1:0] result; + logic we; // Issue and Register interface // Mandatory when X_ISSUE_REGISTER_SPLIT = 0 @@ -117,6 +118,7 @@ module cvxif_example_coprocessor // Result interface copro_alu #( .NrRgprPorts(NrRgprPorts), + .XLEN(XLEN), .hartid_t(hartid_t), .id_t(id_t), .registers_t(registers_t) diff --git a/core/cvxif_fu.sv b/core/cvxif_fu.sv index 255504cd1e..b191fbff4e 100644 --- a/core/cvxif_fu.sv +++ b/core/cvxif_fu.sv @@ -56,7 +56,7 @@ module cvxif_fu assign x_ready_o = 1'b1; // Readyness of cvxif_fu is determined in issue stage by CVXIF issue interface // Result signals - assign x_valid_o = x_illegal_i ? 1'b1 : result_valid_i; + assign x_valid_o = x_illegal_i && x_valid_i ? 1'b1 : result_valid_i; assign x_result_o = result_i.data; assign x_trans_id_o = x_illegal_i ? x_trans_id_i : result_i.id; assign x_we_o = result_i.we; @@ -65,7 +65,7 @@ module cvxif_fu // Handling of illegal instruction exception always_comb begin x_exception_o = '0; // No exception in this interface - if (x_illegal_i) begin + if (x_illegal_i && x_valid_i) begin x_exception_o.valid = '1; x_exception_o.cause = riscv::ILLEGAL_INSTR; if (CVA6Cfg.TvalEn) diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index 9a2ca7a964..390d29c84f 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -394,10 +394,10 @@ module issue_read_operands // check that all operands are available, otherwise stall // forward corresponding register always_comb begin : operands_available - stall_raw = '{default: stall_i}; - stall_rs1 = '{default: stall_i}; - stall_rs2 = '{default: stall_i}; - stall_rs3 = '{default: stall_i}; + stall_raw = '{default: stall_i}; + stall_rs1 = '{default: stall_i}; + stall_rs2 = '{default: stall_i}; + stall_rs3 = '{default: stall_i}; // operand forwarding signals forward_rs1 = '0; forward_rs2 = '0; @@ -417,10 +417,7 @@ module issue_read_operands if (!issue_instr_i[i].use_zimm && ((CVA6Cfg.FpPresent && is_rs1_fpr( issue_instr_i[i].op )) ? rd_clobber_fpr_i[issue_instr_i[i].rs1] != NONE : - rd_clobber_gpr_i[issue_instr_i[i].rs1] != NONE) || - ((CVA6Cfg.CvxifEn && x_issue_valid_o && - x_issue_resp_i.accept && x_issue_resp_i.register_read[0]) && - rd_clobber_gpr_i[issue_instr_i[i].rs1] != NONE)) begin + rd_clobber_gpr_i[issue_instr_i[i].rs1] != NONE)) begin // check if the clobbering instruction is not a CSR instruction, CSR instructions can only // be fetched through the register file since they can't be forwarded // if the operand is available, forward it. CSRs don't write to/from FPR @@ -438,10 +435,7 @@ module issue_read_operands if (((CVA6Cfg.FpPresent && is_rs2_fpr( issue_instr_i[i].op )) ? rd_clobber_fpr_i[issue_instr_i[i].rs2] != NONE : - rd_clobber_gpr_i[issue_instr_i[i].rs2] != NONE) || - ((CVA6Cfg.CvxifEn && - x_issue_valid_o && x_issue_resp_i.accept && x_issue_resp_i.register_read[1]) && - rd_clobber_gpr_i[issue_instr_i[i].rs2] != NONE)) begin + rd_clobber_gpr_i[issue_instr_i[i].rs2] != NONE)) begin // if the operand is available, forward it. CSRs don't write to/from FPR if (rs2_valid_i[i] && (CVA6Cfg.FpPresent && is_rs2_fpr( issue_instr_i[i].op @@ -455,12 +449,9 @@ module issue_read_operands end // Only check clobbered gpr for OFFLOADED instruction - if (((CVA6Cfg.FpPresent && is_imm_fpr( + if ((CVA6Cfg.FpPresent && is_imm_fpr( issue_instr_i[i].op - )) ? rd_clobber_fpr_i[issue_instr_i[i].result[REG_ADDR_SIZE-1:0]] != NONE : 0) || - ((CVA6Cfg.CvxifEn && OPERANDS_PER_INSTR == 3 && - x_issue_valid_o && x_issue_resp_i.accept && x_issue_resp_i.register_read[2]) && - rd_clobber_gpr_i[issue_instr_i[i].result[REG_ADDR_SIZE-1:0]] != NONE)) begin + )) ? rd_clobber_fpr_i[issue_instr_i[i].result[REG_ADDR_SIZE-1:0]] != NONE : 0) begin // if the operand is available, forward it. CSRs don't write to/from FPR so no need to check if (rs3_valid_i[i]) begin forward_rs3[i] = 1'b1; @@ -470,6 +461,24 @@ module issue_read_operands end end end + if (CVA6Cfg.CvxifEn) begin + // Remove unecessary forward and stall in case source register is not needed by coprocessor. + if (x_issue_valid_o && x_issue_resp_i.accept) begin + if (~x_issue_resp_i.register_read[0]) begin + forward_rs1[0] = 1'b0; + stall_rs1[0] = 1'b0; + end + if (~x_issue_resp_i.register_read[1]) begin + forward_rs2[0] = 1'b0; + stall_rs2[0] = 1'b0; + end + if (OPERANDS_PER_INSTR == 3 && ~x_issue_resp_i.register_read[2]) begin + forward_rs3[0] = 1'b0; + stall_rs3[0] = 1'b0; + end + end + stall_raw[0] = stall_rs1[0] || stall_rs2[0] || stall_rs3[0]; + end if (CVA6Cfg.SuperscalarEn) begin if (!issue_instr_i[1].use_zimm && (!CVA6Cfg.FpPresent || (is_rs1_fpr( diff --git a/corev_apu/src/ariane.sv b/corev_apu/src/ariane.sv index de0941f2bb..866c6d6369 100644 --- a/corev_apu/src/ariane.sv +++ b/corev_apu/src/ariane.sv @@ -111,6 +111,7 @@ module ariane import ariane_pkg::*; #( if (CVA6Cfg.CvxifEn) begin : gen_example_coprocessor cvxif_example_coprocessor #( .NrRgprPorts (CVA6Cfg.NrRgprPorts), + .XLEN (CVA6Cfg.XLEN), .readregflags_t (readregflags_t), .writeregflags_t (writeregflags_t), .id_t (id_t), @@ -130,6 +131,13 @@ module ariane import ariane_pkg::*; #( .cvxif_req_i ( cvxif_req ), .cvxif_resp_o ( cvxif_resp ) ); + end else begin + always_comb begin + cvxif_resp = '0; + cvxif_resp.compressed_ready = 1'b1; + cvxif_resp.issue_ready = 1'b1; + cvxif_resp.register_ready = 1'b1; + end end diff --git a/spyglass/reference_summary.rpt b/spyglass/reference_summary.rpt index 84153fe53e..5f432f05a6 100644 --- a/spyglass/reference_summary.rpt +++ b/spyglass/reference_summary.rpt @@ -4,7 +4,7 @@ # This file has been generated by SpyGlass: # Report Name : summary # Report Created by: runner_riscv-public -# Report Created on: Fri Jul 26 00:36:54 2024 +# Report Created on: Thu Aug 1 11:05:24 2024 # Working Directory: /gitlab-runner/runner_riscv-public/builds/yD5zmwgi3/0/riscv-ci/cva6/spyglass # SpyGlass Version : SpyGlass_vS-2021.09-SP2-3 # Policy Name : SpyGlass(SpyGlass_vS-2021.09-SP2-03) @@ -17,9 +17,9 @@ # starc(SpyGlass_vS-2021.09-SP2-03) # starc2005(SpyGlass_vS-2021.09-SP2-03) # -# Total Number of Generated Messages : 1521 +# Total Number of Generated Messages : 1526 # Number of Waived Messages : 2 -# Number of Reported Messages : 1519 +# Number of Reported Messages : 1524 # Number of Overlimit Messages : 0 # # @@ -106,24 +106,24 @@ WARNING STARC05-2.1.3.1 2 Bit-width of function arguments must WARNING STARC05-2.1.4.5 1 Bit-wise operators must be used instead of logic operators in multi-bit operations. -WARNING STARC05-2.1.5.3 1 Conditional expressions should evaluate +WARNING STARC05-2.1.5.3 2 Conditional expressions should evaluate to a scalar. WARNING STARC05-2.2.3.3 14 Do not assign over the same signal in an always construct for sequential circuits -WARNING W224 1 Multi-bit expression found when one-bit +WARNING W224 2 Multi-bit expression found when one-bit expression expected -WARNING W240 322 An input has been declared but is not +WARNING W240 319 An input has been declared but is not read WARNING W263 4 A case expression width does not match case select expression width WARNING W287b 36 Output port of an instance is not connected -WARNING W415a 537 Signal may be multiply assigned (beside +WARNING W415a 544 Signal may be multiply assigned (beside initialization) in the same scope. WARNING W480 3 Loop index is not of type integer WARNING W486 2 Shift overflow - some bits may be lost -WARNING W528 487 A signal or variable is set but never +WARNING W528 486 A signal or variable is set but never read INFO W240 1 An input has been declared but is not read diff --git a/verif/env/uvme/cvxif_vseq/custom_instructions_cvxif_1_0_0.rst b/verif/env/uvme/cvxif_vseq/custom_instructions_cvxif_1_0_0.rst index cbd49d071f..ee53871c86 100644 --- a/verif/env/uvme/cvxif_vseq/custom_instructions_cvxif_1_0_0.rst +++ b/verif/env/uvme/cvxif_vseq/custom_instructions_cvxif_1_0_0.rst @@ -11,7 +11,9 @@ Custom Instruction to challenge CV-X-IF protocol ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This section describes some custom instruction, for stress or challenge the CV-X-IF protocol for the 3 implemented interfaces, it's just to interact with the cvxif agent. -All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). +Most instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). +Except for 4 of them using opcode `MADD, MSUB, NMADD, NMSUB` + - **CUS_NOP**: Custom No Operation **Format**: cus_nop -> |0000000000000000000000000|111_1011| @@ -20,8 +22,6 @@ All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). **Pseudocode**: cus_nop - **Invalid values**: NONE - - **CUS_ADD**: Custom Add **Format**: cus_add rd, rs1, rs2 -> |0000000|rs2|rs1|001|rd|111_1011| @@ -30,8 +30,6 @@ All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). **Pseudocode**: x[rd] = x[rs1] + x[rs2] - **Invalid values**: NONE - - **CUS_DOUBLE_RS1**: Custom Double RS1 **Format**: cus_add rd, rs1, rs1 -> |0000001|rs2|rs1|001|rd|111_1011| @@ -42,8 +40,6 @@ All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). **Pseudocode**: x[rd] = x[rs1] + x[rs1] - **Invalid values**: NONE - - **CUS_DOUBLE_RS2**: Custom Double RS2 **Format**: cus_add rd, rs2, rs2 -> |0000010|rs2|rs1|001|rd|111_1011| @@ -54,8 +50,6 @@ All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). **Pseudocode**: x[rd] = x[rs2] + x[rs2] - **Invalid values**: NONE - - **CUS_ADD_MULTI**: Custom Multicycle Add **Format**: addi rd, rs1, rs2 -> |0000011|rs2|rs1|001|rd|111_1011| @@ -64,8 +58,6 @@ All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). **Pseudocode**: x[rd] = x[rs1] + x[rs2] - **Invalid values**: NONE - - **CUS_ADD_RS3_MADD**: Custom Add with RS3 opcode == MADD **Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_0011| @@ -74,8 +66,6 @@ All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). **Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3] - **Invalid values**: NONE - - **CUS_ADD_RS3_MSUB**: Custom Add with RS3 opcode == MSUB **Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_0111| @@ -84,8 +74,6 @@ All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). **Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3] - **Invalid values**: NONE - - **CUS_ADD_RS3_NMADD**: Custom Add with RS3 opcode == NMADD **Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_1111| @@ -94,18 +82,14 @@ All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). **Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3] - **Invalid values**: NONE - -- **CUS_ADD_RS3_NMADD**: Custom Add with RS3 opcode == NMSUB +- **CUS_ADD_RS3_NMSUB**: Custom Add with RS3 opcode == NMSUB - **Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_0011| + **Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_1011| **Description**: add register rs1, rs2 to rs3, and store the result in rd. **Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3] - **Invalid values**: NONE - - **CUS_ADD_RS3_RTYPE**: Custom Add with RS3, rd is x10 (a0) **Format**: addi a0, rs1, rs2, rs3 -> |0000100|rs2|rs1|001|rs3|100_0011| @@ -114,18 +98,14 @@ All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). **Pseudocode**: x[10] = x[rs1] + x[rs2] + x[rs3] - **Invalid values**: NONE - - **CUS_CNOP** : Custom Compressed NOP - **Format**: cus_cnop -> |111|0|00000|00000|00| + **Format**: cus_cnop -> |111|0|rs1|rs2|00| **Description**: Extends to CUS_NOP : do nothing, it's just a hint instruction. **Pseudocode**: cus_cnop - **Invalid values**: NONE - - **CUS_CADD** : Custom Compressed ADD **Format**: cus_cnop -> |111|1|rs1|rs2|00| @@ -133,5 +113,3 @@ All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011). **Description**: Extends to CUS_ADD rs1, rs2 -> x10 : Add rs1 + rs2 into x10 (a0). **Pseudocode**: cus_cadd - - **Invalid values**: NONE \ No newline at end of file diff --git a/verif/regress/cvxif_verif_regression.sh b/verif/regress/cvxif_verif_regression.sh new file mode 100644 index 0000000000..7661f7c2ad --- /dev/null +++ b/verif/regress/cvxif_verif_regression.sh @@ -0,0 +1,52 @@ +# Copyright 2024 Thales DIS France SAS +# +# Licensed under the Solderpad Hardware Licence, Version 2.0 (the License); +# you may not use this file except in compliance with the License. +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 +# You may obtain a copy of the License at https://solderpad.org/licenses/ +# +# Original Author: Guillaume Chauvon + + +# where are the tools +if ! [ -n "$RISCV" ]; then + echo "Error: RISCV variable undefined" + return +fi + + +# install the required tools +source ./verif/regress/install-verilator.sh +source ./verif/regress/install-spike.sh + +# install the required test suites +source ./verif/regress/install-riscv-tests.sh + +# setup sim env +source ./verif/sim/setup-env.sh + +echo "$SPIKE_INSTALL_DIR$" + +if ! [ -n "$DV_SIMULATORS" ]; then + DV_SIMULATORS=vcs-testharness,spike +fi + +if ! [ -n "$UVM_VERBOSITY" ]; then + export UVM_VERBOSITY=UVM_NONE +fi + +export cvxif=1 # For CVXIF in Spike +export DV_OPTS="$DV_OPTS --issrun_opts=+debug_disable=1+UVM_VERBOSITY=$UVM_VERBOSITY" + + +cd verif/sim/ +make -C ../.. clean +make clean_all +python3 cva6.py --testlist=../tests/testlist_cvxif.yaml --test cvxif_add_nop --iss_yaml cva6.yaml --target cv64a6_imafdc_sv39 --iss=$DV_SIMULATORS $DV_OPTS +make -C ../.. clean +make clean_all +python3 cva6.py --testlist=../tests/testlist_cvxif.yaml --test cvxif_add_nop --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS +make -C ../.. clean +make clean_all + +cd - diff --git a/verif/regress/smoke-tests.sh b/verif/regress/smoke-tests.sh index 68334485a6..7f3a2ebdf8 100644 --- a/verif/regress/smoke-tests.sh +++ b/verif/regress/smoke-tests.sh @@ -36,7 +36,6 @@ if ! [ -n "$UVM_VERBOSITY" ]; then export UVM_VERBOSITY=UVM_NONE fi -export cvxif=1 # For CVXIF in Spike export DV_OPTS="$DV_OPTS --issrun_opts=+debug_disable=1+UVM_VERBOSITY=$UVM_VERBOSITY" CC_OPTS="-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -lgcc" @@ -62,7 +61,6 @@ make clean_all python3 cva6.py --testlist=../tests/testlist_riscv-compliance-cv32a60x.yaml --test rv32i-I-ADD-01 --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS python3 cva6.py --testlist=../tests/testlist_riscv-tests-cv32a60x-p.yaml --test rv32ui-p-add --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS python3 cva6.py --testlist=../tests/testlist_riscv-arch-test-cv32a60x.yaml --test rv32im-cadd-01 --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS --linker=../tests/riscv-arch-test/riscv-target/spike/link.ld -python3 cva6.py --testlist=../tests/testlist_cvxif.yaml --test cvxif_add_nop --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS python3 cva6.py --c_tests ../tests/custom/hello_world/hello_world.c --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS --linker=../tests/custom/common/test.ld --gcc_opts="$CC_OPTS" $DV_OPTS make -C ../.. clean make clean_all diff --git a/verif/tb/uvmt/cva6_tb_wrapper.sv b/verif/tb/uvmt/cva6_tb_wrapper.sv index f13bb39e79..06eb2294c1 100644 --- a/verif/tb/uvmt/cva6_tb_wrapper.sv +++ b/verif/tb/uvmt/cva6_tb_wrapper.sv @@ -114,28 +114,13 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( .noc_resp_i ( axi_ariane_resp ) ); - if (CVA6Cfg.CvxifEn) begin : gen_example_coprocessor - cvxif_example_coprocessor #( - .NrRgprPorts (CVA6Cfg.NrRgprPorts), - .readregflags_t (readregflags_t), - .writeregflags_t (writeregflags_t), - .id_t (id_t), - .hartid_t (hartid_t), - .x_compressed_req_t (x_compressed_req_t), - .x_compressed_resp_t (x_compressed_resp_t), - .x_issue_req_t (x_issue_req_t), - .x_issue_resp_t (x_issue_resp_t), - .x_register_t (x_register_t), - .x_commit_t (x_commit_t), - .x_result_t (x_result_t), - .cvxif_req_t (cvxif_req_t), - .cvxif_resp_t (cvxif_resp_t) - ) i_cvxif_coprocessor ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .cvxif_req_i ( cvxif_req ), - .cvxif_resp_o ( cvxif_resp ) - ); + if (CVA6Cfg.CvxifEn) begin : gen_cvxif_default_response + always_comb begin + cvxif_resp = '0; + cvxif_resp.compressed_ready = 1'b1; + cvxif_resp.issue_ready = 1'b1; + cvxif_resp.register_ready = 1'b1; + end end //---------------------------------------------------------------------------- diff --git a/verif/tests/custom/cv_xif/cvxif_add_nop.S b/verif/tests/custom/cv_xif/cvxif_add_nop.S index 525df19e8d..ead9aa4e93 100644 --- a/verif/tests/custom/cv_xif/cvxif_add_nop.S +++ b/verif/tests/custom/cv_xif/cvxif_add_nop.S @@ -30,7 +30,7 @@ start0: CUS_ADD(01011, 01010, 01011); CUS_ADD(01010, 01011, 01011); lw a0, num1; - CUS_ADD_RS1(01000,01010,01011); + CUS_ADD_RS1(01100,01010,01011); lw a1, num2; CUS_ADD(01010,01011,00000); @@ -48,7 +48,7 @@ branch1: branch2: CUS_ADD(01010, 01010, 01011); lw a0, num1; - CUS_ADD_RS1(01000,01010,01011); + CUS_ADD_RS1(01100,01010,01011); lw a1, num2; CUS_ADD(01010,01011,00000); From 12be3adb81ef37f17ef9ac958fec57e4a01a6dcd Mon Sep 17 00:00:00 2001 From: Asmaa Kassimi <163407779+Asmaa-Kassimi@users.noreply.github.com> Date: Thu, 1 Aug 2024 17:43:13 +0100 Subject: [PATCH 050/183] Solve some of W240 and W415a warnings increased by PMP entries (#2415) --- .gitlab-ci/scripts/report_spyglass_lint.py | 2 + core/load_store_unit.sv | 133 +++++++++++---------- spyglass/reference_summary.rpt | 2 +- spyglass/sg_setup/cva6/cva6_waiver.awl | 1 + 4 files changed, 76 insertions(+), 62 deletions(-) diff --git a/.gitlab-ci/scripts/report_spyglass_lint.py b/.gitlab-ci/scripts/report_spyglass_lint.py index 24b7da9436..23ba6eda18 100644 --- a/.gitlab-ci/scripts/report_spyglass_lint.py +++ b/.gitlab-ci/scripts/report_spyglass_lint.py @@ -94,6 +94,8 @@ def report_spyglass_lint(comparison_results): report = rb.Report() report.add_metric(metric) + for value in metric.values: + print(" | ".join(map(str, value))) report.dump() diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 8e8acd7e81..c1db6e1d9a 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -579,84 +579,94 @@ module load_store_unit end if (data_misaligned) begin - - if (lsu_ctrl.fu == LOAD) begin - misaligned_exception.cause = riscv::LD_ADDR_MISALIGNED; - misaligned_exception.valid = 1'b1; - if (CVA6Cfg.TvalEn) - misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; - if (CVA6Cfg.RVH) begin - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + case (lsu_ctrl.fu) + LOAD: begin + misaligned_exception.cause = riscv::LD_ADDR_MISALIGNED; + misaligned_exception.valid = 1'b1; + if (CVA6Cfg.TvalEn) + misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; + if (CVA6Cfg.RVH) begin + misaligned_exception.tval2 = '0; + misaligned_exception.tinst = lsu_ctrl.tinst; + misaligned_exception.gva = ld_st_v_i; + end end - end - if (lsu_ctrl.fu == STORE) begin - misaligned_exception.cause = riscv::ST_ADDR_MISALIGNED; - misaligned_exception.valid = 1'b1; - if (CVA6Cfg.TvalEn) - misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; - if (CVA6Cfg.RVH) begin - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + STORE: begin + + misaligned_exception.cause = riscv::ST_ADDR_MISALIGNED; + misaligned_exception.valid = 1'b1; + if (CVA6Cfg.TvalEn) + misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; + if (CVA6Cfg.RVH) begin + misaligned_exception.tval2 = '0; + misaligned_exception.tinst = lsu_ctrl.tinst; + misaligned_exception.gva = ld_st_v_i; + end end - end + default: ; + endcase end if (CVA6Cfg.MmuPresent && en_ld_st_translation_i && lsu_ctrl.overflow) begin - if (lsu_ctrl.fu == LOAD) begin - misaligned_exception.cause = riscv::LOAD_PAGE_FAULT; - misaligned_exception.valid = 1'b1; - if (CVA6Cfg.TvalEn) - misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; - if (CVA6Cfg.RVH) begin - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + case (lsu_ctrl.fu) + LOAD: begin + misaligned_exception.cause = riscv::LOAD_PAGE_FAULT; + misaligned_exception.valid = 1'b1; + if (CVA6Cfg.TvalEn) + misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; + if (CVA6Cfg.RVH) begin + misaligned_exception.tval2 = '0; + misaligned_exception.tinst = lsu_ctrl.tinst; + misaligned_exception.gva = ld_st_v_i; + end end - end - if (lsu_ctrl.fu == STORE) begin - misaligned_exception.cause = riscv::STORE_PAGE_FAULT; - misaligned_exception.valid = 1'b1; - if (CVA6Cfg.TvalEn) - misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; - if (CVA6Cfg.RVH) begin - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + STORE: begin + misaligned_exception.cause = riscv::STORE_PAGE_FAULT; + misaligned_exception.valid = 1'b1; + if (CVA6Cfg.TvalEn) + misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; + if (CVA6Cfg.RVH) begin + misaligned_exception.tval2 = '0; + misaligned_exception.tinst = lsu_ctrl.tinst; + misaligned_exception.gva = ld_st_v_i; + end end - end + default: ; + endcase end if (CVA6Cfg.MmuPresent && CVA6Cfg.RVH && en_ld_st_g_translation_i && !en_ld_st_translation_i && lsu_ctrl.g_overflow) begin - if (lsu_ctrl.fu == LOAD) begin - misaligned_exception.cause = riscv::LOAD_GUEST_PAGE_FAULT; - misaligned_exception.valid = 1'b1; - if (CVA6Cfg.TvalEn) - misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; - if (CVA6Cfg.RVH) begin - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + case (lsu_ctrl.fu) + LOAD: begin + misaligned_exception.cause = riscv::LOAD_GUEST_PAGE_FAULT; + misaligned_exception.valid = 1'b1; + if (CVA6Cfg.TvalEn) + misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; + if (CVA6Cfg.RVH) begin + misaligned_exception.tval2 = '0; + misaligned_exception.tinst = lsu_ctrl.tinst; + misaligned_exception.gva = ld_st_v_i; + end end - end - if (lsu_ctrl.fu == STORE) begin - misaligned_exception.cause = riscv::STORE_GUEST_PAGE_FAULT; - misaligned_exception.valid = 1'b1; - if (CVA6Cfg.TvalEn) - misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; - if (CVA6Cfg.RVH) begin - misaligned_exception.tval2 = '0; - misaligned_exception.tinst = lsu_ctrl.tinst; - misaligned_exception.gva = ld_st_v_i; + STORE: begin + misaligned_exception.cause = riscv::STORE_GUEST_PAGE_FAULT; + misaligned_exception.valid = 1'b1; + if (CVA6Cfg.TvalEn) + misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr}; + if (CVA6Cfg.RVH) begin + misaligned_exception.tval2 = '0; + misaligned_exception.tinst = lsu_ctrl.tinst; + misaligned_exception.gva = ld_st_v_i; + end end - end + default: ; + endcase end end + // ------------------ // LSU Control // ------------------ @@ -696,3 +706,4 @@ module load_store_unit endmodule + diff --git a/spyglass/reference_summary.rpt b/spyglass/reference_summary.rpt index 5f432f05a6..b425adb5cb 100644 --- a/spyglass/reference_summary.rpt +++ b/spyglass/reference_summary.rpt @@ -119,7 +119,7 @@ WARNING W263 4 A case expression width does not match case select expression width WARNING W287b 36 Output port of an instance is not connected -WARNING W415a 544 Signal may be multiply assigned (beside +WARNING W415a 538 Signal may be multiply assigned (beside initialization) in the same scope. WARNING W480 3 Loop index is not of type integer WARNING W486 2 Shift overflow - some bits may be lost diff --git a/spyglass/sg_setup/cva6/cva6_waiver.awl b/spyglass/sg_setup/cva6/cva6_waiver.awl index 2445e09b99..44ca186667 100644 --- a/spyglass/sg_setup/cva6/cva6_waiver.awl +++ b/spyglass/sg_setup/cva6/cva6_waiver.awl @@ -11,3 +11,4 @@ waive -file_line {$CVA6_REPO_DIR/common/local/util/sram_cache.sv} {85} -severi waive -file { {$CVA6_REPO_DIR/vendor/pulp-platform/tech_cells_generic/src/rtl/tc_sram.sv} } -severity { {ERROR} } -rule { {ErrorAnalyzeBBox} } waive -file { {$CVA6_REPO_DIR/vendor/pulp-platform/tech_cells_generic/src/rtl/tc_sram.sv} } -severity { {ERROR} } -rule { {SYNTH_5251} } waive -file { {$CVA6_REPO_DIR/common/local/util/tc_sram_wrapper_cache_techno.sv} } -du { {tc_sram_wrapper_cache_techno} } -severity { {ERROR} } -rule { {ErrorAnalyzeBBox} } +waive -rule { {W240} } -comment {Created by akassimi on 26-Jul-2024 18:36:59} From 2e0a202440fb8bae46deebd81a4e8859b8fe71a9 Mon Sep 17 00:00:00 2001 From: Jalali <110232072+AyoubJalali@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:20:47 +0000 Subject: [PATCH 051/183] Add check CSR counter in UVM scoreboard (#2427) --- verif/env/uvme/uvme_cva6_sb.sv | 206 +++++++++++++++++++++++++++++++-- 1 file changed, 195 insertions(+), 11 deletions(-) diff --git a/verif/env/uvme/uvme_cva6_sb.sv b/verif/env/uvme/uvme_cva6_sb.sv index a311183c52..be9b4f529f 100644 --- a/verif/env/uvme/uvme_cva6_sb.sv +++ b/verif/env/uvme/uvme_cva6_sb.sv @@ -46,22 +46,42 @@ class uvme_cva6_sb_c extends uvm_scoreboard; uvma_isacov_instr_c instr_prev; // Store MTVEC value - bit [XLEN-1:0] mtvec_value = 'h0; + bit [XLEN-1:0] mtvec_value = 0; // Store MEPC value bit [XLEN-1:0] mepc_value; // Store trap pc value bit [XLEN-1:0] trap_pc; + bit [XLEN:0] mcycle_update; // Flag to see if mtvec/mepc has been changed - bit mtvec_change = 'h0; - bit mepc_change = 'h0; + bit mtvec_change = 0; + bit mepc_change = 0; static bit has_trap = 0; // Flag for compressed instruction bit trap_is_compressed; + bit signed [XLEN-1:0] cycle; + bit signed [XLEN-1:0] cycleh; + bit signed [XLEN-1:0] write_cycle; + bit signed [XLEN-1:0] read_cycle; + + // can't initialize it by 0 because it's a legal value + bit unsigned [XLEN-1:0] mcycle_read = 'hx; + bit unsigned [XLEN-1:0] mcycle_prev; + + // can't initialize it by 0 because it's a legal value + bit unsigned [XLEN-1:0] mcycleh_read = 'hx; + bit unsigned [XLEN-1:0] mcycleh_prev; + + int mcycle_value; + bit mcycle_change = 0; + bit overflow = 0; + bit write_in_mcycle; + bit write_in_mcycleh; + `uvm_component_utils_begin(uvme_cva6_sb_c) `uvm_field_object(cfg , UVM_DEFAULT) `uvm_field_object(cntxt, UVM_DEFAULT) @@ -110,6 +130,11 @@ class uvme_cva6_sb_c extends uvm_scoreboard; */ extern virtual function void check_mepc(uvma_isacov_instr_c instr); + /** + * Check mcycle[h] CSRs + */ + extern virtual function bit [XLEN:0] check_mcycle_h(uvma_isacov_instr_c instr, uvma_isacov_instr_c instr_prev, int cycle_count); + /** * Creates sub-scoreboard components. */ @@ -237,7 +262,7 @@ function void uvme_cva6_sb_c::check_mepc(uvma_isacov_instr_c instr); if (instr.trap) begin trap_pc = instr.rvfi.pc_rdata[31:0]; - `uvm_info(get_type_name(), $sformatf("Trap PC : 0x%h ", trap_pc), UVM_NONE) + `uvm_info(get_type_name(), $sformatf("Trap PC : 0x%h ", trap_pc), UVM_DEBUG) if (instr.rvfi.insn[1:0] == 2'h3) begin trap_is_compressed = 1'h0; end @@ -289,17 +314,176 @@ function void uvme_cva6_sb_c::check_mepc(uvma_isacov_instr_c instr); endfunction : check_mepc +function bit [XLEN:0] uvme_cva6_sb_c::check_mcycle_h(uvma_isacov_instr_c instr, uvma_isacov_instr_c instr_prev, int cycle_count); + + // Check mcycle value after a CSR read + if (instr_prev == null) return; + + write_in_mcycle = (instr_prev.is_csr_write() && instr_prev.csr_val == 12'hb00) ? 1 : 0; + if (cfg.xlen == 32) begin + write_in_mcycleh = (instr_prev.is_csr_write() && instr_prev.csr_val == 12'hb80) ? 1 : 0; + end + + mcycle_prev = mcycle_read; + mcycle_read = instr.rvfi.name_csrs["mcycle"].rdata; + // Check MCYCLE in a range because of a delay in the UVM RFVI agent while sending an instruction transaction + if (mcycle_read inside {cycle-2 , cycle-1}) begin + `uvm_info(get_type_name(), $sformatf("MCYCLE Match range [0x%h - 0x%h]",cycle-2, cycle-1), UVM_DEBUG) + end + else begin + `uvm_error(get_type_name(), $sformatf("ERROR : MCYCLE value out of range [0x%h - 0x%h]",cycle-2, cycle-1)) + end + + // Ignore check if there's no write into the MCYCLE + if (!write_in_mcycle) begin + // Check if the CSR is really incremented + if (mcycle_read > mcycle_prev) begin + `uvm_info(get_type_name(), $sformatf("MCYCLE is incremented !!"), UVM_DEBUG) + overflow = 0; + end + else if (mcycle_read < mcycle_prev) begin + `uvm_info(get_type_name(), $sformatf("MCYCLE overflow !!"), UVM_DEBUG) + cycleh += 1; + overflow = 1; + end + else begin + `uvm_error(get_type_name(), $sformatf("ERROR : No overflow - MCYCLE isn't incremented")) + overflow = 0; + end + end + + // MCYCLEH is only supported in RV32 + if (cfg.xlen == 32) begin + mcycleh_prev = mcycleh_read; + mcycleh_read = instr.rvfi.name_csrs["mcycleh"].rdata; + // Check MCYCLEH only if there an overflow or a write into the MCYCLEH + if (overflow || write_in_mcycleh) begin + if (mcycleh_read == cycleh) begin + `uvm_info(get_type_name(), $sformatf("MCYCLEH Match value 0x%h", cycleh), UVM_DEBUG) + end + else begin + `uvm_error(get_type_name(), $sformatf("ERROR : MCYCLEH value didn't Match value 0x%h", cycleh)) + end + end + // Ignore check if there's no write into the MCYCLEH or an overflow of MCYCLE is present + if (!write_in_mcycleh && overflow) begin + if (mcycleh_read > mcycleh_prev) begin + `uvm_info(get_type_name(), $sformatf("MCYCLE overflow -> MCYCLEH is incremented !!"), UVM_DEBUG) + end + else if (mcycleh_read < mcycleh_prev) begin + `uvm_info(get_type_name(), $sformatf("MCYCLEH overflow !!"), UVM_DEBUG) + end + else begin + `uvm_error(get_type_name(), $sformatf("ERROR : No overflow - MCYCLEH isn't incremented")) + end + end + // Update the value after a write into the MCYCLEH + if ((instr.is_csr_write() && instr.csr_val == 12'hb80)) begin + if (instr.name == uvma_isacov_pkg::CSRRWI) begin + cycleh = instr.rs1; + `uvm_info(get_type_name(), $sformatf("Write into MCYCLEH the value = 0x%h", cycleh), UVM_DEBUG) + end + if (instr.name == uvma_isacov_pkg::CSRRSI) begin + cycleh = instr.rvfi.rd1_wdata | instr.rs1; + `uvm_info(get_type_name(), $sformatf("Write into MCYCLEH the value = 0x%h", cycleh), UVM_DEBUG) + end + if (instr.name == uvma_isacov_pkg::CSRRCI) begin + cycleh = instr.rvfi.rd1_wdata & ~(instr.rs1); + `uvm_info(get_type_name(), $sformatf("Write into MCYCLEH the value = 0x%h", cycleh), UVM_DEBUG) + end + if (instr.name == uvma_isacov_pkg::CSRRW) begin + cycleh = instr.rs1_value; + `uvm_info(get_type_name(), $sformatf("Write into MCYCLEH the value = 0x%h", cycleh), UVM_DEBUG) + end + if (instr.name == uvma_isacov_pkg::CSRRC) begin + cycleh = instr.rvfi.rd1_wdata & ~(instr.rs1_value); + `uvm_info(get_type_name(), $sformatf("Write into MCYCLEH the value = 0x%h", cycleh), UVM_DEBUG) + end + if (instr.name == uvma_isacov_pkg::CSRRS) begin + cycleh = instr.rvfi.rd1_wdata | instr.rs1_value; + `uvm_info(get_type_name(), $sformatf("Write into MCYCLEH the value = 0x%h", cycleh), UVM_DEBUG) + end + end + end + + // Update the counter value after a write into the MCYCLE + if (instr.group == uvma_isacov_pkg::CSR_GROUP && instr.is_csr_write() && instr.csr_val == 12'hb00) begin + if (instr.name == uvma_isacov_pkg::CSRRWI) begin + mcycle_value = instr.rs1; + mcycle_change = 1'h1; + `uvm_info(get_type_name(), $sformatf("Write into MCYCLE the value = 0x%h", mcycle_value), UVM_DEBUG) + end + if (instr.name == uvma_isacov_pkg::CSRRSI) begin + mcycle_value = instr.rvfi.rd1_wdata | instr.rs1; + mcycle_change = 1'h1; + `uvm_info(get_type_name(), $sformatf("Write into MCYCLE the value = 0x%h", mcycle_value), UVM_DEBUG) + end + if (instr.name == uvma_isacov_pkg::CSRRCI) begin + mcycle_value = instr.rvfi.rd1_wdata & ~(instr.rs1); + mcycle_change = 1'h1; + `uvm_info(get_type_name(), $sformatf("Write into MCYCLE the value = 0x%h", mcycle_value), UVM_DEBUG) + end + if (instr.name == uvma_isacov_pkg::CSRRW) begin + mcycle_value = instr.rs1_value; + mcycle_change = 1'h1; + `uvm_info(get_type_name(), $sformatf("Write into MCYCLE the value = 0x%h", mcycle_value), UVM_DEBUG) + end + if (instr.name == uvma_isacov_pkg::CSRRC) begin + mcycle_value = instr.rvfi.rd1_wdata & ~(instr.rs1_value); + mcycle_change = 1'h1; + `uvm_info(get_type_name(), $sformatf("Write into MCYCLE the value = 0x%h", mcycle_value), UVM_DEBUG) + end + if (instr.name == uvma_isacov_pkg::CSRRS) begin + mcycle_value = instr.rvfi.rd1_wdata | instr.rs1_value; + mcycle_change = 1'h1; + `uvm_info(get_type_name(), $sformatf("Write into MCYCLE the value = 0x%h", mcycle_value), UVM_DEBUG) + end + end + else begin + mcycle_change = 0; + end + + return {mcycle_change, mcycle_value}; + +endfunction : check_mcycle_h + task uvme_cva6_sb_c::run_phase(uvm_phase phase); super.run_phase(phase); - forever begin - instr_trn_fifo.get(instr_trn); - check_pc_trap(instr_trn.instr, instr_prev); - check_mepc(instr_trn.instr); - // Move instructions down the pipeline - instr_prev = instr_trn.instr; - end + fork + begin + forever begin + if (!cntxt.clknrst_cntxt.vif.reset_n) begin + cycle = 0; + end + else begin + if (mcycle_update[XLEN]) begin + read_cycle = write_cycle; + write_cycle = cycle; + cycle = mcycle_update + 2; + mcycle_update[XLEN] = 0; + end + else begin + read_cycle = write_cycle; + write_cycle = cycle; + cycle = cycle + 1; + end + end + @(posedge cntxt.clknrst_cntxt.vif.clk); + end + end + begin + forever begin + instr_trn_fifo.get(instr_trn); + check_pc_trap(instr_trn.instr, instr_prev); + check_mepc(instr_trn.instr); + mcycle_update = check_mcycle_h(instr_trn.instr, instr_prev, read_cycle); + // Move instructions down the pipeline + instr_prev = instr_trn.instr; + end + end + join_none endtask : run_phase From 14fd617455d98b77d8f02363dfe49e2a7d7fdf78 Mon Sep 17 00:00:00 2001 From: JeanRochCoulon Date: Fri, 2 Aug 2024 06:47:03 +0200 Subject: [PATCH 052/183] Fix expected_synth.yml (#2428) Difficult to adjust it all the time ! --- .gitlab-ci/expected_synth.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci/expected_synth.yml b/.gitlab-ci/expected_synth.yml index f0f9d8ef93..e57728dc9c 100644 --- a/.gitlab-ci/expected_synth.yml +++ b/.gitlab-ci/expected_synth.yml @@ -1,2 +1,2 @@ cv32a65x: - gates: 171002 + gates: 171990 From ce4b25c51a54fcba08f21027ab41c1af66c7f6c1 Mon Sep 17 00:00:00 2001 From: JeanRochCoulon Date: Fri, 2 Aug 2024 08:42:11 +0200 Subject: [PATCH 053/183] [HOT FIX] fix is_inside_execute (#2429) fix #2385 --- core/include/config_pkg.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index 7e82dadaac..30e071fd54 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -391,7 +391,7 @@ package config_pkg; function automatic logic is_inside_execute_regions(cva6_cfg_t Cfg, logic [63:0] address); // if we don't specify any region we assume everything is accessible logic [NrMaxRules-1:0] pass; - if (Cfg.NrExecuteRegionRules == 0) begin + if (Cfg.NrExecuteRegionRules != 0) begin pass = '0; for (int unsigned k = 0; k < Cfg.NrExecuteRegionRules; k++) begin pass[k] = range_check(Cfg.ExecuteRegionAddrBase[k], Cfg.ExecuteRegionLength[k], address); From 0c60bc6e3dccd61753aeb2176fc1d586b283578b Mon Sep 17 00:00:00 2001 From: xiaoweish <106955484+xiaoweish@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:50:50 +0800 Subject: [PATCH 054/183] Add debug_test to cva6 (#2339) --- verif/env/uvme/uvme_cva6_cntxt.sv | 3 + verif/env/uvme/uvme_cva6_constants.sv | 28 + verif/env/uvme/uvme_cva6_env.sv | 10 + verif/env/uvme/uvme_cva6_pkg.sv | 2 + verif/env/uvme/uvml_mem_vp.sv | 190 ++++++ verif/regress/debug_test.sh | 75 ++ verif/tb/uvmt/cva6_tb_wrapper.sv | 3 +- verif/tb/uvmt/uvmt_cva6.flist | 1 + verif/tb/uvmt/uvmt_cva6_dut_wrap.sv | 2 + verif/tb/uvmt/uvmt_cva6_tb.sv | 6 +- verif/tests/custom/debug_test/bsp/.gitignore | 1 + verif/tests/custom/debug_test/bsp/Makefile | 36 + verif/tests/custom/debug_test/bsp/README.md | 166 +++++ verif/tests/custom/debug_test/bsp/bsp.h | 184 +++++ .../tests/custom/debug_test/bsp/corev_uvmt.h | 76 +++ verif/tests/custom/debug_test/bsp/crt0.S | 82 +++ verif/tests/custom/debug_test/bsp/handlers.S | 345 ++++++++++ verif/tests/custom/debug_test/bsp/link.ld | 321 +++++++++ .../custom/debug_test/bsp/link_corev-dv.ld | 288 ++++++++ verif/tests/custom/debug_test/bsp/syscalls.c | 379 +++++++++++ verif/tests/custom/debug_test/bsp/vectors.S | 55 ++ verif/tests/custom/debug_test/debug_test.c | 553 +++++++++++++++ verif/tests/custom/debug_test/debugger.S | 642 ++++++++++++++++++ .../custom/debug_test/debugger_exception.S | 77 +++ verif/tests/custom/debug_test/handlers.S | 349 ++++++++++ verif/tests/custom/debug_test/single_step.S | 233 +++++++ verif/tests/custom/debug_test/test.yaml | 11 + verif/tests/custom/debug_test/trigger_code.S | 160 +++++ .../uvmt/base-tests/uvmt_cva6_base_test.sv | 6 + .../uvmt/base-tests/uvmt_cva6_test_cfg.sv | 8 + 30 files changed, 4290 insertions(+), 2 deletions(-) create mode 100644 verif/env/uvme/uvml_mem_vp.sv create mode 100644 verif/regress/debug_test.sh create mode 100644 verif/tests/custom/debug_test/bsp/.gitignore create mode 100644 verif/tests/custom/debug_test/bsp/Makefile create mode 100644 verif/tests/custom/debug_test/bsp/README.md create mode 100644 verif/tests/custom/debug_test/bsp/bsp.h create mode 100644 verif/tests/custom/debug_test/bsp/corev_uvmt.h create mode 100644 verif/tests/custom/debug_test/bsp/crt0.S create mode 100644 verif/tests/custom/debug_test/bsp/handlers.S create mode 100644 verif/tests/custom/debug_test/bsp/link.ld create mode 100644 verif/tests/custom/debug_test/bsp/link_corev-dv.ld create mode 100644 verif/tests/custom/debug_test/bsp/syscalls.c create mode 100644 verif/tests/custom/debug_test/bsp/vectors.S create mode 100644 verif/tests/custom/debug_test/debug_test.c create mode 100644 verif/tests/custom/debug_test/debugger.S create mode 100644 verif/tests/custom/debug_test/debugger_exception.S create mode 100644 verif/tests/custom/debug_test/handlers.S create mode 100644 verif/tests/custom/debug_test/single_step.S create mode 100644 verif/tests/custom/debug_test/test.yaml create mode 100644 verif/tests/custom/debug_test/trigger_code.S diff --git a/verif/env/uvme/uvme_cva6_cntxt.sv b/verif/env/uvme/uvme_cva6_cntxt.sv index 90a5f474fb..3d07cae042 100644 --- a/verif/env/uvme/uvme_cva6_cntxt.sv +++ b/verif/env/uvme/uvme_cva6_cntxt.sv @@ -39,6 +39,9 @@ class uvme_cva6_cntxt_c extends uvm_object; // Memory modelling rand uvml_mem_cva6 mem; + // Handle to debug_req interface + virtual uvma_debug_if debug_vif; + // Events uvm_event sample_cfg_e; uvm_event sample_cntxt_e; diff --git a/verif/env/uvme/uvme_cva6_constants.sv b/verif/env/uvme/uvme_cva6_constants.sv index c77ec83746..9d04dcff7b 100644 --- a/verif/env/uvme/uvme_cva6_constants.sv +++ b/verif/env/uvme/uvme_cva6_constants.sv @@ -27,4 +27,32 @@ parameter uvme_cva6_debug_default_clk_period = 10_000; // 10ns parameter XLEN = 32; parameter ILEN = 32; + +// Control how often to print core scoreboard checked heartbeat messages +parameter PC_CHECKED_HEARTBEAT = 10_000; + +// Map the virtual peripheral registers +parameter CV_VP_REGISTER_BASE = 32'h8080_0000; +parameter CV_VP_REGISTER_SIZE = 32'h0000_1000; + +parameter CV_VP_VIRTUAL_PRINTER_OFFSET = 32'h0000_0000; +parameter CV_VP_RANDOM_NUM_OFFSET = 32'h0000_0040; +parameter CV_VP_CYCLE_COUNTER_OFFSET = 32'h0000_0080; +parameter CV_VP_STATUS_FLAGS_OFFSET = 32'h0000_00c0; +parameter CV_VP_FENCEI_TAMPER_OFFSET = 32'h0000_0100; +parameter CV_VP_INTR_TIMER_OFFSET = 32'h0000_0140; +parameter CV_VP_DEBUG_CONTROL_OFFSET = 32'h0000_0180; +parameter CV_VP_OBI_SLV_RESP_OFFSET = 32'h0000_01c0; +parameter CV_VP_SIG_WRITER_OFFSET = 32'h0000_0200; + +parameter CV_VP_VIRTUAL_PRINTER_BASE = CV_VP_REGISTER_BASE + CV_VP_VIRTUAL_PRINTER_OFFSET; +parameter CV_VP_RANDOM_NUM_BASE = CV_VP_REGISTER_BASE + CV_VP_RANDOM_NUM_OFFSET; +parameter CV_VP_CYCLE_COUNTER_BASE = CV_VP_REGISTER_BASE + CV_VP_CYCLE_COUNTER_OFFSET; +parameter CV_VP_STATUS_FLAGS_BASE = CV_VP_REGISTER_BASE + CV_VP_STATUS_FLAGS_OFFSET; +parameter CV_VP_INTR_TIMER_BASE = CV_VP_REGISTER_BASE + CV_VP_INTR_TIMER_OFFSET; +parameter CV_VP_DEBUG_CONTROL_BASE = CV_VP_REGISTER_BASE + CV_VP_DEBUG_CONTROL_OFFSET; +parameter CV_VP_OBI_SLV_RESP_BASE = CV_VP_REGISTER_BASE + CV_VP_OBI_SLV_RESP_OFFSET; +parameter CV_VP_SIG_WRITER_BASE = CV_VP_REGISTER_BASE + CV_VP_SIG_WRITER_OFFSET; +parameter CV_VP_FENCEI_TAMPER_BASE = CV_VP_REGISTER_BASE + CV_VP_FENCEI_TAMPER_OFFSET; + `endif // __UVME_CVA6_CONSTANTS_SV__ diff --git a/verif/env/uvme/uvme_cva6_env.sv b/verif/env/uvme/uvme_cva6_env.sv index 99268590ed..fc4fc90035 100644 --- a/verif/env/uvme/uvme_cva6_env.sv +++ b/verif/env/uvme/uvme_cva6_env.sv @@ -51,6 +51,9 @@ class uvme_cva6_env_c extends uvm_env; // Handle to agent switch interface virtual uvmt_axi_switch_intf axi_switch_vif; + // Handle to debug_req interface + virtual uvma_debug_if debug_vif; + //CSR register model cva6_csr_reg_block csr_reg_block; cva6_csr_reg_adapter csr_reg_adapter; @@ -323,6 +326,13 @@ function void uvme_cva6_env_c::retrieve_vif(); axi_switch_vif.active <= 1; end + if (!uvm_config_db#(virtual uvma_debug_if)::get(this, "", "debug_vif", debug_vif)) begin + `uvm_fatal("VIF", $sformatf("Could not find vif handle of type %s in uvm_config_db", $typename(debug_vif))) + end + else begin + cntxt.debug_vif = debug_vif; + `uvm_info("VIF", $sformatf("Found vif handle of type %s in uvm_config_db", $typename(debug_vif)), UVM_DEBUG) + end endfunction : retrieve_vif function void uvme_cva6_env_c::connect_predictor(); diff --git a/verif/env/uvme/uvme_cva6_pkg.sv b/verif/env/uvme/uvme_cva6_pkg.sv index 4f700620e8..220521afc1 100644 --- a/verif/env/uvme/uvme_cva6_pkg.sv +++ b/verif/env/uvme/uvme_cva6_pkg.sv @@ -79,6 +79,8 @@ package uvme_cva6_pkg; `include "uvme_cva6_constants.sv" `include "uvme_cva6_tdefs.sv" + `include "uvml_mem_vp.sv" + // Objects `include "uvma_cva6_core_cntrl_cntxt.sv" `include "uvme_cva6_cfg.sv" diff --git a/verif/env/uvme/uvml_mem_vp.sv b/verif/env/uvme/uvml_mem_vp.sv new file mode 100644 index 0000000000..87691b87f6 --- /dev/null +++ b/verif/env/uvme/uvml_mem_vp.sv @@ -0,0 +1,190 @@ +// Copyright 2024 CoreLab Tech +// +// Licensed under the Solderpad Hardware Licence, 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 +// +// https://solderpad.org/licenses/ +// +// 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 WITH SHL-2.0 + +`ifndef __UVML_MEM_VP_SV__ +`define __UVML_MEM_VP_SV__ + +typedef class uvme_cva6_cntxt_c; + +/** + * Memory model + */ +class uvml_mem_vp_c#(int XLEN=`UVML_MEM_XLEN) extends uvml_mem_c#(XLEN); + + int vp_log; + uvme_cva6_cntxt_c cntxt; + + `uvm_object_param_utils_begin(uvml_mem_vp_c#(XLEN)); + `uvm_field_object(cntxt, UVM_DEFAULT) + `uvm_object_utils_end + + /** + * Default constructor + */ + extern function new(string name="uvml_mem_vp_c"); + + /** + * Write to memory array + */ + extern virtual function void write(bit[XLEN-1:0] addr, reg[7:0] data); + + extern virtual function void post_write(bit[XLEN-1:0] addr, reg[7:0] data); + + /** + * Read from memory array in 32 bit. + */ + extern virtual function reg[31:0] read_word(bit[XLEN-1:0] addr); + + /** + * Start delayed debug thread + */ + extern virtual task debug(bit dbg_req_value, + bit request_mode, + bit rand_pulse_duration, + bit rand_start_delay, + int unsigned dbg_pulse_duration, + int unsigned start_delay); + + /** + * Wait for clocks + */ + extern virtual task wait_n_clocks(int unsigned n); + + /** + * Asserts the actual interrupt wires + */ + extern virtual task set_debug_req(bit debug_req); + +endclass : uvml_mem_vp_c + + +function uvml_mem_vp_c::new(string name="uvml_mem_vp_c"); + + super.new(name); + vp_log = $fopen("vp.log", "w"); + +endfunction : new + +function void uvml_mem_vp_c::write(bit[XLEN-1:0] addr, reg[7:0] data); + + super.write(addr, data); + + post_write(addr, data); + +endfunction : write + +function reg[31:0] uvml_mem_vp_c::read_word(bit[XLEN-1:0] addr); + return {read(addr+'h3), read(addr+'h2), read(addr+'h1), read(addr+'h0)}; +endfunction : read_word + +function void uvml_mem_vp_c::post_write(bit[XLEN-1:0] addr, reg[7:0] data); + reg[31:0] wval; + if ( addr==(CV_VP_DEBUG_CONTROL_BASE+32'h3) ) begin + wval = read_word(CV_VP_DEBUG_CONTROL_BASE); + `uvm_info("UVML_MEM_VP", $sformatf("Call to virtual peripheral 'vp_debug_control', wval=0x%0x", wval), UVM_HIGH) + debug(.dbg_req_value (wval[31]), + .request_mode (wval[30]), + .rand_pulse_duration (wval[29]), + .dbg_pulse_duration (wval[28:16]), + .rand_start_delay (wval[15]), + .start_delay (wval[14:0])); + end + else if ( addr==CV_VP_VIRTUAL_PRINTER_BASE ) begin + wval=0; + wval=data; + `uvm_info("VP_VSEQ", $sformatf("Call to virtual peripheral 'virtual_printer', wval=0x%0x", wval), UVM_HIGH) + // Allow $write as this acts as a UART/serial printer + // $write("%c", wval); + $fwrite(vp_log, $sformatf("%c", wval)); + end + else if ( addr==CV_VP_STATUS_FLAGS_BASE ) begin + wval = read_word(CV_VP_STATUS_FLAGS_BASE); + // TODO if (wval == 'd123456789) begin + // TODO `uvm_info("VP_VSEQ", "virtual peripheral: TEST PASSED", UVM_DEBUG) + // TODO cntxt.vp_status_vif.tests_passed = 1; + // TODO cntxt.vp_status_vif.exit_valid = 1; + // TODO cntxt.vp_status_vif.exit_value = 0; + // TODO end + // TODO else if (wval == 'd1) begin + // TODO cntxt.vp_status_vif.tests_failed = 1; + // TODO cntxt.vp_status_vif.exit_valid = 1; + // TODO cntxt.vp_status_vif.exit_value = 1; + // TODO end + end + else if ( addr==(CV_VP_STATUS_FLAGS_BASE+'h4) ) begin + wval = read_word(CV_VP_STATUS_FLAGS_BASE+'h4); + `uvm_info("VP_VSEQ", "virtual peripheral: END OF SIM", UVM_DEBUG) + // TODO cntxt.vp_status_vif.exit_valid = 1; + // TODO cntxt.vp_status_vif.exit_value = wval; + end + +endfunction : post_write + +task uvml_mem_vp_c::debug(bit dbg_req_value, + bit request_mode, + bit rand_pulse_duration, + bit rand_start_delay, + int unsigned dbg_pulse_duration, + int unsigned start_delay); + fork + begin + if(!uvm_config_db#(uvme_cva6_cntxt_c)::get(uvm_root::get(), "uvm_test_top.env", "cntxt", this.cntxt)) begin + `uvm_fatal("UVML_MEM_VP", "cva6 cntxt object handle not found") + end + cntxt.debug_vif.is_active = 1; + if (rand_start_delay) begin + wait_n_clocks($urandom_range(start_delay, 0)); + end + else begin + wait_n_clocks(start_delay); + end + + if (request_mode) begin + set_debug_req(dbg_req_value); + + if (rand_pulse_duration) begin + if (dbg_pulse_duration == 0) + wait_n_clocks($urandom_range(128,1)); + else + wait_n_clocks($urandom_range(dbg_pulse_duration, 1)); + end + else begin + wait_n_clocks(dbg_pulse_duration); + end + set_debug_req(!dbg_req_value); + end + else begin + set_debug_req(dbg_req_value); + end + end + join_none + +endtask : debug + +task uvml_mem_vp_c::wait_n_clocks(int unsigned n); + + repeat (n) @(cntxt.debug_vif.mon_cb); + +endtask : wait_n_clocks + +task uvml_mem_vp_c::set_debug_req(bit debug_req); + + cntxt.debug_vif.drv_cb.debug_drv <= debug_req; + +endtask : set_debug_req + +`endif // __UVML_MEM_VP_SV__ + diff --git a/verif/regress/debug_test.sh b/verif/regress/debug_test.sh new file mode 100644 index 0000000000..ff1773aa81 --- /dev/null +++ b/verif/regress/debug_test.sh @@ -0,0 +1,75 @@ +# Copyright 2024 CoreLab Tech +# +# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 +# You may obtain a copy of the License at https://solderpad.org/licenses/ + +noprint="" +if [ "$1" == "--no-print" ]; then + noprint="-DHAS_PRINTF=0" +fi + +# where are the tools +if ! [ -n "$RISCV" ]; then + echo "Error: RISCV variable undefined" + return +fi + +source ./verif/sim/setup-env.sh + +DV_SIMULATORS=vcs-uvm + +if ! [ -n "$UVM_VERBOSITY" ]; then + export UVM_VERBOSITY=UVM_NONE +fi + +export DV_OPTS="$DV_OPTS --issrun_opts=+UVM_VERBOSITY=$UVM_VERBOSITY" +export DV_OPTS="$DV_OPTS --issrun_opts=+mem_vp_enabled=1" + +make clean +make -C verif/sim clean_all + +cd verif/sim/ + +src0=../tests/custom/debug_test/debug_test.c +srcA=( + ../tests/custom/debug_test/debugger_exception.S + ../tests/custom/debug_test/debugger.S + ../tests/custom/debug_test/handlers.S + ../tests/custom/debug_test/single_step.S + ../tests/custom/debug_test/trigger_code.S + ../tests/custom/debug_test/bsp/crt0.S + ../tests/custom/debug_test/bsp/syscalls.c + ../tests/custom/debug_test/bsp/vectors.S +) + +cflags_opt=( + -mabi=ilp32 \ + -march=rv32imac_zicsr_zifencei \ + -Os -g -static -Wall -pedantic \ + -nostartfiles \ + -Wunused-variable \ + -mno-relax +) + +cflags=( + "${cflags_opt[@]}" + "-DCOMPILER_FLAGS='\"${cflags_opt[*]}\"'" + -I../tests/custom/debug_test/ + -I../tests/custom/debug_test/bsp +) + +default_target="cv32a6_imac_sv0" + +link_ld="../tests/custom/debug_test/bsp/link.ld" + +set -x +python3 cva6.py \ + --target "$default_target" \ + --iss="$DV_SIMULATORS" \ + --iss_yaml=cva6.yaml \ + --c_tests "$src0" \ + --gcc_opts "${srcA[*]} ${cflags[*]}" \ + --linker "$link_ld" \ + $DV_OPTS -v diff --git a/verif/tb/uvmt/cva6_tb_wrapper.sv b/verif/tb/uvmt/cva6_tb_wrapper.sv index 06eb2294c1..5a5a38436b 100644 --- a/verif/tb/uvmt/cva6_tb_wrapper.sv +++ b/verif/tb/uvmt/cva6_tb_wrapper.sv @@ -73,6 +73,7 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o, output rvfi_csr_t rvfi_csr_o, input logic [2:0] irq_i, + uvma_debug_if debug_if, uvma_axi_intf axi_slave, uvmt_axi_switch_intf axi_switch_vif, uvmt_default_inputs_intf default_inputs_vif @@ -106,7 +107,7 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( .irq_i ( {1'b0, irq_i[0]} ), .ipi_i ( irq_i[1] ), .time_irq_i ( irq_i[2] ), - .debug_req_i ( default_inputs_vif.debug_req ), + .debug_req_i ( debug_if.debug_req ), .rvfi_probes_o ( rvfi_probes ), .cvxif_req_o ( cvxif_req ), .cvxif_resp_i ( cvxif_resp ), diff --git a/verif/tb/uvmt/uvmt_cva6.flist b/verif/tb/uvmt/uvmt_cva6.flist index 1b3096b1bc..d4f7651108 100644 --- a/verif/tb/uvmt/uvmt_cva6.flist +++ b/verif/tb/uvmt/uvmt_cva6.flist @@ -23,6 +23,7 @@ // Agents -f ${DV_UVMA_CLKNRST_PATH}/uvma_clknrst_pkg.flist +-f ${DV_UVMA_DEBUG_PATH}/uvma_debug_pkg.flist -f ${DV_UVMA_AXI_PATH}/src/uvma_axi_pkg.flist -f ${DV_UVMA_CORE_CNTRL_PATH}/uvma_core_cntrl_pkg.flist -f ${DV_UVMA_RVFI_PATH}/uvma_rvfi_pkg.flist diff --git a/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv b/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv index 67508f2006..500afcf45e 100644 --- a/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv +++ b/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv @@ -34,6 +34,7 @@ module uvmt_cva6_dut_wrap # ( uvmt_default_inputs_intf default_inputs_vif, uvme_cva6_core_cntrl_if core_cntrl_if, uvma_interrupt_if interrupt_vif, + uvma_debug_if debug_if, output logic[31:0] tb_exit_o, output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o, output rvfi_csr_t rvfi_csr_o @@ -59,6 +60,7 @@ module uvmt_cva6_dut_wrap # ( .rst_ni ( clknrst_if.reset_n ), .boot_addr_i ( boot_addr ), .irq_i ( interrupt_vif.irq ), + .debug_if ( debug_if ), .axi_slave ( axi_if ), .axi_switch_vif ( axi_switch_vif ), .default_inputs_vif ( default_inputs_vif ), diff --git a/verif/tb/uvmt/uvmt_cva6_tb.sv b/verif/tb/uvmt/uvmt_cva6_tb.sv index 5e100905ce..9768c0a213 100644 --- a/verif/tb/uvmt/uvmt_cva6_tb.sv +++ b/verif/tb/uvmt/uvmt_cva6_tb.sv @@ -59,7 +59,7 @@ module uvmt_cva6_tb; // Agent interfaces uvma_clknrst_if clknrst_if(); // clock and resets from the clknrst agent - + uvma_debug_if debug_if(); // debug uvma_axi_intf axi_if( .clk(clknrst_if.clk), .rst_n(clknrst_if.reset_n) @@ -96,6 +96,8 @@ module uvmt_cva6_tb; ); // Status information generated by the Virtual Peripherals in the DUT WRAPPER memory. uvmt_tb_exit_if tb_exit_if ( .tb_exit_o()); + assign debug_if.clk = clknrst_if.clk; + assign debug_if.reset_n = clknrst_if.reset_n; /** * DUT WRAPPER instance */ @@ -113,6 +115,7 @@ module uvmt_cva6_tb; .NUM_WORDS (NUM_WORDS) ) cva6_dut_wrap ( .clknrst_if(clknrst_if), + .debug_if(debug_if), .axi_if (axi_if), .axi_switch_vif (axi_switch_vif), .default_inputs_vif (default_inputs_vif), @@ -361,6 +364,7 @@ module uvmt_cva6_tb; // Add interfaces handles to uvm_config_db uvm_config_db#(virtual uvma_clknrst_if )::set(.cntxt(null), .inst_name("*.env.clknrst_agent"), .field_name("vif"), .value(clknrst_if)); + uvm_config_db#(virtual uvma_debug_if )::set(.cntxt(null), .inst_name("*.env"), .field_name("debug_vif"), .value(debug_if)); uvm_config_db#(virtual uvma_axi_intf )::set(.cntxt(null), .inst_name("*"), .field_name("axi_vif"), .value(axi_if)); uvm_config_db#(virtual uvmt_axi_switch_intf )::set(.cntxt(null), .inst_name("*.env"), .field_name("axi_switch_vif"), .value(axi_switch_vif)); uvm_config_db#(virtual uvmt_rvfi_if#( .CVA6Cfg(CVA6Cfg), .rvfi_instr_t(rvfi_instr_t), .rvfi_csr_t (rvfi_csr_t)))::set(.cntxt(null), .inst_name("*"), .field_name("rvfi_vif"), .value(rvfi_if)); diff --git a/verif/tests/custom/debug_test/bsp/.gitignore b/verif/tests/custom/debug_test/bsp/.gitignore new file mode 100644 index 0000000000..c0a1f349c4 --- /dev/null +++ b/verif/tests/custom/debug_test/bsp/.gitignore @@ -0,0 +1 @@ +libcv-verif.a diff --git a/verif/tests/custom/debug_test/bsp/Makefile b/verif/tests/custom/debug_test/bsp/Makefile new file mode 100644 index 0000000000..b34ad75cea --- /dev/null +++ b/verif/tests/custom/debug_test/bsp/Makefile @@ -0,0 +1,36 @@ +CV_SW_TOOLCHAIN ?= /opt/riscv +RISCV ?= $(CV_SW_TOOLCHAIN) +RISCV_EXE_PREFIX ?= $(RISCV)/bin/riscv32-unknown-elf- +RISCV_CC ?= gcc +RISCV_GCC = $(RISCV_EXE_PREFIX)$(RISCV_CC) +RISCV_AR = $(RISCV_EXE_PREFIX)ar +RISCV_MARCH ?= rv32im_zca +SRC = crt0.S handlers.S syscalls.c vectors.S +OBJ = crt0.o handlers.o syscalls.o vectors.o +LIBCV-VERIF = libcv-verif.a +CFLAGS ?= -Os -g -static -mabi=ilp32 -march=$(RISCV_MARCH) -Wall -pedantic -mno-relax $(RISCV_CFLAGS) + +all: $(LIBCV-VERIF) + +$(LIBCV-VERIF): $(OBJ) + $(RISCV_AR) rcs $@ $(OBJ) + +%.o : %.c + $(RISCV_GCC) $(CFLAGS) -c $< -o $@ + +%.o : %.S + $(RISCV_GCC) $(CFLAGS) -c $< -o $@ + +clean: + rm -f $(OBJ) $(LIBCV-VERIF) + + +vars: + @echo "make bsp variables:" + @echo " CV_SW_TOOLCHAIN = $(CV_SW_TOOLCHAIN)" + @echo " RISCV = $(RISCV)" + @echo " RISCV_EXE_PREFIX = $(RISCV_EXE_PREFIX)" + @echo " RISCV_GCC = $(RISCV_GCC)" + @echo " RISCV_MARCH = $(RISCV_MARCH)" + @echo " RISCV_CFLAGS = $(RISCV_CFLAGS)" + @echo " CFLAGS = $(CFLAGS)" diff --git a/verif/tests/custom/debug_test/bsp/README.md b/verif/tests/custom/debug_test/bsp/README.md new file mode 100644 index 0000000000..2737d94c3f --- /dev/null +++ b/verif/tests/custom/debug_test/bsp/README.md @@ -0,0 +1,166 @@ +Board Support Package (BSP) for CVA6 Verification +================================================= + +This BSP provides the code to support running programs on the CVA6 verification +target. It performs initialization tasks (`crt0.S`), handles +interrupts/exceptions (`vectors.S`, `handlers.S`), provides syscall +implementations (`syscalls.c`) and includes a linker script (`link.ld`) to +control the placement of sections in the binary. + +Each file is described in more detail below followed by instructions for +building and using the BSP. + +C Runtime Initialization +------------------------ + +The C Runtime file `crt0.S` provides the `_start` function which is the entry +point of the program and performs the following tasks: + * Initialize global and stack pointer. + * Store the address of `vector_table` in `mtvec`, setting the lower two bits + to `0x2` to select vectored interrupt mode. + * Zero the BSS section. + * Invoke initialization of C constructors and set destructors to be called on + exit. + * Zero `argc` and `argv` (the stack is not initialized, so these are zeroed + to prevent uninitialized values causing a mismatch against the reference + result). + * Call `main`. + * If `main` returns, call `exit` with its return code. + +Interrupt and Exception Handling +-------------------------------- + +When a RISC-V core traps on an interrupt/exception, the `pc` is stored in `mepc` +and the reason for the trap is stored in `mcause`. The `MSB` of `mcause` +is set to `0` for an exception and `1` for an interrupt; the remaining bits +`mcause[MXLEN-2:0]` contain the exception code. The table of `mcause` values is +defined in Table 3.6 of the [RISC-V Instruction Set Manual Volume II: Privileged +Architecture Version 20190608-Priv-MSU-Ratified](https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMFDQC-and-Priv-v1.11/riscv-privileged-20190608.pdf). + +The core jumps to a location in the vector table according to the `BASE` address +of the vector table stored in `mtvec` and the value of the exception code in +`mcause`. In vectored mode, all exceptions jump to `BASE` and interrupts jump to +`BASE+4*mcause[XLEN-2:0]`. Note that because user software interrupts have +exception code `0`, they jump to the same location as exceptions, therefore the +user software interrupt handler must also handle exceptions. + +The vector table is defined in `vectors.S` and may jump to one of the +following interrupt request handlers in `handlers.S`: + * `u_sw_irq_handler` - handles user software interrupts and all exceptions. + Saves all caller saved registers then checks `mcause` and jumps to the + appropriate handler as follows: + - Breakpoint: jump to `handle_ebreak`. + - Illegal instruction: jump to `handle_illegal`. + - Environment call from M-mode: jump to `handle_ecall`. + - Any other exception or user software interrupt: jump to `handle_unknown`. + * `m_software_irq_handler` - handles machine-mode software interrupts + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_timer_irq_handler` - handles machine-mode timer interrupts + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_external_irq_handler` - handles machine-mode external interrupts + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast0_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast1_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast2_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast3_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast4_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast5_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast6_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast7_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast8_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast9_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast10_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast11_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast12_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast13_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast14_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `m_fast15_irq_handler` - handles machine-mode fast external interrupts (platform extension for CV32) + - Currently jumps to `__no_irq_handler`. Behavior to be defined in future commit. + * `__no_irq_handler` - loops printing "no exception handler installed". + +The following exception handlers may be called from `u_sw_irq_handler`: + * `handle_ecall` - calls `handle_syscall` which checks the syscall number and + calls the corresponding syscall function. + * `handle_ebreak` - currently just prints "ebreak exception handler entered" + * `handle_illegal_insn` - prints "illegal instruction exception handler + entered" + * `unknown_handler` - called when there is no handler for the interrupt/ + exception. This is the only case where `mepc` is not incremented, because we + do not know the appropiate action to take. + +Returning from the `u_sw_irq_handler`. All handlers called by `u_sw_irq_handler` +increment `mepc` before calling `mret`, except for `unknown_handler`. Handlers +that require `mepc` to be incremented jump to `end_handler_incr_mepc` otherwise +they jump to `end_handler_ret`. All caller saved registers are restored before +finally calling `mret`. + +Some test cases require the ability to override the default handlers. In future, +these handlers will be made overridable by defining their labels as `.weak` +symbols. Test cases can then provide their own handlers where necessary. + +System Calls +------------ + +On a bare-metal system there is no OS to handle system calls, therefore, we +define our own system calls in `syscalls.c`. For example, the implementation of +`_write` outputs a byte at a time to the virtual printer peripheral. Many of the +functions provide minimal implementations that simply fail gracefully due to +lack of necessary OS support e.g. no file system. + +The [RISC-V Instruction Set Manual Volume I: Unprivileged ISA Version 20191213]( +https://content.riscv.org/wp-content/uploads/2019/06/riscv-spec.pdf) states that +for an `ecall` the "ABI for the system will define how parameters for the +environment request are passed". This BSP follows the convention used for RISC-V +in `newlib`. Parameters are passed in registers `a0` to `a5` and system call ID +in `a7` (`t0` on RV32E). When handling an `ecall`, `handle_ecall` calls +`handle_syscall` which then calls the appropriate function that implements the +system call, passing parameters as necessary. + +Linker Script +------------- + +The linker script defines the memory layout and controls the mapping of input +sections from object files to output sections in the output binary. + +The `link.ld` script is based on the standard upstream RV32 linker script, with +some changes required for CVA6: + * Memory layout is defined as follows: + * `ram` start=0x0, length=4MB + * `dbg` start=0x1A110800, length=2KB + * Changes to output section placement are as follows: + - `.vectors` start=ORIGIN(`ram`) + - `.init` start=0x80 + - `.heap` starts at end of data and grows upwards + - `.stack` starts at the end of `ram` and grows downwards + - `.debugger` start=ORIGIN(`dbg`) + - `.debugger_exception` start=0x1A110C00 + - `.debugger_stack` follows `.debugger_exception` + +Building and using the BSP Library +---------------------------------- + +The BSP can be built in this directory as follows: +``` +make +``` +This produces libcv-verif.a which can then be linked with a test program as +follows: + +``` +gcc test-program.c -nostartfiles -T/path/to/bsp/link.ld -L/path/to/bsp/ -lcv-verif +``` diff --git a/verif/tests/custom/debug_test/bsp/bsp.h b/verif/tests/custom/debug_test/bsp/bsp.h new file mode 100644 index 0000000000..ca3035146f --- /dev/null +++ b/verif/tests/custom/debug_test/bsp/bsp.h @@ -0,0 +1,184 @@ +// Copyright 2022 Silicon Laboratories Inc. +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you +// may not use this file except in compliance with the License, or, at your +// option, the Apache License version 2.0. +// +// You may obtain a copy of the License at +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// 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. + + +enum { + EXC_CAUSE_INSTR_ACC_FAULT = 1, + EXC_CAUSE_ILLEGAL_INSTR = 2, + EXC_CAUSE_BREAKPOINT = 3, + EXC_CAUSE_LOAD_ACC_FAULT = 5, + EXC_CAUSE_STORE_ACC_FAULT = 7, + EXC_CAUSE_ENV_CALL_U = 8, + EXC_CAUSE_ENV_CALL_M = 11, + EXC_CAUSE_INSTR_BUS_FAULT = 24, + EXC_CAUSE_INSTR_INTEGRITY_FAULT = 25, +}; + +typedef enum { + PMPMODE_OFF = 0, + PMPMODE_TOR = 1, + PMPMODE_NA4 = 2, + PMPMODE_NAPOT = 3 +} pmp_mode_t; + +// Verbosity levels (Akin to the uvm verbosity concept) +typedef enum { + V_OFF = 0, + V_LOW = 1, + V_MEDIUM = 2, + V_HIGH = 3, + V_DEBUG = 4 +} verbosity_t; + +// Matches funct3 values for CSR instructions +typedef enum { + CSRRW = 1, + CSRRS = 2, + CSRRC = 3, + CSRRWI = 5, + CSRRSI = 6, + CSRRCI = 7 +} csr_instr_access_t; + +typedef union { + struct { + volatile uint32_t opcode : 7; + volatile uint32_t rd : 5; + volatile uint32_t funct3 : 3; + volatile uint32_t rs1_uimm : 5; + volatile uint32_t csr : 12; + } volatile fields; + volatile uint32_t raw; +} __attribute__((packed)) csr_instr_t; + +typedef union { + struct { + volatile uint32_t load : 1; + volatile uint32_t store : 1; + volatile uint32_t execute : 1; + volatile uint32_t u : 1; + volatile uint32_t s : 1; + volatile uint32_t res_5_5 : 1; + volatile uint32_t m : 1; + volatile uint32_t match : 4; + volatile uint32_t chain : 1; + volatile uint32_t action : 4; + volatile uint32_t size : 4; + volatile uint32_t timing : 1; + volatile uint32_t select : 1; + volatile uint32_t hit : 1; + volatile uint32_t vu : 1; + volatile uint32_t vs : 1; + volatile uint32_t res_26_25: 2; + volatile uint32_t dmode : 1; + volatile uint32_t type : 4; + } __attribute__((packed)) volatile fields; + volatile uint32_t raw; +} __attribute__((packed)) mcontrol6_t; + +typedef union { + struct { + volatile uint32_t uie : 1; // 0 + volatile uint32_t sie : 1; // 1 + volatile uint32_t wpri : 1; // 2 + volatile uint32_t mie : 1; // 3 + volatile uint32_t upie : 1; // 4 + volatile uint32_t spie : 1; // 5 + volatile uint32_t wpri0 : 1; // 6 + volatile uint32_t mpie : 1; // 7 + volatile uint32_t spp : 1; // 8 + volatile uint32_t wpri1 : 2; // 10: 9 + volatile uint32_t mpp : 2; // 12:11 + volatile uint32_t fs : 2; // 14:13 + volatile uint32_t xs : 2; // 16:15 + volatile uint32_t mprv : 1; // 17 + volatile uint32_t sum : 1; // 18 + volatile uint32_t mxr : 1; // 19 + volatile uint32_t tvm : 1; // 20 + volatile uint32_t tw : 1; // 21 + volatile uint32_t tsr : 1; // 22 + volatile uint32_t wpri3 : 8; // 30:23 + volatile uint32_t sd : 1; // 31 + } volatile fields; + volatile uint32_t raw; +} __attribute__((packed)) mstatus_t; + +typedef union { + struct { + volatile uint32_t mml : 1; + volatile uint32_t mmwp : 1; + volatile uint32_t rlb : 1; + volatile uint32_t reserved_31_3 : 29; + } __attribute__((packed)) volatile fields; + volatile uint32_t raw : 32; +} __attribute__((packed)) mseccfg_t; + +typedef union { + struct { + volatile uint32_t reserved_1_0 : 2; + volatile uint32_t jvt_access : 1; + volatile uint32_t reserved_31_3 : 29; + } __attribute__((packed)) volatile fields; + volatile uint32_t raw : 32; +} __attribute__((packed)) mstateen0_t; + +typedef union { + struct { + volatile uint32_t r : 1; + volatile uint32_t w : 1; + volatile uint32_t x : 1; + volatile uint32_t a : 2; + volatile uint32_t reserved_6_5 : 2; + volatile uint32_t l : 1; + } __attribute__((packed)) volatile fields; + volatile uint32_t raw : 8; +} __attribute__((packed)) pmpsubcfg_t; + +typedef union { + struct { + volatile uint32_t cfg : 8; + } __attribute__((packed)) volatile reg_idx[4]; + volatile uint32_t raw : 32; +} __attribute__((packed)) pmpcfg_t; + +typedef union { + struct { + volatile uint32_t mode : 6; + volatile uint32_t base : 26; + } __attribute__((packed)) volatile fields; + volatile uint32_t raw : 32; +} __attribute__((packed)) jvt_t; + +typedef union { + struct { + volatile uint32_t exccode : 12; + volatile uint32_t res_30_12 : 19; + volatile uint32_t interrupt : 1; + } __attribute__((packed)) volatile clint; + struct { + volatile uint32_t exccode : 12; + volatile uint32_t res_15_12 : 4; + volatile uint32_t mpil : 8; + volatile uint32_t res_26_24 : 3; + volatile uint32_t mpie : 1; + volatile uint32_t mpp : 2; + volatile uint32_t minhv : 1; + volatile uint32_t interrupt : 1; + } __attribute__((packed)) volatile clic; + volatile uint32_t raw : 32; +} __attribute__((packed)) mcause_t; diff --git a/verif/tests/custom/debug_test/bsp/corev_uvmt.h b/verif/tests/custom/debug_test/bsp/corev_uvmt.h new file mode 100644 index 0000000000..6241b71ad6 --- /dev/null +++ b/verif/tests/custom/debug_test/bsp/corev_uvmt.h @@ -0,0 +1,76 @@ +#ifndef __COREV_UVMT_H__ +#define __COREV_UVMT_H__ + +/* +** +** Copyright 2021 OpenHW Group +** Copyright 2021 Silicon Labs +** +** Licensed under the Solderpad Hardware Licence, 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 +** +** https://solderpad.org/licenses/ +** +** 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. +** +******************************************************************************* +** CORE-V UVM Testbench (UVMT) defines +******************************************************************************* +*/ + +#define CV_VP_REGISTER_BASE 0x80800000 + +#define CV_VP_VIRTUAL_PRINTER_OFFSET 0x00000000 +#define CV_VP_RANDOM_NUM_OFFSET 0x00000040 +#define CV_VP_CYCLE_COUNTER_OFFSET 0x00000080 +#define CV_VP_STATUS_FLAGS_OFFSET 0x000000c0 +#define CV_VP_FENCEI_TAMPER_OFFSET 0x00000100 +#define CV_VP_INTR_TIMER_OFFSET 0x00000140 +#define CV_VP_DEBUG_CONTROL_OFFSET 0x00000180 +#define CV_VP_OBI_SLV_RESP_OFFSET 0x000001c0 +#define CV_VP_SIG_WRITER_OFFSET 0x00000200 +#define CV_VP_OBI_ERR_AWAIT_GOAHEAD_OFFSET 0x00000240 + +#define CV_VP_CYCLE_COUNTER_BASE (CV_VP_REGISTER_BASE + CV_VP_CYCLE_COUNTER_OFFSET) +#define CV_VP_DEBUG_CONTROL_BASE (CV_VP_REGISTER_BASE + CV_VP_DEBUG_CONTROL_OFFSET) +#define CV_VP_FENCEI_TAMPER_BASE (CV_VP_REGISTER_BASE + CV_VP_FENCEI_TAMPER_OFFSET) +#define CV_VP_INTR_TIMER_BASE (CV_VP_REGISTER_BASE + CV_VP_INTR_TIMER_OFFSET) +#define CV_VP_OBI_ERR_AWAIT_GOAHEAD_BASE (CV_VP_REGISTER_BASE + CV_VP_OBI_ERR_AWAIT_GOAHEAD_OFFSET) +#define CV_VP_OBI_SLV_RESP_BASE (CV_VP_REGISTER_BASE + CV_VP_OBI_SLV_RESP_OFFSET) +#define CV_VP_RANDOM_NUM_BASE (CV_VP_REGISTER_BASE + CV_VP_RANDOM_NUM_OFFSET) +#define CV_VP_SIG_WRITER_BASE (CV_VP_REGISTER_BASE + CV_VP_SIG_WRITER_OFFSET) +#define CV_VP_STATUS_FLAGS_BASE (CV_VP_REGISTER_BASE + CV_VP_STATUS_FLAGS_OFFSET) +#define CV_VP_VIRTUAL_PRINTER_BASE (CV_VP_REGISTER_BASE + CV_VP_VIRTUAL_PRINTER_OFFSET) + +// -------------------------------------------------------------------------- +// Registers inside the OBI_SLV_RESP VP +// -------------------------------------------------------------------------- +#define CV_VP_OBI_SLV_RESP_I_ERR_ADDR_MIN ((volatile uint32_t*) (CV_VP_OBI_SLV_RESP_BASE + 4*0)) +#define CV_VP_OBI_SLV_RESP_I_ERR_ADDR_MAX ((volatile uint32_t*) (CV_VP_OBI_SLV_RESP_BASE + 4*1)) +#define CV_VP_OBI_SLV_RESP_I_ERR_VALID ((volatile uint32_t*) (CV_VP_OBI_SLV_RESP_BASE + 4*2)) +#define CV_VP_OBI_SLV_RESP_I_EXOKAY_ADDR_MIN ((volatile uint32_t*) (CV_VP_OBI_SLV_RESP_BASE + 4*3)) +#define CV_VP_OBI_SLV_RESP_I_EXOKAY_ADDR_MAX ((volatile uint32_t*) (CV_VP_OBI_SLV_RESP_BASE + 4*4)) +#define CV_VP_OBI_SLV_RESP_I_EXOKAY_VALID ((volatile uint32_t*) (CV_VP_OBI_SLV_RESP_BASE + 4*5)) + +#define CV_VP_OBI_SLV_RESP_D_ERR_ADDR_MIN ((volatile uint32_t*) (CV_VP_OBI_SLV_RESP_BASE + 6*4 + 4*0)) +#define CV_VP_OBI_SLV_RESP_D_ERR_ADDR_MAX ((volatile uint32_t*) (CV_VP_OBI_SLV_RESP_BASE + 6*4 + 4*1)) +#define CV_VP_OBI_SLV_RESP_D_ERR_VALID ((volatile uint32_t*) (CV_VP_OBI_SLV_RESP_BASE + 6*4 + 4*2)) +#define CV_VP_OBI_SLV_RESP_D_EXOKAY_ADDR_MIN ((volatile uint32_t*) (CV_VP_OBI_SLV_RESP_BASE + 6*4 + 4*3)) +#define CV_VP_OBI_SLV_RESP_D_EXOKAY_ADDR_MAX ((volatile uint32_t*) (CV_VP_OBI_SLV_RESP_BASE + 6*4 + 4*4)) +#define CV_VP_OBI_SLV_RESP_D_EXOKAY_VALID ((volatile uint32_t*) (CV_VP_OBI_SLV_RESP_BASE + 6*4 + 4*5)) + +// API for Debug Control VP register +#define CV_VP_DEBUG_CONTROL_DBG_REQ(i) ((i) << 31) +#define CV_VP_DEBUG_CONTROL_REQ_MODE(i) ((i) << 30) +#define CV_VP_DEBUG_CONTROL_RAND_PULSE_DURATION(i) ((i) << 29) +#define CV_VP_DEBUG_CONTROL_PULSE_DURATION(i) ((i) << 16) +#define CV_VP_DEBUG_CONTROL_RAND_START_DELAY(i) ((i) << 15) +#define CV_VP_DEBUG_CONTROL_START_DELAY(i) ((i) << 0) +#define CV_VP_DEBUG_CONTROL *((volatile uint32_t * volatile) (CV_VP_DEBUG_CONTROL_BASE)) + +#endif diff --git a/verif/tests/custom/debug_test/bsp/crt0.S b/verif/tests/custom/debug_test/bsp/crt0.S new file mode 100644 index 0000000000..e957d78e72 --- /dev/null +++ b/verif/tests/custom/debug_test/bsp/crt0.S @@ -0,0 +1,82 @@ +/* Copyright (c) 2017 SiFive Inc. All rights reserved. + * Copyright (c) 2019 ETH Zürich and University of Bologna + * Copyright (c) 2023 Silicon Laboratories Inc. + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the FreeBSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. + */ +/* Make sure the vector table gets linked into the binary. */ +.global vector_table + +/* Make sure the NMI handler gets linked into the binary. */ +.global nmi_handler + +/* Entry point for bare metal programs */ +.section .text.start +.global _start +.type _start, @function + +_start: +/* initialize global pointer */ +.option push +.option norelax +1:auipc gp, %pcrel_hi(__global_pointer$) + addi gp, gp, %pcrel_lo(1b) + +// /* initialize vector table pointer */ +// 1:auipc a0, %pcrel_hi(__jvt_base$) +// addi a0, a0, %pcrel_lo(1b) +// csrw jvt, a0 +.option pop + +/* initialize stack pointer */ + la sp, __stack_start + +/* set vector table address */ + la a0, __vector_start + ori a0, a0, 1 /*vector mode = vectored */ + csrw mtvec, a0 + +/* clear the bss segment */ + la a0, _edata + la a2, _end + sub a2, a2, a0 + li a1, 0 + call memset + +/* new-style constructors and destructors */ + la a0, __libc_fini_array + call atexit + call __libc_init_array + +/* call main */ +// lw a0, 0(sp) /* a0 = argc */ +// addi a1, sp, __SIZEOF_POINTER__ /* a1 = argv */ +// li a2, 0 /* a2 = envp = NULL */ +// Initialize these variables to 0. Cannot use argc or argv +// since the stack is not initialized + li a0, 0 + li a1, 0 + li a2, 0 + + call main + tail exit + +.size _start, .-_start + + +.global _init +.type _init, @function +.global _fini +.type _fini, @function +_init: +_fini: + /* These don't have to do anything since we use init_array/fini_array. Prevent + missing symbol error */ + ret +.size _init, .-_init +.size _fini, .-_fini diff --git a/verif/tests/custom/debug_test/bsp/handlers.S b/verif/tests/custom/debug_test/bsp/handlers.S new file mode 100644 index 0000000000..7509a98aa2 --- /dev/null +++ b/verif/tests/custom/debug_test/bsp/handlers.S @@ -0,0 +1,345 @@ +/* +* Copyright 2019 ETH Zürich and University of Bologna +* +* 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. +*/ + +/* Exception codes */ +#define EXCEPTION_INSN_ACCESS_FAULT 1 +#define EXCEPTION_ILLEGAL_INSN 2 +#define EXCEPTION_BREAKPOINT 3 +#define EXCEPTION_LOAD_ACCESS_FAULT 5 +#define EXCEPTION_STORE_ACCESS_FAULT 7 +#define EXCEPTION_ECALL_M 11 +#define EXCEPTION_ECALL_U 8 +#define EXCEPTION_INSN_BUS_FAULT 24 + +/* NMI interrupt codes */ +#define INTERRUPT_LOAD_BUS_FAULT (1024 | (0x1 << 31)) +#define INTERRUPT_STORE_BUS_FAULT (1025 | (0x1 << 31)) + +.section .text.handlers +.global __no_irq_handler +.global u_sw_irq_handler +.global m_software_irq_handler +.global m_timer_irq_handler +.global m_external_irq_handler +.global m_fast0_irq_handler +.global m_fast1_irq_handler +.global m_fast2_irq_handler +.global m_fast3_irq_handler +.global m_fast4_irq_handler +.global m_fast5_irq_handler +.global m_fast6_irq_handler +.global m_fast7_irq_handler +.global m_fast8_irq_handler +.global m_fast9_irq_handler +.global m_fast10_irq_handler +.global m_fast11_irq_handler +.global m_fast12_irq_handler +.global m_fast13_irq_handler +.global m_fast14_irq_handler +.global m_fast15_irq_handler +.global end_handler_incr_mepc +.global end_handler_ret + +.weak __no_irq_handler +.weak u_sw_irq_handler +.weak m_software_irq_handler +.weak m_timer_irq_handler +.weak m_external_irq_handler +.weak m_fast0_irq_handler +.weak m_fast1_irq_handler +.weak m_fast2_irq_handler +.weak m_fast3_irq_handler +.weak m_fast4_irq_handler +.weak m_fast5_irq_handler +.weak m_fast6_irq_handler +.weak m_fast7_irq_handler +.weak m_fast8_irq_handler +.weak m_fast9_irq_handler +.weak m_fast10_irq_handler +.weak m_fast11_irq_handler +.weak m_fast12_irq_handler +.weak m_fast13_irq_handler +.weak m_fast14_irq_handler +.weak m_fast15_irq_handler + +.weak handle_illegal_insn +.weak handle_insn_access_fault +.weak handle_insn_bus_fault +.weak handle_ecall +.weak handle_ecall_u + +/* exception handling */ +__no_irq_handler: + la a0, no_exception_handler_msg + jal ra, puts + j __no_irq_handler + +m_software_irq_handler: + j __no_irq_handler + +m_timer_irq_handler: + j __no_irq_handler + +m_external_irq_handler: + j __no_irq_handler + +m_fast0_irq_handler: + j __no_irq_handler + +m_fast1_irq_handler: + j __no_irq_handler + +m_fast2_irq_handler: + j __no_irq_handler + +m_fast3_irq_handler: + j __no_irq_handler + +m_fast4_irq_handler: + j __no_irq_handler + +m_fast5_irq_handler: + j __no_irq_handler + +m_fast6_irq_handler: + j __no_irq_handler + +m_fast7_irq_handler: + j __no_irq_handler + +m_fast8_irq_handler: + j __no_irq_handler + +m_fast9_irq_handler: + j __no_irq_handler + +m_fast10_irq_handler: + j __no_irq_handler + +m_fast11_irq_handler: + j __no_irq_handler + +m_fast12_irq_handler: + j __no_irq_handler + +m_fast13_irq_handler: + j __no_irq_handler + +m_fast14_irq_handler: + j __no_irq_handler + +m_fast15_irq_handler: + j __no_irq_handler + +u_sw_irq_handler: + /* While we are still using puts in handlers, save all caller saved + regs. Eventually, some of these saves could be deferred. */ + addi sp,sp,-64 + sw ra, 0(sp) + sw a0, 4(sp) + sw a1, 8(sp) + sw a2, 12(sp) + sw a3, 16(sp) + sw a4, 20(sp) + sw a5, 24(sp) + sw a6, 28(sp) + sw a7, 32(sp) + sw t0, 36(sp) + sw t1, 40(sp) + sw t2, 44(sp) + sw t3, 48(sp) + sw t4, 52(sp) + sw t5, 56(sp) + sw t6, 60(sp) + csrr t0, mtvec + # Check for clic + andi t0, t0, 0x3 + addi t1, zero, 0x3 + # non-clic jump + bne t0, t1, 1f + # clic section (Filter out upper bits, mpp etc.) + csrr t0, mcause + lui t1, 0x1 + addi t1, t1, -1 + and t0, t1, t0 + j 2f + + 1: csrr t0, mcause + 2: li t1, EXCEPTION_INSN_ACCESS_FAULT + beq t0, t1, handle_insn_access_fault + li t1, EXCEPTION_ILLEGAL_INSN + beq t0, t1, handle_illegal_insn + li t1, EXCEPTION_ECALL_M + beq t0, t1, handle_ecall + li t1, EXCEPTION_ECALL_U + beq t0, t1, handle_ecall_u + li t1, EXCEPTION_BREAKPOINT + beq t0, t1, handle_ebreak + li t1, EXCEPTION_INSN_BUS_FAULT + beq t0, t1, handle_insn_bus_fault + j handle_unknown + +handle_ecall: + jal ra, handle_syscall + j end_handler_incr_mepc + +handle_ecall_u: + jal ra, handle_syscall + j end_handler_incr_mepc + +handle_ebreak: + /* TODO support debug handling requirements. */ + la a0, ebreak_msg + jal ra, puts + j end_handler_incr_mepc + +handle_illegal_insn: + la a0, illegal_insn_msg + jal ra, puts + j end_handler_incr_mepc + +handle_insn_access_fault: + la a0, insn_access_fault_msg + jal ra, puts + j end_handler_incr_mepc + +handle_insn_bus_fault: + la a0, insn_bus_fault_msg + jal ra, puts + /* Do not advnace the mepc, tests should handle this appropriately */ + j end_handler_ret + +handle_unknown: + la a0, unknown_msg + jal ra, puts + /* We don't know what interrupt/exception is being handled, so don't + increment mepc. */ + j end_handler_ret + +end_handler_incr_mepc: + csrr t0, mepc + lb t1, 0(t0) + li a0, 0x3 + and t1, t1, a0 + /* Increment mepc by 2 or 4 depending on whether the instruction at mepc + is compressed or not. */ + bne t1, a0, end_handler_incr_mepc2 + addi t0, t0, 2 +end_handler_incr_mepc2: + addi t0, t0, 2 + csrw mepc, t0 +end_handler_ret: + lw ra, 0(sp) + lw a0, 4(sp) + lw a1, 8(sp) + lw a2, 12(sp) + lw a3, 16(sp) + lw a4, 20(sp) + lw a5, 24(sp) + lw a6, 28(sp) + lw a7, 32(sp) + lw t0, 36(sp) + lw t1, 40(sp) + lw t2, 44(sp) + lw t3, 48(sp) + lw t4, 52(sp) + lw t5, 56(sp) + lw t6, 60(sp) + addi sp,sp,64 + mret + +.weak handle_data_load_bus_fault +.weak handle_data_store_bus_fault + +.section .nmi, "ax" +.global nmi_handler +.global nmi_end_handler_ret + +nmi_handler: + addi sp,sp,-64 + sw ra, 0(sp) + sw a0, 4(sp) + sw a1, 8(sp) + sw a2, 12(sp) + sw a3, 16(sp) + sw a4, 20(sp) + sw a5, 24(sp) + sw a6, 28(sp) + sw a7, 32(sp) + sw t0, 36(sp) + sw t1, 40(sp) + sw t2, 44(sp) + sw t3, 48(sp) + sw t4, 52(sp) + sw t5, 56(sp) + sw t6, 60(sp) + csrr t0, mcause + li t1, INTERRUPT_LOAD_BUS_FAULT + beq t0, t1, handle_data_load_bus_fault + li t1, INTERRUPT_STORE_BUS_FAULT + beq t0, t1, handle_data_store_bus_fault + + j nmi_end_handler_ret + +handle_data_load_bus_fault: + la a0, data_load_bus_fault_msg + jal ra, puts + j nmi_end_handler_ret + +handle_data_store_bus_fault: + la a0, data_store_bus_fault_msg + jal ra, puts + j nmi_end_handler_ret + +nmi_end_handler_ret: + lw ra, 0(sp) + lw a0, 4(sp) + lw a1, 8(sp) + lw a2, 12(sp) + lw a3, 16(sp) + lw a4, 20(sp) + lw a5, 24(sp) + lw a6, 28(sp) + lw a7, 32(sp) + lw t0, 36(sp) + lw t1, 40(sp) + lw t2, 44(sp) + lw t3, 48(sp) + lw t4, 52(sp) + lw t5, 56(sp) + lw t6, 60(sp) + addi sp,sp,64 + mret + +.section .rodata +data_load_bus_fault_msg: + .string "CVA6 BSP: data load bus fault exception handler entered\n" +data_store_bus_fault_msg: + .string "CVA6 BSP: data store bus fault exception handler entered\n" +insn_access_fault_msg: + .string "CVA6 BSP: instruction access fault exception handler entered\n" +insn_bus_fault_msg: + .string "CVA6 BSP: instruction bus fault exception handler entered\n" +illegal_insn_msg: + .string "CVA6 BSP: illegal instruction exception handler entered\n" +ecall_msg: + .string "CVA6 BSP: ecall exception handler entered\n" +ebreak_msg: + .string "CVA6 BSP: ebreak exception handler entered\n" +unknown_msg: + .string "CVA6 BSP: unknown exception handler entered\n" +no_exception_handler_msg: + .string "CVA6 BSP: no exception handler installed\n" diff --git a/verif/tests/custom/debug_test/bsp/link.ld b/verif/tests/custom/debug_test/bsp/link.ld new file mode 100644 index 0000000000..9d7181f3be --- /dev/null +++ b/verif/tests/custom/debug_test/bsp/link.ld @@ -0,0 +1,321 @@ +/* Script for -z combreloc */ +/* Copyright (C) 2014-2020 Free Software Foundation, Inc. + Copyright (C) 2019 ETH Zürich and University of Bologna + Copyright (C) 2020 OpenHW Group + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ + +/* This linker script is adapted from the default linker script for upstream + RISC-V GCC. It has been modified for use in verification of CORE-V cores. +*/ + +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", + "elf32-littleriscv") +OUTPUT_ARCH(riscv) +ENTRY(_start) + +/* CORE-V */ +MEMORY +{ + /* Our testbench is a bit weird in that we initialize the RAM (thus + allowing initialized sections to be placed there). Infact we dump all + sections to ram. */ + + ram (rwxai) : ORIGIN = 0x80000000, LENGTH = 0x400000 + dbg (rwxai) : ORIGIN = 0x800, LENGTH = 0x1000 +} + +SECTIONS +{ + /* CORE-V Debugger Code: This section address must be the same as the + DM_HaltAddress parameter in the RTL */ + .debugger (ORIGIN(dbg)): + { + PROVIDE(_debugger_start = .); + KEEP(*(.debugger)); + } >dbg + .debugger_exception (0x1000): + { + PROVIDE(_debugger_exception = .); + KEEP(*(.debugger_exception)); + } >dbg + /* Debugger Stack*/ + .debugger_stack : ALIGN(16) + { + PROVIDE(__debugger_stack_start = ALIGN(ORIGIN(dbg) + LENGTH(dbg) - 15, 16)); + } >dbg + + + /* CORE-V: crt0 init code */ + .init (ORIGIN(ram)): + { + KEEP (*(SORT_NONE(.init))) + KEEP (*(.text.start)) + } >ram + + . = ALIGN(0x1000); + .tohost : { *(.tohost) } + + /* CORE-V: interrupt vectors */ + . = ALIGN(0x1000); + .vectors : + { + . = ALIGN(0x1000); + PROVIDE(__vector_start = .); + KEEP(*(.vectors)); + } >ram + + + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x10000)); . = SEGMENT_START("text-segment", 0x10000) + SIZEOF_HEADERS; + .interp : { *(.interp) } >ram + .note.gnu.build-id : { *(.note.gnu.build-id) } >ram + .hash : { *(.hash) } >ram + .gnu.hash : { *(.gnu.hash) } >ram + .dynsym : { *(.dynsym) } >ram + .dynstr : { *(.dynstr) } >ram + .gnu.version : { *(.gnu.version) } >ram + .gnu.version_d : { *(.gnu.version_d) } >ram + .gnu.version_r : { *(.gnu.version_r) } >ram + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } >ram + .rela.plt : + { + *(.rela.plt) + } >ram + + .plt : { *(.plt) } + .iplt : { *(.iplt) } + .text : + { + /* FIXME: the naming for text.tbljal will most likely change and move out of .text */ + . = ALIGN(1024); + *(.text.tbljal) + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(SORT(.text.sorted.*)) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf.em. */ + *(.gnu.warning) + } >ram + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >ram + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } >ram + .rodata1 : { *(.rodata1) } >ram + .sdata2 : + { + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + } >ram + .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } >ram + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } >ram + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } >ram + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >ram + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } >ram + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } >ram + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } >ram + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >ram + .exception_ranges : ONLY_IF_RW { *(.exception_ranges*) } >ram + /* Thread Local Storage sections */ + .tdata : + { + PROVIDE_HIDDEN (__tdata_start = .); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } >ram + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } >ram + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ram + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >ram + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >ram + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >ram + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >ram + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + . = DATA_SEGMENT_RELRO_END (0, .); + .data : + { + __DATA_BEGIN__ = .; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } >ram + .data1 : { *(.data1) } >ram + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : + { + __SDATA_BEGIN__ = .; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + } >ram + _edata = .; PROVIDE (edata = .); + . = .; + __bss_start = .; + .sbss : + { + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } >ram + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we do not + pad the .data section. */ + . = ALIGN(. != 0 ? 32 / 8 : 1); + } >ram + . = ALIGN(32 / 8); + . = SEGMENT_START("ldata-segment", .); + . = ALIGN(32 / 8); + __bss_end = .; + __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, + MAX(__DATA_BEGIN__ + 0x800, __bss_end - 0x800)); + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + + /* Heap grows upward towards end of ram */ + .heap : ALIGN(16) + { + PROVIDE(__heap_start = .); + /* If end of ram is not 16-byte aligned, align to previous 16-byte + boundary */ + PROVIDE(__heap_end = ALIGN(ORIGIN(ram) + LENGTH(ram) - 15, 16)); + . = __heap_end; + } >ram + + /* Stack grows downward from end of ram */ + .stack (__heap_end) : ALIGN(16) /* this is a requirement of the ABI(?) */ + { + PROVIDE(__stack_start = __heap_end); + . = __stack_start; + } >ram + + + + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .debug_addr 0 : { *(.debug_addr) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} + diff --git a/verif/tests/custom/debug_test/bsp/link_corev-dv.ld b/verif/tests/custom/debug_test/bsp/link_corev-dv.ld new file mode 100644 index 0000000000..e581f98659 --- /dev/null +++ b/verif/tests/custom/debug_test/bsp/link_corev-dv.ld @@ -0,0 +1,288 @@ +/* Copyright (C) 2014-2020 Free Software Foundation, Inc. + Copyright (C) 2019 ETH Zürich and University of Bologna + Copyright (C) 2020 OpenHW Group + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ + +/* This linker script is adapted from the default linker script for upstream + RISC-V GCC. It has been modified for use in verification of CORE-V cores. +*/ + +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", + "elf32-littleriscv") +OUTPUT_ARCH(riscv) +ENTRY(_start) + +/* + * The only changes from the default linker file are: + * - MEMORY section will be generated into its own file, linkcmds.memory + * - debug part of SECTIONS removed and generated (if desired) into its own linkcmds.dbgsec + * - New SECTIONS defined for generated pma-adapted memory regions + */ + +/* Memory layout */ +INCLUDE linkcmds.memory +/* Debug section */ +INCLUDE linkcmds.dbgsec +/* PMA sections */ +INCLUDE linkcmds.pmasec +/* Fixed address sections - Must be dynamically relocatable by generator script */ +INCLUDE linkcmds.fixadd + +SECTIONS +{ + + /* CORE-V: crt0 init code */ + .init (__boot_address): + { + KEEP (*(SORT_NONE(.init))) + KEEP (*(.text.start)) + } >rom + + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x10000)); . = SEGMENT_START("text-segment", 0x10000) + SIZEOF_HEADERS; + .interp : { *(.interp) } >ram + .note.gnu.build-id : { *(.note.gnu.build-id) } >ram + .hash : { *(.hash) } >ram + .gnu.hash : { *(.gnu.hash) } >ram + .dynsym : { *(.dynsym) } >ram + .dynstr : { *(.dynstr) } >ram + .gnu.version : { *(.gnu.version) } >ram + .gnu.version_d : { *(.gnu.version_d) } >ram + .gnu.version_r : { *(.gnu.version_r) } >ram + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } >rom + .rela.plt : + { + *(.rela.plt) + } >rom + + .plt : { *(.plt) } + .iplt : { *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(SORT(.text.sorted.*)) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf.em. */ + *(.gnu.warning) + } >rom + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >rom + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } >ram + .rodata1 : { *(.rodata1) } >ram + .sdata2 : + { + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + } >rom + .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } >ram + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } >ram + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } >ram + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >ram + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } >ram + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } >ram + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } >ram + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >ram + .exception_ranges : ONLY_IF_RW { *(.exception_ranges*) } >ram + /* Thread Local Storage sections */ + .tdata : + { + PROVIDE_HIDDEN (__tdata_start = .); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } >ram + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } >ram + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ram + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >ram + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >ram + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >ram + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >ram + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + . = DATA_SEGMENT_RELRO_END (0, .); + .data : + { + __DATA_BEGIN__ = .; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } >ram + .data1 : { *(.data1) } >ram + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : + { + __SDATA_BEGIN__ = .; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + } >ram + _edata = .; PROVIDE (edata = .); + . = .; + __bss_start = .; + .sbss : + { + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } >ram + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we do not + pad the .data section. */ + . = ALIGN(. != 0 ? 32 / 8 : 1); + } >ram + . = ALIGN(32 / 8); + . = SEGMENT_START("ldata-segment", .); + . = ALIGN(32 / 8); + __bss_end = .; + __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, + MAX(__DATA_BEGIN__ + 0x800, __bss_end - 0x800)); + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + + /* Heap grows upward towards end of ram */ + .heap : ALIGN(16) + { + PROVIDE(__heap_start = .); + /* If end of ram is not 16-byte aligned, align to previous 16-byte + boundary */ + PROVIDE(__heap_end = ALIGN(ORIGIN(ram) + LENGTH(ram) - 15, 16)); + . = __heap_end; + } >ram + + /* Stack grows downward from end of ram */ + .stack (__heap_end) : ALIGN(16) /* this is a requirement of the ABI(?) */ + { + PROVIDE(__stack_start = __heap_end); + . = __stack_start; + } >ram + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .debug_addr 0 : { *(.debug_addr) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} + diff --git a/verif/tests/custom/debug_test/bsp/syscalls.c b/verif/tests/custom/debug_test/bsp/syscalls.c new file mode 100644 index 0000000000..f3833ba4fb --- /dev/null +++ b/verif/tests/custom/debug_test/bsp/syscalls.c @@ -0,0 +1,379 @@ +/* An extremely minimalist syscalls.c for newlib + * Based on riscv newlib libgloss/riscv/sys_*.c + * + * Copyright 2019 Claire Wolf + * Copyright 2019 ETH Zürich and University of Bologna + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "corev_uvmt.h" +#undef errno +extern int errno; + +/* write to this reg for outputting strings */ +#define STDOUT_REG CV_VP_VIRTUAL_PRINTER_BASE +/* write test result of program to this reg */ +#define RESULT_REG (CV_VP_STATUS_FLAGS_BASE) +/* write exit value of program to this reg */ +#define EXIT_REG (CV_VP_STATUS_FLAGS_BASE + 4) + +#define STDOUT_FILENO 1 + +/* It turns out that older newlib versions use different symbol names which goes + * against newlib recommendations. Anyway this is fixed in later version. + */ +#if __NEWLIB__ <= 2 && __NEWLIB_MINOR__ <= 5 +#define _sbrk sbrk +#define _write write +#define _close close +#define _lseek lseek +#define _read read +#define _fstat fstat +#define _isatty isatty +#endif +/* Upstream newlib now defines this in libgloss/riscv/internal_syscall.h. */ +long +__syscall_error(long a0) +{ + errno = -a0; + return -1; +} + +void unimplemented_syscall() +{ + const char *p = "BSP: Unimplemented system call called!\n"; + while (*p) + *(volatile int *)STDOUT_REG = *(p++); +} + +int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) +{ + errno = ENOSYS; + return -1; +} + +int _access(const char *file, int mode) +{ + errno = ENOSYS; + return -1; +} + +int _chdir(const char *path) +{ + errno = ENOSYS; + return -1; +} + +int _chmod(const char *path, mode_t mode) +{ + errno = ENOSYS; + return -1; +} + +int _chown(const char *path, uid_t owner, gid_t group) +{ + errno = ENOSYS; + return -1; +} + +int _close(int file) +{ + return -1; +} + +int _execve(const char *name, char *const argv[], char *const env[]) +{ + errno = ENOMEM; + return -1; +} + +void _exit(int exit_status) +{ + *(volatile int *)EXIT_REG = exit_status; + __asm__ volatile("wfi"); + /* _exit should not return */ + while (1) {}; +} + +int _faccessat(int dirfd, const char *file, int mode, int flags) +{ + errno = ENOSYS; + return -1; +} + +int _fork(void) +{ + errno = EAGAIN; + return -1; +} + +int _fstat(int file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; + // errno = -ENOSYS; + // return -1; +} + +int _fstatat(int dirfd, const char *file, struct stat *st, int flags) +{ + errno = ENOSYS; + return -1; +} + +int _ftime(struct timeb *tp) +{ + errno = ENOSYS; + return -1; +} + +char *_getcwd(char *buf, size_t size) +{ + errno = -ENOSYS; + return NULL; +} + +int _getpid() +{ + return 1; +} + +int _gettimeofday(struct timeval *tp, void *tzp) +{ + errno = -ENOSYS; + return -1; +} + +int _isatty(int file) +{ + return (file == STDOUT_FILENO); +} + +int _kill(int pid, int sig) +{ + errno = EINVAL; + return -1; +} + +int _link(const char *old_name, const char *new_name) +{ + errno = EMLINK; + return -1; +} + +off_t _lseek(int file, off_t ptr, int dir) +{ + return 0; +} + +int _lstat(const char *file, struct stat *st) +{ + errno = ENOSYS; + return -1; +} + +int _open(const char *name, int flags, int mode) +{ + return -1; +} + +int _openat(int dirfd, const char *name, int flags, int mode) +{ + errno = ENOSYS; + return -1; +} + +ssize_t _read(int file, void *ptr, size_t len) +{ + return 0; +} + +int _stat(const char *file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; + // errno = ENOSYS; + // return -1; +} + +long _sysconf(int name) +{ + + return -1; +} + +clock_t _times(struct tms *buf) +{ + return -1; +} + +int _unlink(const char *name) +{ + errno = ENOENT; + return -1; +} + +int _utime(const char *path, const struct utimbuf *times) +{ + errno = ENOSYS; + return -1; +} + +int _wait(int *status) +{ + errno = ECHILD; + return -1; +} + +ssize_t _write(int file, const void *ptr, size_t len) +{ + const char *cptr = (char *)ptr; + if (file != STDOUT_FILENO) + { + errno = ENOSYS; + return -1; + } + + const void *eptr = cptr + len; + while (cptr != eptr) + *(volatile int *)STDOUT_REG = *cptr++; + return len; +} + +extern char __heap_start[]; +extern char __heap_end[]; +static char *brk = __heap_start; + +int _brk(void *addr) +{ + brk = addr; + return 0; +} + +void *_sbrk(ptrdiff_t incr) +{ + char *old_brk = brk; + volatile uint32_t sp; + + char *new_brk = brk += incr; + __asm__ volatile("mv %0, x2" : "=r"(sp) : : ); + + if (new_brk < (char *) sp && new_brk < __heap_end) + { + brk = new_brk; + + return old_brk; + } + else + { + errno = ENOMEM; + return (void *) -1; + } +} + +void handle_syscall (long a0, + long a1, + long a2, + long a3, + __attribute__((unused)) long a4, + __attribute__((unused)) long a5, + __attribute__((unused)) long a6, + long a7) { + #ifdef __riscv_32e + register long syscall_id asm("t0"); + #else + long syscall_id = a7; + #endif + + switch (syscall_id) { + case SYS_exit: + _exit (a0); + break; + case SYS_read: + _read (a0, (void *) a1, a2); + break; + case SYS_write: + _write (a0, (const void *) a1, a2); + break; + case SYS_getpid: + _getpid (); + break; + case SYS_kill: + _kill (a0, a1); + break; + case SYS_open: + _open ((const char *) a0, a1, a2); + break; + case SYS_openat: + _openat (a0, (const char *) a1, a2, a3); + break; + case SYS_close: + _close (a0); + break; + case SYS_lseek: + _lseek (a0, a1, a2); + break; + case SYS_brk: + _brk ((void *) a0); + break; + case SYS_link: + _link ((const char *) a0, (const char *) a1); + break; + case SYS_unlink: + _unlink ((const char *) a0); + break; + case SYS_chdir: + _chdir ((const char *) a0); + break; + case SYS_getcwd: + _getcwd ((char *) a0, a1); + break; + case SYS_stat: + _stat ((const char *) a0, (struct stat *) a1); + break; + case SYS_fstat: + _fstat (a0, (struct stat *) a1); + break; + case SYS_lstat: + _lstat ((const char *) a0, (struct stat *) a1); + break; + case SYS_fstatat: + _fstatat (a0, (const char *) a1, (struct stat *) a2, a3); + break; + case SYS_access: + _access ((const char *) a0, a1); + break; + case SYS_faccessat: + _faccessat (a0, (const char *) a1, a2, a3); + break; + case SYS_gettimeofday: + _gettimeofday ((struct timeval *) a0, (void *) a1); + break; + case SYS_times: + _times ((struct tms *) a0); + break; + default: + unimplemented_syscall (); + break; + } +} diff --git a/verif/tests/custom/debug_test/bsp/vectors.S b/verif/tests/custom/debug_test/bsp/vectors.S new file mode 100644 index 0000000000..1f97e896de --- /dev/null +++ b/verif/tests/custom/debug_test/bsp/vectors.S @@ -0,0 +1,55 @@ +/* +* Copyright 2019 ETH Zürich and University of Bologna +* +* 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. +*/ + +.section .vectors, "ax" +.option push +.option norvc +.global vector_table + +vector_table: + j u_sw_irq_handler + j __no_irq_handler + j __no_irq_handler + j m_software_irq_handler + j __no_irq_handler + j __no_irq_handler + j __no_irq_handler + j m_timer_irq_handler + j __no_irq_handler + j __no_irq_handler + j __no_irq_handler + j m_external_irq_handler + j __no_irq_handler + j __no_irq_handler + j __no_irq_handler + j __no_irq_handler + j m_fast0_irq_handler + j m_fast1_irq_handler + j m_fast2_irq_handler + j m_fast3_irq_handler + j m_fast4_irq_handler + j m_fast5_irq_handler + j m_fast6_irq_handler + j m_fast7_irq_handler + j m_fast8_irq_handler + j m_fast9_irq_handler + j m_fast10_irq_handler + j m_fast11_irq_handler + j m_fast12_irq_handler + j m_fast13_irq_handler + j m_fast14_irq_handler + j m_fast15_irq_handler +.option pop diff --git a/verif/tests/custom/debug_test/debug_test.c b/verif/tests/custom/debug_test/debug_test.c new file mode 100644 index 0000000000..5111d735c4 --- /dev/null +++ b/verif/tests/custom/debug_test/debug_test.c @@ -0,0 +1,553 @@ +/* +** +** Copyright 2020 OpenHW Group +** +** Licensed under the Solderpad Hardware Licence, 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 +** +** https://solderpad.org/licenses/ +** +** 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. +** +******************************************************************************* +** Basic debugger test. Needs more work and bugs fixed +** It will launch a debug request and have debugger code execute (debugger.S) +******************************************************************************* +*/ + +#include +#include +#include +#include "corev_uvmt.h" + +volatile int glb_hart_status = 0; // Written by main code only, read by debug code +volatile int glb_debug_status = 0; // Written by debug code only, read by main code +volatile int glb_ebreak_status = 0; // Written by ebreak code only, read by main code +volatile int glb_illegal_insn_status = 0; // Written by illegal instruction code only, read by main code +volatile int glb_debug_exception_status = 0; // Written by debug code during exception only +volatile int glb_exception_ebreak_status = 0; // Written by main code, read by exception handler + +volatile int glb_previous_dpc = 0; // holds last dpc, used for checking correctness of stepping +volatile int glb_step_info = 0; // info to dbg code about actions to take on stepping +volatile int glb_step_count = 0; // Written by debug code for each time single step is entered +// Expectation flags. Raise an error if handler or routine is enterred when not expected, +volatile int glb_expect_illegal_insn = 0; +volatile int glb_expect_ebreak_handler = 0; +volatile int glb_expect_debug_entry = 0; +volatile int glb_expect_debug_exception = 0; +volatile int glb_expect_irq_entry = 0; +volatile int glb_irq_timeout = 0; +// Counter values +// Checked at start and end of debug code +// Only lower 32 bits checked, as simulation cannot overflow on 32 bits +volatile int glb_mcycle_start = 0; +volatile int glb_mcycle_end = 0; +volatile int glb_minstret_start = 0; +volatile int glb_minstret_end = 0; +#define TEST_FAILED *(volatile int *)CV_VP_STATUS_FLAGS_BASE = 1 +#define TEST_PASSED *(volatile int *)CV_VP_STATUS_FLAGS_BASE = 123456789 + +extern int __stack_start; +typedef union { + struct { + unsigned int start_delay : 15; // 14: 0 + unsigned int rand_start_delay : 1; // 15 + unsigned int pulse_width : 13; // 28:16 + unsigned int rand_pulse_width : 1; // 29 + unsigned int pulse_mode : 1; // 30 0 = level, 1 = pulse + unsigned int value : 1; // 31 + } fields; + unsigned int bits; +} debug_req_control_t; + +#define DEBUG_REQ_CONTROL_REG *((volatile uint32_t *) (CV_VP_DEBUG_CONTROL_BASE)) +#define TIMER_REG_ADDR ((volatile uint32_t *) (CV_VP_INTR_TIMER_BASE+0)) +#define TIMER_VAL_ADDR ((volatile uint32_t *) (CV_VP_INTR_TIMER_BASE+4)) + +typedef union { + struct { + unsigned int uie : 1; // 0 // Implemented if USER mode enabled + unsigned int sie : 1; // 1 + unsigned int wpri : 1; // 2 + unsigned int mie : 1; // 3 // Implemented + unsigned int upie : 1; // 4 // Implemented if USER mode enabled + unsigned int spie : 1; // 5 + unsigned int wpri0 : 1; // 6 + unsigned int mpie : 1; // 7 // Implemented + unsigned int spp : 1; // 8 + unsigned int wpri1 : 2; // 10: 9 + unsigned int mpp : 2; // 12:11 // Implemented + unsigned int fs : 2; // 14:13 + unsigned int xs : 2; // 16:15 + unsigned int mprv : 1; // 17 + unsigned int sum : 1; // 18 + unsigned int mxr : 1; // 19 + unsigned int tvm : 1; // 20 + unsigned int tw : 1; // 21 + unsigned int tsr : 1; // 22 + unsigned int wpri3 : 8; // 30:23 + unsigned int sd : 1; // 31 + } fields; + unsigned int bits; +} mstatus_t; + +extern void _single_step(int d); +// Tag is simply to help debug and determine where the failure came from +void check_debug_status(int tag, int value) +{ + if(glb_debug_status != value){ + printf("ERROR: check_debug_status(%d, %d): Tag=%d status=%d, exp=%d \n\n", + tag, value, tag, glb_debug_status, value); + TEST_FAILED; + } +} +void check_debug_exception_status(int tag, int value) +{ + if(glb_debug_exception_status != value){ + printf("ERROR: check_debug_exception_status(%d, %d): Tag=%d status=%d, exp=%d \n\n", + tag, value, tag, glb_debug_exception_status, value); + TEST_FAILED; + } +} +void check_hart_status(int tag, int value) +{ + if(glb_hart_status != value){ + printf("ERROR: check_hart_status(%d, %d): Tag=%d status=%d, exp=%d \n\n", + tag, value, tag, glb_hart_status, value); + TEST_FAILED; + } +} +void check_ebreak_status(int tag, int value) +{ + if(glb_ebreak_status != value){ + printf("ERROR: check_ebreak_status(%d, %d): Tag=%d status=%d, exp=%d \n\n", + tag, value, tag, glb_ebreak_status, value); + TEST_FAILED; + } +} +void check_illegal_insn_status(int tag, int value) +{ + if(glb_illegal_insn_status != value){ + printf("ERROR: check_illegal_insn_status(%d, %d): Tag=%d status=%d, exp=%d \n\n", + tag, value, tag, glb_illegal_insn_status, value); + TEST_FAILED; + } +} +void delay(int count) { + for (volatile int d = 0; d < count; d++); +} + +void mstatus_mie_enable() { + int mie_bit = 0x1 << 3; + asm volatile("csrrs x0, mstatus, %0" : : "r" (mie_bit)); +} + +void mstatus_mie_disable() { + int mie_bit = 0x1 << 3; + asm volatile("csrrc x0, mstatus, %0" : : "r" (mie_bit)); +} + +void mie_enable_all() { + uint32_t mie_mask = (uint32_t) -1; + asm volatile("csrrs x0, mie, %0" : : "r" (mie_mask)); +} + +void mie_disable_all() { + uint32_t mie_mask = (uint32_t) -1; + asm volatile("csrrc x0, mie, %0" : : "r" (mie_mask)); +} + +void mie_enable(uint32_t irq) { + // Enable the interrupt irq in MIE + uint32_t mie_bit = 0x1 << irq; + asm volatile("csrrs x0, mie, %0" : : "r" (mie_bit)); +} + +void mie_disable(uint32_t irq) { + // Disable the interrupt irq in MIE + uint32_t mie_bit = 0x1 << irq; + asm volatile("csrrc x0, mie, %0" : : "r" (mie_bit)); +} + +void mm_ram_assert_irq(uint32_t mask, uint32_t cycle_delay) { + *TIMER_REG_ADDR = mask; + *TIMER_VAL_ADDR = 1 + cycle_delay; +} + +void counters_enable() { + // Enable counters mcycle (bit0) and minstret (bit2) + uint32_t mask = 1<<2 | 1<<0; + asm volatile("csrrc x0, 0x320, %0" : : "r" (mask)); +} +#define MACHINE 3 +int main(int argc, char *argv[]) +{ + unsigned int temp,temp1,temp2; + debug_req_control_t debug_req_control; + mstatus_t mstatus, mstatus_cmp; + counters_enable(); + printf("\nBasic test checking debug functionality.\n"); + + printf("------------------------\n"); + printf(" Test1: check initialization values\n"); + //check_debug_status(0,0); + + temp1 = 0xFFFFFFFF; + /* get relevant CSRs and compare init values*/ + __asm__ volatile("csrr %0, mstatus" : "=r"(temp1)); + __asm__ volatile("csrw mstatus, %0 " : "=r"(temp1)); + __asm__ volatile("csrr %0, mstatus" : "=r"(mstatus.bits)); + __asm__ volatile("csrr %0, mie" : "=r"(temp)); + __asm__ volatile("csrw mie, %0 " : "=r"(temp1)); + __asm__ volatile("csrr %0, mie" : "=r"(temp2)); + printf("\tmstats_rval = 0x%0x 0x%0x 0x%0x 0x%0x\n",temp2,mstatus.bits,temp,temp1); + + check_debug_status(0,0); + printf("------------------------\n"); + printf(" Test2.1: check access to Debug and Trigger registers\n"); + // debug specifcation 13.2: 4.8 Core Debug Registers are not accessable unless in debug mode + + // ---------------------- + // Check Debug Write Access + temp = 0xFFFFFFFF; + temp1 = glb_illegal_insn_status+1; + glb_expect_illegal_insn = 1; + __asm__ volatile("csrw dcsr, %0" : "=r"(temp)); // Debug DCSR + check_illegal_insn_status(11,temp1++); + glb_expect_illegal_insn = 1; + __asm__ volatile("csrw dpc, %0" : "=r"(temp)); // Debug DPC + check_illegal_insn_status(12,temp1++); + glb_expect_illegal_insn = 1; + __asm__ volatile("csrw dscratch, %0" : "=r"(temp)); // Debug DSCRATCH0 + check_illegal_insn_status(13,temp1++); + glb_expect_illegal_insn = 1; + __asm__ volatile("csrw 0x7b3, %0" : "=r"(temp)); // Debug DSCRATCH1 + check_illegal_insn_status(14,temp1++); + + // Check Read Access + temp1 = glb_illegal_insn_status+1; + // Allow illegal instruction handler to run + glb_expect_illegal_insn = 1; + __asm__ volatile("csrr %0, dcsr" : "=r"(temp)); // Debug DCSR + check_illegal_insn_status(1,temp1++); + glb_expect_illegal_insn = 1; + __asm__ volatile("csrr %0, dpc" : "=r"(temp)); // Debug DPC + check_illegal_insn_status(2,temp1++); + glb_expect_illegal_insn = 1; + __asm__ volatile("csrr %0, dscratch": "=r"(temp)); // Debug DSCRATCH0 + check_illegal_insn_status(3,temp1++); + glb_expect_illegal_insn = 1; + __asm__ volatile("csrr %0, 0x7b3" : "=r"(temp)); // Debug DSCRATCH1 + check_illegal_insn_status(4,temp1++); + + printf("------------------------\n"); + printf(" Test2.2: check access to Trigger registers\n"); + + // NOTE: As of July 2024, CVA6 does not implement the trigger module. + // TODO: Consider adding trigger module support in future revisions. + + // Writes are ignored + temp = 0xFFFFFFFF; //TODO:MT should these be writes? + __asm__ volatile("csrw 0x7a0, %0" : "=r"(temp)); // Trigger TSELECT + __asm__ volatile("csrw 0x7a1, %0" : "=r"(temp)); // Trigger TDATA1 + __asm__ volatile("csrw 0x7a2, %0" : "=r"(temp)); // Trigger TDATA2 + __asm__ volatile("csrw 0x7a3, %0" : "=r"(temp)); // Trigger TDATA3 + __asm__ volatile("csrw 0x7a4, %0" : "=r"(temp)); // Trigger TINFO + + // Read default value + __asm__ volatile("csrr %0, 0x7a0" : "=r"(temp)); // Trigger TSELECT + // CVA6 if(temp != 0x0){printf("ERROR: TSELET Read\n");TEST_FAILED;} + + __asm__ volatile("csrr %0, 0x7a1" : "=r"(temp)); // Trigger TDATA1 + // CVA6 // 31:28 type = 2 + // CVA6 // 27 dmode = 1 + // CVA6 // 15:12 action = 1 + // CVA6 // 6 m(achine) = 1 + // CVA6 if(temp != (2<<28 | 1<<27 | 1<<12 | 1<<6)){printf("ERROR: TDATA1 Read\n");TEST_FAILED;} + + __asm__ volatile("csrr %0, 0x7a2" : "=r"(temp)); // Trigger TDATA2 + // CVA6 if(temp != 0x0){printf("ERROR: TDATA2 Read\n");TEST_FAILED;} + + __asm__ volatile("csrr %0, 0x7a3" : "=r"(temp)); // Trigger TDATA3 + // CVA6 if(temp != 0x0){printf("ERROR: TDATA3 Read\n");TEST_FAILED;} + + __asm__ volatile("csrr %0, 0x7a4" : "=r"(temp)); // Trigger TINFO + // CVA6 // tmatch = 1<<2 + // CVA6 if(temp != 1<<2){printf("ERROR: TINFO Read %d \n",temp);TEST_FAILED;} + + + // Do not expect or allow any more illegal instructions + + + mstatus_cmp = (mstatus_t) { + .fields.mpp = MACHINE // + }; + if(mstatus_cmp.bits != mstatus.bits) {printf("ERROR: init mstatus mismatch exp=%x val=%x\n", + mstatus_cmp.bits, mstatus.bits); TEST_FAILED;} + //TODO:MT are these switched up? + printf("------------------------\n"); + printf(" Test3.1: check hart ebreak executes ebreak handler but does not execute debugger code\n"); + glb_expect_ebreak_handler = 1; + asm volatile("c.ebreak"); + check_ebreak_status(32,1); + + printf("------------------------\n"); + printf(" Test3.2: check hart c.ebreak executes ebreak handler but does not execute debugger code\n"); + glb_expect_ebreak_handler = 1; + asm volatile(".4byte 0x00100073"); + check_ebreak_status(32,2); + + printf("------------------------\n"); + printf(" Test4: request hardware debugger\n"); + + debug_req_control = (debug_req_control_t) { + .fields.value = 1, + .fields.pulse_mode = 1, //PULSE Mode + .fields.rand_pulse_width = 0, + .fields.pulse_width = 5,// TODO:MT determine pulse width with non-sticky debug_req + .fields.rand_start_delay = 0, + .fields.start_delay = 200 + }; + glb_expect_debug_entry = 1; + DEBUG_REQ_CONTROL_REG = debug_req_control.bits; + + glb_hart_status = 4; // Basic test + while(glb_debug_status != glb_hart_status){ + printf("Wait for Debugger\n"); + } + check_debug_status(41,glb_hart_status); + + printf("------------------------\n"); + printf(" Test5: have debugger execute ebreak 3 more times\n"); + + glb_hart_status = 5; + glb_expect_debug_entry = 1; + DEBUG_REQ_CONTROL_REG = debug_req_control.bits; + while(glb_debug_status != (5+3)){ + printf("Wait for Debugger\n"); + } + check_debug_status(51,(5+3)); + + printf("------------------------\n"); + printf(" Test6: Test CSR access and default values in debug mode\n"); + glb_hart_status = 6; + glb_expect_debug_entry = 1; + DEBUG_REQ_CONTROL_REG = debug_req_control.bits; + while(glb_debug_status != glb_hart_status){ + printf("Wait for Debugger\n"); + } + check_debug_status(61,glb_hart_status); + + + printf("------------------------\n"); + printf(" Test10: check hart ebreak executes debugger code\n"); + glb_hart_status = 10; + glb_expect_debug_entry = 1; + asm volatile(".4byte 0x00100073"); + check_debug_status(33,glb_hart_status); + + printf("------------------------\n"); + printf(" Test11: check illegal csr exception during debug launches debugger exception and no csr modified\n"); + glb_hart_status = 11; + glb_expect_debug_entry = 1; + glb_expect_debug_exception = 1; + DEBUG_REQ_CONTROL_REG = debug_req_control.bits; + while(glb_debug_status != glb_hart_status){ + printf("Wait for Debugger\n"); + } + check_debug_status(111,glb_hart_status); + check_debug_exception_status(111,glb_hart_status); + //FIXME TBD BUG : need to update test to check actual csrs not modified. + + printf("------------------------\n"); + printf(" Test12: check ecall exception during debug launches debugger exception and no csr modified\n"); + glb_hart_status = 12; + glb_expect_debug_entry = 1; + glb_expect_debug_exception = 1; + DEBUG_REQ_CONTROL_REG = debug_req_control.bits; + while(glb_debug_status != glb_hart_status){ + printf("Wait for Debugger\n"); + } + check_debug_status(112,glb_hart_status); + check_debug_exception_status(112,glb_hart_status); + //FIXME TBD BUG : need to update test to check actual csrs not modified. + + printf("------------------------\n"); + printf(" Test13: check mret during debug launches debugger exception and no csr modified\n"); + glb_hart_status = 13; + glb_expect_debug_entry = 1; + glb_expect_debug_exception = 1; + DEBUG_REQ_CONTROL_REG = debug_req_control.bits; + while(glb_debug_status != glb_hart_status){ + printf("Wait for Debugger\n"); + } + check_debug_status(113,glb_hart_status); + check_debug_exception_status(113,glb_hart_status); + + printf("------------------------\n"); + printf(" Test14: Check exception ebreak enters debug mode\n"); + glb_hart_status = 14; + glb_expect_illegal_insn = 1; + glb_exception_ebreak_status = 1; + glb_expect_debug_entry = 1; + + // DCSR read will cause illegal instruction. + // Exception routine reads glb_exception_ebreak_status=1 and executes c.ebreak + __asm__ volatile("csrr %0, dcsr" : "=r"(temp)); // Debug DCSR + + while(glb_debug_status != glb_hart_status){ + printf("Wait for Debugger\n"); + } + + check_illegal_insn_status(114,temp1++); + check_debug_status(114, glb_hart_status); + printf("----------------------\n"); + printf("Test 16: dret in m-mode causes exception\n"); + + glb_expect_illegal_insn = 1; + __asm__ volatile("dret"); + check_illegal_insn_status(16, temp1++); + + printf("------------------------\n"); + printf("Test 17: WFI before debug_req_i and WFI in debug mode\n"); + printf("If test hangs, WFI is NOT converted to NOP\n"); + + glb_expect_debug_entry = 1; + glb_hart_status = 17; + // start_delay is set to 200, should get the wfi executing before dbg request is asserted + DEBUG_REQ_CONTROL_REG = debug_req_control.bits; + + // Execute WFI, when debug is asserted, it will act as NOP and enter debug mode + // If not, test will hang + __asm__ volatile("wfi"); + check_debug_status(117, glb_hart_status); + + printf("----------------------\n"); + printf("Checking interrupt, as this is needed by later tests\n"); + + // Assert and check irq, as this is needed by some tests. + mstatus_mie_enable(); + mie_enable(30); + glb_expect_irq_entry = 1; + mm_ram_assert_irq(0x40000000, 1); + while(glb_expect_irq_entry == 1); + mm_ram_assert_irq(0,0); + printf("Irq check done\n"); + + // Check that stoupcount bit (10) in dcsr has no affect + printf("-------------------------\n"); + printf("Test 21: Setting stopcount bit=1\n"); + glb_expect_debug_entry = 1; + glb_hart_status = 21; + + DEBUG_REQ_CONTROL_REG = debug_req_control.bits; + while(glb_debug_status != glb_hart_status){ + printf("Wait for Debugger\n"); + } + check_debug_status(121, glb_hart_status); + + + printf("------------------------\n"); + printf("Test 18: Single stepping\n"); + glb_hart_status = 18; + + // Run single step code (in single_step.S) + _single_step(0); + + // Single step code should generate 2 illegal insn + temp1++; + check_illegal_insn_status(118, temp1++); + check_debug_status(118, glb_hart_status); + + printf("Stepped %d times\n", glb_step_count); + + + printf("------------------------\n"); + printf("Test 19: irq in debug\n"); + glb_hart_status = 19; + glb_expect_debug_entry = 1; + + // Does not expect irq to be taken while in debug mode + // but it will be taken when we exit from debug. + // Timeout added in debug code to check for taken irq or not + glb_expect_irq_entry = 1; + DEBUG_REQ_CONTROL_REG=debug_req_control.bits; + + while(glb_debug_status != glb_hart_status){ + printf("Wait for Debugger\n"); + } + + check_debug_status(119, glb_hart_status); + if(glb_irq_timeout != 0) { + printf("glb_irq_timeout != 0, interrupt taken in debug.\n"); + TEST_FAILED; + } + + // Test debug req vs irq timing + printf("-----------------------\n"); + printf("Test 20: Asserting debug_req and irq at the same cycle\n"); + glb_expect_debug_entry = 1; + glb_expect_irq_entry = 1; + glb_hart_status = 20; + DEBUG_REQ_CONTROL_REG = debug_req_control.bits; + // 170 halts on first instuction in interrupt handler + // 175 gives same timing for interrupt and debug_req_i + mm_ram_assert_irq(0x40000000, 175+20); + + while(glb_debug_status != glb_hart_status){ + printf("Wait for Debugger\n"); + } + check_debug_status(120, glb_hart_status); + + + // Execute fence instruction in debug + printf("-----------------------------\n"); + printf("Test 22: Execute fence in debug mode\n"); + glb_expect_debug_entry = 1; + glb_hart_status = 22; + DEBUG_REQ_CONTROL_REG = debug_req_control.bits; + + while(glb_debug_status != glb_hart_status) { + printf("Wait for debugger\n"); + } + + check_debug_status(121, glb_hart_status); + + printf("------------------------\n"); + printf("Test 23: trigger match in debug mode with match disabled\n"); + glb_hart_status = 23; + glb_expect_debug_entry = 1; + + // Request debug + DEBUG_REQ_CONTROL_REG = debug_req_control.bits; + + while(glb_debug_status != glb_hart_status){ + printf("Wait for Debugger\n"); + } + + check_debug_status(123, glb_hart_status); + printf("------------------------\n"); + printf("Test 24: trigger register access in D-mode\n"); + glb_hart_status = 24; + glb_expect_debug_entry = 1; + + // Request debug + DEBUG_REQ_CONTROL_REG = debug_req_control.bits; + + while(glb_debug_status != glb_hart_status){ + printf("Wait for Debugger\n"); + } + + check_debug_status(124, glb_hart_status); + + //-------------------------------- + //return EXIT_FAILURE; + printf("------------------------\n"); + printf("Finished \n"); + return EXIT_SUCCESS; +} diff --git a/verif/tests/custom/debug_test/debugger.S b/verif/tests/custom/debug_test/debugger.S new file mode 100644 index 0000000000..d7ab3f045d --- /dev/null +++ b/verif/tests/custom/debug_test/debugger.S @@ -0,0 +1,642 @@ + +/* +** +** Copyright 2020 OpenHW Group +** +** Licensed under the Solderpad Hardware Licence, 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 +** +** https://solderpad.org/licenses/ +** +** 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. +** +******************************************************************************* +** Debugger code +******************************************************************************* +*/ + +#include "corev_uvmt.h" + +.section .debugger, "ax" +.global _debugger_start +.global glb_debug_status +.global glb_hart_status +.global glb_expect_debug_entry +.global glb_step_info +.global glb_previous_dpc +.global glb_step_count +.global glb_irq_timeout +.global glb_mcycle_start +.global glb_mcycle_end +.global glb_minstret_start +.global glb_minstret_end +.global _step_trig_point +.global __debugger_stack_start +.global _debugger_fail +.global _debugger_end +.set timer_reg_addr, CV_VP_INTR_TIMER_BASE+0 +.set timer_val_addr, CV_VP_INTR_TIMER_BASE+4 +.set test_ret_val, CV_VP_STATUS_FLAGS_BASE +.set test_fail, 0x1 + +_debugger_start: + // Debugger Stack + csrw dscratch, a0 // dscratch0 + la a0, __debugger_stack_start + //sw t0, 0(a0) + csrw 0x7b3, t0 // dscratch1 + sw t1, 4(a0) + sw t2, 8(a0) + sw a1, 12(a0) + sw a2, 16(a0) + // Check if expecting debug entry + la a1, glb_expect_debug_entry + lw t1, 0(a1) + beq x0,t1,_debugger_fail + + // Read lower 32 bits of mcycle and minstret + // and store in globals for check at exit + csrr t1, mcycle + csrr t2, minstret + la a1, glb_mcycle_start + sw t1, 0(a1) + la a1, glb_minstret_start + sw t2, 0(a1) + + // Determine Test to execute in debugger code based on glb_hart_status + la a2, glb_hart_status + lw t2, 0(a2) + + // ebreak test will loop in debugger code over several iterations + // and will increment the global status each time + li t0,5 + beq t2,t0,_debugger_ebreak // Test 5 + + // For all other tests, + // Set debug status = hart status + la a1, glb_debug_status + sw t2, 0(a1) + + li t0, 4 + beq t2,t0,_debugger_simple // Test 4 + + li t0,6 + beq t2,t0,_debugger_csr // Test 6 + + li t0,10 + beq t2,t0,_debugger_ebreak_entry // Test 10 + + li t0,11 + beq t2,t0,_debugger_csr_exception // Test 11 + + li t0,12 + beq t2,t0,_debugger_ecall_exception // Test 12 + + li t0,13 + beq t2,t0,_debugger_mret_call // Test 13 + + li t0,14 + beq t2,t0, _debugger_ebreak_entry // Test 14 + + + li t0,17 + beq t2,t0, _debugger_wfi_test // Test 17 + + li t0,18 + beq t2, t0, _debugger_single_step + + li t0, 19 + beq t2, t0, _debugger_irq + + li t0, 20 + beq t2, t0, _debugger_req_and_irq + + li t0, 21 + beq t2, t0, _debugger_stopcount + + li t0, 22 + beq t2, t0, _debugger_fence + + li t0, 23 + beq t2, t0, _debugger_trigger_disabled_in_debug + + li t0, 24 + beq t2, t0, _debugger_trigger_regs_access + +_debugger_trigger_regs_access: + # R/W trigger regs otherwise not accessed + # to close coverage holes + li t0, 0xff + csrw 0x7a4, t0 # tinfo + csrr t0, 0x7a4 + li t1, 4 + bne t0, t1, _debugger_fail + + li t0, 0xff + csrw 0x7a3, t0 # tdata3 + csrr t0, 0x7a3 + bne t0, x0, _debugger_fail + + li t0, 0xff + csrw 0x7a0, t0 # tsel + csrr t0, 0x7a0 + bne t0, x0, _debugger_fail + + j _debugger_end + + +_debugger_fence: + fence + nop + nop + fence.i + nop + nop + j _debugger_end + +_debugger_req_and_irq: + // Debug was requested at the same cycle as irq + // Check dpc to see that pc is not at irq handler + // IRQ used was 30, so addr would be 30*4=120, 0x78 + csrr t0, dpc + li t1, 0x78 + beq t0, t1, _debugger_fail + j _debugger_end + +_debugger_stopcount: + li t0, 1<<10 + csrrs x0, dcsr, t0 + j _debugger_end +_debugger_irq: + // Assert irq + li a1, timer_reg_addr + li t0, 0x40000000 + sw t0, 0(a1) + li a1, timer_val_addr + li t0, 2 + sw t0, 0(a1) + + li t1, 1000 +// Wait for 1000 cycles, then timeout +_irq_wait_loop: + la a1, glb_expect_irq_entry + lw t0, 0(a1); + beq t1, x0, _irq_loop_end + addi t1, t1, -1 + bne t0, x0, _irq_wait_loop +_irq_loop_end: + la a1, glb_irq_timeout + sw t1, 0(a1) + j _debugger_end + +_debugger_single_step: + // Copy step_info + la a1, glb_step_info + lw t0, 0(a1) + + // Check action to take + li t1, 0 + beq t0, t1, _debugger_single_step_basic + li t1, 1 + beq t0, t1, _debugger_single_step_enable + li t1, 2 + beq t0, t1, _debugger_single_step_disable + li t1, 3 + //beq t0, t1, _debugger_single_step_illegal_insn + beq t0, t1, _debugger_single_step_basic + li t1, 4 + beq t0, t1, _debugger_single_step_trig_setup + li t1, 5 + beq t0, t1, _debugger_single_step_stepie_enable + li t1, 6 + beq t0, t1, _debugger_single_step_stepie_disable + li t1, 7 + beq t0, t1, _debugger_single_step_cebreak + li t1, 8 + beq t0, t1, _debugger_single_step_ebreak + li t1, 9 + beq t0, t1, _debugger_single_step_ebreak_exception + li t1, 10 + beq t0, t1, _debugger_single_step_cebreak_exception + j _debugger_fail + +_debugger_single_step_stepie_disable: + // enable stepi + li t0, 4<<28 | 1<<15 | 1<<2 | 0<<11 + csrw dcsr, t0 + + j _debugger_single_step_end +_debugger_single_step_stepie_enable: + // enable stepi + li t0, 4<<28 | 1<<15 | 1<<2 | 1<<11 + csrw dcsr, t0 + + j _debugger_single_step_end +_debugger_single_step_enable: + // Check dcsr + csrr t0, dcsr + li t1, 4<<28 | 1<<15 | 1<<6 | 3<<0 + bne t0, t1, _debugger_fail + + // Enable step bit in dcsr + li t0, 4<<28 | 1<<15 | 1<<2 + csrw dcsr, t0 + + // ebreak used to enter single step test, incr dpc + csrr t0, dpc + addi t0, t0, 2 + csrw dpc, t0 + j _debugger_single_step_end + +_debugger_single_step_disable: + // Turn off single stepping + li t0, 1<<15 + csrw dcsr, t0 + // Clear glb_expect_debug entry + // as this will not be done in + // _debugger_end for single step + la a1, glb_expect_debug_entry + sw x0, 0(a1) + j _debugger_end + +_debugger_single_step_trig_setup: + // Set trigger to match on _step_trig_point + la t0, _step_trig_point + csrw tdata2,t0 + li t1, 1<<2 + csrw tdata1,t1 + li t1, 2<<28 | 1<<27 | 1<<12 | 1<<6 | 1 <<2 + csrr t2,tdata1 + bne t1,t2,_debugger_fail + j _debugger_single_step_basic + +_debugger_single_step_end: + // Store dpc to variable for checking in next step + la a1, glb_previous_dpc + csrr t0, dpc + sw t0, 0(a1) + + // Increase step count + la a1, glb_step_count + lw t0, 0(a1) + addi t0, t0, 1 + sw t0, 0(a1) + + // Clear step info if not 3 (exception) or 5 (irq while stepping) + // 6, 7 or 8, 9, 10 + // In exception test we expect jumps + // to mtvec and other places, so keep + // step info to waive dpc checks + la a1, glb_step_info + lw t0, 0(a1) + li t1, 3 + beq t0, t1, _debugger_end + li t1, 5 + beq t0, t1, _debugger_end + li t1, 6 + beq t0, t1, _debugger_end + li t1, 7 + beq t0, t1, _debugger_end + li t1, 8 + beq t0, t1, _debugger_end + li t1, 9 + beq t0, t1, _debugger_end + li t1, 10 + beq t0, t1, _debugger_end + li t1, 0 + sw t1, 0(a1) + + // return to m-mode + j _debugger_end + +_debugger_single_step_illegal_insn: + // Check dcsr + // ebreakm step stepen + li t1, 4<<28 | 1<<15 | 4<<6 | 1<<2 | 3<<0 + csrr t2, dcsr + bne t1, t2, _debugger_fail + // read dpc and mtvec + //csrr t0, dpc + //csrr t1, mtvec + //andi t1, t1, 0xffffff00 + //bne t0, t1, _debugger_fail + j _debugger_single_step_end + +_debugger_step_trig_entry: + // Advance dpc to skip first match instruction + csrr t0, dpc + la a1, _step_trig_exit + csrw dpc, a1 + j _debugger_single_step_end + +_debugger_single_step_cebreak: + # If cause == 1, we need to advance dpc by 2 + li t1, 4<<28 | 1<<15 | 1<<6 | 1<<2 | 3<<0 + csrr t2, dcsr + beq t1, t2, _inc_dpc_cebreak + + j _debugger_single_step_end +_inc_dpc_cebreak: + csrr t1, dpc + addi t1, t1, 2 + csrw dpc, t1 + j _debugger_single_step_end + +_debugger_single_step_ebreak: + # If cause == 1, we need to advance dpc by 4 + li t1, 4<<28 | 1<<15 | 1<<6 | 1<<2 | 3<<0 + csrr t2, dcsr + beq t1, t2, _inc_dpc_ebreak + + j _debugger_single_step_end +_inc_dpc_ebreak: + csrr t1, dpc + addi t1, t1, 4 + csrw dpc, t1 + + # Turn off dcsr.ebreakm for next two tests + li t1, 4<<28 | 0<<15 | 1<<6 | 1<<2 | 3<<0 + csrw dcsr, t1 + j _debugger_single_step_end + +_debugger_single_step_ebreak_exception: + j _debugger_single_step_end + +_debugger_single_step_cebreak_exception: + # depc != 0 => we have passed the first + # instruction of the handler, and we can + # set dcsr.ebreakm again + csrr t0, dpc + bne t0, x0, _end + + li t1, 4<<28 | 1<<15 | 1<<6 | 1<<2 | 3<<0 + csrw dcsr, t1 + +_end: + j _debugger_single_step_end + +_debugger_single_step_basic: + // Check dcsr, jump to match-in-step if flagged in dcsr + li t1, 4<<28 | 1<<15 | 2<<6 | 1<<2 | 3<<0 + csrr t2, dcsr + beq t1, t2, _debugger_step_trig_entry + + + // Ensure tval (0x343) always == 0 + csrr t1, 0x343 + bne x0, t1, _debugger_fail +// ebreakm step stepen + li t1, 4<<28 | 1<<15 | 4<<6 | 1<<2 | 3<<0 + bne t1, t2, _debugger_fail + // Check that dpc increased by 2 or 4 + csrr t0, dpc + la a1, glb_previous_dpc + lw t1, 0(a1) + sub t0, t0, t1 + li t1, 2 + beq t0, t1, _debugger_single_step_end + li t1, 4 + beq t0, t1, _debugger_single_step_end + + // Waive dpc errors if we expect illegal instruction + la a1, glb_step_info + lw t0, 0(a1) + li t1, 3 +// bne t0, t1, _debugger_fail + j _debugger_single_step_end + +_debugger_csr_exception: + csrr t2,0xea8 // illegal insn + +_debugger_ecall_exception: + ecall // exception + +_debugger_mret_call: + mret // will invoke debugger exception routine + +_debugger_ebreak_entry: + la a1, glb_debug_status + li t1, 4<<28 | 1<<6 | 3<<0 | 1<<15 + csrr t2,dcsr + bne t1,t2,_debugger_fail + csrr a1,dpc + addi a1,a1,4 # uncompressed ebreak used to enter debug here + csrw dpc,a1 + //sw t1, 0(a1) + j _debugger_end + +_debugger_simple: + // Check cause 0x3, debugger + csrr t2,dcsr + li t1, 4<<28 | 3<<6 | 3<<0 + bne t1, t2, _debugger_fail + + //csrr t2,0xea8 // illegal insn + li t1, 1 + //sw t1, 0(a1) + j _debugger_end + +_debugger_csr: + // Check CSR access + // When done, set the ebreakm bit to allow next test to enter debug with ebreak + + // TBD BUG FIXME : make sure appropriate list of CSR (from sspecifications) + //csrr t2,mvendorid + //csrr t2,marchid + //csrr t2,mimpid + csrr t2,mhartid + + // machine trap setup + csrr t2,mstatus + csrr t2,misa + csrr t2,mie + csrr t2,mtvec + //FIXME csrr t2,mtval + + // machine trap handling + csrr t2,mscratch + csrr t2,mepc + csrr t2,mcause + csrr t2,mip + + // ----------------------- + // Debug CSRs + + // Expect DCSR + // 31:28 XDEBUGER Version = 4 + // 8:6 Cause = 3 debugger + // 1:0 Privelege = 3 Machine + // TBD FIXME BUG documentation update needed + li t1, 4<<28 | 3<<6 | 3<<0 + csrr t2,dcsr + bne t1,t2,_debugger_fail + csrr t2,dpc + beq x0,t2,_debugger_fail + //Already test this csrr t2,dscratch //dscratch0 + //Already test this csrr t2,0x7b3 //dscratch1 + + // Set ebreakm in dcsr + li t1, 4<<28 | 3<<6 | 3<<0| 1<<15 + csrw dcsr, t1 + + // ---------------------- + // Trigger CSRs + + // Expect TMATCH=TDATA1 + // 31:28 type = 2 + // 27 dmode = 1 + // 15:12 action = 1 + // 6 m(achine) = 1 + li t1, 2<<28 | 1<<27 | 1<<12 | 1<<6 + csrr t2,tdata1 + bne t1,t2,_debugger_fail + csrr t2,tselect + bne x0,t2,_debugger_fail + csrr t2,tdata2 + bne x0,t2,_debugger_fail + csrr t2,tdata3 + bne x0,t2,_debugger_fail + + j _debugger_end + +_debugger_ebreak: + li t0, 4<<28 | 3<<6 | 3<<0 + csrr t1, dcsr + bne t0, t1, _debugger_fail + // Increment glb_debug_status + la a1, glb_debug_status + lw t1, 0(a1) + addi t1,t1,1 + sw t1, 0(a1) + // Repeat executing debug code until debug status = hart_status + 3 + addi t0, t2, 3 + beq t1, t0, _debugger_end + // Execute non-compressed ebreak for iteration 2 + addi t0, t2, 2 + beq t1, t0, _uncompressed_ebreak + // Debugger Un-Stack and call debugger code from start using ebreak + csrr t0, 0x7b3 + lw t1, 4(a0) + lw t2, 8(a0) + lw a1, 12(a0) + lw a2, 16(a0) + csrr a0, dscratch + ebreak +_uncompressed_ebreak: + // Debugger Un-Stack and call debugger code from start using ebreak + csrr t0, 0x7b3 + lw t1, 4(a0) + lw t2, 8(a0) + lw a1, 12(a0) + lw a2, 16(a0) + csrr a0, dscratch + .4byte 0x00100073 # ebreak + +_debugger_trigger_in_debug: + // setup address to trigger on + la a1, _debugger_trig_point + csrw tdata2,a1 + li t1, 1<<2 + csrw tdata1,t1 + li t1, 2<<28 | 1<<27 | 1<<12 | 1<<6 | 1 <<2 + csrr t2,tdata1 + bne t1,t2,_debugger_fail + + // Clear glb_expect_debug_entry + // If we trig, we'll reenter debug and + // test will fail due to 0 flag + la a1, glb_expect_debug_entry + li t1, 0 + sw t1, 0(a1) +_debugger_trig_point: + // Should _not_trig here + nop + // Clear trigger + li t1, 0<<2 + csrw tdata1, t1 + j _debugger_end + +_debugger_trigger_disabled_in_debug: + // setup address to trigger on + la a1, _debugger_trig_point_dis + // Set trig enable to 0 + csrw tdata2,a1 + li t1, 0<<2 + csrw tdata1,t1 + li t1, 2<<28 | 1<<27 | 1<<12 | 1<<6 | 0 <<2 + csrr t2,tdata1 + bne t1,t2,_debugger_fail + + // Clear glb_expect_debug_entry + // If we trig, we'll reenter debug and + // test will fail due to 0 flag + la a1, glb_expect_debug_entry + li t1, 0 + sw t1, 0(a1) +_debugger_trig_point_dis: + // Should _not_trig here + nop + // Clear trigger + li t1, 0<<2 + csrw tdata1, t1 + j _debugger_end +_debugger_wfi_test: + la a1, glb_debug_status + csrr t2,dcsr + // ebreakm is set by previous test + li t1, 4<<28 | 3<<6 | 3<<0 | 1<<15 + bne t1, t2, _debugger_fail + + // If the following wfi is not converted + // to a nop, test will hang + wfi + j _debugger_end + +_debugger_end: + // Check counter values. + csrr t1, mcycle + la a1, glb_mcycle_start + lw t2, 0(a1) + sub t1, t1, t2 + beq t1, x0, _debugger_fail + + csrr t1, minstret + la a1, glb_minstret_start + lw t2, 0(a1) + sub t1, t1, t2 + beq t1, x0, _debugger_fail + + // If single stepping, do not clear + la a1, glb_hart_status + lw t0, 0(a1) + li t1, 18 + beq t0, t1, _debugger_end_continue + + // Clear debug entry expectation flag + la a1, glb_expect_debug_entry + sw x0, 0(a1) +_debugger_end_continue: + // Debugger Un-Stack + //lw t0, 0(a0) + la a0, __debugger_stack_start + csrr t0, 0x7b3 + lw t1, 4(a0) + lw t2, 8(a0) + lw a1, 12(a0) + lw a2, 16(a0) + csrr a0, dscratch + dret +_debugger_fail: //Test Failed + li a0, CV_VP_STATUS_FLAGS_BASE + li t0, test_fail + sw t0, 0(a0) + nop + nop + nop + nop + diff --git a/verif/tests/custom/debug_test/debugger_exception.S b/verif/tests/custom/debug_test/debugger_exception.S new file mode 100644 index 0000000000..d3d1e9dd4c --- /dev/null +++ b/verif/tests/custom/debug_test/debugger_exception.S @@ -0,0 +1,77 @@ + +/* +** +** Copyright 2020 OpenHW Group +** +** Licensed under the Solderpad Hardware Licence, 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 +** +** https://solderpad.org/licenses/ +** +** 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. +** +******************************************************************************* +** Debugger Exception code +******************************************************************************* +*/ + +#include "corev_uvmt.h" + +.section .debugger_exception, "ax" +.global _debugger_exception_start +.global glb_debug_status +.global glb_hart_status +.global glb_debug_exception_status +.global glb_expect_debug_exception +//.global _debugger_fail +//.global _debugger_end +.set test_fail, 0x1 + +_debugger_exception_start: + // First check to see if exception was expected + la a1, glb_expect_debug_exception + lw t1, 0(a1) + //beq x0,t1,_debugger_fail + beq x0,t1,_debugger_exception_fail + + // Set exception status to hart status + la a1, glb_hart_status + lw t1, 0(a1) + la a2, glb_debug_exception_status + sw t1, 0(a2) + + //j _debugger_end + j _debugger_exception_end + +// Should be exact same function as implmented in debugger.S + // I can't seem to point to that symble from this file +_debugger_exception_end: + // Clear debug entry expectation flag + la a1, glb_expect_debug_entry + sw x0, 0(a1) + la a1, glb_expect_debug_exception + sw x0, 0(a1) + // Debugger Un-Stack + //lw t0, 0(a0) + csrr t0, 0x7b3 + lw t1, 4(a0) + lw t2, 8(a0) + lw a1, 12(a0) + lw a2, 16(a0) + csrr a0, dscratch + dret +// Should be exact same function as implmented in debugger.S +_debugger_exception_fail: + li a0, CV_VP_STATUS_FLAGS_BASE + li t0, test_fail + sw t0, 0(a0) + nop + nop + nop + nop + diff --git a/verif/tests/custom/debug_test/handlers.S b/verif/tests/custom/debug_test/handlers.S new file mode 100644 index 0000000000..0bdee311f8 --- /dev/null +++ b/verif/tests/custom/debug_test/handlers.S @@ -0,0 +1,349 @@ +/* +* Copyright 2019 ETH Zürich and University of Bologna +* +* 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. +*/ + +#include "corev_uvmt.h" + +/* Exception codes */ +#define EXCEPTION_ILLEGAL_INSN 2 +#define EXCEPTION_BREAKPOINT 3 +#define EXCEPTION_ECALL_M 11 + +.section .text.handlers +.global __no_irq_handler +.global u_sw_irq_handler +.global m_software_irq_handler +.global m_timer_irq_handler +.global m_external_irq_handler +.global m_fast0_irq_handler +.global m_fast1_irq_handler +.global m_fast2_irq_handler +.global m_fast3_irq_handler +.global m_fast4_irq_handler +.global m_fast5_irq_handler +.global m_fast6_irq_handler +.global m_fast7_irq_handler +.global m_fast8_irq_handler +.global m_fast9_irq_handler +.global m_fast10_irq_handler +.global m_fast11_irq_handler +.global m_fast12_irq_handler +.global m_fast13_irq_handler +.global m_fast14_irq_handler +.global m_fast15_irq_handler + +.weak m_software_irq_handler +.weak m_timer_irq_handler +.weak m_external_irq_handler +.weak m_fast0_irq_handler +.weak m_fast1_irq_handler +.weak m_fast2_irq_handler +.weak m_fast3_irq_handler +.weak m_fast4_irq_handler +.weak m_fast5_irq_handler +.weak m_fast6_irq_handler +.weak m_fast7_irq_handler +.weak m_fast8_irq_handler +.weak m_fast9_irq_handler +.weak m_fast10_irq_handler +.weak m_fast11_irq_handler +.weak m_fast12_irq_handler +.weak m_fast13_irq_handler +.weak m_fast14_irq_handler +.weak m_fast15_irq_handler + +.global glb_illegal_insn_status +.global glb_ebreak_status +.global glb_expect_illegal_insn +.global glb_expect_ebreak_handler +.global glb_exception_ebreak_status +.global glb_expect_irq_entry +.set test_ret_val, CV_VP_STATUS_FLAGS_BASE +.set test_fail, 0x1 + +/* exception handling */ +__no_irq_handler: + addi sp,sp,-64 + sw ra, 0(sp) + sw a0, 4(sp) + sw a1, 8(sp) + sw a2, 12(sp) + sw a3, 16(sp) + sw a4, 20(sp) + sw a5, 24(sp) + sw a6, 28(sp) + sw a7, 32(sp) + sw t0, 36(sp) + sw t1, 40(sp) + sw t2, 44(sp) + sw t3, 48(sp) + sw t4, 52(sp) + sw t5, 56(sp) + sw t6, 60(sp) + + la a0, no_exception_handler_msg + jal ra, puts + + // Check if we expected to enter irq + la a1, glb_expect_irq_entry + lw t0, 0(a1) + beq t0, x0, _irq_fail + + // Clear entry flag + li t0, 0 + sw t0, 0(a1) + //j __no_irq_handler + + // Return + lw ra, 0(sp) + lw a0, 4(sp) + lw a1, 8(sp) + lw a2, 12(sp) + lw a3, 16(sp) + lw a4, 20(sp) + lw a5, 24(sp) + lw a6, 28(sp) + lw a7, 32(sp) + lw t0, 36(sp) + lw t1, 40(sp) + lw t2, 44(sp) + lw t3, 48(sp) + lw t4, 52(sp) + lw t5, 56(sp) + lw t6, 60(sp) + addi sp,sp,64 + mret + +_irq_fail: + li a0, CV_VP_STATUS_FLAGS_BASE + li t0, test_fail + sw t0, 0(a0) + ret + +u_sw_irq_handler: + /* While we are still using puts in handlers, save all caller saved + regs. Eventually, some of these saves could be deferred. */ + addi sp,sp,-64 + sw ra, 0(sp) + sw a0, 4(sp) + sw a1, 8(sp) + sw a2, 12(sp) + sw a3, 16(sp) + sw a4, 20(sp) + sw a5, 24(sp) + sw a6, 28(sp) + sw a7, 32(sp) + sw t0, 36(sp) + sw t1, 40(sp) + sw t2, 44(sp) + sw t3, 48(sp) + sw t4, 52(sp) + sw t5, 56(sp) + sw t6, 60(sp) + csrr t0, mcause + li t1, EXCEPTION_ILLEGAL_INSN + beq t0, t1, handle_illegal_insn + li t1, EXCEPTION_ECALL_M + beq t0, t1, handle_ecall + li t1, EXCEPTION_BREAKPOINT + beq t0, t1, handle_ebreak + j handle_unknown + +handle_ecall: + la a0, ecall_msg + jal ra, handle_syscall + j end_handler_incr_mepc + +m_software_irq_handler: + j __no_irq_handler + +m_timer_irq_handler: + j __no_irq_handler + +m_external_irq_handler: + j __no_irq_handler + +m_fast0_irq_handler: + j __no_irq_handler + +m_fast1_irq_handler: + j __no_irq_handler + +m_fast2_irq_handler: + j __no_irq_handler + +m_fast3_irq_handler: + j __no_irq_handler + +m_fast4_irq_handler: + j __no_irq_handler + +m_fast5_irq_handler: + j __no_irq_handler + +m_fast6_irq_handler: + j __no_irq_handler + +m_fast7_irq_handler: + j __no_irq_handler + +m_fast8_irq_handler: + j __no_irq_handler + +m_fast9_irq_handler: + j __no_irq_handler + +m_fast10_irq_handler: + j __no_irq_handler + +m_fast11_irq_handler: + j __no_irq_handler + +m_fast12_irq_handler: + j __no_irq_handler + +m_fast13_irq_handler: + j __no_irq_handler + +m_fast14_irq_handler: + j __no_irq_handler + +m_fast15_irq_handler: + j __no_irq_handler + + +handle_ebreak: + /* TODO support debug handling requirements. */ + la a0, ebreak_msg + jal ra, puts + // Check if expecting ebreak handler + la a0, glb_expect_ebreak_handler + lw t0, 0(a0) + bne t0, x0, cont_handle_ebreak + // Not expecting ebreak, assert test failed + li a0, CV_VP_STATUS_FLAGS_BASE + li t0, 1 + sw t0, 0(a0) + j end_handler_incr_mepc +cont_handle_ebreak: + //increment hart status + sw x0, 0(a0) + la a0, glb_ebreak_status + lw t0, 0(a0) + addi t0,t0,1 + sw t0, 0(a0) + j end_handler_incr_mepc + + + +handle_illegal_insn: + la a0, illegal_insn_msg + jal ra, puts + // Check if expecting illegal instruction + la a0, glb_expect_illegal_insn + lw t0, 0(a0) + bne t0, x0, cont_illegal_insn + li a0, CV_VP_STATUS_FLAGS_BASE + li t0, 1 + sw t0, 0(a0) //Test Failed + j end_handler_incr_mepc +cont_illegal_insn: + //increment hart status + sw x0, 0(a0) + la a0, glb_illegal_insn_status + lw t0, 0(a0) + addi t0,t0,1 + sw t0, 0(a0) + + // Check if we are expected to execute ebreak + la a0, glb_exception_ebreak_status + lw t0, 0(a0) + // End handler if no ebreak is to be executed + beq t0, x0, end_handler_incr_mepc + + // Clear ebreak flag + sw x0, 0(a0) + // Execute ebreak + .4byte 0x00100073 + // Exit handler + j end_handler_incr_mepc + + j end_handler_incr_mepc + + + + + + + +handle_unknown: + la a0, unknown_msg + jal ra, puts + /* We don't know what interrupt/exception is being handled, so don't + increment mepc. */ + j end_handler_ret + + + + + + +end_handler_incr_mepc: + csrr t0, mepc + lb t1, 0(t0) + li a0, 0x3 + and t1, t1, a0 + /* Increment mepc by 2 or 4 depending on whether the instruction at mepc + is compressed or not. */ + bne t1, a0, end_handler_incr_mepc2 + addi t0, t0, 2 +end_handler_incr_mepc2: + addi t0, t0, 2 + csrw mepc, t0 +end_handler_ret: + lw ra, 0(sp) + lw a0, 4(sp) + lw a1, 8(sp) + lw a2, 12(sp) + lw a3, 16(sp) + lw a4, 20(sp) + lw a5, 24(sp) + lw a6, 28(sp) + lw a7, 32(sp) + lw t0, 36(sp) + lw t1, 40(sp) + lw t2, 44(sp) + lw t3, 48(sp) + lw t4, 52(sp) + lw t5, 56(sp) + lw t6, 60(sp) + addi sp,sp,64 + mret +/* this interrupt can be generated for verification purposes, random or when the + PC is equal to a given value*/ +verification_irq_handler: + mret + +.section .rodata +illegal_insn_msg: + .string "illegal instruction exception handler entered\n" +ecall_msg: + .string "ecall exception handler entered\n" +ebreak_msg: + .string "ebreak exception handler entered\n" +unknown_msg: + .string "unknown exception handler entered\n" +no_exception_handler_msg: + .string "no exception handler installed\n" diff --git a/verif/tests/custom/debug_test/single_step.S b/verif/tests/custom/debug_test/single_step.S new file mode 100644 index 0000000000..4337b197fe --- /dev/null +++ b/verif/tests/custom/debug_test/single_step.S @@ -0,0 +1,233 @@ +#Copyright 202[x] Silicon Labs, Inc. + +#This file, and derivatives thereof are licensed under the +#Solderpad License, Version 2.0 (the "License"); +#Use of this file means you agree to the terms and conditions +#of the license and are in full compliance with the License. +#You may obtain a copy of the License at +# +# https://solderpad.org/licenses/SHL-2.0/ +# +#Unless required by applicable law or agreed to in writing, software +#and hardware implementations thereof +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESSED OR IMPLIED. +#See the License for the specific language governing permissions and +#limitations under the License. + +#include "corev_uvmt.h" + +.section .single_step_code_sect, "ax" +.set timer_reg_addr, CV_VP_INTR_TIMER_BASE+0 +.set timer_val_addr, CV_VP_INTR_TIMER_BASE+4 +.set test_ret_val, CV_VP_STATUS_FLAGS_BASE +.set test_fail, 0x1 + +.global glb_step_info +.global glb_expect_debug_entry +.global glb_expect_illegal_insn +.global glb_expect_irq_entry +.global _step_trig_point +.global _step_trig_exit +.global _single_step + + +_single_step: + addi sp,sp,-30 + sw t0, 0(sp) + sw t1, 4(sp) + sw a0, 8(sp) + sw a1, 12(sp) + sw a2, 16(sp) + sw ra, 20(sp) + + // Expect debug + la a1, glb_expect_debug_entry + li t0, 1 + sw t0, 0(a1) + + // Set step cause to 1 - enable single stepping + la a1, glb_step_info + li t0, 1 + sw t0, 0(a1) + + // Set t0 to 0 + li t0, 0 + + // Enter debug mode to execute cause=1 + c.ebreak + + // To check if debug code increments DPC correctly, + // Load up t0 in first instruction after ebreak + li t0, 1 + beq t0, x0, _single_step_fail + + // We are single stepping, WFI should complete as NOP + // Test will hang here if WFI is not converted properly + wfi + + // illegal instruction + la a1, glb_expect_illegal_insn + li t0, 1 + sw t0, 0(a1) + + la a1, glb_step_info + li t0, 3 + sw t0, 0(a1) + + csrr t0, dcsr // illegal + + la a1, glb_expect_illegal_insn + li t0, 1 + sw t0, 0(a1) + dret // illegal + + // Trigger match setup + la a1, glb_step_info + li t0, 4 + sw t0, 0(a1) + nop + nop + li t0, 0 + +_step_trig_point: + li t0, 1 // trig here + +_step_trig_exit: + addi t0, t0,2 // debug code moves dpc to here + li t1, 2 + // If trigger was correct, debug code skips + // loading of t0 to 1, and t0 should be of value 2 + bne t0, t1, _single_step_fail + + + //----------------- + // Stepping with interrupt, stepie=1 + la a1, glb_step_info + li t0, 5 + sw t0, 0(a1) + + // Expect irq flag + la a1, glb_expect_irq_entry + li t0, 1 + sw t0, 0(a1) + + // Assert irq + li a1, timer_reg_addr + li t0, 0x40000000 + sw t0, 0(a1) + li a1, timer_val_addr + li t0, 2 + sw t0, 0(a1) + +_irq_wait_loop: + la a1, glb_expect_irq_entry + lw t0, 0(a1); + bne t0, x0, _irq_wait_loop + + + //----------------- + // Stepping with interrupt, stepie=0 + la a1, glb_step_info + li t0, 6 + sw t0, 0(a1) + + // Assert irq + li a1, timer_reg_addr + li t0, 0x40000000 + sw t0, 0(a1) + li a1, timer_val_addr + li t0, 2 + sw t0, 0(a1) + + // Wait out some instructions to give IRQ a chance + // Report an ERROR if IRQ taken as we did not set glb_expect_irq_entry flag + nop + nop + nop + nop + + // De-Assert irq + li a1, timer_reg_addr + li t0, 0x00000000 + sw t0, 0(a1) + li a1, timer_val_addr + li t0, 1 + sw t0, 0(a1) + + nop + nop + + # set step reason to 7 (step with c.ebreak) + la a1, glb_step_info + li t0, 7 + sw t0, 0(a1) + + # Ebreak to cover ebreak vs step cause priority + c.ebreak + + # set step reason to 8 (step with ebreak) + la a1, glb_step_info + li t0, 8 + sw t0, 0(a1) + + # Ebreak to cover ebreak vs step cause priority + .4byte 0x00100073 + + # Set step reason to 9, ebreak without dcsr.ebreakm + la a1, glb_step_info + li t0, 9 + sw t0, 0(a1) + + # Expect to enter ebreak handler + la a0, glb_expect_ebreak_handler + li t0, 1 + sw t0, 0(a0) + + .4byte 0x00100073 + + # Expect to enter ebreak handler + la a0, glb_expect_ebreak_handler + li t0, 1 + sw t0, 0(a0) + # Set step reason to 10, cebreak without dcsr.ebreakm + la a1, glb_step_info + li t0, 10 + sw t0, 0(a1) + + c.ebreak + + # set step reason to 0, normal step + la a1, glb_step_info + li t0, 0 + sw t0, 0(a1) + + ecall + // Cause 2, disable single stepping + la a1, glb_step_info + li t0, 2 + sw t0, 0(a1) + nop + nop + j _single_step_done + +_single_step_fail: + li a0, CV_VP_STATUS_FLAGS_BASE + li t0, test_fail + sw t0, 0(a0) + // Turn off single step + la a1, glb_step_info + li t0, 2 + sw t0, 0(a1) + + j _single_step_done + +_single_step_done: + lw t0, 0(sp) + lw t1, 4(sp) + lw a0, 8(sp) + lw a1, 12(sp) + lw a2, 16(sp) + lw ra, 20(sp) + addi sp,sp,30 + ret diff --git a/verif/tests/custom/debug_test/test.yaml b/verif/tests/custom/debug_test/test.yaml new file mode 100644 index 0000000000..3f975a0737 --- /dev/null +++ b/verif/tests/custom/debug_test/test.yaml @@ -0,0 +1,11 @@ +# Test definition YAML for test + +# Debug directed test +name: debug_test +uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c +program: debug_test +description: > + Debug directed test +# FIXME:The minstret compare issues with this test should be filed as bug and fixed +disable_csr_check: + - minstret diff --git a/verif/tests/custom/debug_test/trigger_code.S b/verif/tests/custom/debug_test/trigger_code.S new file mode 100644 index 0000000000..f66a54ca2c --- /dev/null +++ b/verif/tests/custom/debug_test/trigger_code.S @@ -0,0 +1,160 @@ +#Copyright 202[x] Silicon Labs, Inc. +# +#This file, and derivatives thereof are licensed under the +#Solderpad License, Version 2.0 (the "License"); +#Use of this file means you agree to the terms and conditions +#of the license and are in full compliance with the License. +#You may obtain a copy of the License at +# +# https://solderpad.org/licenses/SHL-2.0/ +# +#Unless required by applicable law or agreed to in writing, software +#and hardware implementations thereof +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESSED OR IMPLIED. +#See the License for the specific language governing permissions and +#limitations under the License. + +#include "corev_uvmt.h" + +.section .trigger_code_sect, "ax" +.set test_ret_val, CV_VP_STATUS_FLAGS_BASE +.set test_fail, 0x1 + +.global _trigger_exit +.global _trigger_test +.global _trigger_code +.global _trigger_test_ebreak +.global _trigger_code_ebreak +.global _trigger_code_illegal_insn +.global _trigger_code_branch_insn +.global _trigger_code_multicycle_insn +.global _trigger_code_cebreak +.type _trigger_code, @function +.type _trigger_code_ebreak, @function +.type _trigger_code_cebreak, @function +.type _trigger_code_illegal_insn, @function +.type _trigger_code_branch_insn, @function +.type _trigger_code_multicycle_insn, @function + + +_trigger_code_ebreak: + .4byte 0x00100073 + ret + +_trigger_code_cebreak: + c.ebreak + ret +_trigger_code_illegal_insn: + dret + ret +_trigger_code_branch_insn: + beq t0, t1, __trigger_fail + ret +_trigger_code_multicycle_insn: + mulhsu t0, t0, t1 + ret +_trigger_test_ebreak: + addi sp,sp,-30 + sw t0, 0(sp) + sw t1, 4(sp) + sw a0, 8(sp) + sw a1, 12(sp) + sw a2, 16(sp) + sw ra, 20(sp) + + # a0 holds argument + # 0 - ebreak + # 1 - c.c.ebreak + # 2 - illegal instruction + # 3 - branch instruction + # 4 - multicycle instruction (mulhsu) + + mv t1, a0 + li t0, 0 + beq t0, t1, _jmp_ebreak + + li t0, 1 + beq t0, t1, _jmp_cebreak + + li t0, 2 + beq t0, t1, _jmp_illegal_insn + + li t0, 3 + beq t0, t1, _jmp_branch_insn + + li t0, 4 + beq t0, t1, _jmp_multicycle_insn + +_jmp_ebreak: + jal ra, _trigger_code_ebreak + j __trigger_done +_jmp_cebreak: + jal ra, _trigger_code_cebreak + j __trigger_done +_jmp_illegal_insn: + jal ra, _trigger_code_illegal_insn + j __trigger_done +_jmp_branch_insn: + jal ra, _trigger_code_branch_insn + j __trigger_done +_jmp_multicycle_insn: + jal ra, _trigger_code_multicycle_insn + j __trigger_done + +# j __trigger_done + + + // We will trigger on the _trigger_code addess + // We should not expect the first instruction to execute + // The debugger code will move the PC to the trigger_exit_code + // Which essentially avoid executing all of the code in the trigger_code +_trigger_code: + add a2,a0,a1 + ret +_trigger_exit: + ret +_trigger_test: + addi sp,sp,-30 + sw t0, 0(sp) + sw t1, 4(sp) + sw a0, 8(sp) + sw a1, 12(sp) + sw a2, 16(sp) + sw ra, 20(sp) + + // a0 holds input to function (expect trigger) + mv t1, a0 + + // Load up some random data to add + li a0, 7893 + li a1, 1452 + li a2, 191 // a2 value will be overwrriten by _trigger_code + mv t2, a2 // keep a copy of the value to compare against + + // Call function that will have a trigger match + // If no trigger match, then a2=a0+a1 + // Else if trigger matched, then a2 is not modified + jal ra, _trigger_code + + // if (expect trigger) check against original value (in t2) + bne t1 ,x0, __trigger_check + // else + // trigger match not expected, function executes as normal + // set execpted value to t2 = a0 + a1 + add t2, a0, a1 +__trigger_check: + beq t2,a2,__trigger_done +__trigger_fail: + li a0, CV_VP_STATUS_FLAGS_BASE + li t0, 1 + sw t0, 0(a0) +__trigger_done: + lw t0, 0(sp) + lw t1, 4(sp) + lw a0, 8(sp) + lw a1, 12(sp) + lw a2, 16(sp) + lw ra, 20(sp) + addi sp,sp,30 + ret diff --git a/verif/tests/uvmt/base-tests/uvmt_cva6_base_test.sv b/verif/tests/uvmt/base-tests/uvmt_cva6_base_test.sv index 66c4bd8e16..73ab8d469b 100644 --- a/verif/tests/uvmt/base-tests/uvmt_cva6_base_test.sv +++ b/verif/tests/uvmt/base-tests/uvmt_cva6_base_test.sv @@ -236,6 +236,12 @@ function void uvmt_cva6_base_test_c::build_phase(uvm_phase phase); pkg_to_cfg (); cfg_hrtbt_monitor(); assign_cfg (); + + if (test_cfg.mem_vp_enabled == 1) begin + set_type_override_by_type(uvml_mem_c#(cva6_config_pkg::CVA6ConfigAxiAddrWidth)::get_type(), + uvml_mem_vp_c#(cva6_config_pkg::CVA6ConfigAxiAddrWidth)::get_type()); + end + create_cntxt (); assign_cntxt (); create_env (); diff --git a/verif/tests/uvmt/base-tests/uvmt_cva6_test_cfg.sv b/verif/tests/uvmt/base-tests/uvmt_cva6_test_cfg.sv index fb719ea16a..c29f177987 100644 --- a/verif/tests/uvmt/base-tests/uvmt_cva6_test_cfg.sv +++ b/verif/tests/uvmt/base-tests/uvmt_cva6_test_cfg.sv @@ -62,6 +62,9 @@ class uvmt_cva6_test_cfg_c extends uvm_object; bit cli_uvm_banner_select_override = 0; string cli_uvm_banner_name_str = ""; + // Virtual Peripherals + bit mem_vp_enabled = 0; + // Run-time control bit run_riscv_gcc_toolchain = 0; bit print_uvm_runflow_banner = 0; @@ -143,6 +146,11 @@ function void uvmt_cva6_test_cfg_c::process_cli_args(); end end + mem_vp_enabled = 0; // default + if ($value$plusargs("mem_vp_enabled=%b", mem_vp_enabled)) begin + `uvm_info("TEST_CFG", $sformatf("process_cli_args() virtual peripherals mem_vp_enabled=0x%0x", mem_vp_enabled), UVM_LOW) + end + `uvm_info("TEST_CFG", "process_cli_args() complete", UVM_HIGH) endfunction : process_cli_args From 3059b1cb25ac15b7aa31f7a49ba144fea8a9d8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Sintzoff?= <61976467+ASintzoff@users.noreply.github.com> Date: Wed, 7 Aug 2024 11:52:07 +0200 Subject: [PATCH 055/183] update riscv-isa-manual to riscv-isa-release-5ddbdd678-2024-08-01 (#2434) since last riscv-isa-manual update (CVA6 commit 0bd8b8693) --- docs/04_cv32a65x/riscv/priv-isa-cv32a65x.html | 21 +- .../riscv/unpriv-isa-cv32a65x.html | 320 +++++++++-------- .../riscv/priv-isa-cv64a6_mmu.html | 35 +- .../riscv/unpriv-isa-cv64a6_mmu.html | 334 ++++++++++-------- docs/riscv-isa/riscv-isa-manual | 2 +- docs/riscv-isa/src/colophon.adoc | 6 +- docs/riscv-isa/src/counters.adoc | 18 +- docs/riscv-isa/src/machine.adoc | 27 +- docs/riscv-isa/src/priv-preface.adoc | 9 +- docs/riscv-isa/src/riscv-privileged.adoc | 2 +- docs/riscv-isa/src/riscv-unprivileged.adoc | 2 +- docs/riscv-isa/src/rnmi.adoc | 2 +- docs/riscv-isa/src/supervisor.adoc | 18 +- docs/riscv-isa/src/zabha.adoc | 2 +- 14 files changed, 434 insertions(+), 364 deletions(-) diff --git a/docs/04_cv32a65x/riscv/priv-isa-cv32a65x.html b/docs/04_cv32a65x/riscv/priv-isa-cv32a65x.html index e7861f8092..a09a365519 100644 --- a/docs/04_cv32a65x/riscv/priv-isa-cv32a65x.html +++ b/docs/04_cv32a65x/riscv/priv-isa-cv32a65x.html @@ -440,7 +440,7 @@