mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-20 04:07:36 -04:00
Compare commits
40 commits
Author | SHA1 | Date | |
---|---|---|---|
|
733743da0f | ||
|
30811d1e7e | ||
|
8bcb14a2df | ||
|
f7fae486ff | ||
|
b9da1d9e2d | ||
|
7b3054156e | ||
|
4a1bffa87a | ||
|
1342bc960b | ||
|
75bc12d01b | ||
|
a165a2bb50 | ||
|
b258d27816 | ||
|
79c7c2c681 | ||
|
d94db10fb1 | ||
|
21506e4c66 | ||
|
b38c259c8c | ||
|
0e2e5128b2 | ||
|
2b1f45cad9 | ||
|
45e845d165 | ||
|
3a389af151 | ||
|
c3fe25aeda | ||
|
f984dc347f | ||
|
028ce43fce | ||
|
c511b21911 | ||
|
aae9b2eb66 | ||
|
d971232cd7 | ||
|
ab89beaebb | ||
|
14ef741bae | ||
|
3e73712c3e | ||
|
6e0cf8d730 | ||
|
bac134b7b5 | ||
|
dfdc72cb5a | ||
|
2d411b2dc8 | ||
|
a55db35bd1 | ||
|
e4c28b0b03 | ||
|
be7c8746c6 | ||
|
373401537e | ||
|
07bb91f5a2 | ||
|
abf21ee221 | ||
|
7b759a8b71 | ||
|
1bc415391a |
119 changed files with 39445 additions and 604 deletions
1
.github/workflows/verible.yml
vendored
1
.github/workflows/verible.yml
vendored
|
@ -21,3 +21,4 @@ jobs:
|
|||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
files: '$(find core -regex ".*\.\(v\|sv\)$" | grep -v "^core/include/.*_config_pkg.sv$")'
|
||||
fail_on_formatting_suggestions: true
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
|||
*.swp
|
||||
*.swo
|
||||
site/*
|
||||
*.ucdb
|
||||
covhtmlreport/*
|
||||
|
|
|
@ -124,7 +124,7 @@ build_tools:
|
|||
stage: light tests
|
||||
rules: *on_dev
|
||||
before_script:
|
||||
- git -C verif/core-v-verif fetch --unshallow
|
||||
- git -C verif/core-v-verif fetch --unshallow || git -C verif/core-v-verif fetch --all
|
||||
- !reference [.copy_spike_artifacts]
|
||||
- rm -rf artifacts/
|
||||
- mkdir -p artifacts/{reports,logs}
|
||||
|
@ -304,6 +304,20 @@ fpga-build:
|
|||
- mv corev_apu/fpga/work-fpga/ariane_xilinx.bit artifacts/ariane_xilinx_$TARGET.bit
|
||||
- python3 .gitlab-ci/scripts/report_fpga.py corev_apu/fpga/reports/ariane.utilization.rpt
|
||||
|
||||
pmp_tests:
|
||||
timeout : 2 hours
|
||||
extends:
|
||||
- .synthesis_test
|
||||
variables:
|
||||
DASHBOARD_JOB_TITLE: "PMP $DV_TARGET"
|
||||
DASHBOARD_JOB_DESCRIPTION: "Physical Memory Protection tests"
|
||||
DASHBOARD_SORT_INDEX: 2
|
||||
DASHBOARD_JOB_CATEGORY: "Test suites"
|
||||
DV_SIMULATORS: "vcs-uvm"
|
||||
SPIKE_TANDEM: 1
|
||||
script: source verif/regress/pmp_cv32a65x_tests.sh
|
||||
after_script: *simu_after_script
|
||||
|
||||
.regress_test:
|
||||
stage: heavy tests
|
||||
before_script:
|
||||
|
@ -543,7 +557,7 @@ simu-gate:
|
|||
PERIOD: "15" # 66 Mhz
|
||||
script:
|
||||
- mkdir -p artifacts/{reports,logs}
|
||||
- git -C verif/core-v-verif fetch --unshallow
|
||||
- git -C verif/core-v-verif fetch --unshallow || git -C verif/core-v-verif fetch --all
|
||||
- !reference [.copy_spike_artifacts]
|
||||
- echo $PERIOD
|
||||
- source ./verif/sim/setup-env.sh
|
||||
|
|
|
@ -3,6 +3,7 @@ This module makes it possible to trigger GitHub workflows.
|
|||
"""
|
||||
|
||||
from os import environ as env
|
||||
import time
|
||||
import requests
|
||||
|
||||
def api_url(owner, repo):
|
||||
|
@ -52,6 +53,7 @@ class DashboardDone(Workflow):
|
|||
'pr_number': str(pr),
|
||||
'success': success,
|
||||
}
|
||||
time.sleep(120)
|
||||
return self._trigger(inputs)
|
||||
|
||||
def send_success(self, pr):
|
||||
|
|
|
@ -82,7 +82,7 @@ hier_metric = rb.TableMetric('Hierarchies details')
|
|||
for i in hier:
|
||||
hier_metric.add_value(
|
||||
i[0], # hier
|
||||
f"{int(float(i[1])/kgate_ratio)} kGates", # area
|
||||
f"{float(i[1])/kgate_ratio:.3f} kGates", # area
|
||||
f"{int(float(i[2]))} %", # %
|
||||
#int(float(i[3]))/int(float(i[1])*100), # % combi
|
||||
#int(float(i[4]))/int(float(i[1])*100), # % reg
|
||||
|
|
11
Bender.yml
11
Bender.yml
|
@ -1,5 +1,5 @@
|
|||
package:
|
||||
name: ariane
|
||||
name: cva6
|
||||
authors:
|
||||
- "Florian Zaruba <zarubaf@iis.ee.ethz.ch>"
|
||||
- "Michael Schaffner <schaffner@iis.ee.ethz.ch>"
|
||||
|
@ -68,6 +68,7 @@ sources:
|
|||
- target: any(cv64a6_imafdcv_sv39, cv64a6_imafdc_sv39, cv64a6_imafdc_sv39_wb, cv64a6_imafdch_sv39, cv64a6_imafdch_sv39_wb, cv32a6_imac_sv0, cv32a6_imac_sv32, cv32a6_imafc_sv32)
|
||||
files:
|
||||
- core/cva6_mmu/cva6_tlb.sv
|
||||
- core/cva6_mmu/cva6_shared_tlb.sv
|
||||
- core/cva6_mmu/cva6_mmu.sv
|
||||
- core/cva6_mmu/cva6_ptw.sv
|
||||
|
||||
|
@ -78,6 +79,8 @@ sources:
|
|||
# Extension Interface
|
||||
- core/cvxif_example/include/cvxif_instr_pkg.sv
|
||||
- core/cvxif_fu.sv
|
||||
- core/cvxif_issue_register_commit_if_driver.sv
|
||||
- core/cvxif_compressed_if_driver.sv
|
||||
- core/cvxif_example/cvxif_example_coprocessor.sv
|
||||
- core/cvxif_example/instr_decoder.sv
|
||||
|
||||
|
@ -95,6 +98,7 @@ sources:
|
|||
- core/csr_regfile.sv
|
||||
- core/decoder.sv
|
||||
- core/ex_stage.sv
|
||||
- core/acc_dispatcher.sv
|
||||
- core/instr_realign.sv
|
||||
- core/id_stage.sv
|
||||
- core/issue_read_operands.sv
|
||||
|
@ -118,6 +122,7 @@ sources:
|
|||
# Frontend (i.e., fetch, decode, dispatch)
|
||||
- core/frontend/btb.sv
|
||||
- core/frontend/bht.sv
|
||||
- core/frontend/bht2lvl.sv
|
||||
- core/frontend/ras.sv
|
||||
- core/frontend/instr_scan.sv
|
||||
- core/frontend/instr_queue.sv
|
||||
|
@ -142,6 +147,7 @@ sources:
|
|||
# Physical Memory Protection
|
||||
- core/pmp/src/pmp.sv
|
||||
- core/pmp/src/pmp_entry.sv
|
||||
- core/pmp/src/pmp_data_if.sv
|
||||
|
||||
- include_dirs:
|
||||
- common/local/util
|
||||
|
@ -153,12 +159,15 @@ sources:
|
|||
- common/local/util
|
||||
files:
|
||||
- common/local/util/tc_sram_wrapper.sv
|
||||
- common/local/util/sram_cache.sv
|
||||
|
||||
- target: all(fpga, xilinx)
|
||||
include_dirs:
|
||||
- common/local/util
|
||||
files:
|
||||
- common/local/util/sram_cache.sv
|
||||
- common/local/util/tc_sram_fpga_wrapper.sv
|
||||
- vendor/pulp-platform/fpga-support/rtl/SyncSpRamBeNx64.sv
|
||||
|
||||
- target: not(synthesis)
|
||||
include_dirs:
|
||||
|
|
13
CODEOWNERS
13
CODEOWNERS
|
@ -1,5 +1,5 @@
|
|||
# Global Owners
|
||||
* @JeanRochCoulon @zarubaf
|
||||
* @JeanRochCoulon
|
||||
|
||||
# Core
|
||||
|
||||
|
@ -7,9 +7,18 @@ core/mmu_sv39 @sjthales
|
|||
core/cvxif_example @Gchauvon
|
||||
core/cvxif_fu.sv @Gchauvon
|
||||
|
||||
# APU
|
||||
# HPDCache
|
||||
|
||||
core/cache_subsystem/hpdcache @cfuguet
|
||||
core/cache_subsystem/cva6_hpdcache* @cfuguet
|
||||
core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv @cfuguet
|
||||
core/include/cv64a6_imafdc_sv39_hpdcache_wb_config_pkg.sv @cfuguet
|
||||
|
||||
# OpenPiton
|
||||
|
||||
corev_apu/openpiton @Jbalkind
|
||||
core/cache_subsystem/wt_l15_adapter.sv @Jbalkind
|
||||
core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv @Jbalkind
|
||||
|
||||
## Documentation
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ Therefore here are guidelines to help the CVA6 team accept new contributions:
|
|||
* If you do not know how to contact us already, get in touch through info@openhwgroup.org or open an issue in GitHub.
|
||||
|
||||
- Specific recommendations:
|
||||
* Always consider using the CV-X-IF interface if your contribution is an instruction-set extension.
|
||||
- and talk to the team if it's not possible.
|
||||
* For instruction set extensions, talk to the team to assess the relevance of including it into the core or as a coprocessor on the CV-X-IF interface.
|
||||
- If the extension is custom (not a RISC-V specified extension), a coprocessor on CV-X-IF is definitely its place.
|
||||
* Your contribution shall be optional and fully disabled by default.
|
||||
- so that projects already using CVA6 are not impacted (no functionality change, no extra silicon...).
|
||||
* To configure your contribution, System Verilog top-level parameters are preferred.
|
||||
|
@ -34,6 +34,12 @@ Therefore here are guidelines to help the CVA6 team accept new contributions:
|
|||
* Your complete contribution shall be identifiable with parameters (or `directives / templating if together we decide to go this way).
|
||||
- If at some point we need to revert it, e.g. if there is no-one maintaining nor using it and it has become a burden to the project.
|
||||
- We call this the "parachute" rule: The CVA6 team does not want to use it but is far more comfortable getting one.
|
||||
- Also, this allows not to lose code coverage in verification when your contribution is not enabled (with some tweaks in the coverage tool).
|
||||
- This rule also applies to CSRs which are specific to your contribution.
|
||||
* To ease maintenance, all common code lines shall exist only once.
|
||||
- Counter-example: CVA6 used to have two different MMU modules (Sv32 and Sv39) for CV32A6 and CV64A6.
|
||||
- It took time to refactor both in a joint design to ease maintenance.
|
||||
- Related reading for reference: [DRY principle](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)
|
||||
* Your contribution shall pass the Continuous Integration (CI) flow
|
||||
- When the contribution is disabled: in all cases, to ensure you have not broken the design.
|
||||
- When the contribution is disabled: the line and condition code coverage shall not be impacted.
|
||||
|
|
|
@ -72,6 +72,7 @@ core/decoder.sv
|
|||
core/ex_stage.sv
|
||||
core/frontend/btb.sv
|
||||
core/frontend/bht.sv
|
||||
core/frontend/bht2lvl.sv
|
||||
core/frontend/ras.sv
|
||||
core/frontend/instr_scan.sv
|
||||
core/frontend/instr_queue.sv
|
||||
|
|
5
Makefile
5
Makefile
|
@ -279,7 +279,8 @@ xil_debug_filter += $(addprefix $(root-dir), corev_apu/riscv-dbg/src/dmi_vjtag_t
|
|||
xil_debug_filter += $(addprefix $(root-dir), corev_apu/riscv-dbg/src/dmi_vjtag.sv)
|
||||
src := $(filter-out $(xil_debug_filter), $(src))
|
||||
|
||||
fpga_src := $(addprefix $(root-dir), $(fpga_src)) src/bootrom/bootrom_$(XLEN).sv
|
||||
fpga_src += corev_apu/fpga/src/bootrom/bootrom_$(XLEN).sv
|
||||
fpga_src := $(addprefix $(root-dir), $(fpga_src))
|
||||
|
||||
# look for testbenches
|
||||
tbs := $(top_level_path) corev_apu/tb/ariane_testharness.sv core/cva6_rvfi.sv
|
||||
|
@ -780,7 +781,7 @@ fpga_filter += $(addprefix $(root-dir), core/cache_subsystem/hpdcache/rtl/src/co
|
|||
fpga_filter += $(addprefix $(root-dir), core/cache_subsystem/hpdcache/rtl/src/common/macros/behav/hpdcache_sram_wbyteenable_1rw.sv)
|
||||
fpga_filter += $(addprefix $(root-dir), core/cache_subsystem/hpdcache/rtl/src/common/macros/behav/hpdcache_sram_wmask_1rw.sv)
|
||||
|
||||
src/bootrom/bootrom_$(XLEN).sv:
|
||||
$(addprefix $(root-dir), corev_apu/fpga/src/bootrom/bootrom_$(XLEN).sv):
|
||||
$(MAKE) -C corev_apu/fpga/src/bootrom BOARD=$(BOARD) XLEN=$(XLEN) PLATFORM=$(PLATFORM) bootrom_$(XLEN).sv
|
||||
|
||||
fpga: $(ariane_pkg) $(src) $(fpga_src) $(uart_src) $(src_flist)
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
# CVA6 RISC-V CPU [](https://github.com/openhwgroup/cva6/actions/workflows/ci.yml) [](https://riscv-ci.pages.thales-invia.fr/dashboard/) [](https://docs.openhwgroup.org/projects/cva6-user-manual/?badge=latest) [](https://github.com/openhwgroup/cva6/releases/)
|
||||
# CVA6 RISC-V CPU [](https://github.com/openhwgroup/cva6/actions/workflows/ci.yml) [](https://riscv-ci.pages.thales-invia.fr/dashboard/dashboard_cva6.html) [](https://docs.openhwgroup.org/projects/cva6-user-manual/?badge=latest) [](https://github.com/openhwgroup/cva6/releases/)
|
||||
|
||||
CVA6 is a 6-stage, single-issue, in-order CPU which implements the 64-bit RISC-V instruction set. It fully implements I, M, A and C extensions as specified in Volume I: User-Level ISA V 2.3 as well as the draft privilege extension 1.10. It implements three privilege levels M, S, U to fully support a Unix-like operating system. Furthermore, it is compliant to the draft external debug spec 0.13.
|
||||
|
||||
It has a configurable size, separate TLBs, a hardware PTW and branch-prediction (branch target buffer and branch history table). The primary design goal was on reducing critical path length.
|
||||
|
||||
A performance model of CVA6 is available in the `perf-model/` folder of this repository.
|
||||
It can be used to investigate performance-related micro-architecture changes.
|
||||
|
||||
<img src="docs/03_cva6_design/_static/ariane_overview.drawio.png"/>
|
||||
|
||||
|
||||
|
@ -408,7 +411,7 @@ Info : Listening on port 4444 for telnet connections
|
|||
Then you will be able to either connect through `telnet` or with `gdb`:
|
||||
|
||||
```
|
||||
riscv64-unknown-elf-gdb /path/to/elf
|
||||
risc-none-elf-gdb /path/to/elf
|
||||
|
||||
(gdb) target remote localhost:3333
|
||||
(gdb) load
|
||||
|
|
|
@ -25,32 +25,32 @@ module instr_tracer #(
|
|||
parameter type exception_t = logic,
|
||||
parameter interrupts_t INTERRUPTS = '0
|
||||
)(
|
||||
input logic pck,
|
||||
input logic rstn,
|
||||
input logic flush_unissued,
|
||||
input logic flush_all,
|
||||
input logic [31:0] instruction,
|
||||
input logic fetch_valid,
|
||||
input logic fetch_ack,
|
||||
input logic issue_ack, // issue acknowledged
|
||||
input scoreboard_entry_t issue_sbe, // issue scoreboard entry
|
||||
input logic [1:0][4:0] waddr, // WB stage
|
||||
input logic [1:0][63:0] wdata,
|
||||
input logic [1:0] we_gpr,
|
||||
input logic [1:0] we_fpr,
|
||||
input scoreboard_entry_t [1:0] commit_instr, // commit instruction
|
||||
input logic [1:0] commit_ack,
|
||||
input logic st_valid, // stores - address translation
|
||||
input logic [CVA6Cfg.PLEN-1:0] st_paddr,
|
||||
input logic ld_valid, // loads
|
||||
input logic ld_kill,
|
||||
input logic [CVA6Cfg.PLEN-1:0] ld_paddr,
|
||||
input bp_resolve_t resolve_branch, // misprediction
|
||||
input exception_t commit_exception,
|
||||
input riscv::priv_lvl_t priv_lvl, // current privilege level
|
||||
input logic debug_mode,
|
||||
input logic pck,
|
||||
input logic rstn,
|
||||
input logic flush_unissued,
|
||||
input logic flush_all,
|
||||
input logic [31:0] instruction [CVA6Cfg.NrIssuePorts-1:0],
|
||||
input logic [CVA6Cfg.NrIssuePorts-1:0] fetch_valid,
|
||||
input logic [CVA6Cfg.NrIssuePorts-1:0] fetch_ack,
|
||||
input logic [CVA6Cfg.NrIssuePorts-1:0] issue_ack, // issue acknowledged
|
||||
input scoreboard_entry_t [CVA6Cfg.NrIssuePorts-1:0] issue_sbe, // issue scoreboard entry
|
||||
input logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr, // WB stage
|
||||
input logic [CVA6Cfg.NrCommitPorts-1:0][63:0] wdata,
|
||||
input logic [CVA6Cfg.NrCommitPorts-1:0] we_gpr,
|
||||
input logic [CVA6Cfg.NrCommitPorts-1:0] we_fpr,
|
||||
input scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr, // commit instruction
|
||||
input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack,
|
||||
input logic st_valid, // stores - address translation
|
||||
input logic [CVA6Cfg.PLEN-1:0] st_paddr,
|
||||
input logic ld_valid, // loads
|
||||
input logic ld_kill,
|
||||
input logic [CVA6Cfg.PLEN-1:0] ld_paddr,
|
||||
input bp_resolve_t resolve_branch, // misprediction
|
||||
input exception_t commit_exception,
|
||||
input riscv::priv_lvl_t priv_lvl, // current privilege level
|
||||
input logic debug_mode,
|
||||
|
||||
input logic[CVA6Cfg.XLEN-1:0] hart_id_i
|
||||
input logic[CVA6Cfg.XLEN-1:0] hart_id_i
|
||||
);
|
||||
|
||||
// keep the decoded instructions in a queue
|
||||
|
@ -94,7 +94,7 @@ module instr_tracer #(
|
|||
forever begin
|
||||
automatic bp_resolve_t bp_instruction = '0;
|
||||
// new cycle, we are only interested if reset is de-asserted
|
||||
@(pck) if (rstn !== 1'b1) begin
|
||||
@(posedge pck) if (rstn !== 1'b1) begin
|
||||
flush();
|
||||
continue;
|
||||
end
|
||||
|
@ -106,20 +106,24 @@ module instr_tracer #(
|
|||
// Instruction Decode
|
||||
// -------------------
|
||||
// we are decoding an instruction
|
||||
if (fetch_valid && fetch_ack) begin
|
||||
decode_instruction = instruction;
|
||||
decode_queue.push_back(decode_instruction);
|
||||
for (int unsigned i = 0; i < CVA6Cfg.NrIssuePorts; ++i) begin
|
||||
if (fetch_valid[i] && fetch_ack[i]) begin
|
||||
decode_instruction = instruction[i];
|
||||
decode_queue.push_back(decode_instruction);
|
||||
end
|
||||
end
|
||||
// -------------------
|
||||
// Instruction Issue
|
||||
// -------------------
|
||||
// we got a new issue ack, so put the element from the decode queue to
|
||||
// the issue queue
|
||||
if (issue_ack && !flush_unissued) begin
|
||||
issue_instruction = decode_queue.pop_front();
|
||||
issue_queue.push_back(issue_instruction);
|
||||
// also save the scoreboard entry to a separate issue queue
|
||||
issue_sbe_queue.push_back(scoreboard_entry_t'(issue_sbe));
|
||||
for (int unsigned i = 0; i < CVA6Cfg.NrIssuePorts; ++i) begin
|
||||
if (issue_ack[i] && !flush_unissued) begin
|
||||
issue_instruction = decode_queue.pop_front();
|
||||
issue_queue.push_back(issue_instruction);
|
||||
// also save the scoreboard entry to a separate issue queue
|
||||
issue_sbe_queue.push_back(scoreboard_entry_t'(issue_sbe[i]));
|
||||
end
|
||||
end
|
||||
|
||||
// --------------------
|
||||
|
|
55
config/riscv-config/cv64a60ax/spec/custom_spec.yaml
Normal file
55
config/riscv-config/cv64a60ax/spec/custom_spec.yaml
Normal file
|
@ -0,0 +1,55 @@
|
|||
# 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: Zbigniew CHAMSKI - Thales
|
||||
|
||||
hart_ids: [0]
|
||||
hart0:
|
||||
icache:
|
||||
reset-val: 0x1
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
icache:
|
||||
implemented: true
|
||||
type:
|
||||
rw: true
|
||||
description: bit for cache-enable of instruction cache
|
||||
msb: 0
|
||||
lsb: 0
|
||||
shadow:
|
||||
shadow_type:
|
||||
description: the register controls the operation of the i-cache unit.
|
||||
address: 0x7c0
|
||||
priv_mode: M
|
||||
dcache:
|
||||
reset-val: 0x1
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
dcache:
|
||||
implemented: true
|
||||
type:
|
||||
rw: true
|
||||
description: bit for cache-enable of data cache
|
||||
shadow:
|
||||
shadow_type:
|
||||
msb: 0
|
||||
lsb: 0
|
||||
description: the register controls the operation of the d-cache unit.
|
||||
address: 0x7c1
|
||||
priv_mode: M
|
||||
|
168
config/riscv-config/cv64a60ax/spec/debug_spec.yaml
Normal file
168
config/riscv-config/cv64a60ax/spec/debug_spec.yaml
Normal file
|
@ -0,0 +1,168 @@
|
|||
# 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: Zbigniew CHAMSKI - Thales
|
||||
# Updated from CV66 64 CEA - Tanuj Khandelwal - Thales
|
||||
|
||||
hart_ids: [0]
|
||||
hart0: &hart0
|
||||
Debug_Spec_Version: '1.0.0'
|
||||
supported_xlen: [64]
|
||||
debug_mode: true
|
||||
parking_loop: 0x800
|
||||
dcsr:
|
||||
reset-val: 0x40000413
|
||||
rv64:
|
||||
accessible: true
|
||||
debugver:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0x4
|
||||
ebreakvs:
|
||||
implemented: false
|
||||
ebreakvu:
|
||||
implemented: false
|
||||
ebreakm:
|
||||
implemented: true
|
||||
ebreaks:
|
||||
implemented: true
|
||||
ebreaku:
|
||||
implemented: true
|
||||
stepie:
|
||||
implemented: true
|
||||
stopcount:
|
||||
implemented: true
|
||||
stoptime:
|
||||
implemented: true
|
||||
cause:
|
||||
implemented: true
|
||||
type:
|
||||
ro_variable: true
|
||||
v:
|
||||
implemented: true
|
||||
mprven:
|
||||
implemented: true
|
||||
nmip:
|
||||
implemented: true
|
||||
type:
|
||||
ro_variable: true
|
||||
step:
|
||||
implemented: true
|
||||
prv:
|
||||
implemented: true
|
||||
rv32:
|
||||
accessible: false
|
||||
dpc:
|
||||
rv64:
|
||||
accessible: true
|
||||
rv32:
|
||||
accessible: false
|
||||
tselect:
|
||||
rv32:
|
||||
accessible: False
|
||||
rv64:
|
||||
accessible: True
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- tselect[63:0] in [0x00000000:0x3]
|
||||
wr_illegal:
|
||||
- unchanged
|
||||
tinfo: #FIXME
|
||||
rv32:
|
||||
accessible: False
|
||||
rv64:
|
||||
accessible: True
|
||||
index_select_reg: tselect
|
||||
index_list:
|
||||
- reset-val: 0x78
|
||||
index_val: 0
|
||||
shadow:
|
||||
shadow_type:
|
||||
type:
|
||||
ro_constant: 0x78
|
||||
- reset-val: 0x8
|
||||
index_val: 1
|
||||
shadow:
|
||||
shadow_type:
|
||||
type:
|
||||
ro_constant: 0x8
|
||||
- reset-val: 0x10
|
||||
index_val: 2
|
||||
shadow:
|
||||
shadow_type:
|
||||
type:
|
||||
ro_constant: 0x10
|
||||
tdata1:
|
||||
rv32:
|
||||
accessible: False
|
||||
rv64:
|
||||
accessible: True
|
||||
index_select_reg: tselect
|
||||
index_list:
|
||||
- reset-val: 0xdeadbeef
|
||||
index_val: 0
|
||||
shadow:
|
||||
shadow_type:
|
||||
type:
|
||||
ro_constant: 0xdeadbeef
|
||||
- reset-val: 0
|
||||
index_val: 1
|
||||
shadow:
|
||||
shadow_type:
|
||||
type: &mywarl
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- writeval[63:0] in [0x0000000000000000:0xFFFFFFFFFFFFFFFF]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
- reset-val: 0
|
||||
index_val: 2
|
||||
shadow:
|
||||
shadow_type:
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- writeval[63:0] in [0x0000000000000000:0xFFFFFFFFFFFFFFFF]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
|
||||
#FIXME NTO SUPPORTED BY RISCV CNFIG
|
||||
# tdata2:
|
||||
# rv64:
|
||||
# accessible: true
|
||||
# type:
|
||||
# ro_variable: true
|
||||
# rv32:
|
||||
# accessible: false
|
||||
# tdata3:
|
||||
# rv64:
|
||||
# accessible: true
|
||||
# type:
|
||||
# ro_variable: true
|
||||
# rv32:
|
||||
# accessible: false
|
||||
dscratch0:
|
||||
rv64:
|
||||
accessible: true
|
||||
rv32:
|
||||
accessible: false
|
||||
dscratch1:
|
||||
rv64:
|
||||
accessible: true
|
||||
rv32:
|
||||
accessible: false
|
1863
config/riscv-config/cv64a60ax/spec/isa_spec.yaml
Normal file
1863
config/riscv-config/cv64a60ax/spec/isa_spec.yaml
Normal file
File diff suppressed because it is too large
Load diff
53
config/riscv-config/cv64a60ax/spec/platform_spec.yaml
Normal file
53
config/riscv-config/cv64a60ax/spec/platform_spec.yaml
Normal file
|
@ -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: Tanuj Khandelwal CEA (copied from riscv-config examples)
|
||||
|
||||
nmi:
|
||||
label: nmi_vector
|
||||
# address: 12288
|
||||
reset:
|
||||
label: reset_vector
|
||||
# address: 16384
|
||||
mtime:
|
||||
implemented: false
|
||||
mtimecmp:
|
||||
implemented: false
|
||||
#mcause_non_standard:
|
||||
# implemented: true
|
||||
mtval_condition_writes:
|
||||
implemented: false
|
||||
scause_non_standard:
|
||||
implemented: false
|
||||
stval_condition_writes:
|
||||
implemented: false
|
||||
zicbo_cache_block_sz :
|
||||
implemented: true
|
||||
zicbom_sz: 64
|
||||
zicboz_sz: 64
|
||||
|
||||
#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
|
|
@ -144,6 +144,7 @@ ${CVA6_REPO_DIR}/core/cva6_fifo_v3.sv
|
|||
// What is "frontend"?
|
||||
${CVA6_REPO_DIR}/core/frontend/btb.sv
|
||||
${CVA6_REPO_DIR}/core/frontend/bht.sv
|
||||
${CVA6_REPO_DIR}/core/frontend/bht2lvl.sv
|
||||
${CVA6_REPO_DIR}/core/frontend/ras.sv
|
||||
${CVA6_REPO_DIR}/core/frontend/instr_scan.sv
|
||||
${CVA6_REPO_DIR}/core/frontend/instr_queue.sv
|
||||
|
|
|
@ -23,36 +23,12 @@ module acc_dispatcher
|
|||
parameter type exception_t = logic,
|
||||
parameter type fu_data_t = logic,
|
||||
parameter type scoreboard_entry_t = logic,
|
||||
localparam type accelerator_req_t = struct packed {
|
||||
logic req_valid;
|
||||
logic resp_ready;
|
||||
riscv::instruction_t insn;
|
||||
logic [CVA6Cfg.XLEN-1:0] rs1;
|
||||
logic [CVA6Cfg.XLEN-1:0] rs2;
|
||||
fpnew_pkg::roundmode_e frm;
|
||||
logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id;
|
||||
logic store_pending;
|
||||
// Invalidation interface
|
||||
logic acc_cons_en;
|
||||
logic inval_ready;
|
||||
},
|
||||
parameter type acc_req_t = accelerator_req_t,
|
||||
parameter type acc_resp_t = struct packed {
|
||||
logic req_ready;
|
||||
logic resp_valid;
|
||||
logic [CVA6Cfg.XLEN-1:0] result;
|
||||
logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id;
|
||||
exception_t exception;
|
||||
// Metadata
|
||||
logic store_pending;
|
||||
logic store_complete;
|
||||
logic load_complete;
|
||||
logic [4:0] fflags;
|
||||
logic fflags_valid;
|
||||
// Invalidation interface
|
||||
logic inval_valid;
|
||||
logic [63:0] inval_addr;
|
||||
},
|
||||
parameter type acc_req_t = logic,
|
||||
parameter type acc_resp_t = logic,
|
||||
parameter type accelerator_req_t = logic,
|
||||
parameter type accelerator_resp_t = logic,
|
||||
parameter type acc_mmu_req_t = logic,
|
||||
parameter type acc_mmu_resp_t = logic,
|
||||
parameter type acc_cfg_t = logic,
|
||||
parameter acc_cfg_t AccCfg = '0
|
||||
) (
|
||||
|
@ -65,10 +41,11 @@ 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-1:0] pmpcfg_i,
|
||||
input logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
|
||||
input pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_i,
|
||||
input logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
|
||||
input logic [2:0] fcsr_frm_i,
|
||||
output logic dirty_v_state_o,
|
||||
input logic acc_mmu_en_i,
|
||||
// Interface with the issue stage
|
||||
input scoreboard_entry_t issue_instr_i,
|
||||
input logic issue_instr_hs_i,
|
||||
|
@ -88,6 +65,9 @@ module acc_dispatcher
|
|||
output logic acc_stall_st_pending_o,
|
||||
input logic acc_no_st_pending_i,
|
||||
input dcache_req_i_t [2:0] dcache_req_ports_i,
|
||||
// Interface with the MMU
|
||||
output acc_mmu_req_t acc_mmu_req_o,
|
||||
input acc_mmu_resp_t acc_mmu_resp_i,
|
||||
// Interface with the controller
|
||||
output logic ctrl_halt_o,
|
||||
input logic [11:0] csr_addr_i,
|
||||
|
@ -219,7 +199,7 @@ module acc_dispatcher
|
|||
end
|
||||
|
||||
// An accelerator instruction was issued.
|
||||
if (acc_req_o.req_valid) insn_ready_d[acc_req_o.trans_id] = 1'b0;
|
||||
if (acc_req_o.acc_req.req_valid) insn_ready_d[acc_req_o.acc_req.trans_id] = 1'b0;
|
||||
end : p_non_speculative_ff
|
||||
|
||||
/*************************
|
||||
|
@ -231,29 +211,31 @@ module acc_dispatcher
|
|||
logic acc_req_ready;
|
||||
|
||||
accelerator_req_t acc_req_int;
|
||||
fall_through_register #(
|
||||
spill_register #(
|
||||
.T(accelerator_req_t)
|
||||
) i_accelerator_req_register (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.clr_i (1'b0),
|
||||
.testmode_i(1'b0),
|
||||
.data_i (acc_req),
|
||||
.valid_i (acc_req_valid),
|
||||
.ready_o (acc_req_ready),
|
||||
.data_o (acc_req_int),
|
||||
.valid_o (acc_req_o.req_valid),
|
||||
.ready_i (acc_resp_i.req_ready)
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.data_i (acc_req),
|
||||
.valid_i(acc_req_valid),
|
||||
.ready_o(acc_req_ready),
|
||||
.data_o (acc_req_int),
|
||||
.valid_o(acc_req_o.acc_req.req_valid),
|
||||
.ready_i(acc_resp_i.acc_resp.req_ready)
|
||||
);
|
||||
|
||||
assign acc_req_o.insn = acc_req_int.insn;
|
||||
assign acc_req_o.rs1 = acc_req_int.rs1;
|
||||
assign acc_req_o.rs2 = acc_req_int.rs2;
|
||||
assign acc_req_o.frm = acc_req_int.frm;
|
||||
assign acc_req_o.trans_id = acc_req_int.trans_id;
|
||||
assign acc_req_o.store_pending = !acc_no_st_pending_i && acc_cons_en_i;
|
||||
assign acc_req_o.acc_cons_en = acc_cons_en_i;
|
||||
assign acc_req_o.inval_ready = inval_ready_i;
|
||||
assign acc_req_o.acc_req.insn = acc_req_int.insn;
|
||||
assign acc_req_o.acc_req.rs1 = acc_req_int.rs1;
|
||||
assign acc_req_o.acc_req.rs2 = acc_req_int.rs2;
|
||||
assign acc_req_o.acc_req.frm = acc_req_int.frm;
|
||||
assign acc_req_o.acc_req.trans_id = acc_req_int.trans_id;
|
||||
assign acc_req_o.acc_req.store_pending = !acc_no_st_pending_i && acc_cons_en_i;
|
||||
assign acc_req_o.acc_req.acc_cons_en = acc_cons_en_i;
|
||||
assign acc_req_o.acc_req.inval_ready = inval_ready_i;
|
||||
|
||||
// MMU interface
|
||||
assign acc_req_o.acc_mmu_resp = acc_mmu_resp_i;
|
||||
assign acc_req_o.acc_mmu_en = acc_mmu_en_i;
|
||||
|
||||
always_comb begin : accelerator_req_dispatcher
|
||||
// Do not fetch from the instruction queue
|
||||
|
@ -263,7 +245,7 @@ module acc_dispatcher
|
|||
acc_req = '0;
|
||||
acc_req_valid = 1'b0;
|
||||
|
||||
// Unpack fu_data_t into accelerator_req_t
|
||||
// Unpack fu_data_t into acc_req_t
|
||||
if (!acc_insn_queue_empty) begin
|
||||
acc_req = '{
|
||||
// Instruction is forwarded from the decoder as an immediate
|
||||
|
@ -297,23 +279,27 @@ module acc_dispatcher
|
|||
logic acc_ld_disp;
|
||||
logic acc_st_disp;
|
||||
|
||||
assign acc_trans_id_o = acc_resp_i.trans_id;
|
||||
assign acc_result_o = acc_resp_i.result;
|
||||
assign acc_valid_o = acc_resp_i.resp_valid;
|
||||
assign acc_exception_o = acc_resp_i.exception;
|
||||
assign acc_trans_id_o = acc_resp_i.acc_resp.trans_id;
|
||||
assign acc_result_o = acc_resp_i.acc_resp.result;
|
||||
assign acc_valid_o = acc_resp_i.acc_resp.resp_valid;
|
||||
assign acc_exception_o = acc_resp_i.acc_resp.exception;
|
||||
// Unpack the accelerator response
|
||||
assign acc_fflags_valid_o = acc_resp_i.fflags_valid;
|
||||
assign acc_fflags_o = acc_resp_i.fflags;
|
||||
assign acc_fflags_valid_o = acc_resp_i.acc_resp.fflags_valid;
|
||||
assign acc_fflags_o = acc_resp_i.acc_resp.fflags;
|
||||
|
||||
// MMU interface
|
||||
assign acc_mmu_req_o = acc_resp_i.acc_mmu_req;
|
||||
|
||||
// Always ready to receive responses
|
||||
assign acc_req_o.resp_ready = 1'b1;
|
||||
assign acc_req_o.acc_req.resp_ready = 1'b1;
|
||||
|
||||
// Signal dispatched load/store to issue stage
|
||||
assign acc_ld_disp = acc_req_valid && (acc_insn_queue_o.operation == ACCEL_OP_LOAD);
|
||||
assign acc_st_disp = acc_req_valid && (acc_insn_queue_o.operation == ACCEL_OP_STORE);
|
||||
assign acc_ld_disp = acc_req_valid && (acc_insn_queue_o.operation == ACCEL_OP_LOAD);
|
||||
assign acc_st_disp = acc_req_valid && (acc_insn_queue_o.operation == ACCEL_OP_STORE);
|
||||
|
||||
// Cache invalidation
|
||||
assign inval_valid_o = acc_resp_i.inval_valid;
|
||||
assign inval_addr_o = acc_resp_i.inval_addr;
|
||||
assign inval_valid_o = acc_resp_i.acc_resp.inval_valid;
|
||||
assign inval_addr_o = acc_resp_i.acc_resp.inval_addr;
|
||||
|
||||
/**************************
|
||||
* Accelerator commit *
|
||||
|
@ -351,8 +337,8 @@ module acc_dispatcher
|
|||
`FF(wait_acc_store_q, wait_acc_store_d, '0)
|
||||
|
||||
// Set on store barrier. Clear when no store is pending.
|
||||
assign wait_acc_store_d = (wait_acc_store_q | commit_st_barrier_i) & acc_resp_i.store_pending;
|
||||
assign ctrl_halt_o = wait_acc_store_q;
|
||||
assign wait_acc_store_d = (wait_acc_store_q | commit_st_barrier_i) & acc_resp_i.acc_resp.store_pending;
|
||||
assign ctrl_halt_o = wait_acc_store_q;
|
||||
|
||||
/**************************
|
||||
* Load/Store tracking *
|
||||
|
@ -390,9 +376,9 @@ module acc_dispatcher
|
|||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.clear_i (1'b0),
|
||||
.en_i (acc_ld_disp ^ acc_resp_i.load_complete),
|
||||
.en_i (acc_ld_disp ^ acc_resp_i.acc_resp.load_complete),
|
||||
.load_i (1'b0),
|
||||
.down_i (acc_resp_i.load_complete),
|
||||
.down_i (acc_resp_i.acc_resp.load_complete),
|
||||
.d_i ('0),
|
||||
.q_o (acc_disp_loads_pending),
|
||||
.overflow_o(acc_disp_loads_overflow)
|
||||
|
@ -435,9 +421,9 @@ module acc_dispatcher
|
|||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.clear_i (1'b0),
|
||||
.en_i (acc_st_disp ^ acc_resp_i.store_complete),
|
||||
.en_i (acc_st_disp ^ acc_resp_i.acc_resp.store_complete),
|
||||
.load_i (1'b0),
|
||||
.down_i (acc_resp_i.store_complete),
|
||||
.down_i (acc_resp_i.acc_resp.store_complete),
|
||||
.d_i ('0),
|
||||
.q_o (acc_disp_stores_pending),
|
||||
.overflow_o(acc_disp_stores_overflow)
|
||||
|
|
|
@ -424,9 +424,9 @@ module cva6_icache
|
|||
logic [CVA6Cfg.ICACHE_SET_ASSOC_WIDTH-1:0] hit_idx;
|
||||
|
||||
for (genvar i = 0; i < CVA6Cfg.ICACHE_SET_ASSOC; i++) begin : gen_tag_cmpsel
|
||||
assign cl_hit[i] = (cl_tag_rdata[i] == cl_tag_d) & vld_rdata[i];
|
||||
assign cl_sel[i] = cl_rdata[i][{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_WIDTH];
|
||||
assign cl_user[i] = cl_ruser[i][{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_USER_WIDTH];
|
||||
assign cl_hit[i] = (cl_tag_rdata[i] == cl_tag_d) & vld_rdata[i];
|
||||
assign cl_sel[i] = cl_rdata[i][{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_WIDTH];
|
||||
assign cl_user[i] = CVA6Cfg.FETCH_USER_EN ? cl_ruser[i][{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_USER_WIDTH] : '0;
|
||||
end
|
||||
|
||||
|
||||
|
@ -441,10 +441,10 @@ module cva6_icache
|
|||
always_comb begin
|
||||
if (cmp_en_q) begin
|
||||
dreq_o.data = cl_sel[hit_idx];
|
||||
dreq_o.user = cl_user[hit_idx];
|
||||
dreq_o.user = CVA6Cfg.FETCH_USER_EN ? cl_user[hit_idx] : '0;
|
||||
end else begin
|
||||
dreq_o.data = mem_rtrn_i.data[{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_WIDTH];
|
||||
dreq_o.user = mem_rtrn_i.user[{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_USER_WIDTH];
|
||||
dreq_o.user = CVA6Cfg.FETCH_USER_EN ? mem_rtrn_i.user[{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_USER_WIDTH] : '0;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -303,8 +303,12 @@ module wt_l15_adapter
|
|||
always_comb begin : p_rtrn_logic
|
||||
icache_rtrn_o.rtype = ICACHE_IFILL_ACK;
|
||||
dcache_rtrn_o.rtype = DCACHE_LOAD_ACK;
|
||||
icache_rtrn_vld_o = 1'b0;
|
||||
dcache_rtrn_vld_o = 1'b0;
|
||||
icache_rtrn_vld_o = 1'b0;
|
||||
dcache_rtrn_vld_o = 1'b0;
|
||||
icache_rtrn_o.inv.vld = rtrn_fifo_data.l15_inval_icache_inval;
|
||||
icache_rtrn_o.inv.all = rtrn_fifo_data.l15_inval_icache_all_way;
|
||||
dcache_rtrn_o.inv.vld = rtrn_fifo_data.l15_inval_dcache_inval;
|
||||
dcache_rtrn_o.inv.all = rtrn_fifo_data.l15_inval_dcache_all_way;
|
||||
if (!rtrn_fifo_empty) begin
|
||||
unique case (rtrn_fifo_data.l15_returntype)
|
||||
L15_LOAD_RET: begin
|
||||
|
@ -370,13 +374,9 @@ module wt_l15_adapter
|
|||
// invalidation signal mapping
|
||||
assign icache_rtrn_o.inv.idx = {rtrn_fifo_data.l15_inval_address_15_4, 4'b0000};
|
||||
assign icache_rtrn_o.inv.way = rtrn_fifo_data.l15_inval_way;
|
||||
assign icache_rtrn_o.inv.vld = rtrn_fifo_data.l15_inval_icache_inval;
|
||||
assign icache_rtrn_o.inv.all = rtrn_fifo_data.l15_inval_icache_all_way;
|
||||
|
||||
assign dcache_rtrn_o.inv.idx = {rtrn_fifo_data.l15_inval_address_15_4, 4'b0000};
|
||||
assign dcache_rtrn_o.inv.way = rtrn_fifo_data.l15_inval_way;
|
||||
assign dcache_rtrn_o.inv.vld = rtrn_fifo_data.l15_inval_dcache_inval;
|
||||
assign dcache_rtrn_o.inv.all = rtrn_fifo_data.l15_inval_dcache_all_way;
|
||||
|
||||
fifo_v2 #(
|
||||
.dtype(l15_rtrn_t),
|
||||
|
|
|
@ -162,9 +162,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 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_o,
|
||||
output riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_o,
|
||||
// PMP addresses - ACC_DISPATCHER
|
||||
output logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_o,
|
||||
output logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr_o,
|
||||
// TO_BE_COMPLETED - PERF_COUNTERS
|
||||
output logic [31:0] mcountinhibit_o,
|
||||
// RVFI
|
||||
|
@ -784,11 +784,13 @@ module csr_regfile
|
|||
riscv::CSR_PMPCFG14,
|
||||
riscv::CSR_PMPCFG15: begin
|
||||
// index is calculated using PMPCFG0 as the offset
|
||||
automatic logic [11:0] index = csr_addr.address[11:0] - riscv::CSR_PMPCFG0;
|
||||
automatic logic [3:0] index = csr_addr.address[11:0] - riscv::CSR_PMPCFG0;
|
||||
|
||||
// if index is not even and XLEN==64, raise exception
|
||||
if (CVA6Cfg.XLEN == 64 && index[0] == 1'b1) read_access_exception = 1'b1;
|
||||
else begin
|
||||
// The following line has no effect. It's here just to prevent the synthesizer from crashing
|
||||
if (CVA6Cfg.XLEN == 64) index = (index >> 1) << 1;
|
||||
csr_rdata = pmpcfg_q[index*4+:CVA6Cfg.XLEN/8];
|
||||
end
|
||||
end
|
||||
|
|
79
core/cva6.sv
79
core/cva6.sv
|
@ -39,7 +39,7 @@ module cva6
|
|||
logic [CVA6Cfg.VLEN-1:0] predict_address; // target address at which to jump, or not
|
||||
},
|
||||
|
||||
localparam type exception_t = struct packed {
|
||||
parameter type exception_t = struct packed {
|
||||
logic [CVA6Cfg.XLEN-1:0] cause; // cause of exception
|
||||
logic [CVA6Cfg.XLEN-1:0] tval; // additional information of causing exception (e.g.: instruction causing it),
|
||||
// address of LD/ST fault
|
||||
|
@ -217,6 +217,14 @@ module cva6
|
|||
logic [CVA6Cfg.DCACHE_USER_WIDTH-1:0] data_ruser;
|
||||
},
|
||||
|
||||
// Accelerator - CVA6
|
||||
parameter type accelerator_req_t = logic,
|
||||
parameter type accelerator_resp_t = logic,
|
||||
|
||||
// Accelerator - CVA6's MMU
|
||||
parameter type acc_mmu_req_t = logic,
|
||||
parameter type acc_mmu_resp_t = logic,
|
||||
|
||||
// AXI types
|
||||
parameter type axi_ar_chan_t = struct packed {
|
||||
logic [CVA6Cfg.AxiIdWidth-1:0] id;
|
||||
|
@ -509,6 +517,11 @@ module cva6
|
|||
// ACCEL Commit
|
||||
logic acc_valid_acc_ex;
|
||||
// --------------
|
||||
// EX <-> ACC_DISP
|
||||
// --------------
|
||||
acc_mmu_req_t acc_mmu_req;
|
||||
acc_mmu_resp_t acc_mmu_resp;
|
||||
// --------------
|
||||
// ID <-> COMMIT
|
||||
// --------------
|
||||
scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_id_commit;
|
||||
|
@ -569,8 +582,8 @@ module cva6
|
|||
logic acc_cons_en_csr;
|
||||
logic debug_mode;
|
||||
logic single_step_csr_commit;
|
||||
riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg;
|
||||
logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr;
|
||||
riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg;
|
||||
logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr;
|
||||
logic [31:0] mcountinhibit_csr_perf;
|
||||
//jvt
|
||||
jvt_t jvt;
|
||||
|
@ -764,16 +777,17 @@ 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_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
|
||||
|
||||
always_comb begin : gen_cvxif_output_assignement
|
||||
cvxif_req.compressed_valid = x_compressed_valid;
|
||||
cvxif_req.compressed_req = x_compressed_req;
|
||||
|
@ -921,7 +935,9 @@ module cva6
|
|||
.icache_dreq_t(icache_dreq_t),
|
||||
.icache_drsp_t(icache_drsp_t),
|
||||
.lsu_ctrl_t(lsu_ctrl_t),
|
||||
.x_result_t(x_result_t)
|
||||
.x_result_t(x_result_t),
|
||||
.acc_mmu_req_t(acc_mmu_req_t),
|
||||
.acc_mmu_resp_t(acc_mmu_resp_t)
|
||||
) ex_stage_i (
|
||||
.clk_i(clk_i),
|
||||
.rst_ni(rst_ni),
|
||||
|
@ -1005,6 +1021,9 @@ module cva6
|
|||
.x_result_ready_o (x_result_ready),
|
||||
// Accelerator
|
||||
.acc_valid_i (acc_valid_acc_ex),
|
||||
// Accelerator MMU access
|
||||
.acc_mmu_req_i (acc_mmu_req),
|
||||
.acc_mmu_resp_o (acc_mmu_resp),
|
||||
// Performance counters
|
||||
.itlb_miss_o (itlb_miss_ex_perf),
|
||||
.dtlb_miss_o (dtlb_miss_ex_perf),
|
||||
|
@ -1366,10 +1385,11 @@ module cva6
|
|||
.inval_valid_i (inval_valid),
|
||||
.inval_ready_o (inval_ready)
|
||||
);
|
||||
end else if (CVA6Cfg.DCacheType inside {
|
||||
config_pkg::HPDCACHE_WT,
|
||||
config_pkg::HPDCACHE_WB,
|
||||
config_pkg::HPDCACHE_WT_WB})
|
||||
end else if (
|
||||
CVA6Cfg.DCacheType == config_pkg::HPDCACHE_WT ||
|
||||
CVA6Cfg.DCacheType == config_pkg::HPDCACHE_WB ||
|
||||
CVA6Cfg.DCacheType == config_pkg::HPDCACHE_WT_WB
|
||||
)
|
||||
begin : gen_cache_hpd
|
||||
cva6_hpdcache_subsystem #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
|
@ -1504,7 +1524,11 @@ module cva6
|
|||
.acc_cfg_t (acc_cfg_t),
|
||||
.AccCfg (AccCfg),
|
||||
.acc_req_t (cvxif_req_t),
|
||||
.acc_resp_t (cvxif_resp_t)
|
||||
.acc_resp_t (cvxif_resp_t),
|
||||
.accelerator_req_t (accelerator_req_t),
|
||||
.accelerator_resp_t(accelerator_resp_t),
|
||||
.acc_mmu_req_t (acc_mmu_req_t),
|
||||
.acc_mmu_resp_t (acc_mmu_resp_t)
|
||||
) i_acc_dispatcher (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
|
@ -1520,6 +1544,7 @@ module cva6
|
|||
.pmpcfg_i (pmpcfg),
|
||||
.pmpaddr_i (pmpaddr),
|
||||
.fcsr_frm_i (frm_csr_id_issue_ex),
|
||||
.acc_mmu_en_i (enable_translation_csr_ex),
|
||||
.dirty_v_state_o (dirty_v_state),
|
||||
.issue_instr_i (issue_instr_id_acc),
|
||||
.issue_instr_hs_i (issue_instr_hs_id_acc),
|
||||
|
@ -1536,6 +1561,8 @@ module cva6
|
|||
.acc_stall_st_pending_o(stall_st_pending_ex),
|
||||
.acc_no_st_pending_i (no_st_pending_commit),
|
||||
.dcache_req_ports_i (dcache_req_ports_ex_cache),
|
||||
.acc_mmu_req_o (acc_mmu_req),
|
||||
.acc_mmu_resp_i (acc_mmu_resp),
|
||||
.ctrl_halt_o (halt_acc_ctrl),
|
||||
.csr_addr_i (csr_addr_ex_csr),
|
||||
.acc_dcache_req_ports_o(dcache_req_ports_acc_cache),
|
||||
|
@ -1565,6 +1592,9 @@ module cva6
|
|||
// D$ connection is unused
|
||||
assign dcache_req_ports_acc_cache = '0;
|
||||
|
||||
// MMU access is unused
|
||||
assign acc_mmu_req = '0;
|
||||
|
||||
// No invalidation interface
|
||||
assign inval_valid = '0;
|
||||
assign inval_addr = '0;
|
||||
|
@ -1632,6 +1662,13 @@ module cva6
|
|||
`endif // PITON_ARIANE
|
||||
|
||||
`ifndef VERILATOR
|
||||
|
||||
logic [31:0] fetch_instructions[CVA6Cfg.NrIssuePorts-1:0];
|
||||
|
||||
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; ++i) begin
|
||||
assign fetch_instructions[i] = fetch_entry_if_id[i].instruction;
|
||||
end
|
||||
|
||||
instr_tracer #(
|
||||
.CVA6Cfg(CVA6Cfg),
|
||||
.bp_resolve_t(bp_resolve_t),
|
||||
|
@ -1645,9 +1682,9 @@ module cva6
|
|||
.rstn(rst_ni),
|
||||
.flush_unissued(flush_unissued_instr_ctrl_id),
|
||||
.flush_all(flush_ctrl_ex),
|
||||
.instruction(id_stage_i.fetch_entry_i[0].instruction),
|
||||
.fetch_valid(id_stage_i.fetch_entry_valid_i[0]),
|
||||
.fetch_ack(id_stage_i.fetch_entry_ready_o[0]),
|
||||
.instruction(fetch_instructions),
|
||||
.fetch_valid(id_stage_i.fetch_entry_valid_i),
|
||||
.fetch_ack(id_stage_i.fetch_entry_ready_o),
|
||||
.issue_ack(issue_stage_i.i_scoreboard.issue_ack_i),
|
||||
.issue_sbe(issue_stage_i.i_scoreboard.issue_instr_o),
|
||||
.waddr(waddr_commit_id),
|
||||
|
|
|
@ -100,8 +100,8 @@ module cva6_mmu
|
|||
|
||||
// PMP
|
||||
|
||||
input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i,
|
||||
input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i
|
||||
input riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_i,
|
||||
input logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr_i
|
||||
);
|
||||
|
||||
// memory management, pte for cva6
|
||||
|
@ -223,7 +223,7 @@ module cva6_mmu
|
|||
.v_i (ld_st_v_i),
|
||||
.update_i (update_dtlb),
|
||||
.lu_access_i (dtlb_lu_access),
|
||||
.lu_asid_i (itlb_lu_asid),
|
||||
.lu_asid_i (dtlb_lu_asid),
|
||||
.lu_vmid_i (vmid_i),
|
||||
.lu_vaddr_i (lsu_vaddr_i),
|
||||
.lu_gpaddr_o (dtlb_gpaddr),
|
||||
|
@ -495,6 +495,7 @@ module cva6_mmu
|
|||
logic lsu_is_store_n, lsu_is_store_q;
|
||||
logic dtlb_hit_n, dtlb_hit_q;
|
||||
logic [CVA6Cfg.PtLevels-2:0] dtlb_is_page_n, dtlb_is_page_q;
|
||||
exception_t misaligned_ex_n, misaligned_ex_q;
|
||||
|
||||
// check if we need to do translation or if we are always ready (e.g.: we are not translating anything)
|
||||
assign lsu_dtlb_hit_o = (en_ld_st_translation_i || en_ld_st_g_translation_i) ? dtlb_lu_hit : 1'b1;
|
||||
|
@ -509,9 +510,13 @@ module cva6_mmu
|
|||
dtlb_hit_n = dtlb_lu_hit;
|
||||
lsu_is_store_n = lsu_is_store_i;
|
||||
dtlb_is_page_n = dtlb_is_page;
|
||||
misaligned_ex_n = misaligned_ex_i;
|
||||
|
||||
lsu_valid_o = lsu_req_q;
|
||||
lsu_exception_o = misaligned_ex_i;
|
||||
lsu_exception_o = misaligned_ex_q;
|
||||
|
||||
// mute misaligned exceptions if there is no request otherwise they will throw accidental exceptions
|
||||
misaligned_ex_n.valid = misaligned_ex_i.valid & lsu_req_i;
|
||||
|
||||
// we work with SV39 or SV32, so if VM is enabled, check that all bits [CVA6Cfg.VLEN-1:CVA6Cfg.SV-1] are equal to bit [CVA6Cfg.SV]
|
||||
canonical_addr_check = (lsu_req_i && en_ld_st_translation_i &&
|
||||
|
@ -536,7 +541,7 @@ module cva6_mmu
|
|||
lsu_dtlb_ppn_o = (CVA6Cfg.PPNW)'(lsu_vaddr_n[((CVA6Cfg.PLEN > CVA6Cfg.VLEN) ? CVA6Cfg.VLEN -1: CVA6Cfg.PLEN -1 ):12]);
|
||||
|
||||
// translation is enabled and no misaligned exception occurred
|
||||
if ((en_ld_st_translation_i || en_ld_st_g_translation_i) && !misaligned_ex_i.valid) begin
|
||||
if ((en_ld_st_translation_i || en_ld_st_g_translation_i) && !misaligned_ex_q.valid) begin
|
||||
lsu_valid_o = 1'b0;
|
||||
|
||||
lsu_dtlb_ppn_o = (en_ld_st_g_translation_i && CVA6Cfg.RVH)? dtlb_g_content.ppn :dtlb_content.ppn;
|
||||
|
@ -736,6 +741,7 @@ module cva6_mmu
|
|||
dtlb_is_page_q <= '0;
|
||||
lsu_tinst_q <= '0;
|
||||
hs_ld_st_inst_q <= '0;
|
||||
misaligned_ex_q <= '0;
|
||||
end else begin
|
||||
lsu_vaddr_q <= lsu_vaddr_n;
|
||||
lsu_req_q <= lsu_req_n;
|
||||
|
@ -749,6 +755,7 @@ module cva6_mmu
|
|||
hs_ld_st_inst_q <= hs_ld_st_inst_n;
|
||||
dtlb_gpte_q <= dtlb_gpte_n;
|
||||
lsu_gpaddr_q <= lsu_gpaddr_n;
|
||||
misaligned_ex_q <= misaligned_ex_n;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
// Date: 26/02/2024
|
||||
// Description: Hardware-PTW (Page-Table-Walker) for CVA6 supporting sv32, sv39 and sv39x4.
|
||||
// This module is an merge of the PTW Sv39 developed by Florian Zaruba,
|
||||
// the PTW Sv32 developed by Sebastien Jacq and the PTW Sv39x4 by Bruno Sá.
|
||||
// the PTW Sv32 developed by Sebastien Jacq and the PTW Sv39x4 by Bruno Sá.
|
||||
|
||||
/* verilator lint_off WIDTH */
|
||||
|
||||
|
@ -83,8 +83,8 @@ module cva6_ptw
|
|||
output logic shared_tlb_miss_o,
|
||||
|
||||
// PMP
|
||||
input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i,
|
||||
input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
|
||||
input riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_i,
|
||||
input logic [avoid_neg(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
|
||||
);
|
||||
|
@ -216,7 +216,7 @@ module cva6_ptw
|
|||
|
||||
// output the correct ASIDs
|
||||
shared_tlb_update_o.asid = tlb_update_asid_q;
|
||||
shared_tlb_update_o.vmid = tlb_update_vmid_q;
|
||||
shared_tlb_update_o.vmid = CVA6Cfg.RVH ? tlb_update_vmid_q : '0;
|
||||
|
||||
bad_paddr_o = ptw_access_exception_o ? ptw_pptr_q : 'b0;
|
||||
if (CVA6Cfg.RVH)
|
||||
|
@ -258,8 +258,8 @@ module cva6_ptw
|
|||
// PAGESIZE=2^12 and LEVELS=3.)
|
||||
// 2. Let pte be the value of the PTE at address a+va.vpn[i]×PTESIZE. (For
|
||||
// Sv32, PTESIZE=4.)
|
||||
// 3. If pte.v = 0, or if pte.r = 0 and pte.w = 1, or if any bits or encodings
|
||||
// that are reserved for future standard use are set within pte, stop and raise
|
||||
// 3. If pte.v = 0, or if pte.r = 0 and pte.w = 1, or if any bits or encodings
|
||||
// that are reserved for future standard use are set within pte, stop and raise
|
||||
// a page-fault exception corresponding to the original access type.
|
||||
// 4. Otherwise, the PTE is valid. If pte.r = 1 or pte.x = 1, go to step 5.
|
||||
// Otherwise, this PTE is a pointer to the next level of the page table.
|
||||
|
@ -296,7 +296,6 @@ module cva6_ptw
|
|||
global_mapping_n = global_mapping_q;
|
||||
// input registers
|
||||
tlb_update_asid_n = tlb_update_asid_q;
|
||||
tlb_update_vmid_n = tlb_update_vmid_q;
|
||||
vaddr_n = vaddr_q;
|
||||
pptr = ptw_pptr_q;
|
||||
|
||||
|
@ -304,6 +303,7 @@ module cva6_ptw
|
|||
gpaddr_n = gpaddr_q;
|
||||
gptw_pptr_n = gptw_pptr_q;
|
||||
gpte_d = gpte_q;
|
||||
tlb_update_vmid_n = tlb_update_vmid_q;
|
||||
end
|
||||
|
||||
shared_tlb_miss_o = 1'b0;
|
||||
|
@ -616,17 +616,17 @@ module cva6_ptw
|
|||
ptw_lvl_q <= '0;
|
||||
tag_valid_q <= 1'b0;
|
||||
tlb_update_asid_q <= '0;
|
||||
tlb_update_vmid_q <= '0;
|
||||
vaddr_q <= '0;
|
||||
ptw_pptr_q <= '0;
|
||||
global_mapping_q <= 1'b0;
|
||||
data_rdata_q <= '0;
|
||||
data_rvalid_q <= 1'b0;
|
||||
if (CVA6Cfg.RVH) begin
|
||||
gpaddr_q <= '0;
|
||||
gptw_pptr_q <= '0;
|
||||
ptw_stage_q <= S_STAGE;
|
||||
gpte_q <= '0;
|
||||
gpaddr_q <= '0;
|
||||
gptw_pptr_q <= '0;
|
||||
ptw_stage_q <= S_STAGE;
|
||||
gpte_q <= '0;
|
||||
tlb_update_vmid_q <= '0;
|
||||
end
|
||||
end else begin
|
||||
state_q <= state_d;
|
||||
|
|
|
@ -336,14 +336,12 @@ module cva6_rvfi
|
|||
assign rvfi_csr_o.``CSR_NAME``.rmask = CSR_ENABLE_COND ? 1 : 0; \
|
||||
assign rvfi_csr_o.``CSR_NAME``.wmask = (rvfi_csr_o.``CSR_NAME``.rdata != {{CVA6Cfg.XLEN - $bits(CSR_SOURCE_NAME)}, CSR_SOURCE_NAME}) && CSR_ENABLE_COND;
|
||||
|
||||
`define COMMA ,
|
||||
|
||||
`define CONNECT_RVFI_SAME(CSR_ENABLE_COND, CSR_NAME) \
|
||||
`CONNECT_RVFI_FULL(CSR_ENABLE_COND, CSR_NAME, csr.``CSR_NAME``_q)
|
||||
|
||||
`CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, fflags, csr.fcsr_q.fflags)
|
||||
`CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, frm, csr.fcsr_q.frm)
|
||||
`CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, fcsr, { csr.fcsr_q.frm `COMMA csr.fcsr_q.fflags})
|
||||
`CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, fcsr, {csr.fcsr_q.frm, csr.fcsr_q.fflags})
|
||||
|
||||
`CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, ftran, csr.fcsr_q.fprec)
|
||||
`CONNECT_RVFI_SAME(CVA6Cfg.FpPresent, dcsr)
|
||||
|
@ -429,7 +427,8 @@ module cva6_rvfi
|
|||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < 16; i++) begin
|
||||
`CONNECT_RVFI_FULL(1'b1, pmpaddr[i], csr.pmpaddr_q[i][CVA6Cfg.PLEN-3:0])
|
||||
`CONNECT_RVFI_FULL(1'b1, pmpaddr[i], {
|
||||
csr.pmpaddr_q[i][CVA6Cfg.PLEN-3:1], pmpcfg_q[i].addr_mode[1]})
|
||||
end
|
||||
endgenerate
|
||||
;
|
||||
|
|
|
@ -22,6 +22,8 @@ module cvxif_fu
|
|||
input logic clk_i,
|
||||
// Asynchronous reset active low - SUBSYSTEM
|
||||
input logic rst_ni,
|
||||
// Virtualization mode state - CSR_REGFILE
|
||||
input logic v_i,
|
||||
// CVXIF instruction is valid - ISSUE_STAGE
|
||||
input logic x_valid_i,
|
||||
// Transaction ID - ISSUE_STAGE
|
||||
|
@ -68,6 +70,10 @@ module cvxif_fu
|
|||
x_exception_o.cause = x_illegal_i ? riscv::ILLEGAL_INSTR : '0;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
x_exception_o.tval = x_off_instr_i; // TODO Optimization : Set exception in IRO.
|
||||
// Hypervisor exception fields
|
||||
x_exception_o.tval2 = {CVA6Cfg.GPLEN{1'b0}};
|
||||
x_exception_o.tinst = '0;
|
||||
x_exception_o.gva = CVA6Cfg.RVH ? v_i : 1'b0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -186,6 +186,7 @@ module decoder
|
|||
ecall = 1'b0;
|
||||
ebreak = 1'b0;
|
||||
check_fprm = 1'b0;
|
||||
tinst = 32'h0;
|
||||
|
||||
if (~ex_i.valid) begin
|
||||
case (instr.rtype.opcode)
|
||||
|
|
|
@ -29,7 +29,9 @@ module ex_stage
|
|||
parameter type icache_dreq_t = logic,
|
||||
parameter type icache_drsp_t = logic,
|
||||
parameter type lsu_ctrl_t = logic,
|
||||
parameter type x_result_t = logic
|
||||
parameter type x_result_t = logic,
|
||||
parameter type acc_mmu_req_t = logic,
|
||||
parameter type acc_mmu_resp_t = logic
|
||||
) (
|
||||
// Subsystem Clock - SUBSYSTEM
|
||||
input logic clk_i,
|
||||
|
@ -161,6 +163,9 @@ module ex_stage
|
|||
input logic x_transaction_rejected_i,
|
||||
// accelerate port result is valid - ACC_DISPATCHER
|
||||
input logic acc_valid_i,
|
||||
// Accelerator MMU access
|
||||
input acc_mmu_req_t acc_mmu_req_i,
|
||||
output acc_mmu_resp_t acc_mmu_resp_o,
|
||||
// Enable virtual memory translation - CSR_REGFILE
|
||||
input logic enable_translation_i,
|
||||
// Enable G-Stage memory translation - CSR_REGFILE
|
||||
|
@ -224,9 +229,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 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i,
|
||||
input riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_i,
|
||||
// Report the PMP addresses - CSR_REGFILE
|
||||
input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
|
||||
input logic [avoid_neg(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
|
||||
|
@ -529,7 +534,9 @@ module ex_stage
|
|||
.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),
|
||||
.acc_mmu_req_t(acc_mmu_req_t),
|
||||
.acc_mmu_resp_t(acc_mmu_resp_t)
|
||||
) lsu_i (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
|
@ -554,6 +561,8 @@ module ex_stage
|
|||
.enable_g_translation_i,
|
||||
.en_ld_st_translation_i,
|
||||
.en_ld_st_g_translation_i,
|
||||
.acc_mmu_req_i,
|
||||
.acc_mmu_resp_o,
|
||||
.icache_areq_i,
|
||||
.icache_areq_o,
|
||||
.priv_lvl_i,
|
||||
|
@ -612,6 +621,7 @@ module ex_stage
|
|||
) cvxif_fu_i (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.v_i,
|
||||
.x_valid_i(|x_valid_i),
|
||||
.x_trans_id_i(cvxif_data.trans_id),
|
||||
.x_illegal_i(x_transaction_rejected_i),
|
||||
|
|
133
core/frontend/bht2lvl.sv
Normal file
133
core/frontend/bht2lvl.sv
Normal file
|
@ -0,0 +1,133 @@
|
|||
// Copyright 2025 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this 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: Gianmarco Ottavi, University of Bologna
|
||||
// Description: Private history BHT
|
||||
|
||||
module bht2lvl #(
|
||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||
parameter type bht_update_t = logic
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic flush_i,
|
||||
input logic [ CVA6Cfg.VLEN-1:0] vpc_i,
|
||||
input bht_update_t bht_update_i,
|
||||
// we potentially need INSTR_PER_FETCH predictions/cycle
|
||||
output ariane_pkg::bht_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] bht_prediction_o
|
||||
);
|
||||
|
||||
// the last bit is always zero, we don't need it for indexing
|
||||
localparam OFFSET = CVA6Cfg.RVC == 1'b1 ? 1 : 2;
|
||||
// re-shape the branch history table
|
||||
localparam NR_ROWS = CVA6Cfg.BHTEntries / CVA6Cfg.INSTR_PER_FETCH;
|
||||
// number of bits needed to index the row
|
||||
localparam ROW_ADDR_BITS = $clog2(CVA6Cfg.INSTR_PER_FETCH);
|
||||
localparam ROW_INDEX_BITS = CVA6Cfg.RVC == 1'b1 ? $clog2(CVA6Cfg.INSTR_PER_FETCH) : 1;
|
||||
// number of bits we should use for prediction
|
||||
localparam PREDICTION_BITS = $clog2(NR_ROWS) + OFFSET + ROW_ADDR_BITS;
|
||||
|
||||
struct packed {
|
||||
logic valid;
|
||||
logic [CVA6Cfg.BHTHist-1:0] hist;
|
||||
logic [2**CVA6Cfg.BHTHist-1:0][1:0] saturation_counter;
|
||||
}
|
||||
bht_d[NR_ROWS-1:0][CVA6Cfg.INSTR_PER_FETCH-1:0],
|
||||
bht_q[NR_ROWS-1:0][CVA6Cfg.INSTR_PER_FETCH-1:0];
|
||||
|
||||
|
||||
logic [$clog2(NR_ROWS)-1:0] index, update_pc;
|
||||
logic [CVA6Cfg.BHTHist-1:0] update_hist;
|
||||
logic [ ROW_INDEX_BITS-1:0] update_row_index;
|
||||
|
||||
assign index = vpc_i[PREDICTION_BITS-1:ROW_ADDR_BITS+OFFSET];
|
||||
assign update_pc = bht_update_i.pc[PREDICTION_BITS-1:ROW_ADDR_BITS+OFFSET];
|
||||
assign update_hist = bht_q[update_pc][update_row_index].hist;
|
||||
|
||||
if (CVA6Cfg.RVC) begin : gen_update_row_index
|
||||
assign update_row_index = bht_update_i.pc[ROW_ADDR_BITS+OFFSET-1:OFFSET];
|
||||
end else begin
|
||||
assign update_row_index = '0;
|
||||
end
|
||||
|
||||
|
||||
logic [1:0] saturation_counter;
|
||||
|
||||
// Get the current history of the entry
|
||||
logic [CVA6Cfg.INSTR_PER_FETCH-1:0][CVA6Cfg.BHTHist-1:0] read_history;
|
||||
for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin
|
||||
assign read_history[i] = bht_q[index][i].hist;
|
||||
end
|
||||
|
||||
// prediction assignment
|
||||
for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_bht_output
|
||||
assign bht_prediction_o[i].valid = bht_q[index][i].valid;
|
||||
assign bht_prediction_o[i].taken = bht_q[index][i].saturation_counter[read_history[i]][1] == 1'b1;
|
||||
end
|
||||
|
||||
always_comb begin : update_bht
|
||||
bht_d = bht_q;
|
||||
saturation_counter = bht_q[update_pc][update_row_index].saturation_counter[update_hist];
|
||||
|
||||
if (bht_update_i.valid) begin
|
||||
bht_d[update_pc][update_row_index].valid = 1'b1;
|
||||
|
||||
if (saturation_counter == 2'b11) begin
|
||||
// we can safely decrease it
|
||||
if (!bht_update_i.taken)
|
||||
bht_d[update_pc][update_row_index].saturation_counter[update_hist] = saturation_counter - 1;
|
||||
// then check if it saturated in the negative regime e.g.: branch not taken
|
||||
end else if (saturation_counter == 2'b00) begin
|
||||
// we can safely increase it
|
||||
if (bht_update_i.taken)
|
||||
bht_d[update_pc][update_row_index].saturation_counter[update_hist] = saturation_counter + 1;
|
||||
end else begin // otherwise we are not in any boundaries and can decrease or increase it
|
||||
if (bht_update_i.taken)
|
||||
bht_d[update_pc][update_row_index].saturation_counter[update_hist] = saturation_counter + 1;
|
||||
else
|
||||
bht_d[update_pc][update_row_index].saturation_counter[update_hist] = saturation_counter - 1;
|
||||
end
|
||||
|
||||
bht_d[update_pc][update_row_index].hist = {
|
||||
update_hist[CVA6Cfg.BHTHist-2:0], bht_update_i.taken
|
||||
};
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
for (int unsigned i = 0; i < NR_ROWS; i++) begin
|
||||
for (int j = 0; j < CVA6Cfg.INSTR_PER_FETCH; j++) begin
|
||||
bht_q[i][j] <= '0;
|
||||
for (int k = 0; k < 2 ** CVA6Cfg.BHTHist; k++) begin
|
||||
bht_q[i][j].saturation_counter[k] <= 2'b10;
|
||||
end
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
// evict all entries
|
||||
if (flush_i) begin
|
||||
for (int i = 0; i < NR_ROWS; i++) begin
|
||||
for (int j = 0; j < CVA6Cfg.INSTR_PER_FETCH; j++) begin
|
||||
bht_q[i][j].valid <= 1'b0;
|
||||
bht_q[i][j].hist <= '0;
|
||||
for (int k = 0; k < 2 ** CVA6Cfg.BHTHist; k++) begin
|
||||
bht_q[i][j].saturation_counter[k] <= 2'b10;
|
||||
end
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
bht_q <= bht_d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
|
@ -510,7 +510,7 @@ module frontend
|
|||
|
||||
if (CVA6Cfg.BHTEntries == 0) begin
|
||||
assign bht_prediction = '0;
|
||||
end else begin : bht_gen
|
||||
end else if (CVA6Cfg.BPType == config_pkg::BHT) begin : bht_gen
|
||||
bht #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.bht_update_t(bht_update_t),
|
||||
|
@ -524,6 +524,18 @@ module frontend
|
|||
.bht_update_i (bht_update),
|
||||
.bht_prediction_o(bht_prediction)
|
||||
);
|
||||
end else if (CVA6Cfg.BPType == config_pkg::PH_BHT) begin : bht2lvl_gen
|
||||
bht2lvl #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.bht_update_t(bht_update_t)
|
||||
) i_bht (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.flush_i (flush_bp_i),
|
||||
.vpc_i (icache_vaddr_q),
|
||||
.bht_update_i (bht_update),
|
||||
.bht_prediction_o(bht_prediction)
|
||||
);
|
||||
end
|
||||
|
||||
// we need to inspect up to CVA6Cfg.INSTR_PER_FETCH instructions for branches
|
||||
|
|
|
@ -269,6 +269,13 @@ module id_stage #(
|
|||
end else begin
|
||||
assign stall_instr_fetch[0] = stall_macro_deco;
|
||||
end
|
||||
end else begin
|
||||
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||
assign is_illegal_rvc[i] = 1'b0;
|
||||
assign instruction_rvc[i] = fetch_entry_i[i].instruction;
|
||||
assign is_compressed_rvc[i] = 1'b0;
|
||||
assign stall_instr_fetch[i] = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
|
|
@ -807,4 +807,12 @@ package ariane_pkg;
|
|||
return gppn;
|
||||
endfunction : make_gppn
|
||||
|
||||
// ----------------------
|
||||
// Helper functions
|
||||
// ----------------------
|
||||
// Avoid negative array slices when defining parametrized sizes
|
||||
function automatic int unsigned avoid_neg(int n);
|
||||
return (n < 0) ? 0 : n;
|
||||
endfunction : avoid_neg
|
||||
|
||||
endpackage
|
||||
|
|
|
@ -74,6 +74,7 @@ package build_config_pkg;
|
|||
cfg.RVZCMP = CVA6Cfg.RVZCMP;
|
||||
cfg.XFVec = CVA6Cfg.XFVec;
|
||||
cfg.CvxifEn = CVA6Cfg.CvxifEn;
|
||||
cfg.CoproType = CVA6Cfg.CoproType;
|
||||
cfg.RVZiCond = CVA6Cfg.RVZiCond;
|
||||
cfg.RVZicntr = CVA6Cfg.RVZicntr;
|
||||
cfg.RVZihpm = CVA6Cfg.RVZihpm;
|
||||
|
@ -102,7 +103,9 @@ package build_config_pkg;
|
|||
cfg.ExceptionAddress = CVA6Cfg.ExceptionAddress;
|
||||
cfg.RASDepth = CVA6Cfg.RASDepth;
|
||||
cfg.BTBEntries = CVA6Cfg.BTBEntries;
|
||||
cfg.BPType = CVA6Cfg.BPType;
|
||||
cfg.BHTEntries = CVA6Cfg.BHTEntries;
|
||||
cfg.BHTHist = CVA6Cfg.BHTHist;
|
||||
cfg.DmBaseAddress = CVA6Cfg.DmBaseAddress;
|
||||
cfg.TvalEn = CVA6Cfg.TvalEn;
|
||||
cfg.DirectVecOnly = CVA6Cfg.DirectVecOnly;
|
||||
|
|
|
@ -35,6 +35,12 @@ package config_pkg;
|
|||
HPDCACHE_WT_WB = 4
|
||||
} cache_type_t;
|
||||
|
||||
/// Branch predictor parameter
|
||||
typedef enum logic {
|
||||
BHT = 0, // Bimodal predictor
|
||||
PH_BHT = 1 // Private History Bimodal predictor
|
||||
} bp_type_t;
|
||||
|
||||
/// Data and Address length
|
||||
typedef enum logic [3:0] {
|
||||
ModeOff = 0,
|
||||
|
@ -45,6 +51,12 @@ package config_pkg;
|
|||
ModeSv64 = 11
|
||||
} vm_mode_t;
|
||||
|
||||
/// Coprocessor type parameter
|
||||
typedef enum {
|
||||
COPRO_NONE,
|
||||
COPRO_EXAMPLE
|
||||
} copro_type_t;
|
||||
|
||||
localparam NrMaxRules = 16;
|
||||
|
||||
typedef struct packed {
|
||||
|
@ -140,6 +152,8 @@ package config_pkg;
|
|||
logic [NrMaxRules-1:0][63:0] CachedRegionLength;
|
||||
// CV-X-IF coprocessor interface enable
|
||||
bit CvxifEn;
|
||||
// Coprocessor type
|
||||
copro_type_t CoproType;
|
||||
// NOC bus type
|
||||
noc_type_e NOCType;
|
||||
// AXI address width
|
||||
|
@ -206,8 +220,12 @@ package config_pkg;
|
|||
int unsigned RASDepth;
|
||||
// Branch target buffer entries
|
||||
int unsigned BTBEntries;
|
||||
// Branch predictor type
|
||||
bp_type_t BPType;
|
||||
// Branch history entries
|
||||
int unsigned BHTEntries;
|
||||
// Branch history bits
|
||||
int unsigned BHTHist;
|
||||
// MMU instruction TLB entries
|
||||
int unsigned InstrTlbEntries;
|
||||
// MMU data TLB entries
|
||||
|
@ -263,6 +281,7 @@ package config_pkg;
|
|||
bit RVZCMT;
|
||||
bit XFVec;
|
||||
bit CvxifEn;
|
||||
copro_type_t CoproType;
|
||||
bit RVZiCond;
|
||||
bit RVZicntr;
|
||||
bit RVZihpm;
|
||||
|
@ -290,7 +309,9 @@ package config_pkg;
|
|||
logic [63:0] ExceptionAddress;
|
||||
int unsigned RASDepth;
|
||||
int unsigned BTBEntries;
|
||||
bp_type_t BPType;
|
||||
int unsigned BHTEntries;
|
||||
int unsigned BHTHist;
|
||||
int unsigned InstrTlbEntries;
|
||||
int unsigned DataTlbEntries;
|
||||
bit unsigned UseSharedTlb;
|
||||
|
|
|
@ -48,6 +48,7 @@ package cva6_config_pkg;
|
|||
RVZCMP: bit'(0),
|
||||
XFVec: bit'(0),
|
||||
CvxifEn: bit'(1),
|
||||
CoproType: config_pkg::COPRO_EXAMPLE,
|
||||
RVZiCond: bit'(0),
|
||||
RVZicntr: bit'(0),
|
||||
RVZihpm: bit'(0),
|
||||
|
@ -61,11 +62,13 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(2),
|
||||
BTBEntries: unsigned'(0),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(32),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(0),
|
||||
DirectVecOnly: bit'(1),
|
||||
NrPMPEntries: unsigned'(8),
|
||||
NrPMPEntries: unsigned'(0),
|
||||
PMPCfgRstVal: {64{64'h0}},
|
||||
PMPAddrRstVal: {64{64'h0}},
|
||||
PMPEntryReadOnly: 64'd0,
|
||||
|
|
|
@ -48,6 +48,7 @@ package cva6_config_pkg;
|
|||
RVZCMP: bit'(0),
|
||||
XFVec: bit'(0),
|
||||
CvxifEn: bit'(1),
|
||||
CoproType: config_pkg::COPRO_EXAMPLE,
|
||||
RVZiCond: bit'(0),
|
||||
RVZicntr: bit'(0),
|
||||
RVZihpm: bit'(0),
|
||||
|
@ -61,7 +62,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(2),
|
||||
BTBEntries: unsigned'(0),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(32),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(0),
|
||||
DirectVecOnly: bit'(1),
|
||||
|
|
|
@ -12,6 +12,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 32;
|
||||
|
||||
localparam CVA6ConfigRVF = 0;
|
||||
localparam CVA6ConfigRVD = 0;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -87,7 +88,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -102,6 +103,7 @@ package cva6_config_pkg;
|
|||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
RVZCMT: bit'(0),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -115,7 +117,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -13,6 +13,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 32;
|
||||
|
||||
localparam CVA6ConfigRVF = 0;
|
||||
localparam CVA6ConfigRVD = 0;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -85,7 +86,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -100,6 +101,7 @@ package cva6_config_pkg;
|
|||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -113,7 +115,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: unsigned'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -13,6 +13,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 32;
|
||||
|
||||
localparam CVA6ConfigRVF = 0;
|
||||
localparam CVA6ConfigRVD = 0;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -85,7 +86,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -100,6 +101,7 @@ package cva6_config_pkg;
|
|||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -113,7 +115,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: unsigned'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -13,6 +13,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 32;
|
||||
|
||||
localparam CVA6ConfigRVF = 0;
|
||||
localparam CVA6ConfigRVD = 0;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -84,7 +85,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -99,6 +100,7 @@ package cva6_config_pkg;
|
|||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -112,7 +114,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -13,6 +13,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 32;
|
||||
|
||||
localparam CVA6ConfigRVF = 1;
|
||||
localparam CVA6ConfigRVD = 0;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -85,7 +86,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -100,6 +101,7 @@ package cva6_config_pkg;
|
|||
RVZCMT: bit'(0),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -113,7 +115,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
118
core/include/cv64a60ax_config_pkg.sv
Normal file
118
core/include/cv64a60ax_config_pkg.sv
Normal file
|
@ -0,0 +1,118 @@
|
|||
// 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: Jean-Roch COULON - Thales
|
||||
//
|
||||
// Copyright 2023 Commissariat a l'Energie Atomique et aux Energies
|
||||
// Alternatives (CEA)
|
||||
//
|
||||
// Author: Tanuj Khandelwal - CEA
|
||||
// Date: Janvary, 2025
|
||||
// Description: CVA6 configuration package using the HPDcache as cache subsystem
|
||||
|
||||
|
||||
package cva6_config_pkg;
|
||||
|
||||
localparam CVA6ConfigXlen = 64;
|
||||
localparam CVA6ConfigRvfiTrace = 1;
|
||||
|
||||
localparam CVA6ConfigAxiIdWidth = 4;
|
||||
localparam CVA6ConfigAxiAddrWidth = 64;
|
||||
localparam CVA6ConfigAxiDataWidth = 64;
|
||||
localparam CVA6ConfigDataUserWidth = 32;
|
||||
|
||||
|
||||
localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{
|
||||
XLEN: unsigned'(CVA6ConfigXlen),
|
||||
VLEN: unsigned'(64),
|
||||
FpgaEn: bit'(0), // for Xilinx and Altera
|
||||
FpgaAlteraEn: bit'(0), // for Altera (only)
|
||||
TechnoCut: bit'(0),
|
||||
SuperscalarEn: bit'(0),
|
||||
NrCommitPorts: unsigned'(2),
|
||||
AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth),
|
||||
AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth),
|
||||
AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth),
|
||||
AxiUserWidth: unsigned'(CVA6ConfigDataUserWidth),
|
||||
MemTidWidth: unsigned'(CVA6ConfigAxiIdWidth),
|
||||
NrLoadBufEntries: unsigned'(8),
|
||||
RVF: bit'(1),
|
||||
RVD: bit'(1),
|
||||
XF16: bit'(0),
|
||||
XF16ALT: bit'(0),
|
||||
XF8: bit'(0),
|
||||
RVA: bit'(1),
|
||||
RVB: bit'(1),
|
||||
ZKN: bit'(1),
|
||||
RVV: bit'(0),
|
||||
RVC: bit'(1),
|
||||
RVH: bit'(0),
|
||||
RVZCMT: bit'(0),
|
||||
RVZCB: bit'(1),
|
||||
RVZCMP: bit'(0),
|
||||
XFVec: bit'(0),
|
||||
CvxifEn: bit'(1),
|
||||
RVZiCond: bit'(1),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
NrScoreboardEntries: unsigned'(8),
|
||||
PerfCounterEn: bit'(1),
|
||||
MmuPresent: bit'(1),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(0),
|
||||
HaltAddress: 64'h800,
|
||||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(4),
|
||||
BTBEntries: unsigned'(16),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(64),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(1),
|
||||
DirectVecOnly: bit'(0),
|
||||
NrPMPEntries: unsigned'(8),
|
||||
PMPCfgRstVal: {64{64'h0}},
|
||||
PMPAddrRstVal: {64{64'h0}},
|
||||
PMPEntryReadOnly: 64'd0,
|
||||
PMPNapotEn: bit'(1),
|
||||
NOCType: config_pkg::NOC_TYPE_AXI4_ATOP,
|
||||
NrNonIdempotentRules: unsigned'(2),
|
||||
NonIdempotentAddrBase: 1024'({64'b0, 64'b0}),
|
||||
NonIdempotentLength: 1024'({64'b0, 64'b0}),
|
||||
NrExecuteRegionRules: unsigned'(3),
|
||||
ExecuteRegionAddrBase: 1024'({64'h8000_0000, 64'h1_0000, 64'h0}),
|
||||
ExecuteRegionLength: 1024'({64'h40000000, 64'h10000, 64'h1000}),
|
||||
NrCachedRegionRules: unsigned'(1),
|
||||
CachedRegionAddrBase: 1024'({64'h8000_0000}),
|
||||
CachedRegionLength: 1024'({64'h40000000}),
|
||||
MaxOutstandingStores: unsigned'(7),
|
||||
DebugEn: bit'(1),
|
||||
AxiBurstWriteEn: bit'(0),
|
||||
IcacheByteSize: unsigned'(32768),
|
||||
IcacheSetAssoc: unsigned'(8),
|
||||
IcacheLineWidth: unsigned'(512),
|
||||
DCacheType: config_pkg::HPDCACHE_WT,
|
||||
DcacheByteSize: unsigned'(32768),
|
||||
DcacheSetAssoc: unsigned'(8),
|
||||
DcacheLineWidth: unsigned'(512),
|
||||
DcacheFlushOnFence: bit'(0),
|
||||
DcacheInvalidateOnFlush: bit'(0),
|
||||
DataUserEn: unsigned'(0),
|
||||
WtDcacheWbufDepth: int'(8),
|
||||
FetchUserWidth: unsigned'(32),
|
||||
FetchUserEn: unsigned'(0),
|
||||
InstrTlbEntries: int'(16),
|
||||
DataTlbEntries: int'(16),
|
||||
UseSharedTlb: bit'(0),
|
||||
SharedTlbDepth: int'(64),
|
||||
NrLoadPipeRegs: int'(0),
|
||||
NrStorePipeRegs: int'(0),
|
||||
DcacheIdWidth: int'(3)
|
||||
};
|
||||
|
||||
endpackage
|
|
@ -13,6 +13,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 64;
|
||||
|
||||
localparam CVA6ConfigRVF = 1;
|
||||
localparam CVA6ConfigRVD = 1;
|
||||
localparam CVA6ConfigF16En = 1;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -88,7 +89,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -103,6 +104,7 @@ package cva6_config_pkg;
|
|||
RVZCMT: bit'(0),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -116,7 +118,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -13,6 +13,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 64;
|
||||
|
||||
localparam CVA6ConfigRVF = 1;
|
||||
localparam CVA6ConfigRVD = 1;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -88,7 +89,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -103,6 +104,7 @@ package cva6_config_pkg;
|
|||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -116,7 +118,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -20,6 +20,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 64;
|
||||
|
||||
localparam CVA6ConfigRVF = 1;
|
||||
localparam CVA6ConfigRVD = 1;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -95,7 +96,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -110,6 +111,7 @@ package cva6_config_pkg;
|
|||
RVZCMT: bit'(0),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -123,7 +125,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -20,6 +20,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 64;
|
||||
|
||||
localparam CVA6ConfigRVF = 1;
|
||||
localparam CVA6ConfigRVD = 1;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -95,7 +96,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -110,6 +111,7 @@ package cva6_config_pkg;
|
|||
RVZCMT: bit'(0),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -123,7 +125,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -13,6 +13,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 64;
|
||||
|
||||
localparam CVA6ConfigRVF = 1;
|
||||
localparam CVA6ConfigRVD = 1;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -88,7 +89,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -103,6 +104,7 @@ package cva6_config_pkg;
|
|||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -116,7 +118,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -13,6 +13,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 64;
|
||||
|
||||
localparam CVA6ConfigRVF = 1;
|
||||
localparam CVA6ConfigRVD = 1;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -88,7 +89,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -103,6 +104,7 @@ package cva6_config_pkg;
|
|||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -116,7 +118,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -13,6 +13,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 64;
|
||||
|
||||
localparam CVA6ConfigRVF = 1;
|
||||
localparam CVA6ConfigRVD = 1;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -88,7 +89,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -103,6 +104,7 @@ package cva6_config_pkg;
|
|||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -116,7 +118,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -13,6 +13,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigXlen = 64;
|
||||
|
||||
localparam CVA6ConfigRVF = 1;
|
||||
localparam CVA6ConfigRVD = 1;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -88,7 +89,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -103,6 +104,7 @@ package cva6_config_pkg;
|
|||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -116,7 +118,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -12,7 +12,10 @@ package cva6_config_pkg;
|
|||
|
||||
localparam CVA6ConfigXlen = 64;
|
||||
|
||||
localparam CVA6ConfigNrCommitPorts = 2;
|
||||
|
||||
localparam CVA6ConfigRVF = 1;
|
||||
localparam CVA6ConfigRVD = 1;
|
||||
localparam CVA6ConfigF16En = 0;
|
||||
localparam CVA6ConfigF16AltEn = 0;
|
||||
localparam CVA6ConfigF8En = 0;
|
||||
|
@ -32,16 +35,16 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigAxiAddrWidth = 64;
|
||||
localparam CVA6ConfigAxiDataWidth = 64;
|
||||
localparam CVA6ConfigFetchUserEn = 0;
|
||||
localparam CVA6ConfigFetchUserWidth = CVA6ConfigXlen;
|
||||
localparam CVA6ConfigFetchUserWidth = 1; // Just not to raise warnings
|
||||
localparam CVA6ConfigDataUserEn = 0;
|
||||
localparam CVA6ConfigDataUserWidth = CVA6ConfigXlen;
|
||||
|
||||
localparam CVA6ConfigIcacheByteSize = 16384;
|
||||
localparam CVA6ConfigIcacheByteSize = 4096;
|
||||
localparam CVA6ConfigIcacheSetAssoc = 4;
|
||||
localparam CVA6ConfigIcacheLineWidth = 128;
|
||||
localparam CVA6ConfigDcacheByteSize = 16384;
|
||||
localparam CVA6ConfigDcacheByteSize = 8192;
|
||||
localparam CVA6ConfigDcacheSetAssoc = 4;
|
||||
localparam CVA6ConfigDcacheLineWidth = 128;
|
||||
localparam CVA6ConfigDcacheLineWidth = 256;
|
||||
|
||||
localparam CVA6ConfigDcacheFlushOnFence = 1'b0;
|
||||
localparam CVA6ConfigDcacheInvalidateOnFlush = 1'b0;
|
||||
|
@ -80,7 +83,7 @@ package cva6_config_pkg;
|
|||
FpgaAlteraEn: bit'(0), // for Altera (only)
|
||||
TechnoCut: bit'(0),
|
||||
SuperscalarEn: bit'(0),
|
||||
NrCommitPorts: unsigned'(1),
|
||||
NrCommitPorts: unsigned'(CVA6ConfigNrCommitPorts),
|
||||
AxiAddrWidth: unsigned'(CVA6ConfigAxiAddrWidth),
|
||||
AxiDataWidth: unsigned'(CVA6ConfigAxiDataWidth),
|
||||
AxiIdWidth: unsigned'(CVA6ConfigAxiIdWidth),
|
||||
|
@ -88,7 +91,7 @@ package cva6_config_pkg;
|
|||
MemTidWidth: unsigned'(CVA6ConfigMemTidWidth),
|
||||
NrLoadBufEntries: unsigned'(CVA6ConfigNrLoadBufEntries),
|
||||
RVF: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVF),
|
||||
RVD: bit'(CVA6ConfigRVD),
|
||||
XF16: bit'(CVA6ConfigF16En),
|
||||
XF16ALT: bit'(CVA6ConfigF16AltEn),
|
||||
XF8: bit'(CVA6ConfigF8En),
|
||||
|
@ -103,6 +106,7 @@ package cva6_config_pkg;
|
|||
RVZCMT: bit'(0),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -116,7 +120,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(CVA6ConfigRASDepth),
|
||||
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(CVA6ConfigTvalEn),
|
||||
DirectVecOnly: bit'(0),
|
||||
|
|
|
@ -55,6 +55,7 @@ package cva6_config_pkg;
|
|||
RVZCMT: bit'(0),
|
||||
XFVec: bit'(0),
|
||||
CvxifEn: bit'(1),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(0),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -68,7 +69,9 @@ package cva6_config_pkg;
|
|||
ExceptionAddress: 64'h808,
|
||||
RASDepth: unsigned'(2),
|
||||
BTBEntries: unsigned'(0),
|
||||
BPType: config_pkg::BHT,
|
||||
BHTEntries: unsigned'(32),
|
||||
BHTHist: unsigned'(3),
|
||||
DmBaseAddress: 64'h0,
|
||||
TvalEn: bit'(0),
|
||||
DirectVecOnly: bit'(1),
|
||||
|
|
|
@ -25,7 +25,9 @@ module load_store_unit
|
|||
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 acc_mmu_req_t = logic,
|
||||
parameter type acc_mmu_resp_t = logic
|
||||
) (
|
||||
// Subsystem Clock - SUBSYSTEM
|
||||
input logic clk_i,
|
||||
|
@ -82,6 +84,10 @@ module load_store_unit
|
|||
// Enable G-Stage memory translation for load/stores - TO_BE_COMPLETED
|
||||
input logic en_ld_st_g_translation_i,
|
||||
|
||||
// Accelerator request for CVA6's MMU
|
||||
input acc_mmu_req_t acc_mmu_req_i,
|
||||
output acc_mmu_resp_t acc_mmu_resp_o,
|
||||
|
||||
// Instruction cache input request - CACHES
|
||||
input icache_arsp_t icache_areq_i,
|
||||
// Instruction cache output request - CACHES
|
||||
|
@ -148,9 +154,9 @@ module load_store_unit
|
|||
input amo_resp_t amo_resp_i,
|
||||
|
||||
// PMP configuration - CSR_REGFILE
|
||||
input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i,
|
||||
input riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_i,
|
||||
// PMP address - CSR_REGFILE
|
||||
input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
|
||||
input logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr_i,
|
||||
|
||||
// RVFI inforamtion - RVFI
|
||||
output lsu_ctrl_t rvfi_lsu_ctrl_o,
|
||||
|
@ -159,26 +165,26 @@ module load_store_unit
|
|||
);
|
||||
|
||||
// data is misaligned
|
||||
logic data_misaligned;
|
||||
logic data_misaligned;
|
||||
// --------------------------------------
|
||||
// 1st register stage - (stall registers)
|
||||
// --------------------------------------
|
||||
// those are the signals which are always correct
|
||||
// e.g.: they keep the value in the stall case
|
||||
lsu_ctrl_t lsu_ctrl;
|
||||
lsu_ctrl_t lsu_ctrl, lsu_ctrl_byp;
|
||||
|
||||
logic pop_st;
|
||||
logic pop_ld;
|
||||
logic pop_st;
|
||||
logic pop_ld;
|
||||
|
||||
// ------------------------------
|
||||
// Address Generation Unit (AGU)
|
||||
// ------------------------------
|
||||
// virtual address as calculated by the AGU in the first cycle
|
||||
logic [ CVA6Cfg.VLEN-1:0] vaddr_i;
|
||||
logic [ CVA6Cfg.XLEN-1:0] vaddr_xlen;
|
||||
logic overflow;
|
||||
logic g_overflow;
|
||||
logic [(CVA6Cfg.XLEN/8)-1:0] be_i;
|
||||
logic [ CVA6Cfg.VLEN-1:0] vaddr_i;
|
||||
logic [ CVA6Cfg.XLEN-1:0] vaddr_xlen;
|
||||
logic overflow;
|
||||
logic g_overflow;
|
||||
logic [(CVA6Cfg.XLEN/8)-1:0] be_i;
|
||||
|
||||
assign vaddr_xlen = $unsigned($signed(fu_data_i.imm) + $signed(fu_data_i.operand_a));
|
||||
assign vaddr_i = vaddr_xlen[CVA6Cfg.VLEN-1:0];
|
||||
|
@ -190,10 +196,10 @@ module load_store_unit
|
|||
assign g_overflow = 1'b0;
|
||||
end
|
||||
|
||||
logic st_valid_i;
|
||||
logic ld_valid_i;
|
||||
logic ld_translation_req;
|
||||
logic st_translation_req;
|
||||
logic st_valid_i;
|
||||
logic ld_valid_i;
|
||||
logic ld_translation_req;
|
||||
logic st_translation_req, cva6_st_translation_req, acc_st_translation_req;
|
||||
logic [CVA6Cfg.VLEN-1:0] ld_vaddr;
|
||||
logic [ 31:0] ld_tinst;
|
||||
logic ld_hs_ld_st_inst;
|
||||
|
@ -202,41 +208,41 @@ module load_store_unit
|
|||
logic [ 31:0] st_tinst;
|
||||
logic st_hs_ld_st_inst;
|
||||
logic st_hlvx_inst;
|
||||
logic translation_req;
|
||||
logic translation_valid;
|
||||
logic [CVA6Cfg.VLEN-1:0] mmu_vaddr;
|
||||
logic [CVA6Cfg.PLEN-1:0] mmu_paddr, lsu_paddr;
|
||||
logic [ 31:0] mmu_tinst;
|
||||
logic mmu_hs_ld_st_inst;
|
||||
logic mmu_hlvx_inst;
|
||||
exception_t mmu_exception;
|
||||
exception_t pmp_exception;
|
||||
icache_areq_t pmp_icache_areq_i;
|
||||
logic pmp_translation_valid;
|
||||
logic dtlb_hit;
|
||||
logic [ CVA6Cfg.PPNW-1:0] dtlb_ppn;
|
||||
logic translation_req, cva6_translation_req, acc_translation_req;
|
||||
logic translation_valid, cva6_translation_valid, acc_translataion_valid;
|
||||
logic [CVA6Cfg.VLEN-1:0] mmu_vaddr, cva6_mmu_vaddr, acc_mmu_vaddr;
|
||||
logic [CVA6Cfg.PLEN-1:0] mmu_paddr, cva6_mmu_paddr, acc_mmu_paddr, lsu_paddr;
|
||||
logic [31:0] mmu_tinst;
|
||||
logic mmu_hs_ld_st_inst;
|
||||
logic mmu_hlvx_inst;
|
||||
exception_t mmu_exception, cva6_mmu_exception, acc_mmu_exception;
|
||||
exception_t pmp_exception;
|
||||
icache_areq_t pmp_icache_areq_i;
|
||||
logic pmp_translation_valid;
|
||||
logic dtlb_hit, cva6_dtlb_hit, acc_dtlb_hit;
|
||||
logic [CVA6Cfg.PPNW-1:0] dtlb_ppn, cva6_dtlb_ppn, acc_dtlb_ppn;
|
||||
|
||||
logic ld_valid;
|
||||
logic [CVA6Cfg.TRANS_ID_BITS-1:0] ld_trans_id;
|
||||
logic [ CVA6Cfg.XLEN-1:0] ld_result;
|
||||
logic st_valid;
|
||||
logic [CVA6Cfg.TRANS_ID_BITS-1:0] st_trans_id;
|
||||
logic [ CVA6Cfg.XLEN-1:0] st_result;
|
||||
logic ld_valid;
|
||||
logic [CVA6Cfg.TRANS_ID_BITS-1:0] ld_trans_id;
|
||||
logic [ CVA6Cfg.XLEN-1:0] ld_result;
|
||||
logic st_valid;
|
||||
logic [CVA6Cfg.TRANS_ID_BITS-1:0] st_trans_id;
|
||||
logic [ CVA6Cfg.XLEN-1:0] st_result;
|
||||
|
||||
logic [ 11:0] page_offset;
|
||||
logic page_offset_matches;
|
||||
logic [ 11:0] page_offset;
|
||||
logic page_offset_matches;
|
||||
|
||||
exception_t misaligned_exception;
|
||||
exception_t ld_ex;
|
||||
exception_t st_ex;
|
||||
|
||||
logic hs_ld_st_inst;
|
||||
logic hlvx_inst;
|
||||
exception_t misaligned_exception, cva6_misaligned_exception, acc_misaligned_exception;
|
||||
exception_t ld_ex;
|
||||
exception_t st_ex;
|
||||
|
||||
logic hs_ld_st_inst;
|
||||
logic hlvx_inst;
|
||||
logic [1:0] sum, mxr;
|
||||
logic [CVA6Cfg.PPNW-1:0] satp_ppn[2:0];
|
||||
logic [CVA6Cfg.ASID_WIDTH-1:0] asid[2:0], asid_to_be_flushed[1:0];
|
||||
logic [CVA6Cfg.VLEN-1:0] vaddr_to_be_flushed[1:0];
|
||||
|
||||
// -------------------
|
||||
// MMU e.g.: TLBs/PTW
|
||||
// -------------------
|
||||
|
@ -387,6 +393,108 @@ module load_store_unit
|
|||
.pmpaddr_i (pmpaddr_i)
|
||||
);
|
||||
|
||||
// ------------------
|
||||
// External MMU port
|
||||
// ------------------
|
||||
|
||||
if (CVA6Cfg.EnableAccelerator) begin
|
||||
// The MMU can be connected to CVA6 or the ACCELERATOR
|
||||
enum logic {
|
||||
CVA6,
|
||||
ACC
|
||||
}
|
||||
mmu_state_d, mmu_state_q;
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
mmu_state_q <= CVA6;
|
||||
end else begin
|
||||
mmu_state_q <= mmu_state_d;
|
||||
end
|
||||
end
|
||||
// Straightforward and slow-reactive MMU arbitration logic
|
||||
// This logic can be optimized to reduce answer latency and contention
|
||||
always_comb begin
|
||||
// Maintain state
|
||||
mmu_state_d = mmu_state_q;
|
||||
// Serve CVA6 and gate the accelerator by default
|
||||
// MMU input
|
||||
misaligned_exception = cva6_misaligned_exception;
|
||||
st_translation_req = cva6_st_translation_req;
|
||||
translation_req = cva6_translation_req;
|
||||
mmu_vaddr = cva6_mmu_vaddr;
|
||||
// MMU output
|
||||
cva6_translation_valid = translation_valid;
|
||||
cva6_mmu_paddr = mmu_paddr;
|
||||
cva6_mmu_exception = mmu_exception;
|
||||
cva6_dtlb_hit = dtlb_hit;
|
||||
cva6_dtlb_ppn = dtlb_ppn;
|
||||
acc_mmu_resp_o.acc_mmu_valid = '0;
|
||||
acc_mmu_resp_o.acc_mmu_paddr = '0;
|
||||
acc_mmu_resp_o.acc_mmu_exception = '0;
|
||||
acc_mmu_resp_o.acc_mmu_dtlb_hit = '0;
|
||||
acc_mmu_resp_o.acc_mmu_dtlb_ppn = '0;
|
||||
unique case (mmu_state_q)
|
||||
CVA6: begin
|
||||
// Only the accelerator is requesting, and the lsu bypass queue is empty.
|
||||
if (acc_mmu_req_i.acc_mmu_req && !lsu_valid_i && lsu_ready_o) begin
|
||||
// Lock the MMU to the accelerator.
|
||||
// If the issue stage is firing a mem op in this cycle,
|
||||
// the bypass queue will buffer it.
|
||||
mmu_state_d = ACC;
|
||||
end
|
||||
// Make this a mealy FSM to cut some latency.
|
||||
// It should be okay timing-wise since cva6's requests already
|
||||
// depend on lsu_valid_i. Moreover, lsu_ready_o is sequentially
|
||||
// generated by the bypass and, in this first implementation,
|
||||
// the acc request already depends combinatorially upon acc_mmu_req_i.acc_mmu_req.
|
||||
end
|
||||
ACC: begin
|
||||
// MMU input
|
||||
misaligned_exception = acc_mmu_req_i.acc_mmu_misaligned_ex;
|
||||
st_translation_req = acc_mmu_req_i.acc_mmu_is_store;
|
||||
translation_req = acc_mmu_req_i.acc_mmu_req;
|
||||
mmu_vaddr = acc_mmu_req_i.acc_mmu_vaddr;
|
||||
// MMU output
|
||||
acc_mmu_resp_o.acc_mmu_valid = translation_valid;
|
||||
acc_mmu_resp_o.acc_mmu_paddr = mmu_paddr;
|
||||
acc_mmu_resp_o.acc_mmu_exception = mmu_exception;
|
||||
acc_mmu_resp_o.acc_mmu_dtlb_hit = dtlb_hit;
|
||||
acc_mmu_resp_o.acc_mmu_dtlb_ppn = dtlb_ppn;
|
||||
cva6_translation_valid = '0;
|
||||
cva6_mmu_paddr = '0;
|
||||
cva6_mmu_exception = '0;
|
||||
cva6_dtlb_hit = '0;
|
||||
cva6_dtlb_ppn = '0;
|
||||
// Get back to CVA6 after the translation
|
||||
if (translation_valid) mmu_state_d = CVA6;
|
||||
end
|
||||
default: mmu_state_d = CVA6;
|
||||
endcase
|
||||
end
|
||||
always_comb begin
|
||||
// Feed forward
|
||||
lsu_ctrl = lsu_ctrl_byp;
|
||||
// Mask the lsu valid so that cva6's req gets buffered in the
|
||||
// bypass queue when the MMU is being used by the accelerator.
|
||||
lsu_ctrl.valid = (mmu_state_q == ACC) ? 1'b0 : lsu_ctrl_byp.valid;
|
||||
end
|
||||
end else begin
|
||||
// MMU input
|
||||
assign misaligned_exception = cva6_misaligned_exception;
|
||||
assign st_translation_req = cva6_st_translation_req;
|
||||
assign translation_req = cva6_translation_req;
|
||||
assign mmu_vaddr = cva6_mmu_vaddr;
|
||||
// MMU output
|
||||
assign cva6_translation_valid = translation_valid;
|
||||
assign cva6_mmu_paddr = mmu_paddr;
|
||||
assign cva6_mmu_exception = mmu_exception;
|
||||
assign cva6_dtlb_hit = dtlb_hit;
|
||||
assign cva6_dtlb_ppn = dtlb_ppn;
|
||||
// No accelerator
|
||||
assign acc_mmu_resp_o = '0;
|
||||
// Feed forward the lsu_ctrl bypass
|
||||
assign lsu_ctrl = lsu_ctrl_byp;
|
||||
end
|
||||
|
||||
logic store_buffer_empty;
|
||||
// ------------------
|
||||
|
@ -418,15 +526,15 @@ module load_store_unit
|
|||
.result_o (st_result),
|
||||
.ex_o (st_ex),
|
||||
// MMU port
|
||||
.translation_req_o (st_translation_req),
|
||||
.translation_req_o (cva6_st_translation_req),
|
||||
.vaddr_o (st_vaddr),
|
||||
.rvfi_mem_paddr_o (rvfi_mem_paddr_o),
|
||||
.tinst_o (st_tinst),
|
||||
.hs_ld_st_inst_o (st_hs_ld_st_inst),
|
||||
.hlvx_inst_o (st_hlvx_inst),
|
||||
.paddr_i (mmu_paddr),
|
||||
.ex_i (mmu_exception),
|
||||
.dtlb_hit_i (dtlb_hit),
|
||||
.paddr_i (cva6_mmu_paddr),
|
||||
.ex_i (cva6_mmu_exception),
|
||||
.dtlb_hit_i (cva6_dtlb_hit),
|
||||
// Load Unit
|
||||
.page_offset_i (page_offset),
|
||||
.page_offset_matches_o(page_offset_matches),
|
||||
|
@ -465,10 +573,10 @@ module load_store_unit
|
|||
.tinst_o (ld_tinst),
|
||||
.hs_ld_st_inst_o (ld_hs_ld_st_inst),
|
||||
.hlvx_inst_o (ld_hlvx_inst),
|
||||
.paddr_i (mmu_paddr),
|
||||
.ex_i (mmu_exception),
|
||||
.dtlb_hit_i (dtlb_hit),
|
||||
.dtlb_ppn_i (dtlb_ppn),
|
||||
.paddr_i (cva6_mmu_paddr),
|
||||
.ex_i (cva6_mmu_exception),
|
||||
.dtlb_hit_i (cva6_dtlb_hit),
|
||||
.dtlb_ppn_i (cva6_dtlb_ppn),
|
||||
// to store unit
|
||||
.page_offset_o (page_offset),
|
||||
.page_offset_matches_i(page_offset_matches),
|
||||
|
@ -510,22 +618,22 @@ module load_store_unit
|
|||
// determine whether this is a load or store
|
||||
always_comb begin : which_op
|
||||
|
||||
ld_valid_i = 1'b0;
|
||||
st_valid_i = 1'b0;
|
||||
ld_valid_i = 1'b0;
|
||||
st_valid_i = 1'b0;
|
||||
|
||||
translation_req = 1'b0;
|
||||
mmu_vaddr = {CVA6Cfg.VLEN{1'b0}};
|
||||
mmu_tinst = {32{1'b0}};
|
||||
mmu_hs_ld_st_inst = 1'b0;
|
||||
mmu_hlvx_inst = 1'b0;
|
||||
cva6_translation_req = 1'b0;
|
||||
cva6_mmu_vaddr = {CVA6Cfg.VLEN{1'b0}};
|
||||
mmu_tinst = {32{1'b0}};
|
||||
mmu_hs_ld_st_inst = 1'b0;
|
||||
mmu_hlvx_inst = 1'b0;
|
||||
|
||||
// check the operation to activate the right functional unit accordingly
|
||||
unique case (lsu_ctrl.fu)
|
||||
// all loads go here
|
||||
LOAD: begin
|
||||
ld_valid_i = lsu_ctrl.valid;
|
||||
translation_req = ld_translation_req;
|
||||
mmu_vaddr = ld_vaddr;
|
||||
ld_valid_i = lsu_ctrl.valid;
|
||||
cva6_translation_req = ld_translation_req;
|
||||
cva6_mmu_vaddr = ld_vaddr;
|
||||
if (CVA6Cfg.RVH) begin
|
||||
mmu_tinst = ld_tinst;
|
||||
mmu_hs_ld_st_inst = ld_hs_ld_st_inst;
|
||||
|
@ -534,9 +642,9 @@ module load_store_unit
|
|||
end
|
||||
// all stores go here
|
||||
STORE: begin
|
||||
st_valid_i = lsu_ctrl.valid;
|
||||
translation_req = st_translation_req;
|
||||
mmu_vaddr = st_vaddr;
|
||||
st_valid_i = lsu_ctrl.valid;
|
||||
cva6_translation_req = st_translation_req;
|
||||
cva6_mmu_vaddr = st_vaddr;
|
||||
if (CVA6Cfg.RVH) begin
|
||||
mmu_tinst = st_tinst;
|
||||
mmu_hs_ld_st_inst = st_hs_ld_st_inst;
|
||||
|
@ -594,7 +702,7 @@ module load_store_unit
|
|||
// the misaligned exception is passed to the functional unit via the MMU, which in case
|
||||
// can augment the exception if other memory related exceptions like a page fault or access errors
|
||||
always_comb begin : data_misaligned_detection
|
||||
misaligned_exception = {
|
||||
cva6_misaligned_exception = {
|
||||
{CVA6Cfg.XLEN{1'b0}}, {CVA6Cfg.XLEN{1'b0}}, {CVA6Cfg.GPLEN{1'b0}}, {32{1'b0}}, 1'b0, 1'b0
|
||||
};
|
||||
data_misaligned = 1'b0;
|
||||
|
@ -640,26 +748,26 @@ module load_store_unit
|
|||
if (data_misaligned) begin
|
||||
case (lsu_ctrl.fu)
|
||||
LOAD: begin
|
||||
misaligned_exception.cause = riscv::LD_ADDR_MISALIGNED;
|
||||
misaligned_exception.valid = 1'b1;
|
||||
cva6_misaligned_exception.cause = riscv::LD_ADDR_MISALIGNED;
|
||||
cva6_misaligned_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
cva6_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;
|
||||
cva6_misaligned_exception.tval2 = '0;
|
||||
cva6_misaligned_exception.tinst = lsu_ctrl.tinst;
|
||||
cva6_misaligned_exception.gva = ld_st_v_i;
|
||||
end
|
||||
end
|
||||
STORE: begin
|
||||
|
||||
misaligned_exception.cause = riscv::ST_ADDR_MISALIGNED;
|
||||
misaligned_exception.valid = 1'b1;
|
||||
cva6_misaligned_exception.cause = riscv::ST_ADDR_MISALIGNED;
|
||||
cva6_misaligned_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
cva6_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;
|
||||
cva6_misaligned_exception.tval2 = '0;
|
||||
cva6_misaligned_exception.tinst = lsu_ctrl.tinst;
|
||||
cva6_misaligned_exception.gva = ld_st_v_i;
|
||||
end
|
||||
end
|
||||
default: ;
|
||||
|
@ -670,25 +778,25 @@ module load_store_unit
|
|||
|
||||
case (lsu_ctrl.fu)
|
||||
LOAD: begin
|
||||
misaligned_exception.cause = riscv::LOAD_PAGE_FAULT;
|
||||
misaligned_exception.valid = 1'b1;
|
||||
cva6_misaligned_exception.cause = riscv::LOAD_PAGE_FAULT;
|
||||
cva6_misaligned_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
cva6_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;
|
||||
cva6_misaligned_exception.tval2 = '0;
|
||||
cva6_misaligned_exception.tinst = lsu_ctrl.tinst;
|
||||
cva6_misaligned_exception.gva = ld_st_v_i;
|
||||
end
|
||||
end
|
||||
STORE: begin
|
||||
misaligned_exception.cause = riscv::STORE_PAGE_FAULT;
|
||||
misaligned_exception.valid = 1'b1;
|
||||
cva6_misaligned_exception.cause = riscv::STORE_PAGE_FAULT;
|
||||
cva6_misaligned_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
cva6_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;
|
||||
cva6_misaligned_exception.tval2 = '0;
|
||||
cva6_misaligned_exception.tinst = lsu_ctrl.tinst;
|
||||
cva6_misaligned_exception.gva = ld_st_v_i;
|
||||
end
|
||||
end
|
||||
default: ;
|
||||
|
@ -699,25 +807,25 @@ module load_store_unit
|
|||
|
||||
case (lsu_ctrl.fu)
|
||||
LOAD: begin
|
||||
misaligned_exception.cause = riscv::LOAD_GUEST_PAGE_FAULT;
|
||||
misaligned_exception.valid = 1'b1;
|
||||
cva6_misaligned_exception.cause = riscv::LOAD_GUEST_PAGE_FAULT;
|
||||
cva6_misaligned_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
cva6_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;
|
||||
cva6_misaligned_exception.tval2 = '0;
|
||||
cva6_misaligned_exception.tinst = lsu_ctrl.tinst;
|
||||
cva6_misaligned_exception.gva = ld_st_v_i;
|
||||
end
|
||||
end
|
||||
STORE: begin
|
||||
misaligned_exception.cause = riscv::STORE_GUEST_PAGE_FAULT;
|
||||
misaligned_exception.valid = 1'b1;
|
||||
cva6_misaligned_exception.cause = riscv::STORE_GUEST_PAGE_FAULT;
|
||||
cva6_misaligned_exception.valid = 1'b1;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
misaligned_exception.tval = {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{1'b0}}, lsu_ctrl.vaddr};
|
||||
cva6_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;
|
||||
cva6_misaligned_exception.tval2 = '0;
|
||||
cva6_misaligned_exception.tinst = lsu_ctrl.tinst;
|
||||
cva6_misaligned_exception.gva = ld_st_v_i;
|
||||
end
|
||||
end
|
||||
default: ;
|
||||
|
@ -759,12 +867,10 @@ module load_store_unit
|
|||
.pop_ld_i (pop_ld),
|
||||
.pop_st_i (pop_st),
|
||||
|
||||
.lsu_ctrl_o(lsu_ctrl),
|
||||
.lsu_ctrl_o(lsu_ctrl_byp),
|
||||
.ready_o (lsu_ready_o)
|
||||
);
|
||||
|
||||
assign rvfi_lsu_ctrl_o = lsu_ctrl;
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
// Date: 2.10.2019
|
||||
// Description: purely combinatorial PMP unit (with extraction for more complex configs such as NAPOT)
|
||||
|
||||
module pmp #(
|
||||
module pmp
|
||||
import ariane_pkg::*;
|
||||
#(
|
||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty
|
||||
) (
|
||||
// Input
|
||||
|
@ -20,8 +22,8 @@ module pmp #(
|
|||
input riscv::pmp_access_t access_type_i,
|
||||
input riscv::priv_lvl_t priv_lvl_i,
|
||||
// Configuration
|
||||
input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] conf_addr_i,
|
||||
input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] conf_i,
|
||||
input logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] conf_addr_i,
|
||||
input riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] conf_i,
|
||||
// Output
|
||||
output logic allow_o
|
||||
);
|
||||
|
|
|
@ -36,8 +36,8 @@ module pmp_data_if
|
|||
input riscv::priv_lvl_t ld_st_priv_lvl_i,
|
||||
input logic ld_st_v_i,
|
||||
// PMP
|
||||
input riscv::pmpcfg_t [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0] pmpcfg_i,
|
||||
input logic [(CVA6Cfg.NrPMPEntries > 0 ? CVA6Cfg.NrPMPEntries-1 : 0):0][CVA6Cfg.PLEN-3:0] pmpaddr_i
|
||||
input riscv::pmpcfg_t [avoid_neg(CVA6Cfg.NrPMPEntries-1):0] pmpcfg_i,
|
||||
input logic [avoid_neg(CVA6Cfg.NrPMPEntries-1):0][CVA6Cfg.PLEN-3:0] pmpaddr_i
|
||||
);
|
||||
// virtual address causing the exception
|
||||
logic [CVA6Cfg.XLEN-1:0] fetch_vaddr_xlen, lsu_vaddr_xlen;
|
||||
|
|
|
@ -143,7 +143,7 @@ proc do_create_io_pll {} {
|
|||
set_instance_parameter_value iopll_0 {gui_new_mif_file_path} {~/pll.mif}
|
||||
set_instance_parameter_value iopll_0 {gui_number_of_clocks} {5}
|
||||
set_instance_parameter_value iopll_0 {gui_operation_mode} {direct}
|
||||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency0} {200.0}
|
||||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency0} {100.0}
|
||||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency1} {125.0}
|
||||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency10} {100.0}
|
||||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency11} {100.0}
|
||||
|
@ -161,7 +161,7 @@ proc do_create_io_pll {} {
|
|||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency7} {100.0}
|
||||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency8} {100.0}
|
||||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency9} {100.0}
|
||||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps0} {5000.0}
|
||||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps0} {10000.0}
|
||||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps1} {8000.0}
|
||||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps10} {10000.0}
|
||||
set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps11} {10000.0}
|
||||
|
|
|
@ -437,60 +437,60 @@ if (CVA6Cfg.XLEN==32 ) begin
|
|||
|
||||
end else begin
|
||||
|
||||
assign master[ariane_soc::Debug].aw_id = master_to_dm[0].aw_id;
|
||||
assign master[ariane_soc::Debug].aw_addr = master_to_dm[0].aw_addr;
|
||||
assign master[ariane_soc::Debug].aw_len = master_to_dm[0].aw_len;
|
||||
assign master[ariane_soc::Debug].aw_size = master_to_dm[0].aw_size;
|
||||
assign master[ariane_soc::Debug].aw_burst = master_to_dm[0].aw_burst;
|
||||
assign master[ariane_soc::Debug].aw_lock = master_to_dm[0].aw_lock;
|
||||
assign master[ariane_soc::Debug].aw_cache = master_to_dm[0].aw_cache;
|
||||
assign master[ariane_soc::Debug].aw_prot = master_to_dm[0].aw_prot;
|
||||
assign master[ariane_soc::Debug].aw_qos = master_to_dm[0].aw_qos;
|
||||
assign master[ariane_soc::Debug].aw_atop = master_to_dm[0].aw_atop;
|
||||
assign master[ariane_soc::Debug].aw_region = master_to_dm[0].aw_region;
|
||||
assign master[ariane_soc::Debug].aw_user = master_to_dm[0].aw_user;
|
||||
assign master[ariane_soc::Debug].aw_valid = master_to_dm[0].aw_valid;
|
||||
assign master_to_dm[0].aw_id = master[ariane_soc::Debug].aw_id;
|
||||
assign master_to_dm[0].aw_addr = master[ariane_soc::Debug].aw_addr;
|
||||
assign master_to_dm[0].aw_len = master[ariane_soc::Debug].aw_len;
|
||||
assign master_to_dm[0].aw_size = master[ariane_soc::Debug].aw_size;
|
||||
assign master_to_dm[0].aw_burst= master[ariane_soc::Debug].aw_burst;
|
||||
assign master_to_dm[0].aw_lock = master[ariane_soc::Debug].aw_lock;
|
||||
assign master_to_dm[0].aw_cache= master[ariane_soc::Debug].aw_cache;
|
||||
assign master_to_dm[0].aw_prot = master[ariane_soc::Debug].aw_prot;
|
||||
assign master_to_dm[0].aw_qos = master[ariane_soc::Debug].aw_qos;
|
||||
assign master_to_dm[0].aw_atop = master[ariane_soc::Debug].aw_atop;
|
||||
assign master_to_dm[0].aw_region = master[ariane_soc::Debug].aw_region;
|
||||
assign master_to_dm[0].aw_user = master[ariane_soc::Debug].aw_user;
|
||||
assign master_to_dm[0].aw_valid= master[ariane_soc::Debug].aw_valid;
|
||||
|
||||
assign master_to_dm[0].aw_ready =master[ariane_soc::Debug].aw_ready;
|
||||
assign master[ariane_soc::Debug].aw_ready = master_to_dm[0].aw_ready;
|
||||
|
||||
assign master[ariane_soc::Debug].w_data = master_to_dm[0].w_data;
|
||||
assign master[ariane_soc::Debug].w_strb = master_to_dm[0].w_strb;
|
||||
assign master[ariane_soc::Debug].w_last = master_to_dm[0].w_last;
|
||||
assign master[ariane_soc::Debug].w_user = master_to_dm[0].w_user;
|
||||
assign master[ariane_soc::Debug].w_valid = master_to_dm[0].w_valid;
|
||||
assign master_to_dm[0].w_data = master[ariane_soc::Debug].w_data;
|
||||
assign master_to_dm[0].w_strb = master[ariane_soc::Debug].w_strb;
|
||||
assign master_to_dm[0].w_last = master[ariane_soc::Debug].w_last;
|
||||
assign master_to_dm[0].w_user = master[ariane_soc::Debug].w_user;
|
||||
assign master_to_dm[0].w_valid= master[ariane_soc::Debug].w_valid;
|
||||
|
||||
assign master_to_dm[0].w_ready =master[ariane_soc::Debug].w_ready;
|
||||
assign master[ariane_soc::Debug].w_ready = master_to_dm[0].w_ready;
|
||||
|
||||
assign master_to_dm[0].b_id =master[ariane_soc::Debug].b_id;
|
||||
assign master_to_dm[0].b_resp =master[ariane_soc::Debug].b_resp;
|
||||
assign master_to_dm[0].b_user =master[ariane_soc::Debug].b_user;
|
||||
assign master_to_dm[0].b_valid =master[ariane_soc::Debug].b_valid;
|
||||
assign master[ariane_soc::Debug].b_id = master_to_dm[0].b_id;
|
||||
assign master[ariane_soc::Debug].b_resp = master_to_dm[0].b_resp;
|
||||
assign master[ariane_soc::Debug].b_user = master_to_dm[0].b_user;
|
||||
assign master[ariane_soc::Debug].b_valid= master_to_dm[0].b_valid;
|
||||
|
||||
assign master[ariane_soc::Debug].b_ready = master_to_dm[0].b_ready;
|
||||
assign master_to_dm[0].b_ready = master[ariane_soc::Debug].b_ready;
|
||||
|
||||
assign master[ariane_soc::Debug].ar_id = master_to_dm[0].ar_id;
|
||||
assign master[ariane_soc::Debug].ar_addr = master_to_dm[0].ar_addr;
|
||||
assign master[ariane_soc::Debug].ar_len = master_to_dm[0].ar_len;
|
||||
assign master[ariane_soc::Debug].ar_size = master_to_dm[0].ar_size;
|
||||
assign master[ariane_soc::Debug].ar_burst = master_to_dm[0].ar_burst;
|
||||
assign master[ariane_soc::Debug].ar_lock = master_to_dm[0].ar_lock;
|
||||
assign master[ariane_soc::Debug].ar_cache = master_to_dm[0].ar_cache;
|
||||
assign master[ariane_soc::Debug].ar_prot = master_to_dm[0].ar_prot;
|
||||
assign master[ariane_soc::Debug].ar_qos = master_to_dm[0].ar_qos;
|
||||
assign master[ariane_soc::Debug].ar_region = master_to_dm[0].ar_region;
|
||||
assign master[ariane_soc::Debug].ar_user = master_to_dm[0].ar_user;
|
||||
assign master[ariane_soc::Debug].ar_valid = master_to_dm[0].ar_valid;
|
||||
assign master_to_dm[0].ar_id = master[ariane_soc::Debug].ar_id;
|
||||
assign master_to_dm[0].ar_addr = master[ariane_soc::Debug].ar_addr;
|
||||
assign master_to_dm[0].ar_len = master[ariane_soc::Debug].ar_len;
|
||||
assign master_to_dm[0].ar_size = master[ariane_soc::Debug].ar_size;
|
||||
assign master_to_dm[0].ar_burst = master[ariane_soc::Debug].ar_burst;
|
||||
assign master_to_dm[0].ar_lock = master[ariane_soc::Debug].ar_lock;
|
||||
assign master_to_dm[0].ar_cache = master[ariane_soc::Debug].ar_cache;
|
||||
assign master_to_dm[0].ar_prot = master[ariane_soc::Debug].ar_prot;
|
||||
assign master_to_dm[0].ar_qos = master[ariane_soc::Debug].ar_qos;
|
||||
assign master_to_dm[0].ar_region = master[ariane_soc::Debug].ar_region;
|
||||
assign master_to_dm[0].ar_user = master[ariane_soc::Debug].ar_user;
|
||||
assign master_to_dm[0].ar_valid = master[ariane_soc::Debug].ar_valid;
|
||||
|
||||
assign master_to_dm[0].ar_ready =master[ariane_soc::Debug].ar_ready;
|
||||
assign master[ariane_soc::Debug].ar_ready = master_to_dm[0].ar_ready;
|
||||
|
||||
assign master_to_dm[0].r_id =master[ariane_soc::Debug].r_id;
|
||||
assign master_to_dm[0].r_data =master[ariane_soc::Debug].r_data;
|
||||
assign master_to_dm[0].r_resp =master[ariane_soc::Debug].r_resp;
|
||||
assign master_to_dm[0].r_last =master[ariane_soc::Debug].r_last;
|
||||
assign master_to_dm[0].r_user =master[ariane_soc::Debug].r_user;
|
||||
assign master_to_dm[0].r_valid =master[ariane_soc::Debug].r_valid;
|
||||
assign master[ariane_soc::Debug].r_id = master_to_dm[0].r_id;
|
||||
assign master[ariane_soc::Debug].r_data = master_to_dm[0].r_data;
|
||||
assign master[ariane_soc::Debug].r_resp = master_to_dm[0].r_resp;
|
||||
assign master[ariane_soc::Debug].r_last = master_to_dm[0].r_last;
|
||||
assign master[ariane_soc::Debug].r_user = master_to_dm[0].r_user;
|
||||
assign master[ariane_soc::Debug].r_valid = master_to_dm[0].r_valid;
|
||||
|
||||
assign master[ariane_soc::Debug].r_ready = master_to_dm[0].r_ready;
|
||||
assign master_to_dm[0].r_ready = master[ariane_soc::Debug].r_ready;
|
||||
|
||||
end
|
||||
|
||||
|
@ -744,19 +744,13 @@ end
|
|||
|
||||
|
||||
logic clk_200MHz_ref;
|
||||
AXI_BUS #(
|
||||
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
|
||||
.AXI_DATA_WIDTH ( AxiDataWidth ),
|
||||
.AXI_ID_WIDTH ( AxiIdWidthSlaves ),
|
||||
.AXI_USER_WIDTH ( AxiUserWidth )
|
||||
) uart_bus();
|
||||
|
||||
cva6_peripherals #(
|
||||
.AxiAddrWidth ( AxiAddrWidth ),
|
||||
.AxiDataWidth ( AxiDataWidth ),
|
||||
.AxiIdWidth ( AxiIdWidthSlaves ),
|
||||
.AxiUserWidth ( AxiUserWidth ),
|
||||
.InclUART ( 1'b0 ),
|
||||
.InclUART ( 1'b1 ),
|
||||
.InclGPIO ( 1'b1 ),
|
||||
.InclSPI ( 1'b0 ),
|
||||
.InclEthernet ( 1'b0 )
|
||||
|
@ -765,8 +759,7 @@ cva6_peripherals #(
|
|||
.clk_200MHz_i ( clk_200MHz_ref ),
|
||||
.rst_ni ( ndmreset_n ),
|
||||
.plic ( master[ariane_soc::PLIC] ),
|
||||
// .uart ( master[ariane_soc::UART] ),
|
||||
.uart ( uart_bus ),
|
||||
.uart ( master[ariane_soc::UART] ),
|
||||
.spi ( master[ariane_soc::SPI] ),
|
||||
.gpio ( master[ariane_soc::GPIO] ),
|
||||
.eth_clk_i ( eth_clk ),
|
||||
|
@ -797,84 +790,6 @@ cva6_peripherals #(
|
|||
|
||||
|
||||
|
||||
// UART Through JTAG//
|
||||
|
||||
logic uart_amm_ready;
|
||||
logic uart_amm_read;
|
||||
logic uart_amm_write;
|
||||
logic uart_amm_read_n;
|
||||
logic uart_amm_write_n;
|
||||
logic uart_amm_chipselect;
|
||||
logic uart_amm_irq;
|
||||
logic [0:0] uart_amm_address;
|
||||
logic [31:0] uart_amm_rdata;
|
||||
logic [31:0] uart_amm_wdata;
|
||||
|
||||
|
||||
assign uart_amm_read_n = ~uart_amm_read;
|
||||
assign uart_amm_write_n = ~uart_amm_write;
|
||||
|
||||
cva6_intel_jtag_uart_0 uart_i (
|
||||
.clk (clk), // input, width = 1, clk.clk
|
||||
.rst_n (ndmreset_n), // input, width = 1, reset.reset_n
|
||||
.av_chipselect (uart_amm_chipselect), // input, width = 1, avalon_jtag_slave.chipselect
|
||||
.av_address (uart_amm_address), // input, width = 1, .address
|
||||
.av_read_n (uart_amm_read_n), // input, width = 1, .read_n
|
||||
.av_readdata (uart_amm_rdata), // output, width = 32, .readdata
|
||||
.av_write_n (uart_amm_write_n), // input, width = 1, .write_n
|
||||
.av_writedata (uart_amm_wdata), // input, width = 32, .writedata
|
||||
.av_waitrequest (uart_amm_ready), // output, width = 1, .waitrequest
|
||||
.av_irq (uart_amm_irq) // output, width = 1, irq.irq
|
||||
);
|
||||
|
||||
//axi4 to avalon converter
|
||||
interconnect_altera_mm_interconnect_1920_v5r556a axi_to_avalon_uart (
|
||||
.axi_bridge_1_m0_awid (master[ariane_soc::UART].aw_id), // input, width = 8, axi_bridge_1_m0.awid
|
||||
.axi_bridge_1_m0_awaddr (master[ariane_soc::UART].aw_addr), // input, width = 64, .awaddr
|
||||
.axi_bridge_1_m0_awlen (master[ariane_soc::UART].aw_len), // input, width = 8, .awlen
|
||||
.axi_bridge_1_m0_awsize (master[ariane_soc::UART].aw_size), // input, width = 3, .awsize
|
||||
.axi_bridge_1_m0_awburst (master[ariane_soc::UART].aw_burst), // input, width = 2, .awburst
|
||||
.axi_bridge_1_m0_awlock (master[ariane_soc::UART].aw_lock), // input, width = 1, .awlock
|
||||
.axi_bridge_1_m0_awcache (master[ariane_soc::UART].aw_cache), // input, width = 4, .awcache
|
||||
.axi_bridge_1_m0_awprot (master[ariane_soc::UART].aw_prot), // input, width = 3, .awprot
|
||||
.axi_bridge_1_m0_awvalid (master[ariane_soc::UART].aw_valid), // input, width = 1, .awvalid
|
||||
.axi_bridge_1_m0_awready (master[ariane_soc::UART].aw_ready), // output, width = 1, .awready
|
||||
.axi_bridge_1_m0_wdata (master[ariane_soc::UART].w_data), // input, width = 64, .wdata
|
||||
.axi_bridge_1_m0_wstrb (master[ariane_soc::UART].w_strb), // input, width = 8, .wstrb
|
||||
.axi_bridge_1_m0_wlast (master[ariane_soc::UART].w_last), // input, width = 1, .wlast
|
||||
.axi_bridge_1_m0_wvalid (master[ariane_soc::UART].w_valid), // input, width = 1, .wvalid
|
||||
.axi_bridge_1_m0_wready (master[ariane_soc::UART].w_ready), // output, width = 1, .wready
|
||||
.axi_bridge_1_m0_bid (master[ariane_soc::UART].b_id), // output, width = 8, .bid
|
||||
.axi_bridge_1_m0_bresp (master[ariane_soc::UART].b_resp), // output, width = 2, .bresp
|
||||
.axi_bridge_1_m0_bvalid (master[ariane_soc::UART].b_valid), // output, width = 1, .bvalid
|
||||
.axi_bridge_1_m0_bready (master[ariane_soc::UART].b_ready), // input, width = 1, .bready
|
||||
.axi_bridge_1_m0_arid (master[ariane_soc::UART].ar_id), // input, width = 8, .arid
|
||||
.axi_bridge_1_m0_araddr (master[ariane_soc::UART].ar_addr), // input, width = 64, .araddr
|
||||
.axi_bridge_1_m0_arlen (master[ariane_soc::UART].ar_len), // input, width = 8, .arlen
|
||||
.axi_bridge_1_m0_arsize (master[ariane_soc::UART].ar_size), // input, width = 3, .arsize
|
||||
.axi_bridge_1_m0_arburst (master[ariane_soc::UART].ar_burst), // input, width = 2, .arburst
|
||||
.axi_bridge_1_m0_arlock (master[ariane_soc::UART].ar_lock), // input, width = 1, .arlock
|
||||
.axi_bridge_1_m0_arcache (master[ariane_soc::UART].ar_cache), // input, width = 4, .arcache
|
||||
.axi_bridge_1_m0_arprot (master[ariane_soc::UART].ar_prot), // input, width = 3, .arprot
|
||||
.axi_bridge_1_m0_arvalid (master[ariane_soc::UART].ar_valid), // input, width = 1, .arvalid
|
||||
.axi_bridge_1_m0_arready (master[ariane_soc::UART].ar_ready), // output, width = 1, .arready
|
||||
.axi_bridge_1_m0_rid (master[ariane_soc::UART].r_id), // output, width = 8, .rid
|
||||
.axi_bridge_1_m0_rdata (master[ariane_soc::UART].r_data), // output, width = 64, .rdata
|
||||
.axi_bridge_1_m0_rresp (master[ariane_soc::UART].r_resp), // output, width = 2, .rresp
|
||||
.axi_bridge_1_m0_rlast (master[ariane_soc::UART].r_last), // output, width = 1, .rlast
|
||||
.axi_bridge_1_m0_rvalid (master[ariane_soc::UART].r_valid), // output, width = 1, .rvalid
|
||||
.axi_bridge_1_m0_rready (master[ariane_soc::UART].r_ready), // input, width = 1, .rready
|
||||
.jtag_uart_0_avalon_jtag_slave_address (uart_amm_address), // output, width = 1, jtag_uart_0_avalon_jtag_slave.address
|
||||
.jtag_uart_0_avalon_jtag_slave_write (uart_amm_write), // output, width = 1, .write
|
||||
.jtag_uart_0_avalon_jtag_slave_read (uart_amm_read), // output, width = 1, .read
|
||||
.jtag_uart_0_avalon_jtag_slave_readdata (uart_amm_rdata), // input, width = 32, .readdata
|
||||
.jtag_uart_0_avalon_jtag_slave_writedata (uart_amm_wdata), // output, width = 32, .writedata
|
||||
.jtag_uart_0_avalon_jtag_slave_waitrequest (uart_amm_ready), // input, width = 1, .waitrequest
|
||||
.jtag_uart_0_avalon_jtag_slave_chipselect (uart_amm_chipselect), // output, width = 1, .chipselect
|
||||
.axi_bridge_1_clk_reset_reset_bridge_in_reset_reset (~ndmreset_n), // input, width = 1, axi_bridge_1_clk_reset_reset_bridge_in_reset.reset
|
||||
.axi_bridge_1_m0_translator_clk_reset_reset_bridge_in_reset_reset (~ndmreset_n), // input, width = 1, axi_bridge_1_m0_translator_clk_reset_reset_bridge_in_reset.reset
|
||||
.emif_fm_0_emif_usr_clk_clk (clk) // input, width = 1, emif_fm_0_emif_usr_clk.clk
|
||||
);
|
||||
|
||||
// ---------------------
|
||||
// Board peripherals
|
||||
|
|
|
@ -192,123 +192,85 @@ module cva6_peripherals #(
|
|||
// ---------------
|
||||
// 2. UART
|
||||
// ---------------
|
||||
logic uart_penable;
|
||||
logic uart_pwrite;
|
||||
logic [31:0] uart_paddr;
|
||||
logic uart_psel;
|
||||
logic [31:0] uart_pwdata;
|
||||
logic [31:0] uart_prdata;
|
||||
logic uart_pready;
|
||||
logic uart_pslverr;
|
||||
|
||||
axi2apb_64_32 #(
|
||||
.AXI4_ADDRESS_WIDTH ( AxiAddrWidth ),
|
||||
.AXI4_RDATA_WIDTH ( AxiDataWidth ),
|
||||
.AXI4_WDATA_WIDTH ( AxiDataWidth ),
|
||||
.AXI4_ID_WIDTH ( AxiIdWidth ),
|
||||
.AXI4_USER_WIDTH ( AxiUserWidth ),
|
||||
.BUFF_DEPTH_SLAVE ( 2 ),
|
||||
.APB_ADDR_WIDTH ( 32 )
|
||||
) i_axi2apb_64_32_uart (
|
||||
.ACLK ( clk_i ),
|
||||
.ARESETn ( rst_ni ),
|
||||
.test_en_i ( 1'b0 ),
|
||||
.AWID_i ( uart.aw_id ),
|
||||
.AWADDR_i ( uart.aw_addr ),
|
||||
.AWLEN_i ( uart.aw_len ),
|
||||
.AWSIZE_i ( uart.aw_size ),
|
||||
.AWBURST_i ( uart.aw_burst ),
|
||||
.AWLOCK_i ( uart.aw_lock ),
|
||||
.AWCACHE_i ( uart.aw_cache ),
|
||||
.AWPROT_i ( uart.aw_prot ),
|
||||
.AWREGION_i( uart.aw_region ),
|
||||
.AWUSER_i ( uart.aw_user ),
|
||||
.AWQOS_i ( uart.aw_qos ),
|
||||
.AWVALID_i ( uart.aw_valid ),
|
||||
.AWREADY_o ( uart.aw_ready ),
|
||||
.WDATA_i ( uart.w_data ),
|
||||
.WSTRB_i ( uart.w_strb ),
|
||||
.WLAST_i ( uart.w_last ),
|
||||
.WUSER_i ( uart.w_user ),
|
||||
.WVALID_i ( uart.w_valid ),
|
||||
.WREADY_o ( uart.w_ready ),
|
||||
.BID_o ( uart.b_id ),
|
||||
.BRESP_o ( uart.b_resp ),
|
||||
.BVALID_o ( uart.b_valid ),
|
||||
.BUSER_o ( uart.b_user ),
|
||||
.BREADY_i ( uart.b_ready ),
|
||||
.ARID_i ( uart.ar_id ),
|
||||
.ARADDR_i ( uart.ar_addr ),
|
||||
.ARLEN_i ( uart.ar_len ),
|
||||
.ARSIZE_i ( uart.ar_size ),
|
||||
.ARBURST_i ( uart.ar_burst ),
|
||||
.ARLOCK_i ( uart.ar_lock ),
|
||||
.ARCACHE_i ( uart.ar_cache ),
|
||||
.ARPROT_i ( uart.ar_prot ),
|
||||
.ARREGION_i( uart.ar_region ),
|
||||
.ARUSER_i ( uart.ar_user ),
|
||||
.ARQOS_i ( uart.ar_qos ),
|
||||
.ARVALID_i ( uart.ar_valid ),
|
||||
.ARREADY_o ( uart.ar_ready ),
|
||||
.RID_o ( uart.r_id ),
|
||||
.RDATA_o ( uart.r_data ),
|
||||
.RRESP_o ( uart.r_resp ),
|
||||
.RLAST_o ( uart.r_last ),
|
||||
.RUSER_o ( uart.r_user ),
|
||||
.RVALID_o ( uart.r_valid ),
|
||||
.RREADY_i ( uart.r_ready ),
|
||||
.PENABLE ( uart_penable ),
|
||||
.PWRITE ( uart_pwrite ),
|
||||
.PADDR ( uart_paddr ),
|
||||
.PSEL ( uart_psel ),
|
||||
.PWDATA ( uart_pwdata ),
|
||||
.PRDATA ( uart_prdata ),
|
||||
.PREADY ( uart_pready ),
|
||||
.PSLVERR ( uart_pslverr )
|
||||
);
|
||||
// UART Through JTAG//
|
||||
|
||||
if (InclUART) begin : gen_uart
|
||||
apb_uart i_apb_uart (
|
||||
.CLK ( clk_i ),
|
||||
.RSTN ( rst_ni ),
|
||||
.PSEL ( uart_psel ),
|
||||
.PENABLE ( uart_penable ),
|
||||
.PWRITE ( uart_pwrite ),
|
||||
.PADDR ( uart_paddr[4:2] ),
|
||||
.PWDATA ( uart_pwdata ),
|
||||
.PRDATA ( uart_prdata ),
|
||||
.PREADY ( uart_pready ),
|
||||
.PSLVERR ( uart_pslverr ),
|
||||
.INT ( irq_sources[0] ),
|
||||
.OUT1N ( ), // keep open
|
||||
.OUT2N ( ), // keep open
|
||||
.RTSN ( ), // no flow control
|
||||
.DTRN ( ), // no flow control
|
||||
.CTSN ( 1'b0 ),
|
||||
.DSRN ( 1'b0 ),
|
||||
.DCDN ( 1'b0 ),
|
||||
.RIN ( 1'b0 ),
|
||||
.SIN ( rx_i ),
|
||||
.SOUT ( tx_o )
|
||||
);
|
||||
end else begin
|
||||
/* pragma translate_off */
|
||||
`ifndef VERILATOR
|
||||
mock_uart i_mock_uart (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.penable_i ( uart_penable ),
|
||||
.pwrite_i ( uart_pwrite ),
|
||||
.paddr_i ( uart_paddr ),
|
||||
.psel_i ( uart_psel ),
|
||||
.pwdata_i ( uart_pwdata ),
|
||||
.prdata_o ( uart_prdata ),
|
||||
.pready_o ( uart_pready ),
|
||||
.pslverr_o ( uart_pslverr )
|
||||
);
|
||||
`endif
|
||||
/* pragma translate_on */
|
||||
end
|
||||
logic uart_amm_ready;
|
||||
logic uart_amm_read;
|
||||
logic uart_amm_write;
|
||||
logic uart_amm_read_n;
|
||||
logic uart_amm_write_n;
|
||||
logic uart_amm_chipselect;
|
||||
logic uart_amm_irq;
|
||||
logic [0:0] uart_amm_address;
|
||||
logic [31:0] uart_amm_rdata;
|
||||
logic [31:0] uart_amm_wdata;
|
||||
|
||||
|
||||
assign uart_amm_read_n = ~uart_amm_read;
|
||||
assign uart_amm_write_n = ~uart_amm_write;
|
||||
|
||||
cva6_intel_jtag_uart_0 uart_i (
|
||||
.clk (clk_i), // input, width = 1, clk.clk
|
||||
.rst_n (rst_ni),
|
||||
.av_chipselect (uart_amm_chipselect), // input, width = 1, avalon_jtag_slave.chipselect
|
||||
.av_address (uart_amm_address), // input, width = 1, .address
|
||||
.av_read_n (uart_amm_read_n), // input, width = 1, .read_n
|
||||
.av_readdata (uart_amm_rdata), // output, width = 32, .readdata
|
||||
.av_write_n (uart_amm_write_n), // input, width = 1, .write_n
|
||||
.av_writedata (uart_amm_wdata), // input, width = 32, .writedata
|
||||
.av_waitrequest (uart_amm_ready), // output, width = 1, .waitrequest
|
||||
.av_irq (irq_sources[0]) // output, width = 1, irq.irq
|
||||
);
|
||||
|
||||
//axi4 to avalon converter
|
||||
interconnect_altera_mm_interconnect_1920_v5r556a axi_to_avalon_uart (
|
||||
.axi_bridge_1_m0_awid (uart.aw_id), // input, width = 8, axi_bridge_1_m0.awid
|
||||
.axi_bridge_1_m0_awaddr (uart.aw_addr), // input, width = 64, .awaddr
|
||||
.axi_bridge_1_m0_awlen (uart.aw_len), // input, width = 8, .awlen
|
||||
.axi_bridge_1_m0_awsize (uart.aw_size), // input, width = 3, .awsize
|
||||
.axi_bridge_1_m0_awburst (uart.aw_burst), // input, width = 2, .awburst
|
||||
.axi_bridge_1_m0_awlock (uart.aw_lock), // input, width = 1, .awlock
|
||||
.axi_bridge_1_m0_awcache (uart.aw_cache), // input, width = 4, .awcache
|
||||
.axi_bridge_1_m0_awprot (uart.aw_prot), // input, width = 3, .awprot
|
||||
.axi_bridge_1_m0_awvalid (uart.aw_valid), // input, width = 1, .awvalid
|
||||
.axi_bridge_1_m0_awready (uart.aw_ready), // output, width = 1, .awready
|
||||
.axi_bridge_1_m0_wdata (uart.w_data), // input, width = 64, .wdata
|
||||
.axi_bridge_1_m0_wstrb (uart.w_strb), // input, width = 8, .wstrb
|
||||
.axi_bridge_1_m0_wlast (uart.w_last), // input, width = 1, .wlast
|
||||
.axi_bridge_1_m0_wvalid (uart.w_valid), // input, width = 1, .wvalid
|
||||
.axi_bridge_1_m0_wready (uart.w_ready), // output, width = 1, .wready
|
||||
.axi_bridge_1_m0_bid (uart.b_id), // output, width = 8, .bid
|
||||
.axi_bridge_1_m0_bresp (uart.b_resp), // output, width = 2, .bresp
|
||||
.axi_bridge_1_m0_bvalid (uart.b_valid), // output, width = 1, .bvalid
|
||||
.axi_bridge_1_m0_bready (uart.b_ready), // input, width = 1, .bready
|
||||
.axi_bridge_1_m0_arid (uart.ar_id), // input, width = 8, .arid
|
||||
.axi_bridge_1_m0_araddr (uart.ar_addr), // input, width = 64, .araddr
|
||||
.axi_bridge_1_m0_arlen (uart.ar_len), // input, width = 8, .arlen
|
||||
.axi_bridge_1_m0_arsize (uart.ar_size), // input, width = 3, .arsize
|
||||
.axi_bridge_1_m0_arburst (uart.ar_burst), // input, width = 2, .arburst
|
||||
.axi_bridge_1_m0_arlock (uart.ar_lock), // input, width = 1, .arlock
|
||||
.axi_bridge_1_m0_arcache (uart.ar_cache), // input, width = 4, .arcache
|
||||
.axi_bridge_1_m0_arprot (uart.ar_prot), // input, width = 3, .arprot
|
||||
.axi_bridge_1_m0_arvalid (uart.ar_valid), // input, width = 1, .arvalid
|
||||
.axi_bridge_1_m0_arready (uart.ar_ready), // output, width = 1, .arready
|
||||
.axi_bridge_1_m0_rid (uart.r_id), // output, width = 8, .rid
|
||||
.axi_bridge_1_m0_rdata (uart.r_data), // output, width = 64, .rdata
|
||||
.axi_bridge_1_m0_rresp (uart.r_resp), // output, width = 2, .rresp
|
||||
.axi_bridge_1_m0_rlast (uart.r_last), // output, width = 1, .rlast
|
||||
.axi_bridge_1_m0_rvalid (uart.r_valid), // output, width = 1, .rvalid
|
||||
.axi_bridge_1_m0_rready (uart.r_ready), // input, width = 1, .rready
|
||||
.jtag_uart_0_avalon_jtag_slave_address (uart_amm_address), // output, width = 1, jtag_uart_0_avalon_jtag_slave.address
|
||||
.jtag_uart_0_avalon_jtag_slave_write (uart_amm_write), // output, width = 1, .write
|
||||
.jtag_uart_0_avalon_jtag_slave_read (uart_amm_read), // output, width = 1, .read
|
||||
.jtag_uart_0_avalon_jtag_slave_readdata (uart_amm_rdata), // input, width = 32, .readdata
|
||||
.jtag_uart_0_avalon_jtag_slave_writedata (uart_amm_wdata), // output, width = 32, .writedata
|
||||
.jtag_uart_0_avalon_jtag_slave_waitrequest (uart_amm_ready), // input, width = 1, .waitrequest
|
||||
.jtag_uart_0_avalon_jtag_slave_chipselect (uart_amm_chipselect), // output, width = 1, .chipselect
|
||||
.axi_bridge_1_clk_reset_reset_bridge_in_reset_reset (~rst_ni), // input, width = 1, axi_bridge_1_clk_reset_reset_bridge_in_reset.reset
|
||||
.axi_bridge_1_m0_translator_clk_reset_reset_bridge_in_reset_reset (~rst_ni), // input, width = 1, axi_bridge_1_m0_translator_clk_reset_reset_bridge_in_reset.reset
|
||||
.emif_fm_0_emif_usr_clk_clk (clk_i) // input, width = 1, emif_fm_0_emif_usr_clk.clk
|
||||
);
|
||||
|
||||
// ---------------
|
||||
// 3. SPI
|
||||
|
|
|
@ -22,7 +22,7 @@ int is_transmit_empty()
|
|||
|
||||
char is_transmit_empty_altera()
|
||||
{
|
||||
return read_reg_u8(UART_THR+6);
|
||||
return ((read_reg_u8(UART_THR+7) << 8 ) + read_reg_u8(UART_THR+6));
|
||||
}
|
||||
|
||||
int is_receive_empty()
|
||||
|
@ -30,7 +30,7 @@ int is_receive_empty()
|
|||
#ifndef PLAT_AGILEX
|
||||
return !(read_reg_u8(UART_LINE_STATUS) & 0x1);
|
||||
#else
|
||||
return !(read_reg_u8(UART_THR+1) & 0x8);
|
||||
return (read_reg_u8(UART_THR) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -108,38 +108,36 @@ module ariane import ariane_pkg::*; #(
|
|||
.noc_resp_i ( noc_resp_i )
|
||||
);
|
||||
|
||||
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),
|
||||
.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 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;
|
||||
if (CVA6Cfg.CvxifEn) begin: gen_cvxif
|
||||
if (CVA6Cfg.CoproType == config_pkg::COPRO_EXAMPLE) begin: gen_COPRO_EXAMPLE
|
||||
cvxif_example_coprocessor #(
|
||||
.NrRgprPorts (CVA6Cfg.NrRgprPorts),
|
||||
.XLEN (CVA6Cfg.XLEN),
|
||||
.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 else begin: gen_COPRO_NONE
|
||||
assign cvxif_resp = '{compressed_ready: 1'b1, issue_ready: 1'b1, register_ready: 1'b1, default: '0};
|
||||
end
|
||||
end else begin: gen_no_cvxif
|
||||
assign cvxif_resp = '0;
|
||||
end
|
||||
|
||||
|
||||
|
||||
endmodule // ariane
|
||||
|
|
BIN
docs/03_cva6_design/_static/bht2lvl.png
Normal file
BIN
docs/03_cva6_design/_static/bht2lvl.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
17
docs/07_cv32a60x/index.rst
Normal file
17
docs/07_cv32a60x/index.rst
Normal file
|
@ -0,0 +1,17 @@
|
|||
CV32A60X documentation
|
||||
======================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
..
|
||||
riscv/unpriv.rst
|
||||
riscv/priv.rst
|
||||
|
||||
Below are links to RISC-V ISA documents tailored for the CV32A60X and to CV32A60X-specific design documentation.
|
||||
Only those CSRs and Instructions that are supported by the CV32A60X are documented here.
|
||||
|
||||
| `Unprivileged RISC-V ISA <https://cva6-cv32a60x.readthedocs.io/en/latest/07_cv32a60x/riscv/unpriv.html>`_
|
||||
| `Privileged RISC-V ISA <https://cva6-cv32a60x.readthedocs.io/en/latest/07_cv32a60x/riscv/priv.html>`_
|
||||
| `Design Documentation for CV32A60X <https://cva6-cv32a60x.readthedocs.io/en/latest/07_cv32a60x/design/design.html>`_
|
||||
|
10
docs/07_cv32a60x/riscv/Makefile
Normal file
10
docs/07_cv32a60x/riscv/Makefile
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright 2025 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: André Sintzoff - Thales DIS
|
||||
|
||||
CONFIG := cv32a60x
|
||||
include ../../riscv-isa/build.mk
|
14
docs/07_cv32a60x/riscv/priv.rst
Normal file
14
docs/07_cv32a60x/riscv/priv.rst
Normal file
|
@ -0,0 +1,14 @@
|
|||
..
|
||||
Copyright (c) 2025 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: André Sintzoff - Thales DIS
|
||||
|
||||
Privileged RISC-V ISA
|
||||
=====================
|
||||
|
||||
.. raw:: html
|
||||
:file: priv-isa-cv32a60x.html
|
14
docs/07_cv32a60x/riscv/unpriv.rst
Normal file
14
docs/07_cv32a60x/riscv/unpriv.rst
Normal file
|
@ -0,0 +1,14 @@
|
|||
..
|
||||
Copyright (c) 2025 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: André Sintzoff - Thales DIS
|
||||
|
||||
Unprivileged RISC-V ISA
|
||||
=======================
|
||||
|
||||
.. raw:: html
|
||||
:file: unpriv-isa-cv32a60x.html
|
|
@ -6,6 +6,8 @@ prepare:
|
|||
|
||||
make -C 06_cv64a6_mmu/riscv priv-html unpriv-html
|
||||
|
||||
make -C 07_cv32a60x/riscv priv-html unpriv-html
|
||||
|
||||
sphinx:
|
||||
sphinx-build . _build
|
||||
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
|
||||
ifeval::["{ohg-config}"=="CV32A60X"]
|
||||
:archi-CVA6:
|
||||
:archi-CV32A60X:
|
||||
// specify that it is a custom architecture
|
||||
:archi-not-default:
|
||||
endif::[]
|
||||
|
||||
ifeval::["{ohg-config}"=="CV32A65X"]
|
||||
:archi-CVA6:
|
||||
:archi-CV32A65X:
|
||||
// specify that it is a custom architecture
|
||||
:archi-not-default:
|
||||
endif::[]
|
||||
|
||||
ifeval::["{ohg-config}"=="CV64A6_MMU"]
|
||||
:archi-CVA6:
|
||||
:archi-CV64A6_MMU:
|
||||
// specify that it is a custom architecture
|
||||
:archi-not-default:
|
||||
endif::[]
|
||||
|
|
|
@ -69,5 +69,6 @@ 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
|
||||
07_cv32a60x/index.rst
|
||||
06_cv64a6_mmu/index.rst
|
||||
05_cva6_apu/index.rst
|
||||
|
|
|
@ -398,7 +398,7 @@ field is not implemented. The Implementation value should reflect the
|
|||
design of the RISC-V processor itself and not any surrounding system.
|
||||
endif::[]
|
||||
|
||||
ifeval::["{ohg-config}" == "CV32A65X"]
|
||||
ifdef::archi-CV32A60X,archi-CV32A65X[]
|
||||
The `mimpid` CSR provides a unique encoding of the version of the
|
||||
processor implementation.
|
||||
|
||||
|
@ -508,7 +508,7 @@ For RV32 only, `mstatush` is a 32-bit read/write register formatted as
|
|||
shown in <<mstatushreg>>. Bits 30:4 of `mstatush` generally contain the same fields found in bits 62:36 of `mstatus` for RV64. Fields SD, SXL, and UXL do not exist in `mstatush`.
|
||||
endif::[]
|
||||
|
||||
ifeval::["{ohg-config}" == "CV32A65X"]
|
||||
ifdef::archi-CV32A60X,archi-CV32A65X[]
|
||||
[{ohg-config}] `mstatush` is a 32-bit read/write register formatted as
|
||||
shown in <<mstatushreg>>.
|
||||
endif::[]
|
||||
|
@ -1249,7 +1249,7 @@ different encoding than XS.
|
|||
====
|
||||
endif::[]
|
||||
|
||||
ifeval::["{ohg-config}" == "CV32A65X"]
|
||||
ifdef::archi-CV32A60X,archi-CV32A65X[]
|
||||
[{ohg-config}] The FS[1:0] and VS[1:0] *WARL* fields and the XS[1:0] read-only field are used
|
||||
to reduce the cost of context save and restore by setting and tracking
|
||||
the current state of the floating-point unit and any other user-mode
|
||||
|
@ -2115,7 +2115,7 @@ ifdef::archi-CVA6[]
|
|||
As the Sscofpmf extension is not implemented, `mip`.LCOFIP and `mie`.LCOFIE are read-only zeros.
|
||||
endif::[]
|
||||
|
||||
ifeval::["{ohg-config}" == "CV32A65X"]
|
||||
ifdef::archi-CV32A60X,archi-CV32A65X[]
|
||||
[{ohg-config}]
|
||||
Multiple simultaneous interrupts destined for M-mode are handled in the
|
||||
following decreasing priority order: MEI, MSI, MTI.
|
||||
|
@ -2218,7 +2218,7 @@ As XLEN=64, `mcycleh`, `minstreth`, and `mhpmcounter__n__h`
|
|||
do not exist.
|
||||
endif::[]
|
||||
|
||||
ifeval::["{ohg-config}" == "CV32A65X"]
|
||||
ifdef::archi-CV32A60X,archi-CV32A65X[]
|
||||
As the Sscofpmf extension is not implemented, the `mhpmevent__n__h` CSRs
|
||||
are not provided.
|
||||
endif::[]
|
||||
|
@ -3509,7 +3509,7 @@ As "{ohg-config}" does not distinguished different reset conditions,
|
|||
The `mcause` returns 0 after reset.
|
||||
endif::[]
|
||||
|
||||
ifeval::["{ohg-config}" == "CV32A65X"]
|
||||
ifdef::archi-CV32A60X,archi-CV32A65X[]
|
||||
[{ohg-config}] Privilege mode is always M.
|
||||
As little-endian memory accesses are supported,
|
||||
the `mstatus`/`mstatush` field MBE is reset to 0.
|
||||
|
@ -4068,6 +4068,13 @@ endif::[]
|
|||
[[pmp]]
|
||||
=== Physical Memory Protection
|
||||
|
||||
ifeval::[{NrPMPEntries} == 0]
|
||||
[{ohg-config}] There is no optional physical memory protection (PMP)
|
||||
unit.
|
||||
endif::[]
|
||||
|
||||
ifeval::[{NrPMPEntries} != 0]
|
||||
|
||||
To support secure processing and contain faults, it is desirable to
|
||||
limit the physical addresses accessible by software running on a hart.
|
||||
An optional physical memory protection (PMP) unit provides per-hart
|
||||
|
@ -4491,3 +4498,5 @@ ifeval::["{ohg-config}" == "CV32A65X"]
|
|||
[{ohg-config}] As page-based virtual memory systems is not implemented, memory accesses
|
||||
check the PMP settings synchronously.
|
||||
endif::[]
|
||||
|
||||
endif::[]
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
== Formal Memory Model Specifications, Version 0.1
|
||||
[[mm-formal]]
|
||||
|
||||
ifeval::["{ohg-config}" == "CV32A65X"]
|
||||
ifdef::archi-CV32A60X,archi-CV32A65X[]
|
||||
{ohg-config}: No RVWMO memory model.
|
||||
endif::[]
|
||||
|
|
|
@ -16,6 +16,39 @@ ifdef::archi-CVA6[]
|
|||
listings for {ohg-config}.
|
||||
endif::[]
|
||||
|
||||
ifeval::[{RVA} == true]
|
||||
:AMO: AMO
|
||||
endif::[]
|
||||
ifeval::[{RVA} == false]
|
||||
:AMO: not used
|
||||
endif::[]
|
||||
ifeval::[{RVF} == true]
|
||||
:LOAD-FP: LOAD-FP
|
||||
:STORE-FP: STORE-FP
|
||||
:MADD: MADD
|
||||
:MSUB: MSUB
|
||||
:NMSUB: NMSUB
|
||||
:NMADD: NMADD
|
||||
:OP-FP: OP-FP
|
||||
endif::[]
|
||||
ifeval::[{RVF} == false]
|
||||
:LOAD-FP: _not-used_
|
||||
:STORE-FP: not used
|
||||
:MADD: not used
|
||||
:MSUB: not used
|
||||
:NMSUB: not used
|
||||
:NMADD: not used
|
||||
:OP-FP: not used
|
||||
endif::[]
|
||||
ifeval::[{RVV} == true]
|
||||
:OP-V: OP-V
|
||||
:OP-VE: OP-VE
|
||||
endif::[]
|
||||
ifeval::[{RVV} == false]
|
||||
:OP-V: not used
|
||||
:OP-VE: not used
|
||||
endif::[]
|
||||
|
||||
// note: ≥ is unicode for >=
|
||||
[[opcodemap]]
|
||||
.RISC-V base opcode map, inst[1:0]=11
|
||||
|
@ -23,10 +56,10 @@ endif::[]
|
|||
|===
|
||||
|inst[4:2] .2+|000 .2+|001 .2+|010 .2+|011 .2+|100 .2+|101 .2+|110 .2+|111 (>32b)
|
||||
|inst[6:5]
|
||||
|00 |LOAD |LOAD-FP |_custom-0_ |MISC-MEM |OP-IMM |AUIPC |OP-IMM-32 |48b
|
||||
|01 |STORE |STORE-FP |_custom-1_ |AMO |OP |LUI |OP-32 |64b
|
||||
|10 |MADD |MSUB |NMSUB |NMADD |OP-FP |OP-V |_custom-2/rv128_|48b
|
||||
|11 |BRANCH |JALR |_reserved_ |JAL |SYSTEM |OP-VE |_custom-3/rv128_|≥80b
|
||||
|00 |LOAD |{LOAD-FP}|_custom-0_ |MISC-MEM |OP-IMM |AUIPC |OP-IMM-32 |48b
|
||||
|01 |STORE |{STORE-FP}|_custom-1_|{AMO} |OP |LUI |OP-32 |64b
|
||||
|10 |{MADD} |{MSUB} |{NMSUB} |{NMADD} |{OP-FP}|{OP-V} |_custom-2/rv128_|48b
|
||||
|11 |BRANCH |JALR |_reserved_ |JAL |SYSTEM |{OP-VE} |_custom-3/rv128_|≥80b
|
||||
|===
|
||||
|
||||
<<opcodemap>> shows a map of the major opcodes for
|
||||
|
|
|
@ -7,6 +7,6 @@ endif::[]
|
|||
|
||||
=== "Zcmop" Compressed May-Be-Operations Extension, Version 1.0
|
||||
|
||||
ifeval::[{RVZimop} == false]
|
||||
ifeval::[{RVZcmop} == false]
|
||||
{ohg-config}: This extension is not supported.
|
||||
endif::[]
|
||||
|
|
|
@ -51,14 +51,24 @@ DEFAULT_PARAMS = {
|
|||
'RVZabha': False,
|
||||
'RVZacas': False,
|
||||
'RVZawrs': False,
|
||||
'RVZcmop': False,
|
||||
'RVZfa': False,
|
||||
'RVZfbf-RZvfbf': False,
|
||||
'RVZfh': False,
|
||||
'RVZfinx': False,
|
||||
'RVZicbo': False,
|
||||
'RVZicfilp': False,
|
||||
'RVZifencei': False,
|
||||
'RVZihintntl': False,
|
||||
'RVZihintpause': False,
|
||||
'RVZimop': False,
|
||||
'RVZk': False,
|
||||
'RVZpm': False,
|
||||
'RVZsmcdeleg': False,
|
||||
'RVZsmcntrpmf': False,
|
||||
'RVZsmcsrind-RVZsscsrind': False,
|
||||
'RVZsmctr': False,
|
||||
'RVZsmdbltrp': False,
|
||||
'RVZsmepmp': False,
|
||||
'RVZsmmpm': False,
|
||||
'RVZsmrnmi': False,
|
||||
|
@ -181,6 +191,7 @@ def main():
|
|||
file.append("../core/cva6.sv")
|
||||
file.append("../core/frontend/frontend.sv")
|
||||
file.append("../core/frontend/bht.sv")
|
||||
file.append("../core/frontend/bht2lvl.sv")
|
||||
file.append("../core/frontend/btb.sv")
|
||||
file.append("../core/frontend/ras.sv")
|
||||
file.append("../core/frontend/instr_queue.sv")
|
||||
|
|
79
perf-model/README.md
Normal file
79
perf-model/README.md
Normal file
|
@ -0,0 +1,79 @@
|
|||
# CVA6 cycle-accurate performance model
|
||||
|
||||
This repository contains a cycle-accurate performance model of CVA6 control-path.
|
||||
|
||||
It was developed to explore microarchitecture changes in CVA6 before implementing them.
|
||||
|
||||
To cite this model, please head to the end of this document.
|
||||
|
||||
|
||||
## Getting started
|
||||
|
||||
### Adapt RVFI trace generation
|
||||
|
||||
The regular expression expects the cycle number to be in the RVFI trace.
|
||||
The value is not used by the model but it is used to compare the model and CVA6.
|
||||
|
||||
To emit cycle number in RVFI trace, modify `corev_apu/tb/rvfi_tracer.sv` in CVA6 repository as below.
|
||||
|
||||
```diff
|
||||
- $fwrite(f, "core 0: 0x%h (0x%h) DASM(%h)\n",
|
||||
- pc64, rvfi_i[i].insn, rvfi_i[i].insn);
|
||||
+ $fwrite(f, "core 0: 0x%h (0x%h) @%d DASM(%h)\n",
|
||||
+ pc64, rvfi_i[i].insn, cycles, rvfi_i[i].insn);
|
||||
```
|
||||
|
||||
|
||||
### Generate an RVFI trace
|
||||
|
||||
To generate an RVFI trace, follow the instructions in the CVA6 repository to run a simulation.
|
||||
The RVFI trace will be in `verif/sim/out_<date>/<simulator>/<test-name>.log`.
|
||||
|
||||
|
||||
### Running the model
|
||||
|
||||
```bash
|
||||
python3 model.py verif/sim/out_<date>/<simulator>/<test-name>.log
|
||||
```
|
||||
|
||||
|
||||
### Exploring design space
|
||||
|
||||
In `model.py`, the `main` function runs the model with arguments which override default values.
|
||||
Generic parameters are available in `Model.__init__`.
|
||||
You can add new parameters to explore here.
|
||||
|
||||
To perform exploration, run the model in a loop, like `issue_commit_graph` does.
|
||||
The `display_scores` function is meant to print a 3D plot if you have `matplotlib`.
|
||||
`issue_commit_graph` prints the scores so that you can store it and display the figure without re-running the model.
|
||||
|
||||
|
||||
## Files
|
||||
|
||||
| Name | Description |
|
||||
| :--- | :--- |
|
||||
| `cycle_diff.py` | Calculates duration of each instruction in an RVFI trace |
|
||||
| `isa.py` | Module to create Python objects from RISC-V instructions |
|
||||
| `model.py` | The CVA6 performance model |
|
||||
|
||||
|
||||
## Citing
|
||||
|
||||
```bibtex
|
||||
@inproceedings{cf24,
|
||||
author = {Allart, C\^{o}me and Coulon, Jean-Roch and Sintzoff, Andr\'{e} and Potin, Olivier and Rigaud, Jean-Baptiste},
|
||||
title = {Using a Performance Model to Implement a Superscalar CVA6},
|
||||
year = {2024},
|
||||
isbn = {9798400704925},
|
||||
publisher = {Association for Computing Machinery},
|
||||
url = {https://doi.org/10.1145/3637543.3652871},
|
||||
doi = {10.1145/3637543.3652871},
|
||||
abstract = {A performance model of CVA6 RISC-V processor is built to evaluate performance-related modifications before implementing them in RTL. Its accuracy is 99.2\% on CoreMark. This model is used to evaluate a superscalar feature for CVA6. During design phase, the model helped detecting and fixing performance bugs. The superscalar feature resulted in a CVA6 performance improvement of 40\% on CoreMark.},
|
||||
booktitle = {Proceedings of the 21st ACM International Conference on Computing Frontiers: Workshops and Special Sessions},
|
||||
pages = {43–46},
|
||||
numpages = {4},
|
||||
keywords = {CVA6, Cycle-Based Model, Multi-Issue, Performance, RISC-V, Superscalar},
|
||||
location = {Ischia, Italy},
|
||||
series = {CF '24 Companion}
|
||||
}
|
||||
```
|
80
perf-model/cycle_diff.py
Normal file
80
perf-model/cycle_diff.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
# 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
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
re_csrr_minstret = re.compile(r"^csrr\s+\w+,\s*minstret$")
|
||||
re_full = re.compile(
|
||||
r"([a-z]+)\s+0:\s*0x00000000([0-9a-f]+)\s*\(([0-9a-fx]+)\)\s*(\S*)@\s*([0-9]+)\s*(.*)"
|
||||
)
|
||||
|
||||
class Trace:
|
||||
def __init__(self, addr, cycle, mnemo, flags):
|
||||
self.addr = addr
|
||||
self.cycle = cycle
|
||||
self.mnemo = mnemo
|
||||
self.flags = flags
|
||||
self.delta = None
|
||||
|
||||
def report(self):
|
||||
"""True if the instruction is a loading instruction"""
|
||||
return f"+{self.delta} {self.flags} 0x{self.addr}: {self.mnemo}"
|
||||
|
||||
def print_data(name, value):
|
||||
"Prints 'name = data' with alignment of the '='"
|
||||
spaces = ' ' * (24 - len(name))
|
||||
print(f"{name}{spaces} = {value}")
|
||||
|
||||
def read_traces(input_file):
|
||||
"Collect stage traces from file"
|
||||
l = []
|
||||
def filter_add(trace):
|
||||
if not hasattr(filter_add, "accepting"):
|
||||
filter_add.accepting = False
|
||||
if re_csrr_minstret.search(trace.mnemo):
|
||||
filter_add.accepting = not filter_add.accepting
|
||||
return
|
||||
if filter_add.accepting:
|
||||
l.append(trace)
|
||||
with open(input_file, "r", encoding="utf8") as f:
|
||||
for line in [l.strip() for l in f]:
|
||||
found = re_full.search(line)
|
||||
if found:
|
||||
addr = found.group(2)
|
||||
flags = found.group(4)
|
||||
cycle = int(found.group(5))
|
||||
mnemo = found.group(6)
|
||||
filter_add(Trace(addr, cycle, mnemo, flags))
|
||||
#l.append(Trace(addr, cycle, mnemo, flags))
|
||||
return l
|
||||
|
||||
def write_traces(outfile, traces):
|
||||
"Write all instructions to output file"
|
||||
print("output file:", outfile)
|
||||
with open(outfile, "w", encoding="utf8") as f:
|
||||
for trace in traces:
|
||||
f.write(trace.report() + "\n")
|
||||
|
||||
def main(input_file: str):
|
||||
"Main function"
|
||||
traces = read_traces(input_file)
|
||||
cycle = traces[0].cycle
|
||||
cycle_number = traces[-1].cycle - cycle + 1
|
||||
for trace in traces:
|
||||
trace.delta = trace.cycle - cycle
|
||||
cycle = trace.cycle
|
||||
print_data("cycle number", cycle_number)
|
||||
print_data("Coremark/MHz", 1000000 / cycle_number)
|
||||
print_data("instruction number", len(traces))
|
||||
print_data("IPC", len(traces) / cycle_number)
|
||||
write_traces("traceout.log", traces)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1])
|
574
perf-model/isa.py
Normal file
574
perf-model/isa.py
Normal file
|
@ -0,0 +1,574 @@
|
|||
# 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
|
||||
|
||||
"""
|
||||
Represents the instruction set
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
class Reg:
|
||||
"""Constants to represent registers"""
|
||||
# ABI names
|
||||
zero = 0
|
||||
ra = 1
|
||||
sp = 2
|
||||
gp = 3
|
||||
tp = 4
|
||||
t0 = 5
|
||||
t1 = 6
|
||||
t2 = 7
|
||||
s0 = 8
|
||||
fp = 8
|
||||
s1 = 9
|
||||
a0 = 10
|
||||
a1 = 11
|
||||
a2 = 12
|
||||
a3 = 13
|
||||
a4 = 14
|
||||
a5 = 15
|
||||
a6 = 16
|
||||
a7 = 17
|
||||
s2 = 18
|
||||
s3 = 19
|
||||
s4 = 20
|
||||
s5 = 21
|
||||
s6 = 22
|
||||
s7 = 23
|
||||
s8 = 24
|
||||
s9 = 25
|
||||
s10 = 26
|
||||
s11 = 27
|
||||
t3 = 28
|
||||
t4 = 29
|
||||
t5 = 30
|
||||
t6 = 31
|
||||
# Register names
|
||||
x0 = 0
|
||||
x1 = 1
|
||||
x2 = 2
|
||||
x3 = 3
|
||||
x4 = 4
|
||||
x5 = 5
|
||||
x6 = 6
|
||||
x7 = 7
|
||||
x8 = 8
|
||||
x9 = 9
|
||||
x10 = 10
|
||||
x11 = 11
|
||||
x12 = 12
|
||||
x13 = 13
|
||||
x14 = 14
|
||||
x15 = 15
|
||||
x16 = 16
|
||||
x17 = 17
|
||||
x18 = 18
|
||||
x19 = 19
|
||||
x20 = 20
|
||||
x21 = 21
|
||||
x22 = 22
|
||||
x23 = 23
|
||||
x24 = 24
|
||||
x25 = 25
|
||||
x26 = 26
|
||||
x27 = 27
|
||||
x28 = 28
|
||||
x29 = 29
|
||||
x30 = 30
|
||||
x31 = 31
|
||||
|
||||
def sign_ext(imm, index, xlen=32):
|
||||
"""
|
||||
Sign extends a value
|
||||
imm: value to sign extend
|
||||
index: index of the sign bit of the value
|
||||
len: target len for sign extended value
|
||||
"""
|
||||
imm_bits = index + 1
|
||||
assert (imm >> imm_bits) == 0
|
||||
neg = imm >> index
|
||||
sext_bits = xlen - imm_bits
|
||||
sext_ones = (1 << sext_bits) - 1
|
||||
sext = neg * sext_ones << imm_bits
|
||||
return sext | imm
|
||||
|
||||
@dataclass
|
||||
class AddrFields:
|
||||
"""Represents the data used to build a memory address"""
|
||||
base_reg: int
|
||||
offset: int
|
||||
|
||||
class Rtype:
|
||||
"""R-type instructions"""
|
||||
def __init__(self, instr):
|
||||
self.funct7 = instr.bin >> 25
|
||||
self.rs2 = (instr.bin >> 20) & 31
|
||||
self.rs1 = (instr.bin >> 15) & 31
|
||||
self.funct3 = (instr.bin >> 12) & 7
|
||||
self.rd = (instr.bin >> 7) & 31
|
||||
self.opcode = instr.bin & 63
|
||||
|
||||
class Itype:
|
||||
"""I-type instructions"""
|
||||
def __init__(self, instr):
|
||||
self.rs1 = (instr.bin >> 15) & 31
|
||||
self.funct3 = (instr.bin >> 12) & 7
|
||||
self.rd = (instr.bin >> 7) & 31
|
||||
self.opcode = instr.bin & 63
|
||||
self.imm = sign_ext(instr.bin >> 20, 11)
|
||||
|
||||
class Stype:
|
||||
"""S-type instructions"""
|
||||
def __init__(self, instr):
|
||||
self.rs2 = (instr.bin >> 20) & 31
|
||||
self.rs1 = (instr.bin >> 15) & 31
|
||||
self.funct3 = (instr.bin >> 12) & 7
|
||||
self.opcode = instr.bin & 63
|
||||
self.imm = sign_ext(
|
||||
((instr.bin >> 25) << 5) \
|
||||
| ((instr.bin >> 7) & 31)
|
||||
, 11)
|
||||
|
||||
class Btype:
|
||||
"""B-type instructions"""
|
||||
def __init__(self, instr):
|
||||
self.rs2 = (instr.bin >> 20) & 31
|
||||
self.rs1 = (instr.bin >> 15) & 31
|
||||
self.funct3 = (instr.bin >> 12) & 7
|
||||
self.opcode = instr.bin & 63
|
||||
self.imm = sign_ext(
|
||||
((instr.bin >> 31) << 12) \
|
||||
| (((instr.bin >> 7) & 1) << 11) \
|
||||
| (((instr.bin >> 25) & 0x3f) << 5) \
|
||||
| (((instr.bin >> 8) & 15) << 1)
|
||||
, 12)
|
||||
|
||||
class Utype:
|
||||
"""U-type instructions"""
|
||||
def __init__(self, instr):
|
||||
self.imm_31_12 = instr.bin >> 12
|
||||
self.imm_4_0 = (instr.bin >> 7) & 31
|
||||
self.rd = (instr.bin >> 7) & 31
|
||||
self.opcode = instr.bin & 63
|
||||
self.imm = self.imm_31_12 << 12
|
||||
|
||||
class Jtype:
|
||||
"""J-type instructions"""
|
||||
def __init__(self, instr):
|
||||
self.rd = (instr.bin >> 7) & 31
|
||||
self.opcode = instr.bin & 63
|
||||
self.imm = sign_ext(
|
||||
((instr.bin >> 31) << 20) \
|
||||
| (((instr.bin >> 12) & 0xff) << 12) \
|
||||
| (((instr.bin >> 20) & 1) << 11) \
|
||||
| (((instr.bin >> 21) & 0x3ff) << 1)
|
||||
, 20)
|
||||
|
||||
class MOItype:
|
||||
"""Memory ordering instructions"""
|
||||
def __init__(self, instr):
|
||||
self.fm = instr.bin >> 28
|
||||
self.PI = (instr.bin >> 27) & 1
|
||||
self.PO = (instr.bin >> 26) & 1
|
||||
self.PR = (instr.bin >> 25) & 1
|
||||
self.PW = (instr.bin >> 24) & 1
|
||||
self.SI = (instr.bin >> 23) & 1
|
||||
self.SO = (instr.bin >> 22) & 1
|
||||
self.SR = (instr.bin >> 21) & 1
|
||||
self.SW = (instr.bin >> 20) & 1
|
||||
self.rs1 = (instr.bin >> 15) & 31
|
||||
self.funct3 = (instr.bin >> 12) & 7
|
||||
self.rd = (instr.bin >> 7) & 31
|
||||
self.opcode = instr.bin & 63
|
||||
|
||||
class CRtype:
|
||||
"""Compressed register"""
|
||||
def __init__(self, instr):
|
||||
self.funct4 = instr.bin >> 12
|
||||
r = (instr.bin >> 7) & 31
|
||||
self.rs2 = (instr.bin >> 2) & 31
|
||||
self.op = instr.bin & 3
|
||||
self.rs1 = r
|
||||
base = instr.base()
|
||||
if base == 'C.J[AL]R/C.MV/C.ADD':
|
||||
if self.funct4 & 1:
|
||||
if self.rs2 == 0:
|
||||
if r == 0:
|
||||
base = 'C.EBREAK'
|
||||
else:
|
||||
base = 'C.JALR'
|
||||
else:
|
||||
base = 'C.ADD'
|
||||
else:
|
||||
if self.rs2 == 0:
|
||||
base = 'C.JR'
|
||||
else:
|
||||
base = 'C.MV'
|
||||
if base in CRtype.regreg:
|
||||
self.rd = r
|
||||
self.name = base
|
||||
|
||||
control = ['C.JR', 'C.JALR']
|
||||
regreg = ['C.MV', 'C.ADD']
|
||||
|
||||
class CItype:
|
||||
"""Compressed immediate"""
|
||||
def __init__(self, instr):
|
||||
self.funct3 = instr.bin >> 13
|
||||
r = (instr.bin >> 7) & 31
|
||||
self.op = instr.bin & 3
|
||||
base = instr.base()
|
||||
if base == 'C.LUI/C.ADDI16SP':
|
||||
if r == Reg.sp:
|
||||
base = 'C.ADDI16SP'
|
||||
else:
|
||||
base = 'C.LUI'
|
||||
if base in CItype.SPload + CItype.constgen:
|
||||
self.rd = r
|
||||
if base in CItype.SPload:
|
||||
self.rs1 = Reg.sp
|
||||
self.offset = CItype.offset[base](instr.bin)
|
||||
# zero-extended offset
|
||||
if base == 'C.LI':
|
||||
self.imm = sign_ext(CItype.imm(instr.bin), 5)
|
||||
if base == 'C.LUI':
|
||||
self.nzimm = sign_ext(CItype.imm(instr.bin) << 12, 17)
|
||||
if base in CItype.regimm:
|
||||
self.rd = r
|
||||
self.rs1 = r
|
||||
if base == 'C.ADDI':
|
||||
self.nzimm = sign_ext(CItype.imm(instr.bin), 5)
|
||||
if base == 'C.ADDIW':
|
||||
self.imm = sign_ext(CItype.imm(instr.bin), 5)
|
||||
if base == 'C.ADDI16SP':
|
||||
self.nzimm = sign_ext(CItype.immsp(instr.bin), 9)
|
||||
if base == 'C.SLLI':
|
||||
self.shamt = CItype.imm(instr.bin)
|
||||
|
||||
SPload = ['C.LWSP', 'C.LDSP', 'C.LQSP', 'C.FLWSP', 'C.FLDSP']
|
||||
constgen = ['C.LI', 'C.LUI']
|
||||
regimm = ['C.ADDI', 'C.ADDIW', 'C.ADDI16SP', 'C.SLLI']
|
||||
|
||||
Woffset = lambda i: (((i >> 12) & 1) << 5) | (((i >> 4) & 7) << 2) \
|
||||
| (((i >> 2) & 3) << 6)
|
||||
Doffset = lambda i: (((i >> 12) & 1) << 5) | (((i >> 5) & 3) << 3) \
|
||||
| (((i >> 2) & 7) << 6)
|
||||
Qoffset = lambda i: (((i >> 12) & 1) << 5) | (((i >> 6) & 1) << 4) \
|
||||
| (((i >> 2) & 15) << 6)
|
||||
imm = lambda i: (((i >> 12) & 1) << 5) | ((i >> 2) & 31)
|
||||
immsp = lambda i: (((i >> 12) & 1) << 9) | (((i >> 6) & 1) << 4) \
|
||||
| (((i >> 5) & 1) << 6) | (((i >> 3) & 3) << 7) \
|
||||
| (((i >> 2) & 1) << 5)
|
||||
|
||||
offset = {
|
||||
'C.LWSP': Woffset,
|
||||
'C.LDSP': Doffset,
|
||||
'C.LQSP': Qoffset,
|
||||
'C.FLWSP': Woffset,
|
||||
'C.FLDSP': Doffset,
|
||||
}
|
||||
|
||||
class CSStype:
|
||||
"""Compressed stack-relative store"""
|
||||
def __init__(self, instr):
|
||||
self.funct3 = instr.bin >> 13
|
||||
self.rs1 = Reg.sp
|
||||
self.rs2 = (instr.bin >> 2) & 31
|
||||
self.op = instr.bin & 3
|
||||
self.offset = CSStype.offset[instr.base()](instr.bin)
|
||||
# zero-extended offset
|
||||
|
||||
Woffset = lambda i: (((i >> 9) & 15) << 2) | (((i >> 7) & 3) << 6)
|
||||
Doffset = lambda i: (((i >> 10) & 7) << 3) | (((i >> 7) & 7) << 6)
|
||||
Qoffset = lambda i: (((i >> 11) & 3) << 4) | (((i >> 7) & 15) << 6)
|
||||
|
||||
offset = {
|
||||
'C.SWSP': Woffset,
|
||||
'C.SDSP': Doffset,
|
||||
'C.SQSP': Qoffset,
|
||||
'C.FSWSP': Woffset,
|
||||
'C.FSDSP': Doffset,
|
||||
}
|
||||
|
||||
class CIWtype:
|
||||
"""Compressed wide immediate"""
|
||||
def __init__(self, instr):
|
||||
i = instr.bin
|
||||
self.funct3 = i >> 13
|
||||
rd_ = (i >> 2) & 7
|
||||
self.rd = rd_ + 8
|
||||
self.op = i & 3
|
||||
self.nzuimm = (((i >> 11) & 3) << 4) | (((i >> 7) & 15) << 6) \
|
||||
| (((i >> 6) & 1) << 2) | (((i >> 5) & 1) << 3)
|
||||
# zero-extended (unsigned) non-zero immediate
|
||||
if instr.base() == 'C.ADDI4SPN':
|
||||
self.rs1 = Reg.sp
|
||||
|
||||
CLS_Woffset = lambda i: (((i >> 10) & 7) << 3) | (((i >> 6) & 1) << 2) \
|
||||
| (((i >> 5) & 1) << 6)
|
||||
CLS_Doffset = lambda i: (((i >> 10) & 7) << 3) | (((i >> 5) & 3) << 6)
|
||||
CLS_Qoffset = lambda i: (((i >> 11) & 3) << 4) | (((i >> 10) & 1) << 8) \
|
||||
| (((i >> 5) & 3) << 6)
|
||||
|
||||
class CLtype:
|
||||
"""Compressed load"""
|
||||
def __init__(self, instr):
|
||||
self.funct3 = instr.bin >> 13
|
||||
rs1_ = (instr.bin >> 7) & 7
|
||||
rd_ = (instr.bin >> 2) & 7
|
||||
self.rs1 = rs1_ + 8
|
||||
self.rd = rd_ + 8
|
||||
self.op = instr.bin & 3
|
||||
self.offset = CLtype.offset[instr.base()](instr.bin)
|
||||
# zero-extended offset
|
||||
|
||||
offset = {
|
||||
'C.LW': CLS_Woffset,
|
||||
'C.LD': CLS_Doffset,
|
||||
'C.LQ': CLS_Qoffset,
|
||||
'C.FLW': CLS_Woffset,
|
||||
'C.FLD': CLS_Doffset,
|
||||
}
|
||||
|
||||
class CStype:
|
||||
"""Compressed store"""
|
||||
def __init__(self, instr):
|
||||
self.funct3 = instr.bin >> 13
|
||||
rs1_ = (instr.bin >> 7) & 7
|
||||
rs2_ = (instr.bin >> 2) & 7
|
||||
self.rs1 = rs1_ + 8
|
||||
self.rs2 = rs2_ + 8
|
||||
self.op = instr.bin & 3
|
||||
self.offset = CStype.offset[instr.base()](instr.bin)
|
||||
# zero-extended offset
|
||||
|
||||
offset = {
|
||||
'C.SW': CLS_Woffset,
|
||||
'C.SD': CLS_Doffset,
|
||||
'C.SQ': CLS_Qoffset,
|
||||
'C.FSW': CLS_Woffset,
|
||||
'C.FSD': CLS_Doffset,
|
||||
}
|
||||
|
||||
class CAtype:
|
||||
"""Compressed arithmetic"""
|
||||
def __init__(self, instr):
|
||||
self.funct6 = instr.bin >> 10
|
||||
r = (instr.bin >> 7) & 7
|
||||
self.rd = r + 8
|
||||
self.rs1 = r + 8
|
||||
self.funct2 = (instr.bin >> 5) & 3
|
||||
self.rs2 = ((instr.bin >> 2) & 7) + 8
|
||||
self.op = instr.bin & 3
|
||||
|
||||
class CBtype:
|
||||
"""Compressed branch"""
|
||||
def __init__(self, instr):
|
||||
i = instr.bin
|
||||
base = instr.base()
|
||||
self.funct3 = i >> 13
|
||||
self.offset = (i >> 10) & 7
|
||||
rs1_ = (i >> 7) & 7
|
||||
self.rs1 = rs1_ + 8
|
||||
self.op = instr.bin & 3
|
||||
if base in CBtype.branch:
|
||||
self.offset = sign_ext(
|
||||
(((i >> 12) & 1) << 8) \
|
||||
| (((i >> 10) & 3) << 3) \
|
||||
| (((i >> 5) & 3) << 6) \
|
||||
| (((i >> 3) & 3) << 1) \
|
||||
| (((i >> 2) & 1) << 5)
|
||||
, 8)
|
||||
if base in CBtype.regimm:
|
||||
if base == 'C.ANDI':
|
||||
self.shamt = sign_ext(CItype.imm(i), 5)
|
||||
else:
|
||||
self.shamt = CItype.imm(i)
|
||||
self.rd = self.rs1
|
||||
|
||||
branch = ['C.BEQZ', 'C.BNEZ']
|
||||
regimm = ['C.SRLI', 'C.SRAI', 'C.ANDI']
|
||||
|
||||
class CJtype:
|
||||
"""Compressed jump"""
|
||||
def __init__(self, instr):
|
||||
self.funct3 = instr.bin >> 13
|
||||
assert instr.base() in ['C.J', 'C.JAL']
|
||||
self.offset = sign_ext(CJtype.offset(instr.bin), 11)
|
||||
self.jump_target = (instr.bin >> 2) & 0x7ff
|
||||
self.op = instr.bin & 3
|
||||
|
||||
offset = lambda i: (((i >> 12) & 1) << 11) | (((i << 11) & 1) << 4) \
|
||||
| (((i >> 9) & 3) << 8) | (((i >> 8) & 1) << 10) \
|
||||
| (((i >> 7) & 1) << 6) | (((i >> 6) & 1) << 7) \
|
||||
| (((i >> 3) & 1) << 1) | (((i >> 2) & 1) << 5)
|
||||
|
||||
class Instr:
|
||||
"""Instructions"""
|
||||
|
||||
table_16_4_RV32 = [
|
||||
['C.ADDI4SPN', 'C.FLD', 'C.LW', 'C.FLW',
|
||||
'Reserved', 'C.FSD', 'C.SW', 'C.FSW'],
|
||||
['C.ADDI', 'C.JAL', 'C.LI', 'C.LUI/C.ADDI16SP',
|
||||
'MISC-ALU', 'C.J', 'C.BEQZ', 'C.BNEZ'],
|
||||
['C.SLLI', 'C.FLDSP', 'C.LWSP', 'C.FLWSP',
|
||||
'C.J[AL]R/C.MV/C.ADD', 'C.FSDSP', 'C.SWSP', 'C.FSWSP'],
|
||||
]
|
||||
|
||||
table_24_1 = [
|
||||
['LOAD', 'LOAD-FP', 'custom-0', 'MISC-MEM', 'OP-IMM', 'AUIPC', 'OP-IMM-32', '48b'],
|
||||
['STORE', 'STORE-FP', 'custom-1', 'AMO', 'OP', 'LUI', 'OP-32', '64b'],
|
||||
['MADD', 'MSUB', 'NMSUB', 'NMADD', 'OP-FP', 'reserved', 'custom-2/rv128', '48b'],
|
||||
['BRANCH', 'JALR', 'reserved', 'JAL', 'SYSTEM', 'reserved', 'custom-3/rv128', '80b'],
|
||||
]
|
||||
type_of_base = {
|
||||
'OP-IMM': Itype,
|
||||
'LUI': Utype,
|
||||
'AUIPC': Utype,
|
||||
'OP': Rtype,
|
||||
'OP-32': Rtype,
|
||||
'JAL': Jtype,
|
||||
'JALR': Itype,
|
||||
'BRANCH': Btype,
|
||||
'LOAD': Itype,
|
||||
'STORE': Stype,
|
||||
'SYSTEM': Itype,
|
||||
'C.LWSP': CItype,
|
||||
'C.LDSP': CItype,
|
||||
'C.LQSP': CItype,
|
||||
'C.FLWSP': CItype,
|
||||
'C.FLDSP': CItype,
|
||||
'C.SWSP': CSStype,
|
||||
'C.SDSP': CSStype,
|
||||
'C.SQSP': CSStype,
|
||||
'C.FSWSP': CSStype,
|
||||
'C.FSDSP': CSStype,
|
||||
'C.LW': CLtype,
|
||||
'C.LD': CLtype,
|
||||
'C.LQ': CLtype,
|
||||
'C.FLW': CLtype,
|
||||
'C.FLD': CLtype,
|
||||
'C.SW': CStype,
|
||||
'C.SD': CStype,
|
||||
'C.SQ': CStype,
|
||||
'C.FSW': CStype,
|
||||
'C.FSD': CStype,
|
||||
'C.J': CJtype,
|
||||
'C.JAL': CJtype,
|
||||
'C.J[AL]R/C.MV/C.ADD': CRtype,
|
||||
'C.BEQZ': CBtype,
|
||||
'C.BNEZ': CBtype,
|
||||
'C.LI': CItype,
|
||||
'C.LUI/C.ADDI16SP': CItype,
|
||||
'C.ADDI': CItype,
|
||||
'C.ADDIW': CItype,
|
||||
'C.ADDI4SPN': CIWtype,
|
||||
'C.SLLI': CItype,
|
||||
'MISC-ALU': CAtype,
|
||||
}
|
||||
iloads = ['C.LW', 'C.LWSP', 'LOAD']
|
||||
floads = ['C.FLD', 'C.FLW', 'C.FLDSP', 'C.FLWSP', 'LOAD-FP']
|
||||
istores = ['C.SW', 'C.SWSP', 'STORE']
|
||||
fstores = ['C.FSD', 'C.FSW', 'C.FSDSP', 'C.FSWSP', 'STORE-FP']
|
||||
loads = iloads + floads
|
||||
stores = istores + fstores
|
||||
|
||||
def __init__(self, bincode):
|
||||
self.bin = bincode
|
||||
self.inst_1_0 = self.bin & 3
|
||||
|
||||
def base(self):
|
||||
"""Get the name of the base instruction"""
|
||||
result = ""
|
||||
if self.is_compressed():
|
||||
line = self.bin & 3
|
||||
col = (self.bin >> 13) & 7
|
||||
result = Instr.table_16_4_RV32[line][col]
|
||||
else:
|
||||
line = (self.bin >> 5) & 3
|
||||
col = (self.bin >> 2) & 7
|
||||
result = Instr.table_24_1[line][col]
|
||||
return result
|
||||
|
||||
def fields(self):
|
||||
"""Get an object with the fields of the instruction"""
|
||||
return Instr.type_of_base[self.base()](self)
|
||||
|
||||
def is_compressed(self):
|
||||
"""Is the instruction from the C extension?"""
|
||||
return (self.bin & 3) < 3
|
||||
|
||||
def size(self):
|
||||
"""Size of the instruction in bytes"""
|
||||
return 2 if self.is_compressed() else 4
|
||||
|
||||
def is_load(self):
|
||||
"""Is the instruction a load?"""
|
||||
return self.base() in Instr.loads
|
||||
|
||||
def is_store(self):
|
||||
"""Is the instruction a store?"""
|
||||
return self.base() in Instr.stores
|
||||
|
||||
def is_branch(self):
|
||||
"""Is it a taken/not taken branch?"""
|
||||
return self.base() in ['C.BEQZ', 'C.BNEZ', 'BRANCH']
|
||||
|
||||
def is_regjump(self):
|
||||
"""Is it a register jump?"""
|
||||
if self.base() in ['JALR']:
|
||||
return True
|
||||
if self.base() == 'C.J[AL]R/C.MV/C.ADD':
|
||||
return self.fields().name in ['C.JALR', 'C.JR']
|
||||
return False
|
||||
|
||||
def is_jump(self):
|
||||
"""Is it an immediate jump?"""
|
||||
return self.base() in ['JAL', 'C.JAL', 'C.J']
|
||||
|
||||
def is_muldiv(self):
|
||||
"""Is it a muldiv instruction?"""
|
||||
return self.base() in ['OP', 'OP-32'] and self.fields().funct7 == 1
|
||||
|
||||
def offset(self):
|
||||
"""Get offset from instr (sometimes it is just 'imm' in RISCV spec)"""
|
||||
fields = self.fields()
|
||||
return fields.offset if hasattr(fields, 'offset') else fields.imm
|
||||
|
||||
def addr_fields(self):
|
||||
"""Get the register and offset to build an address"""
|
||||
return AddrFields(self.fields().rs1, self.offset())
|
||||
|
||||
def has_WAW_from(self, other):
|
||||
"""b.has_WAW_from(a) if a.rd == b.rd"""
|
||||
a = other.fields()
|
||||
b = self.fields()
|
||||
if not (hasattr(a, 'rd') and hasattr(b, 'rd')):
|
||||
return False
|
||||
return a.rd == b.rd and a.rd != Reg.zero
|
||||
|
||||
def has_RAW_from(self, other):
|
||||
"""b.has_RAW_from(a) if b.rsX == a.rd"""
|
||||
a = other.fields()
|
||||
b = self.fields()
|
||||
if not hasattr(a, 'rd') or a.rd == Reg.zero:
|
||||
return False
|
||||
if hasattr(b, 'rs1') and a.rd == b.rs1:
|
||||
return True
|
||||
return hasattr(b, 'rs2') and a.rd == b.rs2
|
||||
|
||||
def has_WAR_from(self, other):
|
||||
"""b.has_WAR_from(a) if b.rd == a.rsX"""
|
||||
a = other.fields()
|
||||
b = self.fields()
|
||||
if not hasattr(b, 'rd') or b.rd == Reg.zero:
|
||||
return False
|
||||
if hasattr(a, 'rs1') and a.rs1 == b.rd:
|
||||
return True
|
||||
return hasattr(a, 'rs2') and a.rs2 == b.rd
|
666
perf-model/model.py
Normal file
666
perf-model/model.py
Normal file
|
@ -0,0 +1,666 @@
|
|||
# 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
|
||||
|
||||
"""
|
||||
Performance model of the cva6
|
||||
"""
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from collections import defaultdict
|
||||
|
||||
#from matplotlib import pyplot as plt
|
||||
|
||||
from isa import Instr, Reg
|
||||
|
||||
EventKind = Enum('EventKind', [
|
||||
'WAW', 'WAR', 'RAW',
|
||||
'BMISS', 'BHIT',
|
||||
'STRUCT',
|
||||
'issue', 'done', 'commit',
|
||||
])
|
||||
|
||||
def to_signed(value, xlen=32):
|
||||
signed = value
|
||||
if signed >> (xlen - 1):
|
||||
signed -= 1 << xlen
|
||||
return signed
|
||||
|
||||
class Event:
|
||||
"""Represents an event on an instruction"""
|
||||
def __init__(self, kind, cycle):
|
||||
self.kind = kind
|
||||
self.cycle = cycle
|
||||
|
||||
def __repr__(self):
|
||||
return f"@{self.cycle}: {self.kind}"
|
||||
|
||||
class Instruction(Instr):
|
||||
"""Represents a RISC-V instruction with annotations"""
|
||||
|
||||
def __init__(self, line, address, hex_code, mnemo):
|
||||
Instr.__init__(self, int(hex_code, base=16))
|
||||
self.line = line
|
||||
self.address = int(address, base=16)
|
||||
self.hex_code = hex_code
|
||||
self.mnemo = mnemo
|
||||
self.events = []
|
||||
|
||||
def mnemo_name(self):
|
||||
"""The name of the instruction (fisrt word of the mnemo)"""
|
||||
return self.mnemo.split()[0]
|
||||
|
||||
def next_addr(self):
|
||||
"""Address of next instruction"""
|
||||
return self.address + self.size()
|
||||
|
||||
_ret_regs = [Reg.ra, Reg.t0]
|
||||
|
||||
def is_ret(self):
|
||||
"Does CVA6 consider this instruction as a ret?"
|
||||
f = self.fields()
|
||||
# Strange conditions, no imm check, no rd-discard check
|
||||
return self.is_regjump() \
|
||||
and f.rs1 in Instruction._ret_regs \
|
||||
and (self.is_compressed() or f.rs1 != f.rd)
|
||||
|
||||
def is_call(self):
|
||||
"Does CVA6 consider this instruction as a ret?"
|
||||
base = self.base()
|
||||
f = self.fields()
|
||||
return base == 'C.JAL' \
|
||||
or base == 'C.J[AL]R/C.MV/C.ADD' and f.name == 'C.JALR' \
|
||||
or base in ['JAL', 'JALR'] and f.rd in Instruction._ret_regs
|
||||
|
||||
def __repr__(self):
|
||||
return self.mnemo
|
||||
|
||||
@dataclass
|
||||
class Entry:
|
||||
"""A scoreboard entry"""
|
||||
instr: Instruction
|
||||
cycles_since_issue = 0
|
||||
done: bool = False
|
||||
|
||||
def __repr__(self):
|
||||
status = "DONE" if self.done else "WIP "
|
||||
addr = f"0x{self.instr.address:08X}"
|
||||
return f"{status} {addr}:`{self.instr}` for {self.cycles_since_issue}"
|
||||
|
||||
@dataclass
|
||||
class LastIssue:
|
||||
"""To store the last issued instruction"""
|
||||
instr: Instruction
|
||||
issue_cycle: int
|
||||
|
||||
class IqLen:
|
||||
"""Model of the instruction queue with only a size counter"""
|
||||
def __init__(self, fetch_size, debug=False):
|
||||
self.fetch_size = 4
|
||||
while self.fetch_size < fetch_size:
|
||||
self.fetch_size <<= 1
|
||||
self.debug = debug
|
||||
self.len = self.fetch_size
|
||||
self.new_fetch = True
|
||||
|
||||
def fetch(self):
|
||||
"""Fetch bytes"""
|
||||
self.len += self.fetch_size
|
||||
self._debug(f"fetched {self.fetch_size}, got {self.len}")
|
||||
self.new_fetch = True
|
||||
|
||||
def flush(self):
|
||||
"""Flush instruction queue (bmiss or exception)"""
|
||||
self.len = 0
|
||||
self._debug(f"flushed, got {self.len}")
|
||||
self.new_fetch = False
|
||||
|
||||
def jump(self):
|
||||
"""Loose a fetch cycle and truncate (jump, branch hit taken)"""
|
||||
if self.new_fetch:
|
||||
self.len -= self.fetch_size
|
||||
self._debug(f"jumping, removed {self.fetch_size}, got {self.len}")
|
||||
self.new_fetch = False
|
||||
self._truncate()
|
||||
self._debug(f"jumped, got {self.len}")
|
||||
|
||||
def has(self, instr):
|
||||
"""Does the instruction queue have this instruction?"""
|
||||
length = self.len
|
||||
if self._is_crossword(instr):
|
||||
length -= (self.fetch_size - 2)
|
||||
self._debug(f"comparing {length} to {instr.size()} ({instr})")
|
||||
return length >= instr.size()
|
||||
|
||||
def remove(self, instr):
|
||||
"""Remove instruction from queue"""
|
||||
self.len -= instr.size()
|
||||
self._debug(f"removed {instr.size()}, got {self.len}")
|
||||
self._truncate(self._addr_index(instr.next_addr()))
|
||||
if instr.is_jump():
|
||||
self.jump()
|
||||
|
||||
def _addr_index(self, addr):
|
||||
return addr & (self.fetch_size - 1)
|
||||
|
||||
def _is_crossword(self, instr):
|
||||
is_last = self._addr_index(instr.address) == self.fetch_size - 2
|
||||
return is_last and not instr.is_compressed()
|
||||
|
||||
def _truncate(self, index=0):
|
||||
occupancy = self.fetch_size - self._addr_index(self.len)
|
||||
to_remove = index - occupancy
|
||||
if to_remove < 0:
|
||||
to_remove += self.fetch_size
|
||||
self.len -= to_remove
|
||||
self._debug(f"truncated, removed {to_remove}, got {self.len}")
|
||||
|
||||
def _debug(self, message):
|
||||
if self.debug:
|
||||
print(f"iq: {message}")
|
||||
|
||||
class Ras:
|
||||
"Return Address Stack"
|
||||
def __init__(self, depth=2, debug=False):
|
||||
self.depth = depth - 1
|
||||
self.stack = []
|
||||
self.debug = debug
|
||||
self.last_dropped = None
|
||||
|
||||
def push(self, addr):
|
||||
"Push an address on the stack, forget oldest entry if full"
|
||||
self.stack.append(addr)
|
||||
self._debug(f"pushed 0x{addr:08X}")
|
||||
if len(self.stack) > self.depth:
|
||||
self.stack.pop(0)
|
||||
self._debug("overflown")
|
||||
|
||||
def drop(self):
|
||||
"Drop an address from the stack"
|
||||
self._debug("dropping")
|
||||
if len(self.stack) > 0:
|
||||
self.last_dropped = self.stack.pop()
|
||||
else:
|
||||
self.last_dropped = None
|
||||
self._debug("was already empty")
|
||||
|
||||
def read(self):
|
||||
"Read the top of the stack without modifying it"
|
||||
self._debug("reading")
|
||||
if self.last_dropped is not None:
|
||||
addr = self.last_dropped
|
||||
self._debug(f"read 0x{addr:08X}")
|
||||
return addr
|
||||
self._debug("was empty")
|
||||
return None
|
||||
|
||||
def resolve(self, instr):
|
||||
"Push or pop depending on the instruction"
|
||||
self._debug(f"issuing {instr}")
|
||||
if instr.is_ret():
|
||||
self._debug("detected ret")
|
||||
self.drop()
|
||||
if instr.is_call():
|
||||
self._debug("detected call")
|
||||
self.push(instr.next_addr())
|
||||
|
||||
def _debug(self, message):
|
||||
if self.debug:
|
||||
print(f"RAS: {message}")
|
||||
|
||||
class Bht:
|
||||
"Branch History Table"
|
||||
|
||||
@dataclass
|
||||
class Entry:
|
||||
"A BTB entry"
|
||||
valid: bool = False
|
||||
sat_counter: int = 0
|
||||
|
||||
def __init__(self, entries=128):
|
||||
self.contents = [Bht.Entry() for _ in range(entries)]
|
||||
|
||||
def predict(self, addr):
|
||||
"Is the branch taken? None if don't know"
|
||||
entry = self.contents[self._index(addr)]
|
||||
if entry.valid:
|
||||
return entry.sat_counter >= 2
|
||||
return None
|
||||
|
||||
def resolve(self, addr, taken):
|
||||
"Update branch prediction"
|
||||
index = self._index(addr)
|
||||
entry = self.contents[index]
|
||||
entry.valid = True
|
||||
if taken:
|
||||
if entry.sat_counter < 3:
|
||||
entry.sat_counter += 1
|
||||
else:
|
||||
if entry.sat_counter > 0:
|
||||
entry.sat_counter -= 1
|
||||
|
||||
def _index(self, addr):
|
||||
return (addr >> 1) % len(self.contents)
|
||||
|
||||
Fu = Enum('Fu', ['ALU', 'MUL', 'BRANCH', 'LDU', 'STU'])
|
||||
|
||||
# We have
|
||||
# - FLU gathering ALU + BRANCH (+ CSR, not significant in CoreMark)
|
||||
# - LSU for loads and stores
|
||||
# - FP gathering MUL + second ALU (+ Floating, unused in CoreMark)
|
||||
# This way we do not have more write-back ports than currently with F
|
||||
|
||||
def to_fu(instr):
|
||||
if instr.is_branch() or instr.is_regjump():
|
||||
return Fu.BRANCH
|
||||
if instr.is_muldiv():
|
||||
return Fu.MUL
|
||||
if instr.is_load():
|
||||
return Fu.LDU
|
||||
if instr.is_store():
|
||||
return Fu.STU
|
||||
return Fu.ALU
|
||||
|
||||
class FusBusy:
|
||||
"Is each functional unit busy"
|
||||
def __init__(self, has_alu2 = False):
|
||||
self.has_alu2 = has_alu2
|
||||
|
||||
self.alu = False
|
||||
self.mul = False
|
||||
self.branch = False
|
||||
self.ldu = False
|
||||
self.stu = False
|
||||
self.alu2 = False
|
||||
|
||||
self.issued_mul = False
|
||||
|
||||
def _alu2_ready(self):
|
||||
return self.has_alu2 and not self.alu2
|
||||
|
||||
def is_ready(self, fu):
|
||||
return {
|
||||
Fu.ALU: self._alu2_ready() or not self.alu,
|
||||
Fu.MUL: not self.mul,
|
||||
Fu.BRANCH: not self.branch,
|
||||
Fu.LDU: not self.ldu,
|
||||
Fu.STU: not self.stu,
|
||||
}[fu]
|
||||
|
||||
def is_ready_for(self, instr):
|
||||
return self.is_ready(to_fu(instr))
|
||||
|
||||
def issue(self, instr):
|
||||
return {
|
||||
Fu.ALU: FusBusy.issue_alu,
|
||||
Fu.MUL: FusBusy.issue_mul,
|
||||
Fu.BRANCH: FusBusy.issue_branch,
|
||||
Fu.LDU: FusBusy.issue_ldu,
|
||||
Fu.STU: FusBusy.issue_stu,
|
||||
}[to_fu(instr)](self)
|
||||
|
||||
def issue_mul(self):
|
||||
self.mul = True
|
||||
self.issued_mul = True
|
||||
|
||||
def issue_alu(self):
|
||||
if not self._alu2_ready():
|
||||
assert not self.alu
|
||||
self.alu = True
|
||||
self.branch = True
|
||||
else:
|
||||
self.alu2 = True
|
||||
|
||||
def issue_branch(self):
|
||||
self.alu = True
|
||||
self.branch = True
|
||||
# Stores are not allowed yet
|
||||
self.stu = True
|
||||
|
||||
def issue_ldu(self):
|
||||
self.ldu = True
|
||||
self.stu = True
|
||||
|
||||
def issue_stu(self):
|
||||
self.stu = True
|
||||
self.ldu = True
|
||||
|
||||
def cycle(self):
|
||||
self.alu = self.issued_mul
|
||||
self.mul = False
|
||||
self.branch = self.issued_mul
|
||||
self.ldu = False
|
||||
self.stu = False
|
||||
self.alu2 = False
|
||||
self.issued_mul = False
|
||||
|
||||
class Model:
|
||||
"""Models the scheduling of CVA6"""
|
||||
|
||||
re_instr = re.compile(
|
||||
r"([a-z]+)\s+0:\s*0x00000000([0-9a-f]+)\s*\(([0-9a-fx]+)\)\s*@\s*([0-9]+)\s*(.*)"
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
debug=False,
|
||||
issue=1,
|
||||
commit=2,
|
||||
sb_len=8,
|
||||
fetch_size=None,
|
||||
has_forwarding=True,
|
||||
has_renaming=True):
|
||||
self.ras = Ras(debug=debug)
|
||||
self.bht = Bht()
|
||||
self.instr_queue = []
|
||||
self.scoreboard = []
|
||||
self.fus = FusBusy(issue > 1)
|
||||
self.last_issued = None
|
||||
self.last_committed = None
|
||||
self.retired = []
|
||||
self.sb_len = sb_len
|
||||
self.debug = debug
|
||||
self.iqlen = IqLen(fetch_size or 4 * issue, debug)
|
||||
self.issue_width = issue
|
||||
self.commit_width = commit
|
||||
self.has_forwarding = has_forwarding
|
||||
self.has_renaming = has_renaming
|
||||
self.log = []
|
||||
|
||||
def log_event_on(self, instr, kind, cycle):
|
||||
"""Log an event on the instruction"""
|
||||
if self.debug:
|
||||
print(f"{instr}: {kind}")
|
||||
event = Event(kind, cycle)
|
||||
instr.events.append(event)
|
||||
self.log.append((event, instr))
|
||||
|
||||
def predict_branch(self, instr):
|
||||
"""Predict if branch is taken or not"""
|
||||
pred = self.bht.predict(instr.address)
|
||||
if pred is not None:
|
||||
return pred
|
||||
return instr.offset() >> 31 != 0
|
||||
|
||||
def predict_regjump(self, instr):
|
||||
"""Predict destination address of indirect jump"""
|
||||
if instr.is_ret():
|
||||
return self.ras.read() or 0
|
||||
return 0 # always miss, as there is no btb yet
|
||||
|
||||
def predict_pc(self, last):
|
||||
"""Predict next program counter depending on last issued instruction"""
|
||||
if last.is_branch():
|
||||
taken = self.predict_branch(last)
|
||||
offset = to_signed(last.offset()) if taken else last.size()
|
||||
return last.address + offset
|
||||
if last.is_regjump():
|
||||
return self.predict_regjump(last)
|
||||
return None
|
||||
|
||||
def issue_manage_last_branch(self, instr, cycle):
|
||||
"""Flush IQ if branch miss, jump if branch hit"""
|
||||
if self.last_issued is not None:
|
||||
last = self.last_issued.instr
|
||||
pred = self.predict_pc(last)
|
||||
if pred is not None:
|
||||
bmiss = pred != instr.address
|
||||
resolved = cycle >= self.last_issued.issue_cycle + 6
|
||||
if bmiss and not resolved:
|
||||
self.iqlen.flush()
|
||||
branch = EventKind.BMISS if bmiss else EventKind.BHIT
|
||||
if branch not in [e.kind for e in instr.events]:
|
||||
self.log_event_on(instr, branch, cycle)
|
||||
taken = instr.address != last.next_addr()
|
||||
if taken and not bmiss:
|
||||
# last (not instr) was like a jump
|
||||
self.iqlen.jump()
|
||||
|
||||
def commit_manage_last_branch(self, instr, cycle):
|
||||
"Resolve branch prediction"
|
||||
if self.last_committed is not None:
|
||||
last = self.last_committed
|
||||
if last.is_branch():
|
||||
taken = instr.address != last.next_addr()
|
||||
self.bht.resolve(last.address, taken)
|
||||
self.last_committed = instr
|
||||
|
||||
def find_data_hazards(self, instr, cycle):
|
||||
"""Detect and log data hazards"""
|
||||
found = False
|
||||
for entry in self.scoreboard:
|
||||
if instr.has_WAW_from(entry.instr) and not self.has_renaming:
|
||||
self.log_event_on(instr, EventKind.WAW, cycle)
|
||||
found = True
|
||||
can_forward = self.has_forwarding and entry.done
|
||||
if instr.has_RAW_from(entry.instr) and not can_forward:
|
||||
self.log_event_on(instr, EventKind.RAW, cycle)
|
||||
found = True
|
||||
return found
|
||||
|
||||
def find_structural_hazard(self, instr, cycle):
|
||||
"""Detect and log structural hazards"""
|
||||
if not self.fus.is_ready_for(instr):
|
||||
self.log_event_on(instr, EventKind.STRUCT, cycle)
|
||||
return True
|
||||
return False
|
||||
|
||||
def try_issue(self, cycle):
|
||||
"""Try to issue an instruction"""
|
||||
if len(self.instr_queue) == 0 or len(self.scoreboard) >= self.sb_len:
|
||||
return
|
||||
can_issue = True
|
||||
instr = self.instr_queue[0]
|
||||
if self.find_data_hazards(instr, cycle):
|
||||
can_issue = False
|
||||
if self.find_structural_hazard(instr, cycle):
|
||||
can_issue = False
|
||||
self.issue_manage_last_branch(instr, cycle)
|
||||
if not self.iqlen.has(instr):
|
||||
can_issue = False
|
||||
if can_issue:
|
||||
self.iqlen.remove(instr)
|
||||
instr = self.instr_queue.pop(0)
|
||||
self.log_event_on(instr, EventKind.issue, cycle)
|
||||
entry = Entry(instr)
|
||||
self.scoreboard.append(entry)
|
||||
self.fus.issue(instr)
|
||||
self.last_issued = LastIssue(instr, cycle)
|
||||
self.ras.resolve(instr)
|
||||
|
||||
def try_execute(self, cycle):
|
||||
"""Try to execute instructions"""
|
||||
for entry in self.scoreboard:
|
||||
entry.cycles_since_issue += 1
|
||||
instr = entry.instr
|
||||
duration = 1
|
||||
if instr.is_load() or instr.is_store():
|
||||
duration = 2
|
||||
if instr.is_muldiv():
|
||||
duration = 2
|
||||
if entry.cycles_since_issue == duration:
|
||||
self.log_event_on(instr, EventKind.done, cycle)
|
||||
entry.done = True
|
||||
|
||||
def try_commit(self, cycle, commit_port):
|
||||
"""Try to commit an instruction"""
|
||||
if len(self.scoreboard) == 0:
|
||||
return
|
||||
entry = self.scoreboard[0]
|
||||
can_commit = True
|
||||
if commit_port > 0:
|
||||
if entry.instr.is_store():
|
||||
can_commit = False
|
||||
if not entry.done:
|
||||
can_commit = False
|
||||
if can_commit:
|
||||
instr = self.scoreboard.pop(0).instr
|
||||
self.log_event_on(instr, EventKind.commit, cycle)
|
||||
self.retired.append(instr)
|
||||
self.commit_manage_last_branch(instr, cycle)
|
||||
|
||||
def run_cycle(self, cycle):
|
||||
"""Runs a cycle"""
|
||||
self.fus.cycle()
|
||||
for commit_port in range(self.commit_width):
|
||||
self.try_commit(cycle, commit_port)
|
||||
self.try_execute(cycle)
|
||||
for _ in range(self.issue_width):
|
||||
self.try_issue(cycle)
|
||||
self.iqlen.fetch()
|
||||
|
||||
def load_file(self, path):
|
||||
"""Fill a model from a trace file"""
|
||||
with open(path, "r", encoding="utf8") as file:
|
||||
for line in [l.strip() for l in file]:
|
||||
found = Model.re_instr.search(line)
|
||||
if found:
|
||||
address = found.group(2)
|
||||
hex_code = found.group(3)
|
||||
mnemo = found.group(5)
|
||||
instr = Instruction(line, address, hex_code, mnemo)
|
||||
self.instr_queue.append(instr)
|
||||
|
||||
def run(self, cycles=None):
|
||||
"""Run until completion"""
|
||||
cycle = 0
|
||||
while len(self.instr_queue) > 0 or len(self.scoreboard) > 0:
|
||||
self.run_cycle(cycle)
|
||||
if self.debug:
|
||||
print(f"Scoreboard @{cycle}")
|
||||
for entry in self.scoreboard:
|
||||
print(f" {entry}")
|
||||
print(f"iqlen = {self.iqlen.len}")
|
||||
print()
|
||||
cycle += 1
|
||||
|
||||
if cycles is not None and cycle > cycles:
|
||||
break
|
||||
return cycle
|
||||
|
||||
def write_trace(output_file, instructions):
|
||||
"""Write cycle-annotated trace"""
|
||||
pattern = re.compile(r"@\s*[0-9]+")
|
||||
|
||||
lines = []
|
||||
for instr in instructions:
|
||||
commit_event = instr.events[-1]
|
||||
assert commit_event.kind == EventKind.commit
|
||||
cycle = commit_event.cycle
|
||||
annotated = re.sub(pattern, f"@ {cycle}", instr.line)
|
||||
#if EventKind.STRUCT in [e.kind for e in instr.events]:
|
||||
# annotated += " #STRUCT"
|
||||
#if EventKind.RAW in [e.kind for e in instr.events]:
|
||||
# annotated += " #RAW"
|
||||
lines.append(f"{annotated}\n")
|
||||
|
||||
with open(output_file, 'w') as f:
|
||||
f.writelines(lines)
|
||||
|
||||
def print_data(name, value, ts=24, sep='='):
|
||||
"Prints 'name = data' with alignment of the '='"
|
||||
|
||||
spaces = ' ' * (ts - len(name))
|
||||
print(f"{name}{spaces} {sep} {value}")
|
||||
|
||||
def display_scores(scores):
|
||||
"""Display a 3D graph of scores against commit/issue-wide"""
|
||||
bars = []
|
||||
for x, l in enumerate(scores):
|
||||
for y, z in enumerate(l):
|
||||
bars.append((x, y, z))
|
||||
|
||||
x, y, z, dx, dy, dz = [], [], [], [], [], []
|
||||
for bx, by, bz in bars:
|
||||
x.append(bx)
|
||||
y.append(by)
|
||||
z.append(0)
|
||||
dx.append(.5)
|
||||
dy.append(.5)
|
||||
dz.append(bz)
|
||||
|
||||
#fig = plt.figure()
|
||||
#ax1 = fig.add_subplot(111, projection='3d')
|
||||
#ax1.bar3d(x, y, z, dx, dy, dz)
|
||||
#ax1.set_xlabel("issue")
|
||||
#ax1.set_ylabel("commit")
|
||||
#ax1.set_zlabel("CoreMark/MHz")
|
||||
#plt.show()
|
||||
|
||||
def issue_commit_graph(input_file, n = 3):
|
||||
"""Plot the issue/commit graph"""
|
||||
|
||||
r = range(n + 1)
|
||||
scores = [[0 for _ in r] for _ in r]
|
||||
|
||||
if input_file is None:
|
||||
scores = [[0, 0, 0, 0, 0, 0], [0, 2.651936045910317, 2.651936045910317, 2.651936045910317, 2.651936045910317, 2.651936045910317], [0, 3.212779150348426, 3.6292766488711137, 3.6292766488711137, 3.6292766488711137, 3.6292766488711137], [0, 3.2550388000624966, 3.900216852056974, 3.914997572701505, 3.914997572701505, 3.914997572701505], [0, 3.2596436557555526, 3.9257869239889134, 3.9420984578510834, 3.9421606193922765, 3.9421606193922765], [0, 3.260695897718491, 3.944757614368385, 3.9623576027736505, 3.9625460150656, 3.9625460150656]] # pylint: disable=line-too-long
|
||||
else:
|
||||
r = range(1, n + 1)
|
||||
for issue in r:
|
||||
for commit in r:
|
||||
print("running", issue, commit)
|
||||
model = Model(issue=issue, commit=commit)
|
||||
model.load_file(input_file)
|
||||
model.run()
|
||||
n_cycles = count_cycles(filter_timed_part(model.retired))
|
||||
score = 1000000 / n_cycles
|
||||
scores[issue][commit] = score
|
||||
print(scores)
|
||||
display_scores(scores)
|
||||
|
||||
def filter_timed_part(all_instructions):
|
||||
"Keep only timed part from a trace"
|
||||
filtered = []
|
||||
re_csrr_minstret = re.compile(r"^csrr\s+\w\w,\s*minstret$")
|
||||
accepting = False
|
||||
for instr in all_instructions:
|
||||
if re_csrr_minstret.search(instr.mnemo):
|
||||
accepting = not accepting
|
||||
continue
|
||||
if accepting:
|
||||
filtered.append(instr)
|
||||
return filtered
|
||||
|
||||
def count_cycles(retired):
|
||||
start = min(e.cycle for e in retired[0].events)
|
||||
end = max(e.cycle for e in retired[-1].events)
|
||||
return end - start
|
||||
|
||||
def print_stats(instructions):
|
||||
ecount = defaultdict(lambda: 0)
|
||||
|
||||
for instr in instructions:
|
||||
for e in instr.events:
|
||||
ecount[e.kind] += 1
|
||||
cycle = e.cycle
|
||||
n_instr = len(instructions)
|
||||
n_cycles = count_cycles(instructions)
|
||||
|
||||
print_data("cycle number", n_cycles)
|
||||
print_data("Coremark/MHz", 1000000 / n_cycles)
|
||||
print_data("instruction number", n_instr)
|
||||
for ek, count in ecount.items():
|
||||
print_data(f"{ek}/instr", f"{100 * count / n_instr:.2f}%")
|
||||
|
||||
def main(input_file: str):
|
||||
"Entry point"
|
||||
|
||||
model = Model(debug=True, issue=2, commit=2)
|
||||
model.load_file(input_file)
|
||||
model.run()
|
||||
|
||||
write_trace('annotated.log', model.retired)
|
||||
print_stats(filter_timed_part(model.retired))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1])
|
|
@ -22,6 +22,7 @@ ariane:
|
|||
src/ex_stage.sv,
|
||||
src/frontend/btb.sv,
|
||||
src/frontend/bht.sv,
|
||||
src/frontend/bht2lvl.sv,
|
||||
src/frontend/ras.sv,
|
||||
src/frontend/instr_scan.sv,
|
||||
src/frontend/frontend.sv,
|
||||
|
|
|
@ -60,11 +60,7 @@ BINUTILS_CONFIGURE_OPTS() {
|
|||
--target=$1
|
||||
--prefix=${INSTALL_DIR}
|
||||
--disable-werror
|
||||
--disable-gdb
|
||||
--disable-nls
|
||||
--disable-sim
|
||||
--disable-libdecnumber
|
||||
--disable-readline
|
||||
)
|
||||
echo "${OPTS[@]}"
|
||||
}
|
||||
|
|
358
verif/docs/VerifPlans/PMP/VP_IP000.yml
Normal file
358
verif/docs/VerifPlans/PMP/VP_IP000.yml
Normal file
|
@ -0,0 +1,358 @@
|
|||
!Feature
|
||||
next_elt_id: 15
|
||||
name: TRISTAN Restrictions
|
||||
id: 0
|
||||
display_order: 0
|
||||
subfeatures: !!omap
|
||||
- 000_general: !Subfeature
|
||||
name: 000_general
|
||||
tag: VP_PMP_F000_S000
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S000_I000
|
||||
description: "\nthe verif plan is written for 32bits architecture only"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 001_number of harts: !Subfeature
|
||||
name: 001_number of harts
|
||||
tag: VP_PMP_F000_S001
|
||||
next_elt_id: 2
|
||||
display_order: 1
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S001_I000
|
||||
description: "\nthere is only 1 hart in cv32a6"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 002_mxlen: !Subfeature
|
||||
name: 002_mxlen
|
||||
tag: VP_PMP_F000_S002
|
||||
next_elt_id: 1
|
||||
display_order: 2
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S002_I000
|
||||
description: "\nMXLEN is always 32bits"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 003_xlen: !Subfeature
|
||||
name: 003_xlen
|
||||
tag: VP_PMP_F000_S003
|
||||
next_elt_id: 1
|
||||
display_order: 3
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S003_I000
|
||||
description: "\nXLEN=MXLEN=32, so the PMP address registers are XLEN bits
|
||||
long, so no zero-extension needed"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 004_granularity: !Subfeature
|
||||
name: 004_granularity
|
||||
tag: VP_PMP_F000_S004
|
||||
next_elt_id: 1
|
||||
display_order: 4
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S004_I000
|
||||
description: "\nPMP granularity is 8 bytes (G=1), but the verif plan is written
|
||||
to take G=0 into account (NA4)"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 005_number of pmp entries: !Subfeature
|
||||
name: 005_number of pmp entries
|
||||
tag: VP_PMP_F000_S005
|
||||
next_elt_id: 1
|
||||
display_order: 5
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S005_I000
|
||||
description: "\nthere are 8 HW implemented PMP entries"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 006_hardwired regions: !Subfeature
|
||||
name: 006_hardwired regions
|
||||
tag: VP_PMP_F000_S006
|
||||
next_elt_id: 1
|
||||
display_order: 6
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S006_I000
|
||||
description: "\nnone of the 8 PMP entries is hardwired privileges"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 007_virtual memory: !Subfeature
|
||||
name: 007_virtual memory
|
||||
tag: VP_PMP_F000_S007
|
||||
next_elt_id: 1
|
||||
display_order: 7
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S007_I000
|
||||
description: "\nno virtual memory is implemented\nas a consequence no page-based
|
||||
virtual memory is implemented"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 008_physical memory regions: !Subfeature
|
||||
name: 008_physical memory regions
|
||||
tag: VP_PMP_F000_S008
|
||||
next_elt_id: 1
|
||||
display_order: 8
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S008_I000
|
||||
description: "\nthe list of all physical memory regions\n - system memory
|
||||
regions\n - I-$\n - D-$\n - I-scratchpad (preload mode)\n - I-scratchpad
|
||||
(functional mode)\n - D-scratchpad\n - ahb_periph"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 009_pmp entry disabling: !Subfeature
|
||||
name: 009_pmp entry disabling
|
||||
tag: VP_PMP_F000_S009
|
||||
next_elt_id: 1
|
||||
display_order: 9
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S009_I000
|
||||
description: "\nwe assume an already written PMP entry (i) can be disabled\n\
|
||||
\ - if L=0, by clearing pmpcfg(i)\n - if L=1, only by hart reset"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 010_access-faults (violations): !Subfeature
|
||||
name: 010_access-faults (violations)
|
||||
tag: VP_PMP_F000_S010
|
||||
next_elt_id: 1
|
||||
display_order: 10
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S010_I000
|
||||
description: "\nThe testbench/testcases architecture ensures that:\n - any
|
||||
time there is an access-fault type, we check it matches the related access-type\n
|
||||
- all violations are trapped at the processor\n\n{Page 56 Volume II: RISC-V
|
||||
Privileged Architectures V20211203}\nPMP violations are always trapped precisely
|
||||
at the processor"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 011_testcases modularity: !Subfeature
|
||||
name: 011_testcases modularity
|
||||
tag: VP_PMP_F000_S011
|
||||
next_elt_id: 1
|
||||
display_order: 11
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S011_I000
|
||||
description: "\nThe verif plan is written assuming there is a way (like SystemVerilog
|
||||
interaction):\n - to factorize the testcases in code blocks (in particular
|
||||
configuration code block and access code block)\n - to randomize the code
|
||||
blocks data and addresses\n - to randomize the sequence of code blocks"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 012_access types: !Subfeature
|
||||
name: 012_access types
|
||||
tag: VP_PMP_F000_S012
|
||||
next_elt_id: 1
|
||||
display_order: 12
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S012_I000
|
||||
description: "at the time of writing,\nthe verif plan makes no distinction
|
||||
between load and load-reserved instructions. they are gathered in the same
|
||||
access type, subtleties unknown\nthe verif plan makes no distinction between
|
||||
store, store-conditional, and AMO instructions. they are gathered in the
|
||||
same access type, subtleties unknown"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 013_multiple accesses instructions: !Subfeature
|
||||
name: 013_multiple accesses instructions
|
||||
tag: VP_PMP_F000_S013
|
||||
next_elt_id: 1
|
||||
display_order: 13
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S013_I000
|
||||
description: "\nwe assume there is no added value to test multiple accesses
|
||||
instructions"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 014_misaligned instructions: !Subfeature
|
||||
name: 014_misaligned instructions
|
||||
tag: VP_PMP_F000_S014
|
||||
next_elt_id: 1
|
||||
display_order: 14
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F000_S014_I000
|
||||
description: "\nwe assume that instructions are mandatorily aligned"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: ''
|
||||
pfc: -1
|
||||
test_type: -1
|
||||
cov_method: -1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
45
verif/docs/VerifPlans/PMP/VP_IP001.yml
Normal file
45
verif/docs/VerifPlans/PMP/VP_IP001.yml
Normal file
|
@ -0,0 +1,45 @@
|
|||
!Feature
|
||||
next_elt_id: 1
|
||||
name: PMP granularity
|
||||
id: 1
|
||||
display_order: 1
|
||||
subfeatures: !!omap
|
||||
- 000_granularity_check: !Subfeature
|
||||
name: 000_granularity_check
|
||||
tag: VP_PMP_F001_S000
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F001_S000_I000
|
||||
description: "{Page 59 Volume II: RISC-V Privileged Architectures V20211203}\n
|
||||
\nSoftware may determine the PMP granularity by writing zero to pmp0cfg,
|
||||
then writing all ones to pmpaddr0, then reading back pmpaddr0.\nIf G is
|
||||
the index of the least-signicant bit set, the PMP granularity is 2G+2 bytes."
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: '59'
|
||||
ref_section: ''
|
||||
ref_viewer: evince
|
||||
verif_goals: determine the PMP granularity 2^(G+2) bytes by writing zero to
|
||||
pmp(0)cfg, then writing all ones to pmpaddr(0), then reading back pmpaddr(0).
|
||||
G is the index G of the least-significant bit set
|
||||
pfc: 11
|
||||
test_type: 2
|
||||
cov_method: 0
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nFTR07-b\nSoftware may determine the PMP granularity
|
||||
by writing zero to pmp0cfg, then writing all ones to pmpaddr0, then reading
|
||||
back pmpaddr0.\n If G is the index of the least-signicant bit set, the
|
||||
PMP granularity is 2G+2 bytes.\n\n\nTST01 (HIGH-PRIO) => FTR07-b\n[determine
|
||||
the PMP granularity 2^(G+2) bytes by writing zero to pmp(0)cfg, then writing
|
||||
all ones to pmpaddr(0), then reading back pmpaddr(0). G is the index G of
|
||||
the least-significant bit set]"
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
159
verif/docs/VerifPlans/PMP/VP_IP002.yml
Normal file
159
verif/docs/VerifPlans/PMP/VP_IP002.yml
Normal file
|
@ -0,0 +1,159 @@
|
|||
!Feature
|
||||
next_elt_id: 4
|
||||
name: CSRs M-mode only
|
||||
id: 2
|
||||
display_order: 2
|
||||
subfeatures: !!omap
|
||||
- 000_configure_1_pmp_entry: !Subfeature
|
||||
name: 000_configure_1_pmp_entry
|
||||
tag: VP_PMP_F002_S001
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F002_S001_I000
|
||||
description: "{Section 3.7.1 Page 57 Volume II: RISC-V Privileged Architectures
|
||||
V20211203}\n\nPMP CSRs are only accessible to M-mode"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure 1 PMP entry (i) (the 1st one),\n - check for each
|
||||
PMP entry (i) reset value (read zero) by reading in M mode\n - check for
|
||||
each PMP entry (i) that pmp(i)cfg and pmpaddr(i) are not writable/readable
|
||||
in S or U modes\n - check for each PMP entry (i) that pmp(i)cfg and pmpaddr(i)
|
||||
are writable/readable in M-mode only\n - check for each PMP entry (i) that
|
||||
pmp(i)cfg and pmpaddr(i) are not writable/readable in S or U modes"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST02(group) => FTR02-d\n [check that all 8 HW implemented
|
||||
PMP entries are writable/readable in M-mode (L=0)]\n [check that no HW
|
||||
implemented PMP entry are writable/readable in S or U modes (L=0)]\n \
|
||||
\ - random values may be used\n - before any configuration (after hart
|
||||
reset), check all pmp(i)cfg and pmpaddr(i) are M-mode read zero\n\nTST02-1
|
||||
(HIGH-PRIO)\n[configure 1 PMP entry ([FTR02-b1]: maybe mandatorily the first
|
||||
one): with L=0,\n - if possible, the PMP entry number is a configurable
|
||||
parameter\n - check for PMP entry (i) where L=0 that pmp(i)cfg and pmpaddr(i)
|
||||
are not writable/readable in S or U modes\n - check for PMP entry (i) where
|
||||
L=0 that pmp(i)cfg and pmpaddr(i) are writable/readable in M-mode only\n\
|
||||
\ - check for PMP entry (i) where L=0 that pmp(i)cfg and pmpaddr(i) are
|
||||
not writable/readable in S or U modes]"
|
||||
- 001_configure_2_pmp_entries: !Subfeature
|
||||
name: 001_configure_2_pmp_entries
|
||||
tag: VP_PMP_F002_S002
|
||||
next_elt_id: 1
|
||||
display_order: 1
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F002_S002_I000
|
||||
description: "{Section 3.7.1 Page 57 Volume II: RISC-V Privileged Architectures
|
||||
V20211203}\n\nPMP CSRs are only accessible to M-mode"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure 2 PMP entries (the 2 first ones in incrementing order),\n\
|
||||
\ - reuse of VP_PMP_F002_S001_I000 sequence"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST02(group) => FTR02-d\n [check that all 8 HW implemented
|
||||
PMP entries are writable/readable in M-mode (L=0)]\n [check that no HW
|
||||
implemented PMP entry are writable/readable in S or U modes (L=0)]\n \
|
||||
\ - random values may be used\n - before any configuration (after hart
|
||||
reset), check all pmp(i)cfg and pmpaddr(i) are M-mode read zero\n\nTST02-2
|
||||
(LOW-PRIO) = 2 times reuse/call of TST02-1\n[configure 2 PMP entries ([FTR02-b1]:
|
||||
maybe mandatorily the 2 first ones): both with L=0,\n - check for PMP entry
|
||||
(i) where L=0 that pmp(i)cfg and pmpaddr(i) are not writable/readable in
|
||||
S or U modes\n - check for PMP entry (i) where L=0 that pmp(i)cfg and pmpaddr(i)
|
||||
are writable/readable in M-mode only\n - check for PMP entry (i) where
|
||||
L=0 that pmp(i)cfg and pmpaddr(i) are not writable/readable in S or U modes]"
|
||||
- 002_configure_N_pmp_entries: !Subfeature
|
||||
name: 002_configure_N_pmp_entries
|
||||
tag: VP_PMP_F002_S003
|
||||
next_elt_id: 1
|
||||
display_order: 2
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F002_S003_I000
|
||||
description: "{Section 3.7.1 Page 57 Volume II: RISC-V Privileged Architectures
|
||||
V20211203}\n\nPMP CSRs are only accessible to M-mode"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure N PMP entries (the N first ones in incrementing order),\n\
|
||||
\ - reuse of VP_PMP_F002_S001_I000 sequence"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST02(group) => FTR02-d\n [check that all 8 HW implemented
|
||||
PMP entries are writable/readable in M-mode (L=0)]\n [check that no HW
|
||||
implemented PMP entry are writable/readable in S or U modes (L=0)]\n \
|
||||
\ - random values may be used\n - before any configuration (after hart
|
||||
reset), check all pmp(i)cfg and pmpaddr(i) are M-mode read zero\n\nTST02-3
|
||||
(LOW-PRIO) = N times reuse/call of TST02-1\n[configure N PMP entries ([FTR02-b1]:
|
||||
maybe mandatorily the N first ones): all with L=0,\n - check for PMP entry
|
||||
(i) where L=0 that pmp(i)cfg and pmpaddr(i) are not writable/readable in
|
||||
S or U modes\n - check for PMP entry (i) where L=0 that pmp(i)cfg and pmpaddr(i)
|
||||
are writable/readable in M-mode only\n - check for PMP entry (i) where
|
||||
L=0 that pmp(i)cfg and pmpaddr(i) are not writable/readable in S or U modes]"
|
||||
- 003_configure_8_pmp_entries: !Subfeature
|
||||
name: 003_configure_8_pmp_entries
|
||||
tag: VP_PMP_F002_S004
|
||||
next_elt_id: 1
|
||||
display_order: 3
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F002_S004_I000
|
||||
description: "{Section 3.7.1 Page 57 Volume II: RISC-V Privileged Architectures
|
||||
V20211203}\n\nPMP CSRs are only accessible to M-mode"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure all 8 PMP entries (in incrementing order),\n - reuse
|
||||
of VP_PMP_F002_S001_I000 sequence"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST02(group) => FTR02-d\n [check that all 8 HW implemented
|
||||
PMP entries are writable/readable in M-mode (L=0)]\n [check that no HW
|
||||
implemented PMP entry are writable/readable in S or U modes (L=0)]\n \
|
||||
\ - random values may be used\n - before any configuration (after hart
|
||||
reset), check all pmp(i)cfg and pmpaddr(i) are M-mode read zero\n\nTST02-4
|
||||
(HIGH-PRIO) = 8 times reuse/call of TST02-1\n[configure 8 PMP entries: all
|
||||
with L=0,\n - check for PMP entry (i) where L=0 that pmp(i)cfg and pmpaddr(i)
|
||||
are not writable/readable in S or U modes\n - check for PMP entry (i) where
|
||||
L=0 that pmp(i)cfg and pmpaddr(i) are writable/readable in M-mode only\n\
|
||||
\ - check for PMP entry (i) where L=0 that pmp(i)cfg and pmpaddr(i) are
|
||||
not writable/readable in S or U modes]"
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
277
verif/docs/VerifPlans/PMP/VP_IP003.yml
Normal file
277
verif/docs/VerifPlans/PMP/VP_IP003.yml
Normal file
|
@ -0,0 +1,277 @@
|
|||
!Feature
|
||||
next_elt_id: 5
|
||||
name: CSRs locked access
|
||||
id: 3
|
||||
display_order: 3
|
||||
subfeatures: !!omap
|
||||
- 000_configure_1_pmp_entry: !Subfeature
|
||||
name: 000_configure_1_pmp_entry
|
||||
tag: VP_PMP_F003_S001
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F003_S001_I000
|
||||
description: "{Page 60 Section \"Locking and Privilege Mode\" Volume II: RISC-V
|
||||
Privileged Architectures V20211203}\n\nThe L bit indicates that the PMP
|
||||
entry is locked, i.e., writes to the configuration register and associated
|
||||
address registers are ignored\nIf PMP entry (i) is locked, writes to pmp(i)cfg
|
||||
and pmpaddr(i) are ignored\nLocked PMP entries remain locked until the hart
|
||||
is reset\n\n\n{Page 60 Section \"Locking and Privilege Mode\" Volume II:
|
||||
RISC-V Privileged Architectures V20211203}\n\nSetting the L bit locks the
|
||||
PMP entry even when the A field is set to OFF\n\nAdditionally, if PMP entry
|
||||
(i) is locked and pmp(i)cfg.A is set to TOR, writes to pmpaddr(i-1) are
|
||||
ignored"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure 1 PMP entry (the 1st one) with L=1,\n - write PMP
|
||||
entry (i) with L=1 in M-mode\n - A is random, should also be tried with
|
||||
A=OFF when L=1 (to cover feature above)\n - check PMP entry (i) written
|
||||
value in M-mode\n - check for PMP entry (i) where L=1 that pmp(i)cfg and
|
||||
pmpaddr(i) are effectively locked (M-mode check only)\n - also check for
|
||||
PMP entry (i) where L=1 and pmp(i)cfg.A=TOR that pmpaddr(i-1) is effectively
|
||||
locked\n - apply hart reset\n - check for PMP entry (i) reset value (read
|
||||
zero) by reading in M mode\n - write PMP entry (i) in M-mode\n - check
|
||||
PMP entry (i) written value in M-mode\n\nREUSABILITY\n - if possible, the
|
||||
PMP entry number (i) is a configurable parameter\n - if possible, (L) value
|
||||
is a configurable parameter\n - so the same sub-functions are reused with
|
||||
varying (i) and (L) parameters"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST03(group) => FTR08-a and FTR08-b\n [check that HW
|
||||
implemented PMP entries are not writable/readable in M-mode (L=1)]\n [check
|
||||
that no HW implemented PMP entry are writable/readable in S or U modes (L=1)]\n\
|
||||
\ - before any configuration, check all pmp(i)cfg and pmpaddr(i) are
|
||||
M-mode read zero\n - configure PMP entry (i) with L=1 (or 0): pmp(i)cfg
|
||||
and pmpaddr(i) maybe random values\n - execute following tests specific
|
||||
checks\n - check only hart reset unlocks all => FTR08-b\n - check
|
||||
reset values: all pmp(i)cfg and pmpaddr(i) are M-mode read zero\n\nTST03-1
|
||||
(HIGH-PRIO)\n[configure 1 PMP entry ([FTR02-b1]: maybe mandatorily the first
|
||||
one): with L=1,\n - if possible, the PMP entry number is a configurable
|
||||
parameter\n - if possible, L value is a configurable parameter\n - check
|
||||
for PMP entry (i) where L=1 that pmp(i)cfg and pmpaddr(i) are effectively
|
||||
locked whatever the SW mode => FTR08-a\n - check for PMP entry (i) where
|
||||
L=1 that pmp(i)cfg and pmpaddr(i) are not writable/readable in S or U modes]"
|
||||
- 001_configure_2_pmp_entries_L1: !Subfeature
|
||||
name: 001_configure_2_pmp_entries_L1
|
||||
tag: VP_PMP_F003_S002
|
||||
next_elt_id: 1
|
||||
display_order: 1
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F003_S002_I000
|
||||
description: "{Page 60 Section \"Locking and Privilege Mode\" Volume II: RISC-V
|
||||
Privileged Architectures V20211203}\n\nThe L bit indicates that the PMP
|
||||
entry is locked, i.e., writes to the configuration register and associated
|
||||
address registers are ignored\nIf PMP entry (i) is locked, writes to pmp(i)cfg
|
||||
and pmpaddr(i) are ignored\nLocked PMP entries remain locked until the hart
|
||||
is reset\n\n\n{Page 60 Section \"Locking and Privilege Mode\" Volume II:
|
||||
RISC-V Privileged Architectures V20211203}\n\nSetting the L bit locks the
|
||||
PMP entry even when the A field is set to OFF\n\nAdditionally, if PMP entry
|
||||
(i) is locked and pmp(i)cfg.A is set to TOR, writes to pmpaddr(i-1) are
|
||||
ignored"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure 2 PMP entries (the 2 first ones in incrementing order)
|
||||
with L=1,\n - reuse of VP_PMP_F003_S001_I000 sequence"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST03(group) => FTR08-a and FTR08-b\n [check that HW
|
||||
implemented PMP entries are not writable/readable in M-mode (L=1)]\n [check
|
||||
that no HW implemented PMP entry are writable/readable in S or U modes (L=1)]\n\
|
||||
\ - before any configuration, check all pmp(i)cfg and pmpaddr(i) are
|
||||
M-mode read zero\n - configure PMP entry (i) with L=1 (or 0): pmp(i)cfg
|
||||
and pmpaddr(i) maybe random values\n - execute following tests specific
|
||||
checks\n - check only hart reset unlocks all => FTR08-b\n - check
|
||||
reset values: all pmp(i)cfg and pmpaddr(i) are M-mode read zero\n\nTST03-2
|
||||
(LOW-PRIO) = 2 times reuse/call of TST02-1\n[configure 2 PMP entries ([FTR02-b1]:
|
||||
maybe mandatorily the 2 first ones): both with L=1,\n - check for PMP entry
|
||||
(i) where L=1 that pmp(i)cfg and pmpaddr(i) are effectively locked whatever
|
||||
the SW mode => FTR08-a\n - check for PMP entry (i) where L=1 that pmp(i)cfg
|
||||
and pmpaddr(i) are not writable/readable in S or U modes]"
|
||||
- 002_configure_2_pmp_entries_L0_L1: !Subfeature
|
||||
name: 002_configure_2_pmp_entries_L0_L1
|
||||
tag: VP_PMP_F003_S003
|
||||
next_elt_id: 1
|
||||
display_order: 2
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F003_S003_I000
|
||||
description: "{Page 60 Section \"Locking and Privilege Mode\" Volume II: RISC-V
|
||||
Privileged Architectures V20211203}\n\nThe L bit indicates that the PMP
|
||||
entry is locked, i.e., writes to the configuration register and associated
|
||||
address registers are ignored\nIf PMP entry (i) is locked, writes to pmp(i)cfg
|
||||
and pmpaddr(i) are ignored\nLocked PMP entries remain locked until the hart
|
||||
is reset\n\n\n{Page 60 Section \"Locking and Privilege Mode\" Volume II:
|
||||
RISC-V Privileged Architectures V20211203}\n\nSetting the L bit locks the
|
||||
PMP entry even when the A field is set to OFF\n\nAdditionally, if PMP entry
|
||||
(i) is locked and pmp(i)cfg.A is set to TOR, writes to pmpaddr(i-1) are
|
||||
ignored"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure 2 PMP entries (the 2 first ones in incrementing order)
|
||||
at least one with L=1 and one with L=0,\n - write PMP entry (i) with L=0/1
|
||||
in M-mode\n - A is random, should also be tried with A=OFF when L=1 (to
|
||||
cover feature above)\n - check PMP entry (i) written value in M-mode\n\
|
||||
\ - check for PMP entry (i) where L=0 that pmp(i)cfg and pmpaddr(i) are
|
||||
writable in M mode (read back the written value in M mode)\n - check for
|
||||
PMP entry (i) where L=1 that pmp(i)cfg and pmpaddr(i) are effectively locked
|
||||
(M-mode check only)\n - also check for PMP entry (i) where L=1 and pmp(i)cfg.A=TOR
|
||||
that pmpaddr(i-1) is effectively locked\n - apply hart reset\n - check
|
||||
for PMP entry (i) reset value (read zero) by reading in M mode\n - write
|
||||
PMP entry (i) in M-mode\n - check PMP entry (i) written value in M-mode\n\
|
||||
\nREUSABILITY\n - if possible, the PMP entry number (i) is a configurable
|
||||
parameter\n - if possible, (L) value is a configurable parameter\n - so
|
||||
the same sub-functions are reused with varying (i) and (L) parameters"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST03(group) => FTR08-a and FTR08-b\n [check that HW
|
||||
implemented PMP entries are not writable/readable in M-mode (L=1)]\n [check
|
||||
that no HW implemented PMP entry are writable/readable in S or U modes (L=1)]\n\
|
||||
\ - before any configuration, check all pmp(i)cfg and pmpaddr(i) are
|
||||
M-mode read zero\n - configure PMP entry (i) with L=1 (or 0): pmp(i)cfg
|
||||
and pmpaddr(i) maybe random values\n - execute following tests specific
|
||||
checks\n - check only hart reset unlocks all => FTR08-b\n - check
|
||||
reset values: all pmp(i)cfg and pmpaddr(i) are M-mode read zero\n\nTST03-3
|
||||
(HIGH-PRIO) = 2 times reuse/call of TST02-1\n[configure 2 PMP entries ([FTR02-b1]:
|
||||
maybe mandatorily the 2 first ones): one with L=1 and one with L=0,\n -
|
||||
check for PMP entry (i) where L=1 that pmp(i)cfg and pmpaddr(i) are effectively
|
||||
locked whatever the SW mode => FTR08-a\n - check for PMP entry (i) where
|
||||
L=1 that pmp(i)cfg and pmpaddr(i) are not writable/readable in S or U modes\n\
|
||||
\ - check locked PMP entry (i) has no effect on unlocked PMP entry (j)\n\
|
||||
\ - check for PMP entry (i) where L=0 that pmp(i)cfg and pmpaddr(i) are
|
||||
writable/readable in M-mode only\n - check for PMP entry (i) where L=0
|
||||
that pmp(i)cfg and pmpaddr(i) are not writable/readable in S or U modes]"
|
||||
- 003_configure_N_pmp_entries: !Subfeature
|
||||
name: 003_configure_N_pmp_entries
|
||||
tag: VP_PMP_F003_S004
|
||||
next_elt_id: 1
|
||||
display_order: 3
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F003_S004_I000
|
||||
description: "{Page 60 Section \"Locking and Privilege Mode\" Volume II: RISC-V
|
||||
Privileged Architectures V20211203}\n\nThe L bit indicates that the PMP
|
||||
entry is locked, i.e., writes to the configuration register and associated
|
||||
address registers are ignored\nIf PMP entry (i) is locked, writes to pmp(i)cfg
|
||||
and pmpaddr(i) are ignored\nLocked PMP entries remain locked until the hart
|
||||
is reset\n\n\n{Page 60 Section \"Locking and Privilege Mode\" Volume II:
|
||||
RISC-V Privileged Architectures V20211203}\n\nSetting the L bit locks the
|
||||
PMP entry even when the A field is set to OFF\n\nAdditionally, if PMP entry
|
||||
(i) is locked and pmp(i)cfg.A is set to TOR, writes to pmpaddr(i-1) are
|
||||
ignored"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure N PMP entries (the N first ones in incrementing order)
|
||||
at least one with L=1 and one with L=0,\n - reuse of VP_PMP_F003_S003_I000
|
||||
sequence"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST03(group) => FTR08-a and FTR08-b\n [check that HW
|
||||
implemented PMP entries are not writable/readable in M-mode (L=1)]\n [check
|
||||
that no HW implemented PMP entry are writable/readable in S or U modes (L=1)]\n\
|
||||
\ - before any configuration, check all pmp(i)cfg and pmpaddr(i) are
|
||||
M-mode read zero\n - configure PMP entry (i) with L=1 (or 0): pmp(i)cfg
|
||||
and pmpaddr(i) maybe random values\n - execute following tests specific
|
||||
checks\n - check only hart reset unlocks all => FTR08-b\n - check
|
||||
reset values: all pmp(i)cfg and pmpaddr(i) are M-mode read zero\n\nTST03-4
|
||||
(LOW-PRIO) = N times reuse/call of TST02-1\n[configure N PMP entries ([FTR02-b1]:
|
||||
maybe mandatorily the N first ones): at least one with L=1 and one with
|
||||
L=0,\n - check for PMP entry (i) where L=1 that pmp(i)cfg and pmpaddr(i)
|
||||
are effectively locked whatever the SW mode => FTR08-a\n - check for PMP
|
||||
entry (i) where L=1 that pmp(i)cfg and pmpaddr(i) are not writable/readable
|
||||
in S or U modes\n - check locked PMP entry (i) has no effect on unlocked
|
||||
PMP entry (j)\n - check for PMP entry (i) where L=0 that pmp(i)cfg and
|
||||
pmpaddr(i) are writable/readable in M-mode only\n - check for PMP entry
|
||||
(i) where L=0 that pmp(i)cfg and pmpaddr(i) are not writable/readable in
|
||||
S or U modes]"
|
||||
- 004_configure_8_pmp_entries: !Subfeature
|
||||
name: 004_configure_8_pmp_entries
|
||||
tag: VP_PMP_F003_S005
|
||||
next_elt_id: 1
|
||||
display_order: 4
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F003_S005_I000
|
||||
description: "{Page 60 Section \"Locking and Privilege Mode\" Volume II: RISC-V
|
||||
Privileged Architectures V20211203}\n\nThe L bit indicates that the PMP
|
||||
entry is locked, i.e., writes to the configuration register and associated
|
||||
address registers are ignored\nIf PMP entry (i) is locked, writes to pmp(i)cfg
|
||||
and pmpaddr(i) are ignored\nLocked PMP entries remain locked until the hart
|
||||
is reset\n\n\n{Page 60 Section \"Locking and Privilege Mode\" Volume II:
|
||||
RISC-V Privileged Architectures V20211203}\n\nSetting the L bit locks the
|
||||
PMP entry even when the A field is set to OFF\n\nAdditionally, if PMP entry
|
||||
(i) is locked and pmp(i)cfg.A is set to TOR, writes to pmpaddr(i-1) are
|
||||
ignored"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure all 8 PMP entries (in incrementing order) at least
|
||||
one with L=1 and one with L=0,\n - reuse of VP_PMP_F003_S003_I000 sequence"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST03(group) => FTR08-a and FTR08-b\n [check that HW
|
||||
implemented PMP entries are not writable/readable in M-mode (L=1)]\n [check
|
||||
that no HW implemented PMP entry are writable/readable in S or U modes (L=1)]\n\
|
||||
\ - before any configuration, check all pmp(i)cfg and pmpaddr(i) are
|
||||
M-mode read zero\n - configure PMP entry (i) with L=1 (or 0): pmp(i)cfg
|
||||
and pmpaddr(i) maybe random values\n - execute following tests specific
|
||||
checks\n - check only hart reset unlocks all => FTR08-b\n - check
|
||||
reset values: all pmp(i)cfg and pmpaddr(i) are M-mode read zero\n\nTST03-5
|
||||
(HIGH-PRIO) = 8 times reuse/call of TST02-1\n[configure 8 PMP entries: at
|
||||
least one with L=1 and one with L=0,\n - check for PMP entry (i) where
|
||||
L=1 that pmp(i)cfg and pmpaddr(i) are effectively locked whatever the SW
|
||||
mode => FTR08-a\n - check for PMP entry (i) where L=1 that pmp(i)cfg and
|
||||
pmpaddr(i) are not writable/readable in S or U modes\n - check locked PMP
|
||||
entry (i) has no effect on unlocked PMP entry (j)\n - check for PMP entry
|
||||
(i) where L=0 that pmp(i)cfg and pmpaddr(i) are writable/readable in M-mode
|
||||
only\n - check for PMP entry (i) where L=0 that pmp(i)cfg and pmpaddr(i)
|
||||
are not writable/readable in S or U modes]"
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
146
verif/docs/VerifPlans/PMP/VP_IP004.yml
Normal file
146
verif/docs/VerifPlans/PMP/VP_IP004.yml
Normal file
|
@ -0,0 +1,146 @@
|
|||
!Feature
|
||||
next_elt_id: 4
|
||||
name: CSRs programming order
|
||||
id: 4
|
||||
display_order: 4
|
||||
subfeatures: !!omap
|
||||
- 000_configure_1_pmp_entry: !Subfeature
|
||||
name: 000_configure_1_pmp_entry
|
||||
tag: VP_PMP_F004_S001
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F004_S001_I000
|
||||
description: "{Section 3.7.1 Page 57 Volume II: RISC-V Privileged Architectures
|
||||
V20211203}\n\nthe lowest-numbered PMP CSRs must be implemented first (QUESTION:
|
||||
does it mean programmed first)\nAll PMP CSR fields are WARL and may be read-only
|
||||
zero (QUESTION: does read-only zero mean not implemented?)"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure any PMP entry (i), but the first one\n - reuse of
|
||||
VP_PMP_F003_S003_I000 sequence (Feature: \"CSRs locked access\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST04 => FTR02-b1 and FTR02-b2\n [check if the lowest-numbered
|
||||
PMP CSRs must be programmed first before programming higher-numbered ones]\n
|
||||
\nTST04-1 (LOW-PRIO) extends TST02-1\n[configure any PMP entry, but the
|
||||
first one\n - check for configured PMP entry (i), pmp(i)cfg and pmpaddr(i)
|
||||
are writable/readable in M-mode only\n - check for not configured PMP entry
|
||||
(i), pmp(i)cfg and pmpaddr(i) are M-mode read zero]"
|
||||
- 001_configure_2_pmp_entries: !Subfeature
|
||||
name: 001_configure_2_pmp_entries
|
||||
tag: VP_PMP_F004_S002
|
||||
next_elt_id: 1
|
||||
display_order: 1
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F004_S002_I000
|
||||
description: "{Section 3.7.1 Page 57 Volume II: RISC-V Privileged Architectures
|
||||
V20211203}\n\nthe lowest-numbered PMP CSRs must be implemented first (QUESTION:
|
||||
does it mean programmed first)\nAll PMP CSR fields are WARL and may be read-only
|
||||
zero (QUESTION: does read-only zero mean not implemented?)"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure 2 non-adjacent PMP entries (highest-numbered ones
|
||||
first) (avoid the first PMP entry)\n - reuse of VP_PMP_F003_S003_I000 sequence
|
||||
(Feature: \"CSRs locked access\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST04 => FTR02-b1 and FTR02-b2\n [check if the lowest-numbered
|
||||
PMP CSRs must be programmed first before programming higher-numbered ones]\n
|
||||
\nTST04-2 (HIGH-PRIO) extends TST02-2\n[configure 2 non-adjacent PMP entries
|
||||
(highest-numbered ones first) (avoid the first PMP entry)\n - check for
|
||||
configured PMP entry (i), pmp(i)cfg and pmpaddr(i) are writable/readable
|
||||
in M-mode only\n - check for not configured PMP entry (i), pmp(i)cfg and
|
||||
pmpaddr(i) are M-mode read zero]"
|
||||
- 002_configure_N_pmp_entries: !Subfeature
|
||||
name: 002_configure_N_pmp_entries
|
||||
tag: VP_PMP_F004_S003
|
||||
next_elt_id: 1
|
||||
display_order: 2
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F004_S003_I000
|
||||
description: "{Section 3.7.1 Page 57 Volume II: RISC-V Privileged Architectures
|
||||
V20211203}\n\nthe lowest-numbered PMP CSRs must be implemented first (QUESTION:
|
||||
does it mean programmed first)\nAll PMP CSR fields are WARL and may be read-only
|
||||
zero (QUESTION: does read-only zero mean not implemented?)"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure N PMP entries (highest-numbered ones first) (as non-adjacent
|
||||
as possible, and avoid the first PMP entry)\n - reuse of VP_PMP_F003_S003_I000
|
||||
sequence (Feature: \"CSRs locked access\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST04 => FTR02-b1 and FTR02-b2\n [check if the lowest-numbered
|
||||
PMP CSRs must be programmed first before programming higher-numbered ones]\n
|
||||
\nTST04-3 (LOW-PRIO) extends TST02-3\n[configure N PMP entries (highest-numbered
|
||||
ones first) (as non-adjacent as possible, and avoid the first PMP entry)\n\
|
||||
\ - check for configured PMP entry (i), pmp(i)cfg and pmpaddr(i) are writable/readable
|
||||
in M-mode only\n - check for not configured PMP entry (i), pmp(i)cfg and
|
||||
pmpaddr(i) are M-mode read zero]"
|
||||
- 003_configure_8_pmp_entries: !Subfeature
|
||||
name: 003_configure_8_pmp_entries
|
||||
tag: VP_PMP_F004_S004
|
||||
next_elt_id: 1
|
||||
display_order: 3
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F004_S004_I000
|
||||
description: "{Section 3.7.1 Page 57 Volume II: RISC-V Privileged Architectures
|
||||
V20211203}\n\nthe lowest-numbered PMP CSRs must be implemented first (QUESTION:
|
||||
does it mean programmed first)\nAll PMP CSR fields are WARL and may be read-only
|
||||
zero (QUESTION: does read-only zero mean not implemented?)"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure all 8 PMP entries (highest-numbered ones first)\n\
|
||||
\ - reuse of VP_PMP_F003_S003_I000 sequence (Feature: \"CSRs locked access\"\
|
||||
)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST04 => FTR02-b1 and FTR02-b2\n [check if the lowest-numbered
|
||||
PMP CSRs must be programmed first before programming higher-numbered ones]\n
|
||||
\nTST04-4 (HIGH-PRIO) extends TST02-4\n[configure 8 PMP entries (highest-numbered
|
||||
ones first)\n - check for configured PMP entry (i), pmp(i)cfg and pmpaddr(i)
|
||||
are writable/readable in M-mode only]"
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
90
verif/docs/VerifPlans/PMP/VP_IP005.yml
Normal file
90
verif/docs/VerifPlans/PMP/VP_IP005.yml
Normal file
|
@ -0,0 +1,90 @@
|
|||
!Feature
|
||||
next_elt_id: 2
|
||||
name: CSRs Hardwired regions
|
||||
id: 5
|
||||
display_order: 5
|
||||
subfeatures: !!omap
|
||||
- 000_access with L=0: !Subfeature
|
||||
name: 000_access with L=0
|
||||
tag: VP_PMP_F005_S001
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F005_S001_I000
|
||||
description: "{Page 56 Volume II: RISC-V Privileged Architectures V20211203}\n
|
||||
Certain regions’ privileges can be hardwired: so only ever be visible in
|
||||
machine mode but in no lower-privilege layers.\n\n{Section 3.7.1 Page 57
|
||||
Volume II: RISC-V Privileged Architectures V20211203}\nImplementations may
|
||||
implement zero, 16, or 64 PMP CSRs\n\n{https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/PMP.html}\n
|
||||
A maximum of 16 PMP entries are supported.\nAll PMP CSRs are always implemented,
|
||||
but CSRs (or bitfields of CSRs) related to PMP entries with number CVA6Cfg.NrPMPEntries
|
||||
and above are hardwired to zero.\n\nTRISTAN\n8 PMP entries are implemented"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure the first 8 PMP entries with L=0\n - for each PMP
|
||||
entry (i), check several times that pmp(i)cfg and pmpaddr(i) can be written
|
||||
and can be read back exactly the same (in M-mode)\n\nfor the last 8 PMP
|
||||
entries, check that pmp(i)cfg and pmpaddr(i) always read zero after being
|
||||
written (in M-mode with L=0)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST05 => FTR01-c and FTR01-c-extended\n [check all
|
||||
regions are configurable in M-mode to make sure none is hardwired]\n [regions
|
||||
hardwired privileges might only ever be visible in M-mode]\n\nTST05-1 (HIGH-PRIO)
|
||||
extends TST02-4\n - check the written pmp(i)cfg and pmpaddr(i) values can
|
||||
be read exactly the same as written"
|
||||
- 001_access with L=1: !Subfeature
|
||||
name: 001_access with L=1
|
||||
tag: VP_PMP_F005_S002
|
||||
next_elt_id: 1
|
||||
display_order: 1
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F005_S002_I000
|
||||
description: "{Page 56 Volume II: RISC-V Privileged Architectures V20211203}\n
|
||||
Certain regions’ privileges can be hardwired: so only ever be visible in
|
||||
machine mode but in no lower-privilege layers.\n\n{Section 3.7.1 Page 57
|
||||
Volume II: RISC-V Privileged Architectures V20211203}\nImplementations may
|
||||
implement zero, 16, or 64 PMP CSRs\n\n{https://docs.openhwgroup.org/projects/cva6-user-manual/01_cva6_user/PMP.html}\n
|
||||
A maximum of 16 PMP entries are supported.\nAll PMP CSRs are always implemented,
|
||||
but CSRs (or bitfields of CSRs) related to PMP entries with number CVA6Cfg.NrPMPEntries
|
||||
and above are hardwired to zero.\n\nTRISTAN\n8 PMP entries are implemented"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "configure the first 8 PMP entries with L=1\n - for each PMP
|
||||
entry (i), check once that pmp(i)cfg and pmpaddr(i) can be written and can
|
||||
be read back exactly the same (in M-mode)\n - apply hart reset\n - for
|
||||
each PMP entry (i), check once that pmp(i)cfg and pmpaddr(i) can be written
|
||||
and can be read back exactly the same (in M-mode)\n\nfor the last 8 PMP
|
||||
entries, check that pmp(i)cfg and pmpaddr(i) always read zero after being
|
||||
written (in M-mode with L=1)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST05 => FTR01-c and FTR01-c-extended\n [check all
|
||||
regions are configurable in M-mode to make sure none is hardwired]\n [regions
|
||||
hardwired privileges might only ever be visible in M-mode]\n\nTST05-2 (LOW-PRIO)
|
||||
extends TST03-5\n - check the written pmp(i)cfg and pmpaddr(i) values can
|
||||
be read exactly the same as written (before hart reset)"
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
82
verif/docs/VerifPlans/PMP/VP_IP006.yml
Normal file
82
verif/docs/VerifPlans/PMP/VP_IP006.yml
Normal file
|
@ -0,0 +1,82 @@
|
|||
!Feature
|
||||
next_elt_id: 2
|
||||
name: CSRs reserved values
|
||||
id: 6
|
||||
display_order: 6
|
||||
subfeatures: !!omap
|
||||
- 000_access with L=0: !Subfeature
|
||||
name: 000_access with L=0
|
||||
tag: VP_PMP_F006_S001
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F006_S001_I000
|
||||
description: "{Page 58 Volume II: RISC-V Privileged Architectures V20211203}\n
|
||||
\nThe R, W, and X fields form a collective WARL field for which the combinations
|
||||
with R=0 and W=1 are reserved."
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "repeat following sequence several times on some PMP entries\n\
|
||||
\ - write totally random values to pmp(i)cfg and pmpaddr(i), but with L=0\n\
|
||||
\ - check all pmp(i)cfg and pmpaddr(i) can be read back exactly the same
|
||||
as written except:\n - except with the reserved combinations [R=0 and
|
||||
W=1]\n - except with A=NA4 which must not be selectable as G>0"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST06 => FTR04-a\n[PMP CSR fields are WARL: PMP entry
|
||||
combinations with R=0 and W=1 are reserved/can’t be read]\n[permissions
|
||||
fields could be randomly written; should we try randomization ?]\n\nTST06-1
|
||||
(HIGH-PRIO) extends TST02-4\n - write totally random values to pmp(i)cfg
|
||||
and pmpaddr(i)\n - check all pmp(i)cfg and pmpaddr(i) can be read exactly
|
||||
the same as written except for the reserved combinations with R=0 and W=1"
|
||||
- 001_access with L=1: !Subfeature
|
||||
name: 001_access with L=1
|
||||
tag: VP_PMP_F006_S002
|
||||
next_elt_id: 1
|
||||
display_order: 1
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F006_S002_I000
|
||||
description: "{Page 58 Volume II: RISC-V Privileged Architectures V20211203}\n
|
||||
\nThe R, W, and X fields form a collective WARL field for which the combinations
|
||||
with R=0 and W=1 are reserved."
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "repeat following sequence several times on some PMP entries\n\
|
||||
\ - write totally random values to pmp(i)cfg and pmpaddr(i), but with L=1\n\
|
||||
\ - check all pmp(i)cfg and pmpaddr(i) can be read back exactly the same
|
||||
as written:\n - except with the reserved combinations [R=0 and W=1]\n\
|
||||
\ - except with A=NA4 which must not be selectable as G>0\n - apply
|
||||
hart reset"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST06 => FTR04-a\n[PMP CSR fields are WARL: PMP entry
|
||||
combinations with R=0 and W=1 are reserved/can’t be read]\n[permissions
|
||||
fields could be randomly written; should we try randomization ?]\n\nTST06-2
|
||||
(LOW-PRIO) extends TST03-5\n - write totally random values to pmp(i)cfg
|
||||
and pmpaddr(i)\n - check all pmp(i)cfg and pmpaddr(i) can be read exactly
|
||||
the same as written except for the reserved combinations with R=0 and W=1
|
||||
(before hart reset)"
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
128
verif/docs/VerifPlans/PMP/VP_IP010.yml
Normal file
128
verif/docs/VerifPlans/PMP/VP_IP010.yml
Normal file
|
@ -0,0 +1,128 @@
|
|||
!Feature
|
||||
next_elt_id: 4
|
||||
name: no cfg matching/defined
|
||||
id: 10
|
||||
display_order: 10
|
||||
subfeatures: !!omap
|
||||
- 000_no matching entry - M mode access: !Subfeature
|
||||
name: 000_no matching entry - M mode access
|
||||
tag: VP_PMP_F010_S001
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F010_S001_I000
|
||||
description: "{Page 60 Section \"Priority and Matching Logic\" Volume II:
|
||||
RISC-V Privileged Architectures V20211203}\n\nIf no PMP entry matches an
|
||||
M-mode access, the access succeeds"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: check M-mode access succeeds if no PMP entry matches
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nFTR09-e\n[If no PMP entry matches an M-mode access,
|
||||
the access succeeds]\n \nTST10-1 (HIGH-PRIO) => FTR09-e\n[check M-mode access
|
||||
succeeds if no PMP entry matches]"
|
||||
- 001_no defined entry - M mode access: !Subfeature
|
||||
name: 001_no defined entry - M mode access
|
||||
tag: VP_PMP_F010_S002
|
||||
next_elt_id: 1
|
||||
display_order: 1
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F010_S002_I000
|
||||
description: "{Page 60 Section \"Priority and Matching Logic\" Volume II:
|
||||
RISC-V Privileged Architectures V20211203}\n\nIf no PMP entry matches an
|
||||
M-mode access, the access succeeds\nQUESTION: what happens if no PMP entry
|
||||
is implemented ?\nASSUMPTION: access succeeds"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: check M-mode access succeeds if no PMP entry defined
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nFTR09-e-question\n[what happens if no PMP entry is implemented
|
||||
?]\n \nTST10-2 (HIGH-PRIO) => FTR09-e-question\n[check M-mode access succeeds
|
||||
if no PMP entry defined]"
|
||||
- 002_no matching entry - S/U mode access: !Subfeature
|
||||
name: 002_no matching entry - S/U mode access
|
||||
tag: VP_PMP_F010_S003
|
||||
next_elt_id: 1
|
||||
display_order: 2
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F010_S003_I000
|
||||
description: "{Page 60 Section \"Priority and Matching Logic\" Volume II:
|
||||
RISC-V Privileged Architectures V20211203}\n\nIf no PMP entry matches an
|
||||
S-mode or U-mode access, but at least one PMP entry is implemented, the
|
||||
access fails"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: check S or U mode access fails when no PMP entry matching and
|
||||
at least one PMP entry implemented
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nFTR09-f\n[If no PMP entry matches an S-mode or U-mode
|
||||
access, but at least one PMP entry is implemented, the access fails]\n\n
|
||||
TST10-3 (HIGH-PRIO) => FTR09-f\n[check S or U mode access fails when no
|
||||
PMP entry matching and at least one PMP entry implemented]"
|
||||
- 003_no defined entry - S/U mode access: !Subfeature
|
||||
name: 003_no defined entry - S/U mode access
|
||||
tag: VP_PMP_F010_S004
|
||||
next_elt_id: 1
|
||||
display_order: 3
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F010_S004_I000
|
||||
description: "{Page 60 Section \"Priority and Matching Logic\" Volume II:
|
||||
RISC-V Privileged Architectures V20211203}\n\nIf no PMP entry matches an
|
||||
S-mode or U-mode access, but at least one PMP entry is implemented, the
|
||||
access fails\nQUESTION: what happens if no PMP entry is implemented ?\n
|
||||
ASSUMPTION: access fails"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: check S or U mode access fails when no PMP entry implemented
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nFTR09-f-question\n[what happens if no PMP entry is implemented
|
||||
?]\n \nTST10-4 (HIGH-PRIO) => FTR09-f-question\n[check S or U mode access
|
||||
fails when no PMP entry implemented]"
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
2069
verif/docs/VerifPlans/PMP/VP_IP011.yml
Normal file
2069
verif/docs/VerifPlans/PMP/VP_IP011.yml
Normal file
File diff suppressed because it is too large
Load diff
2052
verif/docs/VerifPlans/PMP/VP_IP012.yml
Normal file
2052
verif/docs/VerifPlans/PMP/VP_IP012.yml
Normal file
File diff suppressed because it is too large
Load diff
1133
verif/docs/VerifPlans/PMP/VP_IP013.yml
Normal file
1133
verif/docs/VerifPlans/PMP/VP_IP013.yml
Normal file
File diff suppressed because it is too large
Load diff
1119
verif/docs/VerifPlans/PMP/VP_IP014.yml
Normal file
1119
verif/docs/VerifPlans/PMP/VP_IP014.yml
Normal file
File diff suppressed because it is too large
Load diff
1502
verif/docs/VerifPlans/PMP/VP_IP015.yml
Normal file
1502
verif/docs/VerifPlans/PMP/VP_IP015.yml
Normal file
File diff suppressed because it is too large
Load diff
1482
verif/docs/VerifPlans/PMP/VP_IP016.yml
Normal file
1482
verif/docs/VerifPlans/PMP/VP_IP016.yml
Normal file
File diff suppressed because it is too large
Load diff
1153
verif/docs/VerifPlans/PMP/VP_IP017.yml
Normal file
1153
verif/docs/VerifPlans/PMP/VP_IP017.yml
Normal file
File diff suppressed because it is too large
Load diff
1129
verif/docs/VerifPlans/PMP/VP_IP018.yml
Normal file
1129
verif/docs/VerifPlans/PMP/VP_IP018.yml
Normal file
File diff suppressed because it is too large
Load diff
525
verif/docs/VerifPlans/PMP/VP_IP019.yml
Normal file
525
verif/docs/VerifPlans/PMP/VP_IP019.yml
Normal file
|
@ -0,0 +1,525 @@
|
|||
!Feature
|
||||
next_elt_id: 20
|
||||
name: cfg NA4 not selectable
|
||||
id: 19
|
||||
display_order: 19
|
||||
subfeatures: !!omap
|
||||
- 000_fetch_L0_X1_addr_hit: !Subfeature
|
||||
name: 000_fetch_L0_X1_addr_hit
|
||||
tag: VP_PMP_F019_S011
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S011_I000
|
||||
description: 'reuse of VP_PMP_F019_S011_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access S/U")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S011_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access S/U\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check instruction fetch access-fault
|
||||
exception raised"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 001_fetch_L1_X1_addr_hit: !Subfeature
|
||||
name: 001_fetch_L1_X1_addr_hit
|
||||
tag: VP_PMP_F019_S014
|
||||
next_elt_id: 1
|
||||
display_order: 1
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S014_I000
|
||||
description: 'reuse of VP_PMP_F019_S014_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access S/U")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S014_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access S/U\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check instruction fetch access-fault
|
||||
exception raised"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 002_load_L0_R1_addr_hit: !Subfeature
|
||||
name: 002_load_L0_R1_addr_hit
|
||||
tag: VP_PMP_F019_S021
|
||||
next_elt_id: 1
|
||||
display_order: 2
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S021_I000
|
||||
description: 'reuse of VP_PMP_F019_S021_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access S/U")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S021_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access S/U\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check load access-fault exception
|
||||
raised"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 003_load_L1_R1_addr_hit: !Subfeature
|
||||
name: 003_load_L1_R1_addr_hit
|
||||
tag: VP_PMP_F019_S024
|
||||
next_elt_id: 1
|
||||
display_order: 3
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S024_I000
|
||||
description: 'reuse of VP_PMP_F019_S024_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access S/U")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S024_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access S/U\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check load access-fault exception
|
||||
raised"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 004_store_L0_W1_addr_hit: !Subfeature
|
||||
name: 004_store_L0_W1_addr_hit
|
||||
tag: VP_PMP_F019_S031
|
||||
next_elt_id: 1
|
||||
display_order: 4
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S031_I000
|
||||
description: 'reuse of VP_PMP_F019_S031_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access S/U")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S031_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access S/U\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check store access-fault exception
|
||||
raised"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 005_store_L1_W1_addr_hit: !Subfeature
|
||||
name: 005_store_L1_W1_addr_hit
|
||||
tag: VP_PMP_F019_S034
|
||||
next_elt_id: 1
|
||||
display_order: 5
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S034_I000
|
||||
description: 'reuse of VP_PMP_F019_S034_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access S/U")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S034_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access S/U\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check store access-fault exception
|
||||
raised"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 006_load_MPP_L0_R1_addr_hit: !Subfeature
|
||||
name: 006_load_MPP_L0_R1_addr_hit
|
||||
tag: VP_PMP_F019_S041
|
||||
next_elt_id: 1
|
||||
display_order: 6
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S041_I000
|
||||
description: 'reuse of VP_PMP_F019_S041_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access S/U")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S041_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access S/U\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check load access-fault exception
|
||||
raised"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 007_load_MPP_L1_R1_addr_hit: !Subfeature
|
||||
name: 007_load_MPP_L1_R1_addr_hit
|
||||
tag: VP_PMP_F019_S044
|
||||
next_elt_id: 1
|
||||
display_order: 7
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S044_I000
|
||||
description: 'reuse of VP_PMP_F019_S044_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access S/U")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S044_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access S/U\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check load access-fault exception
|
||||
raised"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 008_store_MPP_L0_W1_addr_hit: !Subfeature
|
||||
name: 008_store_MPP_L0_W1_addr_hit
|
||||
tag: VP_PMP_F019_S051
|
||||
next_elt_id: 1
|
||||
display_order: 8
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S051_I000
|
||||
description: 'reuse of VP_PMP_F019_S051_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access S/U")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S051_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access S/U\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check store access-fault exception
|
||||
raised"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 009_store_MPP_L1_W1_addr_hit: !Subfeature
|
||||
name: 009_store_MPP_L1_W1_addr_hit
|
||||
tag: VP_PMP_F019_S054
|
||||
next_elt_id: 1
|
||||
display_order: 9
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S054_I000
|
||||
description: 'reuse of VP_PMP_F019_S054_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access S/U")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S054_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access S/U\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check store access-fault exception
|
||||
raised"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 010_fetch_L0_X1_addr_hit: !Subfeature
|
||||
name: 010_fetch_L0_X1_addr_hit
|
||||
tag: VP_PMP_F019_S011
|
||||
next_elt_id: 1
|
||||
display_order: 10
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S011_I000
|
||||
description: 'reuse of VP_PMP_F019_S011_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access M")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S011_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access M\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 011_fetch_L1_X1_addr_hit: !Subfeature
|
||||
name: 011_fetch_L1_X1_addr_hit
|
||||
tag: VP_PMP_F019_S014
|
||||
next_elt_id: 1
|
||||
display_order: 11
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S014_I000
|
||||
description: 'reuse of VP_PMP_F019_S014_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access M")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S014_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access M\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check store access-fault exception
|
||||
raised (TODO: is M mode access prevented by A=OFF)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 012_load_L0_R1_addr_hit: !Subfeature
|
||||
name: 012_load_L0_R1_addr_hit
|
||||
tag: VP_PMP_F019_S021
|
||||
next_elt_id: 1
|
||||
display_order: 12
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S021_I000
|
||||
description: 'reuse of VP_PMP_F019_S021_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access M")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S021_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access M\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 013_load_L1_R1_addr_hit: !Subfeature
|
||||
name: 013_load_L1_R1_addr_hit
|
||||
tag: VP_PMP_F019_S024
|
||||
next_elt_id: 1
|
||||
display_order: 13
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S024_I000
|
||||
description: 'reuse of VP_PMP_F019_S024_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access M")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S024_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access M\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check store access-fault exception
|
||||
raised (TODO: is M mode access prevented by A=OFF)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 014_store_L0_W1_addr_hit: !Subfeature
|
||||
name: 014_store_L0_W1_addr_hit
|
||||
tag: VP_PMP_F019_S031
|
||||
next_elt_id: 1
|
||||
display_order: 14
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S031_I000
|
||||
description: 'reuse of VP_PMP_F019_S031_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access M")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S031_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access M\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 015_store_L1_W1_addr_hit: !Subfeature
|
||||
name: 015_store_L1_W1_addr_hit
|
||||
tag: VP_PMP_F019_S034
|
||||
next_elt_id: 1
|
||||
display_order: 15
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S034_I000
|
||||
description: 'reuse of VP_PMP_F019_S034_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access M")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S034_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access M\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check store access-fault exception
|
||||
raised (TODO: is M mode access prevented by A=OFF)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 016_load_MPP_L0_R1_addr_hit: !Subfeature
|
||||
name: 016_load_MPP_L0_R1_addr_hit
|
||||
tag: VP_PMP_F019_S041
|
||||
next_elt_id: 1
|
||||
display_order: 16
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S041_I000
|
||||
description: 'reuse of VP_PMP_F019_S041_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access M")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S041_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access M\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 017_load_MPP_L1_R1_addr_hit: !Subfeature
|
||||
name: 017_load_MPP_L1_R1_addr_hit
|
||||
tag: VP_PMP_F019_S044
|
||||
next_elt_id: 1
|
||||
display_order: 17
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S044_I000
|
||||
description: 'reuse of VP_PMP_F019_S044_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access M")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S044_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access M\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check store access-fault exception
|
||||
raised (TODO: is M mode access prevented by A=OFF)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 018_store_MPP_L0_W1_addr_hit: !Subfeature
|
||||
name: 018_store_MPP_L0_W1_addr_hit
|
||||
tag: VP_PMP_F019_S051
|
||||
next_elt_id: 1
|
||||
display_order: 18
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S051_I000
|
||||
description: 'reuse of VP_PMP_F019_S051_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access M")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S051_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access M\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
- 019_store_MPP_L1_W1_addr_hit: !Subfeature
|
||||
name: 019_store_MPP_L1_W1_addr_hit
|
||||
tag: VP_PMP_F019_S054
|
||||
next_elt_id: 1
|
||||
display_order: 19
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F019_S054_I000
|
||||
description: 'reuse of VP_PMP_F019_S054_I000 feature description (Cf. Feature:
|
||||
"cfg NA4 access M")'
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "reuse of VP_PMP_F019_S054_I000 verification goals (Cf. Feature:
|
||||
\"cfg NA4 access M\")\n\nCONFIGURATION\n - check that pmpcfg(i).A=OFF
|
||||
(by reading back)\n\nCHECK UPDATE\n - check store access-fault exception
|
||||
raised (TODO: is M mode access prevented by A=OFF)"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: ''
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
376
verif/docs/VerifPlans/PMP/VP_IP021.yml
Normal file
376
verif/docs/VerifPlans/PMP/VP_IP021.yml
Normal file
|
@ -0,0 +1,376 @@
|
|||
!Feature
|
||||
next_elt_id: 6
|
||||
name: multi entries NA4
|
||||
id: 21
|
||||
display_order: 21
|
||||
subfeatures: !!omap
|
||||
- 000_1_entry: !Subfeature
|
||||
name: 000_1_entry
|
||||
tag: VP_PMP_F021_S001
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F021_S001_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose a single PMP entry\n\nCONFIGURATION and ACCESS\n -
|
||||
for each pmp entry, apply any CONFIGURATION+ACCESS scenario above (Cf. Feature:
|
||||
\"cfg NA4 access S/U/M\")\n - make sure the pmp entries address ranges
|
||||
are not overlapping/intersecting\n - NB: obviously, pmp entry configurations
|
||||
with different mstatus.MPRV/MPP values cannot be mixed in same test\n\n\
|
||||
CHECK\n - for each pmp entry, we should obtain the expected CHECK result\n\
|
||||
\nREUSABILITY\n - if possible, the number of PMP entries (N) is a configurable
|
||||
parameter\n - so a single test function can be reused"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST21(group)\n [create scenarios where PMP entries
|
||||
with A=2 (NA4) and with/without matching permissions\n - check only NA4
|
||||
defined addresses are matching]\nTST21-1 = extension of (TST11-11, TST11-21,
|
||||
TST11-31, TST11-41, TST11-51,\n TST11-12, TST11-22,
|
||||
TST11-32, TST11-42, TST11-52,\n TST11-13, TST11-23,
|
||||
TST11-33, TST11-43, TST11-53,\n TST11-14, TST11-24,
|
||||
TST11-34, TST11-44, TST11-54,\n TST11-15, TST11-25,
|
||||
TST11-35, TST11-45, TST11-55,\n TST11-16, TST11-26,
|
||||
TST11-36, TST11-46, TST11-56,\n TST12-11, TST12-21,
|
||||
TST12-31, TST12-41, TST12-51,\n TST12-12, TST12-22,
|
||||
TST12-32, TST12-42, TST12-52,\n TST12-13, TST12-23,
|
||||
TST12-33, TST12-43, TST12-53,\n TST12-14, TST12-24,
|
||||
TST12-34, TST12-44, TST12-54,\n TST12-15, TST12-25,
|
||||
TST12-35, TST12-45, TST12-55,\n TST12-16, TST12-26,
|
||||
TST12-36, TST12-46, TST12-56)\n[configure only one (any, but the first one)
|
||||
PMP entry\n - use A=NA4 for the PMP entry configuration\n - execute the
|
||||
chosen kind of access\n - should be same result]"
|
||||
- 001_2_isolated_entries: !Subfeature
|
||||
name: 001_2_isolated_entries
|
||||
tag: VP_PMP_F021_S002
|
||||
next_elt_id: 1
|
||||
display_order: 1
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F021_S002_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any 2 PMP entries\n\nreuse of VP_PMP_F021_S001_I000 feature
|
||||
description (Cf. Feature: \"multi entries NA4\")"
|
||||
pfc: 3
|
||||
test_type: 4
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST21(group)\n [create scenarios where PMP entries
|
||||
with A=2 (NA4) and with/without matching permissions\n - check only NA4
|
||||
defined addresses are matching]\nTST21-2 = extension of compatible pair
|
||||
of (TST11-11, TST11-21, TST11-31, TST11-41, TST11-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t TST11-12, TST11-22, TST11-32, TST11-42, TST11-52,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t TST11-13, TST11-23, TST11-33,
|
||||
TST11-43, TST11-53,\n \t\t\t\t\t\t\t\t\t TST11-14,
|
||||
TST11-24, TST11-34, TST11-44, TST11-54,\n \t\t\t\t
|
||||
\t\t\t\t\t TST11-15, TST11-25, TST11-35, TST11-45, TST11-55,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t TST11-16, TST11-26, TST11-36, TST11-46,
|
||||
TST11-56,\n \t\t\t\t\t\t\t\t\t TST12-11, TST12-21,
|
||||
TST12-31, TST12-41, TST12-51,\n \t\t\t\t\t\t\t\t\t
|
||||
TST12-12, TST12-22, TST12-32, TST12-42, TST12-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t TST12-13, TST12-23, TST12-33, TST12-43, TST12-53,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t TST12-14, TST12-24, TST12-34,
|
||||
TST12-44, TST12-54,\n \t\t\t\t\t\t\t\t\t TST12-15,
|
||||
TST12-25, TST12-35, TST12-45, TST12-55,\n \t\t\t\t
|
||||
\t\t\t\t\t TST12-16, TST12-26, TST12-36, TST12-46, TST12-56)\n[configure
|
||||
2 non-adjacent PMP entries (highest-numbered ones first) (avoid the first
|
||||
PMP entry)\n - use A=NA4 for each PMP entry configuration\n - execute
|
||||
the 2 kinds of accesses (if possible to chain due to potential access-fault
|
||||
exception)\n - should be same 2 results]"
|
||||
- 002_N_isolated_entries: !Subfeature
|
||||
name: 002_N_isolated_entries
|
||||
tag: VP_PMP_F021_S003
|
||||
next_elt_id: 1
|
||||
display_order: 2
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F021_S003_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any N PMP entries (2<N<8)\n\nreuse of VP_PMP_F021_S001_I000
|
||||
feature description (Cf. Feature: \"multi entries NA4\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST21(group)\n [create scenarios where PMP entries
|
||||
with A=2 (NA4) and with/without matching permissions\n - check only NA4
|
||||
defined addresses are matching]\nTST21-3 = extension of compatible group(N)
|
||||
of (TST11-11, TST11-21, TST11-31, TST11-41, TST11-51,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST11-12, TST11-22, TST11-32, TST11-42,
|
||||
TST11-52,\n \t\t\t\t\t\t\t\t\t\t\t TST11-13, TST11-23,
|
||||
TST11-33, TST11-43, TST11-53,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t TST11-14, TST11-24, TST11-34, TST11-44, TST11-54,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST11-15, TST11-25, TST11-35, TST11-45,
|
||||
TST11-55,\n \t\t\t\t\t\t\t\t\t\t\t TST11-16, TST11-26,
|
||||
TST11-36, TST11-46, TST11-56,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t TST12-11, TST12-21, TST12-31, TST12-41, TST12-51,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST12-12, TST12-22, TST12-32, TST12-42,
|
||||
TST12-52,\n \t\t\t\t\t\t\t\t\t\t\t TST12-13, TST12-23,
|
||||
TST12-33, TST12-43, TST12-53,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t TST12-14, TST12-24, TST12-34, TST12-44, TST12-54,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST12-15, TST12-25, TST12-35, TST12-45,
|
||||
TST12-55,\n \t\t\t\t\t\t\t\t\t\t\t TST12-16, TST12-26,
|
||||
TST12-36, TST12-46, TST12-56)\n[configure N PMP entries (highest-numbered
|
||||
ones first) (as non-adjacent as possible, and avoid the first PMP entry)\n\
|
||||
\ - use A=NA4 for each PMP entry configuration\n - execute the N kinds
|
||||
of accesses (if possible to chain due to potential access-fault exception)\n\
|
||||
\ - should be same N results]"
|
||||
- 003_8_isolated_entries: !Subfeature
|
||||
name: 003_8_isolated_entries
|
||||
tag: VP_PMP_F021_S004
|
||||
next_elt_id: 1
|
||||
display_order: 3
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F021_S004_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose all 8 PMP entries\n\nreuse of VP_PMP_F021_S001_I000 feature
|
||||
description (Cf. Feature: \"multi entries NA4\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST21(group)\n [create scenarios where PMP entries
|
||||
with A=2 (NA4) and with/without matching permissions\n - check only NA4
|
||||
defined addresses are matching]\nTST21-4 = extension of compatible group(8)
|
||||
of (TST11-11, TST11-21, TST11-31, TST11-41, TST11-51,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST11-12, TST11-22, TST11-32, TST11-42,
|
||||
TST11-52,\n \t\t\t\t\t\t\t\t\t\t\t TST11-13, TST11-23,
|
||||
TST11-33, TST11-43, TST11-53,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t TST11-14, TST11-24, TST11-34, TST11-44, TST11-54,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST11-15, TST11-25, TST11-35, TST11-45,
|
||||
TST11-55,\n \t\t\t\t\t\t\t\t\t\t\t TST11-16, TST11-26,
|
||||
TST11-36, TST11-46, TST11-56,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t TST12-11, TST12-21, TST12-31, TST12-41, TST12-51,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST12-12, TST12-22, TST12-32, TST12-42,
|
||||
TST12-52,\n \t\t\t\t\t\t\t\t\t\t\t TST12-13, TST12-23,
|
||||
TST12-33, TST12-43, TST12-53,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t TST12-14, TST12-24, TST12-34, TST12-44, TST12-54,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST12-15, TST12-25, TST12-35, TST12-45,
|
||||
TST12-55,\n \t\t\t\t\t\t\t\t\t\t\t TST12-16, TST12-26,
|
||||
TST12-36, TST12-46, TST12-56)\n[configure 8 PMP entries (highest-numbered
|
||||
ones first)\n - use A=NA4 for each PMP entry configuration\n - execute
|
||||
the 8 kinds of accesses (if possible to chain due to potential access-fault
|
||||
exception)\n - should be same 8 results]"
|
||||
- 004_2_intersecting_entries_fail: !Subfeature
|
||||
name: 004_2_intersecting_entries_fail
|
||||
tag: VP_PMP_F021_S005
|
||||
next_elt_id: 1
|
||||
display_order: 4
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F021_S005_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any 2 PMP entries\n\nCONFIGURATION and ACCESS (Cf. Feature:
|
||||
\"cfg NA4 access S/U/M\")\n - for the least-numbered pmp entry, apply
|
||||
any CONFIGURATION+ACCESS scenario with access-fault\n - for the highest-numbered
|
||||
pmp entry, apply any CONFIGURATION+ACCESS scenario without access-fault\n\
|
||||
\ - make sure the pmp entries address ranges are overlapping/intersecting
|
||||
(at least at 4 consecutive bytes)\n - for each pmp entry, execute one
|
||||
access in its associated pmp address region but outside the overlapping/intersecting
|
||||
address range\n - execute one additional access inside the overlapping/intersecting
|
||||
address range\n - NB: obviously, pmp entry configurations with different
|
||||
access-modes (S/U vs. M) cannot be easily mixed in same test\n - NB:
|
||||
obviously, pmp entry configurations with different mstatus.MPRV/MPP values
|
||||
cannot be mixed in same test\n\nCHECK\n - for each pmp entry, access
|
||||
outside the overlapping/intersecting address range should give the expected
|
||||
CHECK result\n - access inside the overlapping/intersecting address range
|
||||
should generate the access-type related access-fault\n\nREUSABILITY\n \
|
||||
\ - if possible, the number of PMP entries (N) is a configurable parameter\n\
|
||||
\ - so a single test function can be reused"
|
||||
pfc: 3
|
||||
test_type: 4
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST51(group) => FTR09-a, FTR09-b and FTR09-c\n [create
|
||||
scenarios where 2 PMP entries with same pmpaddr\n - one without matching
|
||||
permissions or with A=OFF\n - one with matching permissions and A=NA4/NAPOT/TOR\n\
|
||||
\ - any of them can be the lowest-numbered PMP entry]\nTST51-1\n[configure
|
||||
2 PMP entries\n - configure the lowest-numbered PMP entry with (TST11-12,
|
||||
TST11-22, TST11-32, TST11-42, TST11-52,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST11-15, TST11-25, TST11-35, TST11-45, TST11-55,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST12-12, TST12-22,
|
||||
TST12-32, TST12-42, TST12-52,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST12-15, TST12-25, TST12-35, TST12-45, TST12-55,\n \
|
||||
\ TST13-12, TST13-22, TST13-32, TST13-42,
|
||||
TST13-52,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST13-15,
|
||||
TST13-25, TST13-35, TST13-45, TST13-55,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST14-12, TST14-22, TST14-32, TST14-42, TST14-52,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST14-15, TST14-25,
|
||||
TST14-35, TST14-45, TST14-55,\n \
|
||||
\ TST15-12, TST15-22, TST15-32, TST15-42, TST15-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST15-15, TST15-25, TST15-35,
|
||||
TST15-45, TST15-55,\n \t\t\t\t\t\t\t\t\t \t\t\t\t
|
||||
TST16-12, TST16-22, TST16-32, TST16-42, TST16-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST16-15, TST16-25, TST16-35, TST16-45,
|
||||
TST16-55,\n TST17-12,
|
||||
TST17-22, TST17-32, TST17-42, TST17-52,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST17-15, TST17-25, TST17-35, TST17-45, TST17-55,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST18-12, TST18-22,
|
||||
TST18-32, TST18-42, TST18-52,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST18-15, TST18-25, TST18-35, TST18-45, TST18-55)\n - configure
|
||||
the highest-numbered PMP entry with (TST11-11, TST11-21, TST11-31, TST11-41,
|
||||
TST11-51,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST11-14,
|
||||
TST11-24, TST11-34, TST11-44, TST11-54,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST12-11, TST12-21, TST12-31, TST12-41, TST12-51,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST12-14, TST12-24,
|
||||
TST12-34, TST12-44, TST12-54,\n \
|
||||
\ TST13-11, TST13-21, TST13-31, TST13-41, TST13-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t\tTST13-14, TST13-24, TST13-34,
|
||||
TST13-44, TST13-54,\n \t\t\t\t\t\t\t\t\t \t\t\t\t
|
||||
\tTST14-11, TST14-21, TST14-31, TST14-41, TST14-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t\tTST14-14, TST14-24, TST14-34, TST14-44,
|
||||
TST14-54,\n TST15-11,
|
||||
TST15-21, TST15-31, TST15-41, TST15-51,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST15-14, TST15-24, TST15-34, TST15-44, TST15-54,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST16-11, TST16-21,
|
||||
TST16-31, TST16-41, TST16-51,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST16-14, TST16-24, TST16-34, TST16-44, TST16-54)\n - execute
|
||||
the associated access\n - check associated access-fault exception raised]"
|
||||
- 005_2_intersecting_entries_succeed: !Subfeature
|
||||
name: 005_2_intersecting_entries_succeed
|
||||
tag: VP_PMP_F021_S006
|
||||
next_elt_id: 1
|
||||
display_order: 5
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F021_S006_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any 2 PMP entries\n\nCONFIGURATION and ACCESS (Cf. Feature:
|
||||
\"cfg NA4 access S/U/M\")\n - for the least-numbered pmp entry, apply
|
||||
any CONFIGURATION+ACCESS scenario without access-fault\n - for the highest-numbered
|
||||
pmp entry, apply any CONFIGURATION+ACCESS scenario with access-fault\n \
|
||||
\ - make sure the pmp entries address ranges are overlapping/intersecting
|
||||
(at least at 4 consecutive bytes)\n - for each pmp entry, execute one
|
||||
access in its associated pmp address region but outside the overlapping/intersecting
|
||||
address range\n - execute one additional access inside the overlapping/intersecting
|
||||
address range\n - NB: obviously, pmp entry configurations with different
|
||||
access-modes (S/U vs. M) cannot be easily mixed in same test\n - NB:
|
||||
obviously, pmp entry configurations with different mstatus.MPRV/MPP values
|
||||
cannot be mixed in same test\n\nCHECK\n - for each pmp entry, access
|
||||
outside the overlapping/intersecting address range should give the expected
|
||||
CHECK result\n - access inside the overlapping/intersecting address range
|
||||
should not generate any access-fault\n\nREUSABILITY\n - if possible,
|
||||
the number of PMP entries (N) is a configurable parameter\n - so a single
|
||||
test function can be reused"
|
||||
pfc: 3
|
||||
test_type: 4
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST51(group) => FTR09-a, FTR09-b and FTR09-c\n [create
|
||||
scenarios where 2 PMP entries with same pmpaddr\n - one without matching
|
||||
permissions or with A=OFF\n - one with matching permissions and A=NA4/NAPOT/TOR\n\
|
||||
\ - any of them can be the lowest-numbered PMP entry]\nTST51-2\n[configure
|
||||
2 PMP entries\n - configure the lowest-numbered PMP entry with (TST11-11,
|
||||
TST11-21, TST11-31, TST11-41, TST11-51,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST11-14, TST11-24, TST11-34, TST11-44, TST11-54,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST12-11, TST12-21,
|
||||
TST12-31, TST12-41, TST12-51,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST12-14, TST12-24, TST12-34, TST12-44, TST12-54,\n \
|
||||
\ TST13-11, TST13-21, TST13-31, TST13-41,
|
||||
TST13-51,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST13-14,
|
||||
TST13-24, TST13-34, TST13-44, TST13-54,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST14-11, TST14-21, TST14-31, TST14-41, TST14-51,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST14-14, TST14-24,
|
||||
TST14-34, TST14-44, TST14-54,\n \
|
||||
\ TST15-11, TST15-21, TST15-31, TST15-41, TST15-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST15-14, TST15-24, TST15-34,
|
||||
TST15-44, TST15-54,\n \t\t\t\t\t\t\t\t\t \t\t\t\t
|
||||
TST16-11, TST16-21, TST16-31, TST16-41, TST16-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST16-14, TST16-24, TST16-34, TST16-44,
|
||||
TST16-54)\n - configure the highest-numbered PMP entry with (TST11-12,
|
||||
TST11-22, TST11-32, TST11-42, TST11-52,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST11-15, TST11-25, TST11-35, TST11-45, TST11-55,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST12-12, TST12-22,
|
||||
TST12-32, TST12-42, TST12-52,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST12-15, TST12-25, TST12-35, TST12-45, TST12-55,\n \
|
||||
\ TST13-12, TST13-22, TST13-32,
|
||||
TST13-42, TST13-52,\n \t\t\t\t\t\t\t\t\t \t\t\t\t\
|
||||
\ TST13-15, TST13-25, TST13-35, TST13-45, TST13-55,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST14-12, TST14-22, TST14-32, TST14-42,
|
||||
TST14-52,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST14-15,
|
||||
TST14-25, TST14-35, TST14-45, TST14-55,\n \
|
||||
\ TST15-12, TST15-22, TST15-32, TST15-42, TST15-52,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST15-15, TST15-25,
|
||||
TST15-35, TST15-45, TST15-55,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST16-12, TST16-22, TST16-32, TST16-42, TST16-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST16-15, TST16-25, TST16-35,
|
||||
TST16-45, TST16-55,\n \
|
||||
\ TST17-12, TST17-22, TST17-32, TST17-42, TST17-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST17-15, TST17-25, TST17-35, TST17-45,
|
||||
TST17-55,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST18-12,
|
||||
TST18-22, TST18-32, TST18-42, TST18-52,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST18-15, TST18-25, TST18-35, TST18-45, TST18-55)\n\
|
||||
\ - execute the associated access\n - check no access-fault exception]"
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
376
verif/docs/VerifPlans/PMP/VP_IP022.yml
Normal file
376
verif/docs/VerifPlans/PMP/VP_IP022.yml
Normal file
|
@ -0,0 +1,376 @@
|
|||
!Feature
|
||||
next_elt_id: 6
|
||||
name: multi entries NAPOT
|
||||
id: 22
|
||||
display_order: 22
|
||||
subfeatures: !!omap
|
||||
- 000_1_entry: !Subfeature
|
||||
name: 000_1_entry
|
||||
tag: VP_PMP_F022_S001
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F022_S001_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose a single PMP entry\n\nCONFIGURATION and ACCESS\n -
|
||||
for each pmp entry, apply any CONFIGURATION+ACCESS scenario above (Cf. Feature:
|
||||
\"cfg NAPOT access S/U/M\")\n - make sure the pmp entries address ranges
|
||||
are not overlapping/intersecting\n - NB: obviously, pmp entry configurations
|
||||
with different mstatus.MPRV/MPP values cannot be mixed in same test\n\n\
|
||||
CHECK\n - for each pmp entry, we should obtain the expected CHECK result\n\
|
||||
\nREUSABILITY\n - if possible, the number of PMP entries (N) is a configurable
|
||||
parameter\n - so a single test function can be reused"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST22(group)\n [create scenarios where PMP entries
|
||||
with A=3 (NAPOT) and with/without matching permissions\n - check only
|
||||
NAPOT defined addresses are matching]\nTST22-1 = extension of (TST13-11,
|
||||
TST13-21, TST13-31, TST13-41, TST13-51,\n TST13-12,
|
||||
TST13-22, TST13-32, TST13-42, TST13-52,\n TST13-13,
|
||||
TST13-23, TST13-33, TST13-43, TST13-53,\n TST13-14,
|
||||
TST13-24, TST13-34, TST13-44, TST13-54,\n TST13-15,
|
||||
TST13-25, TST13-35, TST13-45, TST13-55,\n TST13-16,
|
||||
TST13-26, TST13-36, TST13-46, TST13-56,\n TST14-11,
|
||||
TST14-21, TST14-31, TST14-41, TST14-51,\n TST14-12,
|
||||
TST14-22, TST14-32, TST14-42, TST14-52,\n TST14-13,
|
||||
TST14-23, TST14-33, TST14-43, TST14-53,\n TST14-14,
|
||||
TST14-24, TST14-34, TST14-44, TST14-54,\n TST14-15,
|
||||
TST14-25, TST14-35, TST14-45, TST14-55,\n TST14-16,
|
||||
TST14-26, TST14-36, TST14-46, TST14-56)\n[configure only one (any, but the
|
||||
first one) PMP entry\n - use A=NAPOT for the PMP entry configuration\n\
|
||||
\ - execute the chosen kind of access\n - should be same result]"
|
||||
- 001_2_isolated_entries: !Subfeature
|
||||
name: 001_2_isolated_entries
|
||||
tag: VP_PMP_F022_S002
|
||||
next_elt_id: 1
|
||||
display_order: 1
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F022_S002_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any 2 PMP entries\n\nreuse of VP_PMP_F022_S001_I000 feature
|
||||
description (Cf. Feature: \"multi entries NAPOT\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST22(group)\n [create scenarios where PMP entries
|
||||
with A=3 (NAPOT) and with/without matching permissions\n - check only
|
||||
NAPOT defined addresses are matching]\nTST22-2 = extension of compatible
|
||||
pair of (TST13-11, TST13-21, TST13-31, TST13-41, TST13-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t TST13-12, TST13-22, TST13-32, TST13-42,
|
||||
TST13-52,\n \t\t\t\t\t\t\t\t\t TST13-13, TST13-23,
|
||||
TST13-33, TST13-43, TST13-53,\n \t\t\t\t\t\t\t\t\t
|
||||
TST13-14, TST13-24, TST13-34, TST13-44, TST13-54,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t TST13-15, TST13-25, TST13-35, TST13-45, TST13-55,\n\
|
||||
\ \t\t\t\t \t\t\t\t\t TST13-16, TST13-26, TST13-36,
|
||||
TST13-46, TST13-56,\n \t\t\t\t\t\t\t\t\t TST14-11,
|
||||
TST14-21, TST14-31, TST14-41, TST14-51,\n \t\t\t\t
|
||||
\t\t\t\t\t TST14-12, TST14-22, TST14-32, TST14-42, TST14-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t TST14-13, TST14-23, TST14-33, TST14-43,
|
||||
TST14-53,\n \t\t\t\t\t\t\t\t\t TST14-14, TST14-24,
|
||||
TST14-34, TST14-44, TST14-54,\n \t\t\t\t\t\t\t\t\t
|
||||
TST14-15, TST14-25, TST14-35, TST14-45, TST14-55,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t TST14-16, TST14-26, TST14-36, TST14-46, TST14-56)\n
|
||||
[configure 2 non-adjacent PMP entries (highest-numbered ones first) (avoid
|
||||
the first PMP entry)\n - use A=NAPOT for each PMP entry configuration\n\
|
||||
\ - execute the 2 kinds of accesses (if possible to chain due to potential
|
||||
access-fault exception)\n - should be same 2 results]"
|
||||
- 002_N_isolated_entries: !Subfeature
|
||||
name: 002_N_isolated_entries
|
||||
tag: VP_PMP_F022_S003
|
||||
next_elt_id: 1
|
||||
display_order: 2
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F022_S003_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any N PMP entries (2<N<8)\n\nreuse of VP_PMP_F022_S001_I000
|
||||
feature description (Cf. Feature: \"multi entries NAPOT\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST22(group)\n [create scenarios where PMP entries
|
||||
with A=3 (NAPOT) and with/without matching permissions\n - check only
|
||||
NAPOT defined addresses are matching]\nTST22-3 = extension of compatible
|
||||
group(N) of (TST13-11, TST13-21, TST13-31, TST13-41, TST13-51,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST13-12, TST13-22, TST13-32,
|
||||
TST13-42, TST13-52,\n \t\t\t\t\t\t\t\t\t\t\t TST13-13,
|
||||
TST13-23, TST13-33, TST13-43, TST13-53,\n \t\t\t\t
|
||||
\t\t\t\t\t\t\t TST13-14, TST13-24, TST13-34, TST13-44, TST13-54,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST13-15, TST13-25, TST13-35,
|
||||
TST13-45, TST13-55,\n \t\t\t\t\t\t\t\t\t\t\t TST13-16,
|
||||
TST13-26, TST13-36, TST13-46, TST13-56,\n \t\t\t\t
|
||||
\t\t\t\t\t\t\t TST14-11, TST14-21, TST14-31, TST14-41, TST14-51,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST14-12, TST14-22, TST14-32,
|
||||
TST14-42, TST14-52,\n \t\t\t\t\t\t\t\t\t\t\t TST14-13,
|
||||
TST14-23, TST14-33, TST14-43, TST14-53,\n \t\t\t\t
|
||||
\t\t\t\t\t\t\t TST14-14, TST14-24, TST14-34, TST14-44, TST14-54,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST14-15, TST14-25, TST14-35,
|
||||
TST14-45, TST14-55,\n \t\t\t\t\t\t\t\t\t\t\t TST14-16,
|
||||
TST14-26, TST14-36, TST14-46, TST14-56)\n[configure N PMP entries (highest-numbered
|
||||
ones first) (as non-adjacent as possible, and avoid the first PMP entry)\n\
|
||||
\ - use A=NAPOT for each PMP entry configuration\n - execute the N kinds
|
||||
of accesses (if possible to chain due to potential access-fault exception)\n\
|
||||
\ - should be same N results]"
|
||||
- 003_8_isolated_entries: !Subfeature
|
||||
name: 003_8_isolated_entries
|
||||
tag: VP_PMP_F022_S004
|
||||
next_elt_id: 1
|
||||
display_order: 3
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F022_S004_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose all 8 PMP entries\n\nreuse of VP_PMP_F022_S001_I000 feature
|
||||
description (Cf. Feature: \"multi entries NAPOT\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 0
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST22(group)\n [create scenarios where PMP entries
|
||||
with A=3 (NAPOT) and with/without matching permissions\n - check only
|
||||
NAPOT defined addresses are matching]\nTST22-4 = extension of compatible
|
||||
group(8) of (TST13-11, TST13-21, TST13-31, TST13-41, TST13-51,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST13-12, TST13-22, TST13-32,
|
||||
TST13-42, TST13-52,\n \t\t\t\t\t\t\t\t\t\t\t TST13-13,
|
||||
TST13-23, TST13-33, TST13-43, TST13-53,\n \t\t\t\t
|
||||
\t\t\t\t\t\t\t TST13-14, TST13-24, TST13-34, TST13-44, TST13-54,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST13-15, TST13-25, TST13-35,
|
||||
TST13-45, TST13-55,\n \t\t\t\t\t\t\t\t\t\t\t TST13-16,
|
||||
TST13-26, TST13-36, TST13-46, TST13-56,\n \t\t\t\t
|
||||
\t\t\t\t\t\t\t TST14-11, TST14-21, TST14-31, TST14-41, TST14-51,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST14-12, TST14-22, TST14-32,
|
||||
TST14-42, TST14-52,\n \t\t\t\t\t\t\t\t\t\t\t TST14-13,
|
||||
TST14-23, TST14-33, TST14-43, TST14-53,\n \t\t\t\t
|
||||
\t\t\t\t\t\t\t TST14-14, TST14-24, TST14-34, TST14-44, TST14-54,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t\t\t TST14-15, TST14-25, TST14-35,
|
||||
TST14-45, TST14-55,\n \t\t\t\t\t\t\t\t\t\t\t TST14-16,
|
||||
TST14-26, TST14-36, TST14-46, TST14-56)\n[configure 8 PMP entries (highest-numbered
|
||||
ones first)\n - use A=NAPOT for each PMP entry configuration\n - execute
|
||||
the 8 kinds of accesses (if possible to chain due to potential access-fault
|
||||
exception)\n - should be same 8 results]"
|
||||
- 004_2_intersecting_entries_fail: !Subfeature
|
||||
name: 004_2_intersecting_entries_fail
|
||||
tag: VP_PMP_F022_S005
|
||||
next_elt_id: 1
|
||||
display_order: 4
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F022_S005_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any 2 PMP entries\n\nCONFIGURATION and ACCESS (Cf. Feature:
|
||||
\"cfg NAPOT access S/U/M\")\n - for the least-numbered pmp entry, apply
|
||||
any CONFIGURATION+ACCESS scenario with access-fault\n - for the highest-numbered
|
||||
pmp entry, apply any CONFIGURATION+ACCESS scenario without access-fault\n\
|
||||
\ - make sure the pmp entries address ranges are overlapping/intersecting
|
||||
(at least at 4 consecutive bytes)\n - for each pmp entry, execute one
|
||||
access in its associated pmp address region but outside the overlapping/intersecting
|
||||
address range\n - execute one additional access inside the overlapping/intersecting
|
||||
address range\n - NB: obviously, pmp entry configurations with different
|
||||
access-modes (S/U vs. M) cannot be easily mixed in same test\n - NB:
|
||||
obviously, pmp entry configurations with different mstatus.MPRV/MPP values
|
||||
cannot be mixed in same test\n\nCHECK\n - for each pmp entry, access
|
||||
outside the overlapping/intersecting address range should give the expected
|
||||
CHECK result\n - access inside the overlapping/intersecting address range
|
||||
should generate the access-type related access-fault\n\nREUSABILITY\n \
|
||||
\ - if possible, the number of PMP entries (N) is a configurable parameter\n\
|
||||
\ - so a single test function can be reused"
|
||||
pfc: 3
|
||||
test_type: 4
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST51(group) => FTR09-a, FTR09-b and FTR09-c\n [create
|
||||
scenarios where 2 PMP entries with same pmpaddr\n - one without matching
|
||||
permissions or with A=OFF\n - one with matching permissions and A=NA4/NAPOT/TOR\n\
|
||||
\ - any of them can be the lowest-numbered PMP entry]\nTST51-1\n[configure
|
||||
2 PMP entries\n - configure the lowest-numbered PMP entry with (TST11-12,
|
||||
TST11-22, TST11-32, TST11-42, TST11-52,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST11-15, TST11-25, TST11-35, TST11-45, TST11-55,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST12-12, TST12-22,
|
||||
TST12-32, TST12-42, TST12-52,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST12-15, TST12-25, TST12-35, TST12-45, TST12-55,\n \
|
||||
\ TST13-12, TST13-22, TST13-32, TST13-42,
|
||||
TST13-52,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST13-15,
|
||||
TST13-25, TST13-35, TST13-45, TST13-55,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST14-12, TST14-22, TST14-32, TST14-42, TST14-52,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST14-15, TST14-25,
|
||||
TST14-35, TST14-45, TST14-55,\n \
|
||||
\ TST15-12, TST15-22, TST15-32, TST15-42, TST15-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST15-15, TST15-25, TST15-35,
|
||||
TST15-45, TST15-55,\n \t\t\t\t\t\t\t\t\t \t\t\t\t
|
||||
TST16-12, TST16-22, TST16-32, TST16-42, TST16-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST16-15, TST16-25, TST16-35, TST16-45,
|
||||
TST16-55,\n TST17-12,
|
||||
TST17-22, TST17-32, TST17-42, TST17-52,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST17-15, TST17-25, TST17-35, TST17-45, TST17-55,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST18-12, TST18-22,
|
||||
TST18-32, TST18-42, TST18-52,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST18-15, TST18-25, TST18-35, TST18-45, TST18-55)\n - configure
|
||||
the highest-numbered PMP entry with (TST11-11, TST11-21, TST11-31, TST11-41,
|
||||
TST11-51,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST11-14,
|
||||
TST11-24, TST11-34, TST11-44, TST11-54,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST12-11, TST12-21, TST12-31, TST12-41, TST12-51,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST12-14, TST12-24,
|
||||
TST12-34, TST12-44, TST12-54,\n \
|
||||
\ TST13-11, TST13-21, TST13-31, TST13-41, TST13-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t\tTST13-14, TST13-24, TST13-34,
|
||||
TST13-44, TST13-54,\n \t\t\t\t\t\t\t\t\t \t\t\t\t
|
||||
\tTST14-11, TST14-21, TST14-31, TST14-41, TST14-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t\tTST14-14, TST14-24, TST14-34, TST14-44,
|
||||
TST14-54,\n TST15-11,
|
||||
TST15-21, TST15-31, TST15-41, TST15-51,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST15-14, TST15-24, TST15-34, TST15-44, TST15-54,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST16-11, TST16-21,
|
||||
TST16-31, TST16-41, TST16-51,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST16-14, TST16-24, TST16-34, TST16-44, TST16-54)\n - execute
|
||||
the associated access\n - check associated access-fault exception raised]"
|
||||
- 005_2_intersecting_entries_succeed: !Subfeature
|
||||
name: 005_2_intersecting_entries_succeed
|
||||
tag: VP_PMP_F022_S006
|
||||
next_elt_id: 1
|
||||
display_order: 5
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F022_S006_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any 2 PMP entries\n\nCONFIGURATION and ACCESS (Cf. Feature:
|
||||
\"cfg NAPOT access S/U/M\")\n - for the least-numbered pmp entry, apply
|
||||
any CONFIGURATION+ACCESS scenario without access-fault\n - for the highest-numbered
|
||||
pmp entry, apply any CONFIGURATION+ACCESS scenario with access-fault\n \
|
||||
\ - make sure the pmp entries address ranges are overlapping/intersecting
|
||||
(at least at 4 consecutive bytes)\n - for each pmp entry, execute one
|
||||
access in its associated pmp address region but outside the overlapping/intersecting
|
||||
address range\n - execute one additional access inside the overlapping/intersecting
|
||||
address range\n - NB: obviously, pmp entry configurations with different
|
||||
access-modes (S/U vs. M) cannot be easily mixed in same test\n - NB:
|
||||
obviously, pmp entry configurations with different mstatus.MPRV/MPP values
|
||||
cannot be mixed in same test\n\nCHECK\n - for each pmp entry, access
|
||||
outside the overlapping/intersecting address range should give the expected
|
||||
CHECK result\n - access inside the overlapping/intersecting address range
|
||||
should not generate any access-fault\n\nREUSABILITY\n - if possible,
|
||||
the number of PMP entries (N) is a configurable parameter\n - so a single
|
||||
test function can be reused"
|
||||
pfc: 3
|
||||
test_type: 4
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST51(group) => FTR09-a, FTR09-b and FTR09-c\n [create
|
||||
scenarios where 2 PMP entries with same pmpaddr\n - one without matching
|
||||
permissions or with A=OFF\n - one with matching permissions and A=NA4/NAPOT/TOR\n\
|
||||
\ - any of them can be the lowest-numbered PMP entry]\nTST51-2\n[configure
|
||||
2 PMP entries\n - configure the lowest-numbered PMP entry with (TST11-11,
|
||||
TST11-21, TST11-31, TST11-41, TST11-51,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST11-14, TST11-24, TST11-34, TST11-44, TST11-54,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST12-11, TST12-21,
|
||||
TST12-31, TST12-41, TST12-51,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST12-14, TST12-24, TST12-34, TST12-44, TST12-54,\n \
|
||||
\ TST13-11, TST13-21, TST13-31, TST13-41,
|
||||
TST13-51,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST13-14,
|
||||
TST13-24, TST13-34, TST13-44, TST13-54,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST14-11, TST14-21, TST14-31, TST14-41, TST14-51,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST14-14, TST14-24,
|
||||
TST14-34, TST14-44, TST14-54,\n \
|
||||
\ TST15-11, TST15-21, TST15-31, TST15-41, TST15-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST15-14, TST15-24, TST15-34,
|
||||
TST15-44, TST15-54,\n \t\t\t\t\t\t\t\t\t \t\t\t\t
|
||||
TST16-11, TST16-21, TST16-31, TST16-41, TST16-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST16-14, TST16-24, TST16-34, TST16-44,
|
||||
TST16-54)\n - configure the highest-numbered PMP entry with (TST11-12,
|
||||
TST11-22, TST11-32, TST11-42, TST11-52,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST11-15, TST11-25, TST11-35, TST11-45, TST11-55,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST12-12, TST12-22,
|
||||
TST12-32, TST12-42, TST12-52,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST12-15, TST12-25, TST12-35, TST12-45, TST12-55,\n \
|
||||
\ TST13-12, TST13-22, TST13-32,
|
||||
TST13-42, TST13-52,\n \t\t\t\t\t\t\t\t\t \t\t\t\t\
|
||||
\ TST13-15, TST13-25, TST13-35, TST13-45, TST13-55,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST14-12, TST14-22, TST14-32, TST14-42,
|
||||
TST14-52,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST14-15,
|
||||
TST14-25, TST14-35, TST14-45, TST14-55,\n \
|
||||
\ TST15-12, TST15-22, TST15-32, TST15-42, TST15-52,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST15-15, TST15-25,
|
||||
TST15-35, TST15-45, TST15-55,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST16-12, TST16-22, TST16-32, TST16-42, TST16-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST16-15, TST16-25, TST16-35,
|
||||
TST16-45, TST16-55,\n \
|
||||
\ TST17-12, TST17-22, TST17-32, TST17-42, TST17-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST17-15, TST17-25, TST17-35, TST17-45,
|
||||
TST17-55,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST18-12,
|
||||
TST18-22, TST18-32, TST18-42, TST18-52,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST18-15, TST18-25, TST18-35, TST18-45, TST18-55)\n\
|
||||
\ - execute the associated access\n - check no access-fault exception]"
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
378
verif/docs/VerifPlans/PMP/VP_IP023.yml
Normal file
378
verif/docs/VerifPlans/PMP/VP_IP023.yml
Normal file
|
@ -0,0 +1,378 @@
|
|||
!Feature
|
||||
next_elt_id: 6
|
||||
name: multi entries TOR
|
||||
id: 23
|
||||
display_order: 23
|
||||
subfeatures: !!omap
|
||||
- 000_1_entry: !Subfeature
|
||||
name: 000_1_entry
|
||||
tag: VP_PMP_F023_S001
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F023_S001_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose a single PMP entry\n\nCONFIGURATION and ACCESS\n -
|
||||
for each pmp entry, apply any CONFIGURATION+ACCESS scenario above (Cf. Feature:
|
||||
\"cfg TOR access S/U/M\")\n - make sure the pmp entries address ranges
|
||||
are not overlapping/intersecting\n - NB: obviously, pmp entry configurations
|
||||
with different mstatus.MPRV/MPP values cannot be mixed in same test\n\n\
|
||||
CHECK\n - for each pmp entry, we should obtain the expected CHECK result\n\
|
||||
\nREUSABILITY\n - if possible, the number of PMP entries (N) is a configurable
|
||||
parameter\n - so a single test function can be reused"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST23(group) => \n [create scenarios where PMP entries
|
||||
with A=1 (TOR) and with/without matching permissions\n - pmpaddr(i−1)
|
||||
< pmpaddr(i), pmpcfg(i).A=TOR and pmpcfg(i-1) with/without matching permissions\n\
|
||||
\ - check only TOR defined addresses are matching]\nTST23-1 = extension
|
||||
of (TST15-11, TST15-21, TST15-31, TST15-41, TST15-51,\n \
|
||||
\ TST15-12, TST15-22, TST15-32, TST15-42, TST15-52,\n \
|
||||
\ TST15-13, TST15-23, TST15-33, TST15-43, TST15-53,\n \
|
||||
\ TST15-14, TST15-24, TST15-34, TST15-44, TST15-54,\n \
|
||||
\ TST15-15, TST15-25, TST15-35, TST15-45, TST15-55,\n\
|
||||
\ TST15-16, TST15-26, TST15-36, TST15-46, TST15-56,\n\
|
||||
\ TST16-11, TST16-21, TST16-31, TST16-41, TST16-51,\n\
|
||||
\ TST16-12, TST16-22, TST16-32, TST16-42, TST16-52,\n\
|
||||
\ TST16-13, TST16-23, TST16-33, TST16-43, TST16-53,\n\
|
||||
\ TST16-14, TST16-24, TST16-34, TST16-44, TST16-54,\n\
|
||||
\ TST16-15, TST16-25, TST16-35, TST16-45, TST16-55,\n\
|
||||
\ TST16-16, TST16-26, TST16-36, TST16-46, TST16-56)\n
|
||||
[configure only one (any, but the first one) PMP entry\n - execute the
|
||||
chosen kind of access\n - should be same result]"
|
||||
- 001_2_isolated_entries: !Subfeature
|
||||
name: 001_2_isolated_entries
|
||||
tag: VP_PMP_F023_S002
|
||||
next_elt_id: 1
|
||||
display_order: 1
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F023_S002_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any 2 PMP entries\n\nreuse of VP_PMP_F023_S001_I000 feature
|
||||
description (Cf. Feature: \"multi entries TOR\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST23(group) => \n [create scenarios where PMP entries
|
||||
with A=1 (TOR) and with/without matching permissions\n - pmpaddr(i−1)
|
||||
< pmpaddr(i), pmpcfg(i).A=TOR and pmpcfg(i-1) with/without matching permissions\n\
|
||||
\ - check only TOR defined addresses are matching]\nTST23-2 = extension
|
||||
of compatible pair of (TST15-11, TST15-21, TST15-31, TST15-41, TST15-51,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t TST15-12, TST15-22, TST15-32,
|
||||
TST15-42, TST15-52,\n \t\t\t\t\t\t\t\t\t TST15-13,
|
||||
TST15-23, TST15-33, TST15-43, TST15-53,\n \t\t\t\t
|
||||
\t\t\t\t\t TST15-14, TST15-24, TST15-34, TST15-44, TST15-54,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t TST15-15, TST15-25, TST15-35, TST15-45,
|
||||
TST15-55,\n \t\t\t\t\t\t\t\t\t TST15-16, TST15-26,
|
||||
TST15-36, TST15-46, TST15-56,\n \t\t\t\t\t\t\t\t\t
|
||||
TST16-11, TST16-21, TST16-31, TST16-41, TST16-51,\n \
|
||||
\ \t\t\t\t \t\t\t\t\t TST16-12, TST16-22, TST16-32, TST16-42, TST16-52,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t TST16-13, TST16-23, TST16-33,
|
||||
TST16-43, TST16-53,\n \t\t\t\t\t\t\t\t\t TST16-14,
|
||||
TST16-24, TST16-34, TST16-44, TST16-54,\n \t\t\t\t
|
||||
\t\t\t\t\t TST16-15, TST16-25, TST16-35, TST16-45, TST16-55,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t TST16-16, TST16-26, TST16-36, TST16-46,
|
||||
TST16-56)\n [configure 2 non-adjacent PMP entries (highest-numbered ones
|
||||
first) (avoid the first PMP entry)\n - execute the 2 kinds of accesses
|
||||
(if possible to chain due to potential access-fault exception)\n - should
|
||||
be same 2 results]"
|
||||
- 002_N_isolated_entries: !Subfeature
|
||||
name: 002_N_isolated_entries
|
||||
tag: VP_PMP_F023_S003
|
||||
next_elt_id: 1
|
||||
display_order: 2
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F023_S003_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any N PMP entries (2<N<8)\n\nreuse of VP_PMP_F023_S001_I000
|
||||
feature description (Cf. Feature: \"multi entries TOR\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST23(group) => \n [create scenarios where PMP entries
|
||||
with A=1 (TOR) and with/without matching permissions\n - pmpaddr(i−1)
|
||||
< pmpaddr(i), pmpcfg(i).A=TOR and pmpcfg(i-1) with/without matching permissions\n\
|
||||
\ - check only TOR defined addresses are matching]\nTST23-3 = extension
|
||||
of compatible group(N) of (TST15-11, TST15-21, TST15-31, TST15-41, TST15-51,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t\t\t TST15-12, TST15-22, TST15-32,
|
||||
TST15-42, TST15-52,\n \t\t\t\t\t\t\t\t\t\t\t TST15-13,
|
||||
TST15-23, TST15-33, TST15-43, TST15-53,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t TST15-14, TST15-24, TST15-34, TST15-44, TST15-54,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t\t\t TST15-15, TST15-25, TST15-35,
|
||||
TST15-45, TST15-55,\n \t\t\t\t\t\t\t\t\t\t\t TST15-16,
|
||||
TST15-26, TST15-36, TST15-46, TST15-56,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t TST16-11, TST16-21, TST16-31, TST16-41, TST16-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t\t\t TST16-12, TST16-22, TST16-32,
|
||||
TST16-42, TST16-52,\n \t\t\t\t\t\t\t\t\t\t\t TST16-13,
|
||||
TST16-23, TST16-33, TST16-43, TST16-53,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t TST16-14, TST16-24, TST16-34, TST16-44, TST16-54,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t\t\t TST16-15, TST16-25, TST16-35,
|
||||
TST16-45, TST16-55,\n \t\t\t\t\t\t\t\t\t\t\t TST16-16,
|
||||
TST16-26, TST16-36, TST16-46, TST16-56)\n[configure N PMP entries (highest-numbered
|
||||
ones first) (as non-adjacent as possible, and avoid the first PMP entry)\n\
|
||||
\ - execute the N kinds of accesses (if possible to chain due to potential
|
||||
access-fault exception)\n - should be same N results]"
|
||||
- 003_8_isolated_entries: !Subfeature
|
||||
name: 003_8_isolated_entries
|
||||
tag: VP_PMP_F023_S004
|
||||
next_elt_id: 1
|
||||
display_order: 3
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F023_S004_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose all 8 PMP entries\n\nreuse of VP_PMP_F023_S001_I000 feature
|
||||
description (Cf. Feature: \"multi entries TOR\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST23(group) => \n [create scenarios where PMP entries
|
||||
with A=1 (TOR) and with/without matching permissions\n - pmpaddr(i−1)
|
||||
< pmpaddr(i), pmpcfg(i).A=TOR and pmpcfg(i-1) with/without matching permissions\n\
|
||||
\ - check only TOR defined addresses are matching]\nTST23-4 = extension
|
||||
of compatible group(8) of (TST15-11, TST15-21, TST15-31, TST15-41, TST15-51,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t\t\t TST15-12, TST15-22, TST15-32,
|
||||
TST15-42, TST15-52,\n \t\t\t\t\t\t\t\t\t\t\t TST15-13,
|
||||
TST15-23, TST15-33, TST15-43, TST15-53,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t TST15-14, TST15-24, TST15-34, TST15-44, TST15-54,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t\t\t TST15-15, TST15-25, TST15-35,
|
||||
TST15-45, TST15-55,\n \t\t\t\t\t\t\t\t\t\t\t TST15-16,
|
||||
TST15-26, TST15-36, TST15-46, TST15-56,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t TST16-11, TST16-21, TST16-31, TST16-41, TST16-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t\t\t TST16-12, TST16-22, TST16-32,
|
||||
TST16-42, TST16-52,\n \t\t\t\t\t\t\t\t\t\t\t TST16-13,
|
||||
TST16-23, TST16-33, TST16-43, TST16-53,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t TST16-14, TST16-24, TST16-34, TST16-44, TST16-54,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t\t\t TST16-15, TST16-25, TST16-35,
|
||||
TST16-45, TST16-55,\n \t\t\t\t\t\t\t\t\t\t\t TST16-16,
|
||||
TST16-26, TST16-36, TST16-46, TST16-56)\n[configure 8 PMP entries (highest-numbered
|
||||
ones first)\n - execute the 8 kinds of accesses (if possible to chain due
|
||||
to potential access-fault exception)\n - should be same 8 results]"
|
||||
- 004_2_intersecting_entries_fail: !Subfeature
|
||||
name: 004_2_intersecting_entries_fail
|
||||
tag: VP_PMP_F023_S005
|
||||
next_elt_id: 1
|
||||
display_order: 4
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F023_S005_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any 2 PMP entries\n\nCONFIGURATION and ACCESS (Cf. Feature:
|
||||
\"cfg TOR access S/U/M\")\n - for the least-numbered pmp entry, apply
|
||||
any CONFIGURATION+ACCESS scenario with access-fault\n - for the highest-numbered
|
||||
pmp entry, apply any CONFIGURATION+ACCESS scenario without access-fault\n\
|
||||
\ - make sure the pmp entries address ranges are overlapping/intersecting
|
||||
(at least at 4 consecutive bytes)\n - for each pmp entry, execute one
|
||||
access in its associated pmp address region but outside the overlapping/intersecting
|
||||
address range\n - execute one additional access inside the overlapping/intersecting
|
||||
address range\n - NB: obviously, pmp entry configurations with different
|
||||
access-modes (S/U vs. M) cannot be easily mixed in same test\n - NB:
|
||||
obviously, pmp entry configurations with different mstatus.MPRV/MPP values
|
||||
cannot be mixed in same test\n\nCHECK\n - for each pmp entry, access
|
||||
outside the overlapping/intersecting address range should give the expected
|
||||
CHECK result\n - access inside the overlapping/intersecting address range
|
||||
should generate the access-type related access-fault\n\nREUSABILITY\n \
|
||||
\ - if possible, the number of PMP entries (N) is a configurable parameter\n\
|
||||
\ - so a single test function can be reused"
|
||||
pfc: 3
|
||||
test_type: 4
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST51(group) => FTR09-a, FTR09-b and FTR09-c\n [create
|
||||
scenarios where 2 PMP entries with same pmpaddr\n - one without matching
|
||||
permissions or with A=OFF\n - one with matching permissions and A=NA4/NAPOT/TOR\n\
|
||||
\ - any of them can be the lowest-numbered PMP entry]\nTST51-1\n[configure
|
||||
2 PMP entries\n - configure the lowest-numbered PMP entry with (TST11-12,
|
||||
TST11-22, TST11-32, TST11-42, TST11-52,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST11-15, TST11-25, TST11-35, TST11-45, TST11-55,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST12-12, TST12-22,
|
||||
TST12-32, TST12-42, TST12-52,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST12-15, TST12-25, TST12-35, TST12-45, TST12-55,\n \
|
||||
\ TST13-12, TST13-22, TST13-32, TST13-42,
|
||||
TST13-52,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST13-15,
|
||||
TST13-25, TST13-35, TST13-45, TST13-55,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST14-12, TST14-22, TST14-32, TST14-42, TST14-52,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST14-15, TST14-25,
|
||||
TST14-35, TST14-45, TST14-55,\n \
|
||||
\ TST15-12, TST15-22, TST15-32, TST15-42, TST15-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST15-15, TST15-25, TST15-35,
|
||||
TST15-45, TST15-55,\n \t\t\t\t\t\t\t\t\t \t\t\t\t
|
||||
TST16-12, TST16-22, TST16-32, TST16-42, TST16-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST16-15, TST16-25, TST16-35, TST16-45,
|
||||
TST16-55,\n TST17-12,
|
||||
TST17-22, TST17-32, TST17-42, TST17-52,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST17-15, TST17-25, TST17-35, TST17-45, TST17-55,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST18-12, TST18-22,
|
||||
TST18-32, TST18-42, TST18-52,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST18-15, TST18-25, TST18-35, TST18-45, TST18-55)\n - configure
|
||||
the highest-numbered PMP entry with (TST11-11, TST11-21, TST11-31, TST11-41,
|
||||
TST11-51,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST11-14,
|
||||
TST11-24, TST11-34, TST11-44, TST11-54,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST12-11, TST12-21, TST12-31, TST12-41, TST12-51,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST12-14, TST12-24,
|
||||
TST12-34, TST12-44, TST12-54,\n \
|
||||
\ TST13-11, TST13-21, TST13-31, TST13-41, TST13-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t\tTST13-14, TST13-24, TST13-34,
|
||||
TST13-44, TST13-54,\n \t\t\t\t\t\t\t\t\t \t\t\t\t
|
||||
\tTST14-11, TST14-21, TST14-31, TST14-41, TST14-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t\tTST14-14, TST14-24, TST14-34, TST14-44,
|
||||
TST14-54,\n TST15-11,
|
||||
TST15-21, TST15-31, TST15-41, TST15-51,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST15-14, TST15-24, TST15-34, TST15-44, TST15-54,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST16-11, TST16-21,
|
||||
TST16-31, TST16-41, TST16-51,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST16-14, TST16-24, TST16-34, TST16-44, TST16-54)\n - execute
|
||||
the associated access\n - check associated access-fault exception raised]"
|
||||
- 005_2_intersecting_entries_succeed: !Subfeature
|
||||
name: 005_2_intersecting_entries_succeed
|
||||
tag: VP_PMP_F023_S006
|
||||
next_elt_id: 1
|
||||
display_order: 5
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F023_S006_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any 2 PMP entries\n\nCONFIGURATION and ACCESS (Cf. Feature:
|
||||
\"cfg TOR access S/U/M\")\n - for the least-numbered pmp entry, apply
|
||||
any CONFIGURATION+ACCESS scenario without access-fault\n - for the highest-numbered
|
||||
pmp entry, apply any CONFIGURATION+ACCESS scenario with access-fault\n \
|
||||
\ - make sure the pmp entries address ranges are overlapping/intersecting
|
||||
(at least at 4 consecutive bytes)\n - for each pmp entry, execute one
|
||||
access in its associated pmp address region but outside the overlapping/intersecting
|
||||
address range\n - execute one additional access inside the overlapping/intersecting
|
||||
address range\n - NB: obviously, pmp entry configurations with different
|
||||
access-modes (S/U vs. M) cannot be easily mixed in same test\n - NB:
|
||||
obviously, pmp entry configurations with different mstatus.MPRV/MPP values
|
||||
cannot be mixed in same test\n\nCHECK\n - for each pmp entry, access
|
||||
outside the overlapping/intersecting address range should give the expected
|
||||
CHECK result\n - access inside the overlapping/intersecting address range
|
||||
should not generate any access-fault\n\nREUSABILITY\n - if possible,
|
||||
the number of PMP entries (N) is a configurable parameter\n - so a single
|
||||
test function can be reused"
|
||||
pfc: 3
|
||||
test_type: 4
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST51(group) => FTR09-a, FTR09-b and FTR09-c\n [create
|
||||
scenarios where 2 PMP entries with same pmpaddr\n - one without matching
|
||||
permissions or with A=OFF\n - one with matching permissions and A=NA4/NAPOT/TOR\n\
|
||||
\ - any of them can be the lowest-numbered PMP entry]\nTST51-2\n[configure
|
||||
2 PMP entries\n - configure the lowest-numbered PMP entry with (TST11-11,
|
||||
TST11-21, TST11-31, TST11-41, TST11-51,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST11-14, TST11-24, TST11-34, TST11-44, TST11-54,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST12-11, TST12-21,
|
||||
TST12-31, TST12-41, TST12-51,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST12-14, TST12-24, TST12-34, TST12-44, TST12-54,\n \
|
||||
\ TST13-11, TST13-21, TST13-31, TST13-41,
|
||||
TST13-51,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST13-14,
|
||||
TST13-24, TST13-34, TST13-44, TST13-54,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST14-11, TST14-21, TST14-31, TST14-41, TST14-51,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST14-14, TST14-24,
|
||||
TST14-34, TST14-44, TST14-54,\n \
|
||||
\ TST15-11, TST15-21, TST15-31, TST15-41, TST15-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST15-14, TST15-24, TST15-34,
|
||||
TST15-44, TST15-54,\n \t\t\t\t\t\t\t\t\t \t\t\t\t
|
||||
TST16-11, TST16-21, TST16-31, TST16-41, TST16-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST16-14, TST16-24, TST16-34, TST16-44,
|
||||
TST16-54)\n - configure the highest-numbered PMP entry with (TST11-12,
|
||||
TST11-22, TST11-32, TST11-42, TST11-52,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST11-15, TST11-25, TST11-35, TST11-45, TST11-55,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST12-12, TST12-22,
|
||||
TST12-32, TST12-42, TST12-52,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST12-15, TST12-25, TST12-35, TST12-45, TST12-55,\n \
|
||||
\ TST13-12, TST13-22, TST13-32,
|
||||
TST13-42, TST13-52,\n \t\t\t\t\t\t\t\t\t \t\t\t\t\
|
||||
\ TST13-15, TST13-25, TST13-35, TST13-45, TST13-55,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST14-12, TST14-22, TST14-32, TST14-42,
|
||||
TST14-52,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST14-15,
|
||||
TST14-25, TST14-35, TST14-45, TST14-55,\n \
|
||||
\ TST15-12, TST15-22, TST15-32, TST15-42, TST15-52,\n\
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST15-15, TST15-25,
|
||||
TST15-35, TST15-45, TST15-55,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t\t\t TST16-12, TST16-22, TST16-32, TST16-42, TST16-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST16-15, TST16-25, TST16-35,
|
||||
TST16-45, TST16-55,\n \
|
||||
\ TST17-12, TST17-22, TST17-32, TST17-42, TST17-52,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t \t\t\t\t TST17-15, TST17-25, TST17-35, TST17-45,
|
||||
TST17-55,\n \t\t\t\t\t\t\t\t\t \t\t\t\t TST18-12,
|
||||
TST18-22, TST18-32, TST18-42, TST18-52,\n \t\t\t\t
|
||||
\t\t\t\t\t \t\t\t\t TST18-15, TST18-25, TST18-35, TST18-45, TST18-55)\n\
|
||||
\ - execute the associated access\n - check no access-fault exception]"
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
200
verif/docs/VerifPlans/PMP/VP_IP024.yml
Normal file
200
verif/docs/VerifPlans/PMP/VP_IP024.yml
Normal file
|
@ -0,0 +1,200 @@
|
|||
!Feature
|
||||
next_elt_id: 4
|
||||
name: multi entries OFF
|
||||
id: 24
|
||||
display_order: 24
|
||||
subfeatures: !!omap
|
||||
- 000_1_entry: !Subfeature
|
||||
name: 000_1_entry
|
||||
tag: VP_PMP_F024_S001
|
||||
next_elt_id: 1
|
||||
display_order: 0
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F024_S001_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose a single PMP entry\n\nCONFIGURATION and ACCESS\n -
|
||||
for each pmp entry, apply any CONFIGURATION+ACCESS scenario above (Cf. Feature:
|
||||
\"cfg OFF access S/U/M\")\n - make sure the pmp entries address ranges
|
||||
are not overlapping/intersecting\n - NB: obviously, pmp entry configurations
|
||||
with different mstatus.MPRV/MPP values cannot be mixed in same test\n\n\
|
||||
CHECK\n - for each pmp entry, we should obtain the expected CHECK result\n\
|
||||
\nREUSABILITY\n - if possible, the number of PMP entries (N) is a configurable
|
||||
parameter\n - so a single test function can be reused"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST24(group) => FTR09-g\n [create scenarios where PMP
|
||||
entries with A=0 (OFF) and with matching permissions\n - check no address
|
||||
matching for those PMP entries]\n [create scenarios where all PMP entries
|
||||
with A=0 (OFF) and with matching permissions\n - check no address matching
|
||||
for all PMP entries]\n [check S or U mode access fails when all A=OFF with
|
||||
at least one PMP entry implemented] => FTR09-g\nTST24-1 = extension of (TST17-11,
|
||||
TST17-21, TST17-31, TST17-41, TST17-51,\n TST17-13,
|
||||
TST17-23, TST17-33, TST17-43, TST17-53,\n TST17-14,
|
||||
TST17-24, TST17-34, TST17-44, TST17-54,\n TST17-16,
|
||||
TST17-26, TST17-36, TST17-46, TST17-56,\n TST18-14,
|
||||
TST18-24, TST18-34, TST18-44, TST18-54, //TODO: M-mode may not raise an
|
||||
exception\n TST18-16, TST18-26, TST18-36, TST18-46,
|
||||
TST18-56) //TODO: M-mode may not raise an exception\n \
|
||||
\ //TODO: SHOULD WE ADD (TST18-11, TST18-21, TST18-31, TST18-41, TST18-51,\n\
|
||||
\ TST18-13, TST18-23, TST18-33,
|
||||
TST18-43, TST18-53) ?\n[configure only one (any, but the first one) PMP
|
||||
entry\n - execute the chosen kind of access\n - check appropriate access-fault
|
||||
exception raised]"
|
||||
- 001_2_isolated_entries: !Subfeature
|
||||
name: 001_2_isolated_entries
|
||||
tag: VP_PMP_F024_S002
|
||||
next_elt_id: 1
|
||||
display_order: 1
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F024_S002_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any 2 PMP entries\n\nreuse of VP_PMP_F024_S001_I000 feature
|
||||
description (Cf. Feature: \"multi entries OFF\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST24(group) => FTR09-g\n [create scenarios where PMP
|
||||
entries with A=0 (OFF) and with matching permissions\n - check no address
|
||||
matching for those PMP entries]\n [create scenarios where all PMP entries
|
||||
with A=0 (OFF) and with matching permissions\n - check no address matching
|
||||
for all PMP entries]\n [check S or U mode access fails when all A=OFF with
|
||||
at least one PMP entry implemented] => FTR09-g\nTST24-2 = extension of compatible
|
||||
pair of (TST17-11, TST17-21, TST17-31, TST17-41, TST17-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t TST17-13, TST17-23, TST17-33, TST17-43,
|
||||
TST17-53,\n \t\t\t\t\t\t\t\t\t TST17-14, TST17-24,
|
||||
TST17-34, TST17-44, TST17-54,\n \t\t\t\t\t\t\t\t
|
||||
\t TST17-16, TST17-26, TST17-36, TST17-46, TST17-56,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t TST18-14, TST18-24, TST18-34, TST18-44, TST18-54,
|
||||
//TODO: M-mode may not raise an exception\n \t\t
|
||||
\t\t\t\t\t\t\t TST18-16, TST18-26, TST18-36, TST18-46, TST18-56) //TODO:
|
||||
M-mode may not raise an exception\n //TODO: SHOULD
|
||||
WE ADD (TST18-11, TST18-21, TST18-31, TST18-41, TST18-51,\n \
|
||||
\ TST18-13, TST18-23, TST18-33, TST18-43,
|
||||
TST18-53) ?\n[configure 2 non-adjacent PMP entries (highest-numbered ones
|
||||
first) (avoid the first PMP entry)\n - execute the 2 kinds of accesses
|
||||
(if possible to chain due to access-fault)\n - check 2 appropriate access-fault
|
||||
exceptions raised]"
|
||||
- 002_N_isolated_entries: !Subfeature
|
||||
name: 002_N_isolated_entries
|
||||
tag: VP_PMP_F024_S003
|
||||
next_elt_id: 1
|
||||
display_order: 2
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F024_S003_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose any N PMP entries (2<N<8)\n\nreuse of VP_PMP_F024_S001_I000
|
||||
feature description (Cf. Feature: \"multi entries OFF\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST24(group) => FTR09-g\n [create scenarios where PMP
|
||||
entries with A=0 (OFF) and with matching permissions\n - check no address
|
||||
matching for those PMP entries]\n [create scenarios where all PMP entries
|
||||
with A=0 (OFF) and with matching permissions\n - check no address matching
|
||||
for all PMP entries]\n [check S or U mode access fails when all A=OFF with
|
||||
at least one PMP entry implemented] => FTR09-g\nTST24-3 = extension of compatible
|
||||
group(N) of (TST17-11, TST17-21, TST17-31, TST17-41, TST17-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t\t TST17-13, TST17-23, TST17-33, TST17-43,
|
||||
TST17-53,\n \t\t\t\t\t\t\t\t\t\t TST17-14, TST17-24,
|
||||
TST17-34, TST17-44, TST17-54,\n \t\t\t\t\t\t\t\t
|
||||
\t\t TST17-16, TST17-26, TST17-36, TST17-46, TST17-56,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t\t TST18-14, TST18-24, TST18-34, TST18-44,
|
||||
TST18-54, //TODO: M-mode may not raise an exception\n \
|
||||
\ \t\t\t\t\t\t\t\t\t\t TST18-16, TST18-26, TST18-36, TST18-46, TST18-56)
|
||||
//TODO: M-mode may not raise an exception\n //TODO:
|
||||
SHOULD WE ADD (TST18-11, TST18-21, TST18-31, TST18-41, TST18-51,\n \
|
||||
\ TST18-13, TST18-23, TST18-33,
|
||||
TST18-43, TST18-53) ?\n[configure N PMP entries (highest-numbered ones first)
|
||||
(as non-adjacent as possible, and avoid the first PMP entry)\n - execute
|
||||
the N kinds of accesses (if possible to chain due to access-fault)\n -
|
||||
check N appropriate access-fault exceptions raised]"
|
||||
- 003_8_isolated_entries: !Subfeature
|
||||
name: 003_8_isolated_entries
|
||||
tag: VP_PMP_F024_S004
|
||||
next_elt_id: 1
|
||||
display_order: 3
|
||||
items: !!omap
|
||||
- '000': !VerifItem
|
||||
name: '000'
|
||||
tag: VP_PMP_F024_S004_I000
|
||||
description: "{Page 57 Section \"3.7.1 Physical Memory Protection CSRs\" Volume
|
||||
II: RISC-V Privileged Architectures V20211203}\n\nUp to 64 PMP entries are
|
||||
supported"
|
||||
reqt_doc: ''
|
||||
ref_mode: page
|
||||
ref_page: ''
|
||||
ref_section: ''
|
||||
ref_viewer: firefox
|
||||
verif_goals: "choose all 8 PMP entries\n\nreuse of VP_PMP_F024_S001_I000 feature
|
||||
description (Cf. Feature: \"multi entries OFF\")"
|
||||
pfc: 3
|
||||
test_type: 3
|
||||
cov_method: 1
|
||||
cores: -1
|
||||
coverage_loc: ''
|
||||
comments: "<< link to the old pmp_verif_plan.txt and pmp_verif_plan_features.txt
|
||||
files (not up-to-date) : reading below not mandatory but may help for better
|
||||
understanding >>\n\nTST24(group) => FTR09-g\n [create scenarios where PMP
|
||||
entries with A=0 (OFF) and with matching permissions\n - check no address
|
||||
matching for those PMP entries]\n [create scenarios where all PMP entries
|
||||
with A=0 (OFF) and with matching permissions\n - check no address matching
|
||||
for all PMP entries]\n [check S or U mode access fails when all A=OFF with
|
||||
at least one PMP entry implemented] => FTR09-g\nTST24-4 = extension of compatible
|
||||
group(8) of (TST17-11, TST17-21, TST17-31, TST17-41, TST17-51,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t\t\t TST17-13, TST17-23, TST17-33, TST17-43,
|
||||
TST17-53,\n \t\t\t\t\t\t\t\t\t\t\t TST17-14, TST17-24,
|
||||
TST17-34, TST17-44, TST17-54,\n \t\t\t\t\t\t\t\t\t
|
||||
\t\t TST17-16, TST17-26, TST17-36, TST17-46, TST17-56,\n \
|
||||
\ \t\t\t\t\t\t\t\t\t\t\t TST18-14, TST18-24, TST18-34, TST18-44,
|
||||
TST18-54, //TODO: M-mode may not raise an exception\n \
|
||||
\ \t\t\t\t\t\t\t\t\t\t\t TST18-16, TST18-26, TST18-36, TST18-46, TST18-56)
|
||||
//TODO: M-mode may not raise an exception\n //TODO:
|
||||
SHOULD WE ADD (TST18-11, TST18-21, TST18-31, TST18-41, TST18-51,\n \
|
||||
\ TST18-13, TST18-23, TST18-33,
|
||||
TST18-43, TST18-53) ?\n[configure 8 PMP entries (highest-numbered ones first)\n\
|
||||
\ - execute the 8 kinds of accesses (if possible to chain due to access-fault)\n\
|
||||
\ - check 8 appropriate access-fault exceptions raised]"
|
||||
vptool_gitrev: '$Id: a8b561f68549658061625891c533e7d45996bc9e $'
|
||||
io_fmt_gitrev: '$Id: 61ab4e53ca49e21d56c416f0af0fa04d148e8001 $'
|
||||
config_gitrev: '$Id: 5192fced2cfa10be5e18e827922e31e7489ed987 $'
|
||||
ymlcfg_gitrev: '$Id: ce5e73bd5e8e0099334cb657afb7a624a99afbda $'
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue