mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-20 04:07:36 -04:00
Compare commits
78 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 | ||
|
2ef1c1b1fc | ||
|
fd8c890def | ||
|
70972dad54 | ||
|
10fced1c99 | ||
|
0ec65198bc | ||
|
a3372c51f0 | ||
|
07f19ea319 | ||
|
59822e7ad1 | ||
|
be5ac20e46 | ||
|
3e8eb88e88 | ||
|
542fe39adc | ||
|
fb4a8d4472 | ||
|
3ebb510374 | ||
|
9d039197d1 | ||
|
024b8eada8 | ||
|
cbb08e8d19 | ||
|
3ce44b1b4e | ||
|
664c515b22 | ||
|
c19a3c1ace | ||
|
45aa060b5c | ||
|
14998fc161 | ||
|
f80c507aea | ||
|
b9886a27a2 | ||
|
02092dbcf0 | ||
|
24c6a891b8 | ||
|
fb899feec1 | ||
|
b6b259914a | ||
|
023e67e9be | ||
|
98604b5920 | ||
|
7bdfa5f63e | ||
|
8e5872c03b | ||
|
3d2ff00b1c | ||
|
e840a61e80 | ||
|
7af0f2e4d1 | ||
|
41c22069a0 | ||
|
5518a41c08 | ||
|
21b247dca7 | ||
|
86c53c5334 |
186 changed files with 42629 additions and 1974 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}
|
||||
|
@ -170,6 +170,8 @@ smoke-gen:
|
|||
SPIKE_TANDEM: 1
|
||||
script:
|
||||
- bash verif/regress/smoke-gen_tests.sh
|
||||
- cp verif/sim/seedlist.yaml artifacts/logs/
|
||||
- cp verif/sim/uvm_seed.log artifacts/logs/
|
||||
- !reference [.simu_after_script]
|
||||
|
||||
smoke-bench:
|
||||
|
@ -302,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:
|
||||
|
@ -451,6 +467,7 @@ generated_tests:
|
|||
- source verif/regress/dv-generated-tests.sh
|
||||
- mv verif/sim/vcs_results/default/vcs.d/simv.vdb artifacts/coverage
|
||||
- mv verif/sim/seedlist.yaml artifacts/coverage
|
||||
- mv verif/sim/uvm_seed.log artifacts/coverage
|
||||
- python3 .gitlab-ci/scripts/report_pass.py
|
||||
|
||||
.generated_xif_tests:
|
||||
|
@ -471,6 +488,7 @@ generated_tests:
|
|||
- source verif/regress/dv-generated-xif-tests.sh
|
||||
- mv verif/sim/vcs_results/default/vcs.d/simv.vdb artifacts/coverage
|
||||
- mv verif/sim/seedlist.yaml artifacts/coverage
|
||||
- mv verif/sim/uvm_seed.log artifacts/coverage
|
||||
- python3 .gitlab-ci/scripts/report_pass.py
|
||||
|
||||
directed_isacov-tests:
|
||||
|
@ -490,6 +508,7 @@ directed_isacov-tests:
|
|||
- mkdir -p artifacts/coverage
|
||||
- source verif/regress/dv-generated-tests.sh
|
||||
- mv verif/sim/vcs_results/default/vcs.d/simv.vdb artifacts/coverage
|
||||
- mv verif/sim/uvm_seed.log artifacts/coverage
|
||||
- python3 .gitlab-ci/scripts/report_pass.py
|
||||
|
||||
csr_embedded_tests:
|
||||
|
@ -506,6 +525,7 @@ csr_embedded_tests:
|
|||
- mkdir -p artifacts/coverage
|
||||
- source verif/regress/dv-csr-embedded-tests.sh
|
||||
- mv verif/sim/vcs_results/default/vcs.d/simv.vdb artifacts/coverage
|
||||
- mv verif/sim/uvm_seed.log artifacts/coverage
|
||||
- python3 .gitlab-ci/scripts/report_tandem.py verif/sim/out*/"$DV_SIMULATORS"_sim
|
||||
|
||||
.backend_test:
|
||||
|
@ -537,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
|
||||
|
@ -604,6 +624,7 @@ code_coverage-report:
|
|||
- mkdir -p verif/sim/vcs_results/default/vcs.d
|
||||
- mv artifacts/coverage/simv.vdb verif/sim/vcs_results/default/vcs.d/
|
||||
- mv artifacts/coverage/seedlist.yaml verif/sim/seedlist.yaml
|
||||
- mv artifacts/coverage/uvm_seed.log verif/sim/uvm_seed.log
|
||||
- make -C verif/sim generate_cov_dash
|
||||
- mv verif/sim/urgReport artifacts/cov_reports/
|
||||
- python3 .gitlab-ci/scripts/report_coverage.py artifacts/cov_reports/urgReport/hierarchy.txt artifacts/cov_reports/urgReport/"feature.CVA6 Verification Master Plan1.7.-1268999905.txt"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -7,6 +7,7 @@ version: 2
|
|||
submodules:
|
||||
include:
|
||||
- docs/riscv-isa/riscv-isa-manual
|
||||
recursive: true
|
||||
|
||||
build:
|
||||
os: "ubuntu-20.04"
|
||||
|
@ -26,7 +27,7 @@ build:
|
|||
- npm install docs/riscv-isa/riscv-isa-manual/dependencies
|
||||
- gem install -g docs/riscv-isa/riscv-isa-manual/dependencies/Gemfile
|
||||
pre_build:
|
||||
- make -C docs prepare
|
||||
- PATH=$PWD/node_modules/.bin:$PATH make -C docs prepare
|
||||
|
||||
# Build from the docs directory with Sphinx
|
||||
sphinx:
|
||||
|
|
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)
|
||||
|
|
14
README.md
14
README.md
|
@ -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"/>
|
||||
|
||||
|
||||
|
@ -167,9 +170,14 @@ To generate VCD waveforms of the `smoke-tests` regression suite using Verilator,
|
|||
```sh
|
||||
export DV_SIMULATORS=veri-testharness,spike
|
||||
export TRACE_FAST=1
|
||||
bash verif/regress/smoke-tests.sh
|
||||
bash verif/regress/smoke-tests-<cpu_version>.sh
|
||||
```
|
||||
|
||||
Where `<cpu_version>` is one of the following, depending on the CPU variant you want to use.
|
||||
- `cv32a65x`.
|
||||
- `cv32a6_imac_sv32`.
|
||||
- `cv64a6_imafdc_sv39`.
|
||||
|
||||
After each simulation run involving Verilator or VCS, the generated waveforms
|
||||
will be copied to the directory containing the log files (see above,) with
|
||||
the name of the current HW configuration added to the file name right before
|
||||
|
@ -403,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
|
||||
|
||||
// --------------------
|
||||
|
|
|
@ -52,6 +52,7 @@ spike_param_tree:
|
|||
pmpaddr5_write_mask: 0xFFFFFFFE
|
||||
pmpaddr6_write_mask: 0xFFFFFFFE
|
||||
pmpaddr7_write_mask: 0xFFFFFFFE
|
||||
mtvec_write_mask: 0xFFFFFFFE
|
||||
mhartid: 0
|
||||
mvendorid_override_mask : 0xFFFFFFFF
|
||||
mvendorid_override_value: 1538
|
||||
|
|
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
|
|
@ -112,6 +112,7 @@ ${CVA6_REPO_DIR}/core/branch_unit.sv
|
|||
${CVA6_REPO_DIR}/core/compressed_decoder.sv
|
||||
${CVA6_REPO_DIR}/core/macro_decoder.sv
|
||||
${CVA6_REPO_DIR}/core/controller.sv
|
||||
${CVA6_REPO_DIR}/core/zcmt_decoder.sv
|
||||
${CVA6_REPO_DIR}/core/csr_buffer.sv
|
||||
${CVA6_REPO_DIR}/core/csr_regfile.sv
|
||||
${CVA6_REPO_DIR}/core/decoder.sv
|
||||
|
@ -143,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)
|
||||
|
|
|
@ -31,6 +31,8 @@ module branch_unit #(
|
|||
input fu_data_t fu_data_i,
|
||||
// Instruction PC - ISSUE_STAGE
|
||||
input logic [CVA6Cfg.VLEN-1:0] pc_i,
|
||||
// Is zcmt instruction - ISSUE_STAGE
|
||||
input logic is_zcmt_i,
|
||||
// Instruction is compressed - ISSUE_STAGE
|
||||
input logic is_compressed_instr_i,
|
||||
// Branch unit instruction is valid - ISSUE_STAGE
|
||||
|
@ -58,7 +60,6 @@ module branch_unit #(
|
|||
// TODO(zarubaf): The ALU can be used to calculate the branch target
|
||||
jump_base = (fu_data_i.operation == ariane_pkg::JALR) ? fu_data_i.operand_a[CVA6Cfg.VLEN-1:0] : pc_i;
|
||||
|
||||
target_address = {CVA6Cfg.VLEN{1'b0}};
|
||||
resolve_branch_o = 1'b0;
|
||||
resolved_branch_o.target_address = {CVA6Cfg.VLEN{1'b0}};
|
||||
resolved_branch_o.is_taken = 1'b0;
|
||||
|
@ -75,13 +76,21 @@ module branch_unit #(
|
|||
// we need to put the branch target address into rd, this is the result of this unit
|
||||
branch_result_o = next_pc;
|
||||
resolved_branch_o.pc = pc_i;
|
||||
// There are only two sources of mispredicts:
|
||||
// There are only three sources of mispredicts:
|
||||
// 1. Branches
|
||||
// 2. Jumps to register addresses
|
||||
// 3. Zcmt instructions
|
||||
if (branch_valid_i) begin
|
||||
// write target address which goes to PC Gen
|
||||
// write target address which goes to PC Gen or select target address if zcmt
|
||||
resolved_branch_o.target_address = (branch_comp_res_i) ? target_address : next_pc;
|
||||
resolved_branch_o.is_taken = branch_comp_res_i;
|
||||
if (CVA6Cfg.RVZCMT) begin
|
||||
if (is_zcmt_i) begin
|
||||
// Unconditional jump handling
|
||||
resolved_branch_o.is_mispredict = 1'b1; // miss prediction for ZCMT
|
||||
resolved_branch_o.cf_type = ariane_pkg::JumpR;
|
||||
end
|
||||
end
|
||||
// check the outcome of the branch speculation
|
||||
if (ariane_pkg::op_is_branch(fu_data_i.operation)) begin
|
||||
// Set the `cf_type` of the output as `branch`, this will update the BHT.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -188,10 +188,10 @@ module wt_dcache
|
|||
// read controllers (LD unit and PTW/MMU)
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
// 0 is used by MMU, 1 by READ access requests
|
||||
// 0 is used by MMU or implicit read by zcmt, 1 by READ access requests
|
||||
for (genvar k = 0; k < NumPorts - 1; k++) begin : gen_rd_ports
|
||||
// set these to high prio ports
|
||||
if ((k == 0 && CVA6Cfg.MmuPresent) || (k == 1) || (k == 2 && CVA6Cfg.EnableAccelerator)) begin
|
||||
if ((k == 0 && (CVA6Cfg.MmuPresent || CVA6Cfg.RVZCMT )) || (k == 1) || (k == 2 && CVA6Cfg.EnableAccelerator)) begin
|
||||
assign rd_prio[k] = 1'b1;
|
||||
wt_dcache_ctrl #(
|
||||
.CVA6Cfg(CVA6Cfg),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -115,9 +115,8 @@ module commit_stage
|
|||
for (int i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
|
||||
dirty_fp_state_o |= commit_ack_o[i] & (commit_instr_i[i].fu inside {FPU, FPU_VEC} || (CVA6Cfg.FpPresent && ariane_pkg::is_rd_fpr(
|
||||
commit_instr_i[i].op
|
||||
)));
|
||||
// Check if we issued a vector floating-point instruction to the accellerator
|
||||
dirty_fp_state_o |= commit_instr_i[i].fu == ACCEL && commit_instr_i[i].vfp;
|
||||
// Check if we issued a vector floating-point instruction to the accellerator
|
||||
))) | commit_instr_i[i].fu == ACCEL && commit_instr_i[i].vfp;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -302,10 +301,10 @@ module commit_stage
|
|||
end
|
||||
|
||||
if (CVA6Cfg.NrCommitPorts > 1) begin
|
||||
|
||||
commit_ack_o[1] = 1'b0;
|
||||
we_gpr_o[1] = 1'b0;
|
||||
wdata_o[1] = commit_instr_i[1].result;
|
||||
commit_macro_ack[1] = 1'b0;
|
||||
commit_ack_o[1] = 1'b0;
|
||||
we_gpr_o[1] = 1'b0;
|
||||
wdata_o[1] = commit_instr_i[1].result;
|
||||
|
||||
// -----------------
|
||||
// Commit Port 2
|
||||
|
@ -351,10 +350,9 @@ module commit_stage
|
|||
end
|
||||
end
|
||||
if (CVA6Cfg.RVZCMP) begin
|
||||
if (CVA6Cfg.NrCommitPorts > 1)
|
||||
commit_macro_ack_o = (commit_instr_i[0].is_macro_instr || commit_instr_i[1].is_macro_instr) ? commit_macro_ack : commit_ack_o;
|
||||
else
|
||||
commit_macro_ack_o = (commit_instr_i[0].is_macro_instr) ? commit_macro_ack : commit_ack_o;
|
||||
for (int i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
|
||||
commit_macro_ack_o[i] = commit_instr_i[i].is_macro_instr ? commit_macro_ack[i] : commit_ack_o[i];
|
||||
end
|
||||
end else commit_macro_ack_o = commit_ack_o;
|
||||
end
|
||||
|
||||
|
|
|
@ -31,7 +31,9 @@ module compressed_decoder #(
|
|||
// Output instruction is macro - decoder
|
||||
output logic is_macro_instr_o,
|
||||
// Output instruction is compressed - decoder
|
||||
output logic is_compressed_o
|
||||
output logic is_compressed_o,
|
||||
// Output instruction is macro - decoder
|
||||
output logic is_zcmt_instr_o
|
||||
);
|
||||
|
||||
// -------------------
|
||||
|
@ -42,6 +44,7 @@ module compressed_decoder #(
|
|||
is_compressed_o = 1'b1;
|
||||
instr_o = instr_i;
|
||||
is_macro_instr_o = 0;
|
||||
is_zcmt_instr_o = 1'b0;
|
||||
|
||||
// I: | imm[11:0] | rs1 | funct3 | rd | opcode |
|
||||
// S: | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode |
|
||||
|
@ -867,18 +870,13 @@ module compressed_decoder #(
|
|||
3'b000,
|
||||
riscv::OpcodeStoreFp
|
||||
};
|
||||
end else if (CVA6Cfg.RVZCMP) begin
|
||||
if (instr_i[12:10] == 3'b110 || instr_i[12:10] == 3'b111 || instr_i[12:10] == 3'b011) begin //is a push/pop instruction
|
||||
is_macro_instr_o = 1;
|
||||
instr_o = instr_i;
|
||||
end else begin
|
||||
illegal_instr_o = 1'b1;
|
||||
end
|
||||
end else begin
|
||||
illegal_instr_o = 1'b1;
|
||||
end
|
||||
end else if (CVA6Cfg.RVZCMP && (instr_i[12:10] == 3'b110 || instr_i[12:10] == 3'b111 || instr_i[12:10] == 3'b011)) begin
|
||||
is_macro_instr_o = 1;
|
||||
instr_o = instr_i;
|
||||
end else if (CVA6Cfg.RVZCMT && (instr_i[12:10] == 3'b000)) //jt/jalt instruction
|
||||
is_zcmt_instr_o = 1'b1;
|
||||
else illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
riscv::OpcodeC2Swsp: begin
|
||||
// c.swsp -> sw rs2, imm(x2)
|
||||
instr_o = {
|
||||
|
|
|
@ -18,6 +18,7 @@ module csr_regfile
|
|||
#(
|
||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||
parameter type exception_t = logic,
|
||||
parameter type jvt_t = logic,
|
||||
parameter type irq_ctrl_t = logic,
|
||||
parameter type scoreboard_entry_t = logic,
|
||||
parameter type rvfi_probes_csr_t = logic,
|
||||
|
@ -161,13 +162,15 @@ 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
|
||||
output rvfi_probes_csr_t rvfi_csr_o
|
||||
output rvfi_probes_csr_t rvfi_csr_o,
|
||||
//jvt output
|
||||
output jvt_t jvt_o
|
||||
);
|
||||
|
||||
localparam logic [63:0] SMODE_STATUS_READ_MASK = ariane_pkg::smode_status_read_mask(CVA6Cfg);
|
||||
|
@ -295,6 +298,7 @@ module csr_regfile
|
|||
assign pmpaddr_o = pmpaddr_q[(CVA6Cfg.NrPMPEntries>0?CVA6Cfg.NrPMPEntries-1 : 0):0];
|
||||
|
||||
riscv::fcsr_t fcsr_q, fcsr_d;
|
||||
jvt_t jvt_q, jvt_d;
|
||||
// ----------------
|
||||
// Assignments
|
||||
// ----------------
|
||||
|
@ -350,6 +354,13 @@ module csr_regfile
|
|||
read_access_exception = 1'b1;
|
||||
end
|
||||
end
|
||||
riscv::CSR_JVT: begin
|
||||
if (CVA6Cfg.RVZCMT) begin
|
||||
csr_rdata = {jvt_q.base, jvt_q.mode};
|
||||
end else begin
|
||||
read_access_exception = 1'b1;
|
||||
end
|
||||
end
|
||||
// non-standard extension
|
||||
riscv::CSR_FTRAN: begin
|
||||
if (CVA6Cfg.FpPresent && !(mstatus_q.fs == riscv::Off || (CVA6Cfg.RVH && v_q && vsstatus_q.fs == riscv::Off))) begin
|
||||
|
@ -773,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
|
||||
|
@ -886,7 +899,7 @@ module csr_regfile
|
|||
// --------------------
|
||||
cycle_d = cycle_q;
|
||||
instret_d = instret_q;
|
||||
if (!debug_mode_q) begin
|
||||
if (!(CVA6Cfg.DebugEn && debug_mode_q)) begin
|
||||
// increase instruction retired counter
|
||||
for (int i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
|
||||
if (commit_ack_i[i] && !ex_i.valid && (!CVA6Cfg.PerfCounterEn || (CVA6Cfg.PerfCounterEn && !mcountinhibit_q[2])))
|
||||
|
@ -908,12 +921,14 @@ module csr_regfile
|
|||
|
||||
perf_we_o = 1'b0;
|
||||
perf_data_o = 'b0;
|
||||
if (CVA6Cfg.RVZCMT) begin
|
||||
jvt_d = jvt_q;
|
||||
end
|
||||
fcsr_d = fcsr_q;
|
||||
|
||||
fcsr_d = fcsr_q;
|
||||
|
||||
priv_lvl_d = priv_lvl_q;
|
||||
v_d = v_q;
|
||||
debug_mode_d = debug_mode_q;
|
||||
priv_lvl_d = priv_lvl_q;
|
||||
v_d = v_q;
|
||||
debug_mode_d = debug_mode_q;
|
||||
|
||||
if (CVA6Cfg.DebugEn) begin
|
||||
dcsr_d = dcsr_q;
|
||||
|
@ -949,7 +964,7 @@ module csr_regfile
|
|||
mcause_d = mcause_q;
|
||||
mcounteren_d = mcounteren_q;
|
||||
mscratch_d = mscratch_q;
|
||||
mtval_d = mtval_q;
|
||||
if (CVA6Cfg.TvalEn) mtval_d = mtval_q;
|
||||
if (CVA6Cfg.RVH) begin
|
||||
mtinst_d = mtinst_q;
|
||||
mtval2_d = mtval2_q;
|
||||
|
@ -1060,6 +1075,14 @@ module csr_regfile
|
|||
riscv::CSR_DSCRATCH1:
|
||||
if (CVA6Cfg.DebugEn) dscratch1_d = csr_wdata;
|
||||
else update_access_exception = 1'b1;
|
||||
riscv::CSR_JVT: begin
|
||||
if (CVA6Cfg.RVZCMT) begin
|
||||
jvt_d.base = csr_wdata[CVA6Cfg.XLEN-1:6];
|
||||
jvt_d.mode = 6'b000000;
|
||||
end else begin
|
||||
update_access_exception = 1'b1;
|
||||
end
|
||||
end
|
||||
// trigger module CSRs
|
||||
riscv::CSR_TSELECT: update_access_exception = 1'b1; // not implemented
|
||||
riscv::CSR_TDATA1: update_access_exception = 1'b1; // not implemented
|
||||
|
@ -1435,9 +1458,14 @@ module csr_regfile
|
|||
| CVA6Cfg.XLEN'(riscv::MIP_MTIP)
|
||||
| CVA6Cfg.XLEN'(riscv::MIP_MEIP);
|
||||
end else begin
|
||||
mask = CVA6Cfg.XLEN'(riscv::MIP_MSIP)
|
||||
| CVA6Cfg.XLEN'(riscv::MIP_MTIP)
|
||||
| CVA6Cfg.XLEN'(riscv::MIP_MEIP);
|
||||
if (CVA6Cfg.SoftwareInterruptEn) begin
|
||||
mask = CVA6Cfg.XLEN'(riscv::MIP_MSIP) // same shift as MSIE
|
||||
| CVA6Cfg.XLEN'(riscv::MIP_MTIP) // same shift as MTIE
|
||||
| CVA6Cfg.XLEN'(riscv::MIP_MEIP); // same shift as MEIE
|
||||
end else begin
|
||||
mask = CVA6Cfg.XLEN'(riscv::MIP_MTIP) // same shift as MTIE
|
||||
| CVA6Cfg.XLEN'(riscv::MIP_MEIP); // same shift as MEIE
|
||||
end
|
||||
end
|
||||
end
|
||||
mie_d = (mie_q & ~mask) | (csr_wdata & mask); // we only support supervisor and M-mode interrupts
|
||||
|
@ -1715,9 +1743,10 @@ module csr_regfile
|
|||
default: update_access_exception = 1'b1;
|
||||
endcase
|
||||
end
|
||||
|
||||
mstatus_d.sxl = riscv::XLEN_64;
|
||||
mstatus_d.uxl = riscv::XLEN_64;
|
||||
if (CVA6Cfg.IS_XLEN64) begin
|
||||
mstatus_d.sxl = riscv::XLEN_64;
|
||||
mstatus_d.uxl = riscv::XLEN_64;
|
||||
end
|
||||
if (!CVA6Cfg.RVU) begin
|
||||
mstatus_d.mpp = riscv::PRIV_LVL_M;
|
||||
end
|
||||
|
@ -1771,7 +1800,7 @@ module csr_regfile
|
|||
// Machine Mode External Interrupt Pending
|
||||
mip_d[riscv::IRQ_M_EXT] = irq_i[0];
|
||||
// Machine software interrupt
|
||||
mip_d[riscv::IRQ_M_SOFT] = ipi_i;
|
||||
mip_d[riscv::IRQ_M_SOFT] = CVA6Cfg.SoftwareInterruptEn && ipi_i;
|
||||
// Timer interrupt pending, coming from platform timer
|
||||
mip_d[riscv::IRQ_M_TIMER] = time_irq_i;
|
||||
|
||||
|
@ -1931,14 +1960,14 @@ module csr_regfile
|
|||
// 3: The debugger requested entry to Debug Mode. (priority 2)
|
||||
// 4: The hart single stepped because step was set. (priority 1)
|
||||
// we are currently not in debug mode and could potentially enter
|
||||
if (!debug_mode_q) begin
|
||||
if (CVA6Cfg.DebugEn && !debug_mode_q) begin
|
||||
dcsr_d.prv = priv_lvl_o;
|
||||
// save virtualization mode bit
|
||||
dcsr_d.v = (!CVA6Cfg.RVH) ? 1'b0 : v_q;
|
||||
// trigger module fired
|
||||
|
||||
// caused by a breakpoint
|
||||
if (CVA6Cfg.DebugEn && ex_i.valid && ex_i.cause == riscv::BREAKPOINT) begin
|
||||
if (ex_i.valid && ex_i.cause == riscv::BREAKPOINT) begin
|
||||
dcsr_d.prv = priv_lvl_o;
|
||||
// save virtualization mode bit
|
||||
dcsr_d.v = (!CVA6Cfg.RVH) ? 1'b0 : v_q;
|
||||
|
@ -1968,7 +1997,7 @@ module csr_regfile
|
|||
end
|
||||
|
||||
// we've got a debug request
|
||||
if (CVA6Cfg.DebugEn && ex_i.valid && ex_i.cause == riscv::DEBUG_REQUEST) begin
|
||||
if (ex_i.valid && ex_i.cause == riscv::DEBUG_REQUEST) begin
|
||||
dcsr_d.prv = priv_lvl_o;
|
||||
dcsr_d.v = (!CVA6Cfg.RVH) ? 1'b0 : v_q;
|
||||
// save the PC
|
||||
|
@ -1982,7 +2011,7 @@ module csr_regfile
|
|||
end
|
||||
|
||||
// single step enable and we just retired an instruction
|
||||
if (CVA6Cfg.DebugEn && dcsr_q.step && commit_ack_i[0]) begin
|
||||
if (dcsr_q.step && commit_ack_i[0]) begin
|
||||
dcsr_d.prv = priv_lvl_o;
|
||||
dcsr_d.v = (!CVA6Cfg.RVH) ? 1'b0 : v_q;
|
||||
// valid CTRL flow change
|
||||
|
@ -2419,7 +2448,7 @@ module csr_regfile
|
|||
|
||||
unique case (conv_csr_addr.address)
|
||||
riscv::CSR_MIP:
|
||||
csr_rdata_o = csr_rdata | ({{CVA6Cfg.XLEN - 1{1'b0}}, irq_i[1]} << riscv::IRQ_S_EXT);
|
||||
csr_rdata_o = csr_rdata | ({{CVA6Cfg.XLEN - 1{1'b0}}, CVA6Cfg.RVS && irq_i[1]} << riscv::IRQ_S_EXT);
|
||||
// in supervisor mode we also need to check whether we delegated this bit
|
||||
riscv::CSR_SIP: begin
|
||||
if (CVA6Cfg.RVS) begin
|
||||
|
@ -2438,8 +2467,16 @@ module csr_regfile
|
|||
assign fflags_o = fcsr_q.fflags;
|
||||
assign frm_o = fcsr_q.frm;
|
||||
assign fprec_o = fcsr_q.fprec;
|
||||
//JVT outputs
|
||||
if (CVA6Cfg.RVZCMT) begin
|
||||
assign jvt_o.base = jvt_q.base;
|
||||
assign jvt_o.mode = jvt_q.mode;
|
||||
end else begin
|
||||
assign jvt_o.base = '0;
|
||||
assign jvt_o.mode = '0;
|
||||
end
|
||||
// MMU outputs
|
||||
assign satp_ppn_o = CVA6Cfg.RVS ? satp_q.ppn : '0;
|
||||
assign satp_ppn_o = CVA6Cfg.RVS ? satp_q.ppn : '0;
|
||||
assign vsatp_ppn_o = CVA6Cfg.RVH ? vsatp_q.ppn : '0;
|
||||
assign hgatp_ppn_o = CVA6Cfg.RVH ? hgatp_q.ppn : '0;
|
||||
if (CVA6Cfg.RVS) begin
|
||||
|
@ -2501,18 +2538,19 @@ module csr_regfile
|
|||
// sequential process
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
priv_lvl_q <= riscv::PRIV_LVL_M;
|
||||
priv_lvl_q <= riscv::PRIV_LVL_M;
|
||||
// floating-point registers
|
||||
fcsr_q <= '0;
|
||||
fcsr_q <= '0;
|
||||
if (CVA6Cfg.RVZCMT) begin
|
||||
jvt_q <= '0;
|
||||
end
|
||||
// debug signals
|
||||
debug_mode_q <= 1'b0;
|
||||
if (CVA6Cfg.DebugEn) begin
|
||||
dcsr_q <= '0;
|
||||
dcsr_q.prv <= riscv::PRIV_LVL_M;
|
||||
dcsr_q.xdebugver <= 4'h4;
|
||||
dpc_q <= '0;
|
||||
dscratch0_q <= {CVA6Cfg.XLEN{1'b0}};
|
||||
dscratch1_q <= {CVA6Cfg.XLEN{1'b0}};
|
||||
debug_mode_q <= 1'b0;
|
||||
dcsr_q <= '{xdebugver: 4'h4, prv: riscv::PRIV_LVL_M, default: '0};
|
||||
dpc_q <= '0;
|
||||
dscratch0_q <= {CVA6Cfg.XLEN{1'b0}};
|
||||
dscratch1_q <= {CVA6Cfg.XLEN{1'b0}};
|
||||
end
|
||||
// machine mode registers
|
||||
mstatus_q <= 64'b0;
|
||||
|
@ -2525,12 +2563,12 @@ module csr_regfile
|
|||
mcause_q <= {CVA6Cfg.XLEN{1'b0}};
|
||||
mcounteren_q <= {CVA6Cfg.XLEN{1'b0}};
|
||||
mscratch_q <= {CVA6Cfg.XLEN{1'b0}};
|
||||
mtval_q <= {CVA6Cfg.XLEN{1'b0}};
|
||||
fiom_q <= '0;
|
||||
dcache_q <= {{CVA6Cfg.XLEN - 1{1'b0}}, 1'b1};
|
||||
icache_q <= {{CVA6Cfg.XLEN - 1{1'b0}}, 1'b1};
|
||||
mcountinhibit_q <= '0;
|
||||
acc_cons_q <= {{CVA6Cfg.XLEN - 1{1'b0}}, CVA6Cfg.EnableAccelerator};
|
||||
if (CVA6Cfg.TvalEn) mtval_q <= {CVA6Cfg.XLEN{1'b0}};
|
||||
fiom_q <= '0;
|
||||
dcache_q <= {{CVA6Cfg.XLEN - 1{1'b0}}, 1'b1};
|
||||
icache_q <= {{CVA6Cfg.XLEN - 1{1'b0}}, 1'b1};
|
||||
mcountinhibit_q <= '0;
|
||||
acc_cons_q <= {{CVA6Cfg.XLEN - 1{1'b0}}, CVA6Cfg.EnableAccelerator};
|
||||
// supervisor mode registers
|
||||
if (CVA6Cfg.RVS) begin
|
||||
medeleg_q <= {CVA6Cfg.XLEN{1'b0}};
|
||||
|
@ -2587,6 +2625,9 @@ module csr_regfile
|
|||
priv_lvl_q <= priv_lvl_d;
|
||||
// floating-point registers
|
||||
fcsr_q <= fcsr_d;
|
||||
if (CVA6Cfg.RVZCMT) begin
|
||||
jvt_q <= jvt_d;
|
||||
end
|
||||
// debug signals
|
||||
if (CVA6Cfg.DebugEn) begin
|
||||
debug_mode_q <= debug_mode_d;
|
||||
|
@ -2708,6 +2749,7 @@ module csr_regfile
|
|||
// RVFI
|
||||
//-------------
|
||||
assign rvfi_csr_o.fcsr_q = CVA6Cfg.FpPresent ? fcsr_q : '0;
|
||||
assign rvfi_csr_o.jvt_q = CVA6Cfg.RVZCMT ? jvt_q : '0;
|
||||
assign rvfi_csr_o.dcsr_q = CVA6Cfg.DebugEn ? dcsr_q : '0;
|
||||
assign rvfi_csr_o.dpc_q = CVA6Cfg.DebugEn ? dpc_q : '0;
|
||||
assign rvfi_csr_o.dscratch0_q = CVA6Cfg.DebugEn ? dscratch0_q : '0;
|
||||
|
@ -2729,7 +2771,7 @@ module csr_regfile
|
|||
assign rvfi_csr_o.mscratch_q = mscratch_q;
|
||||
assign rvfi_csr_o.mepc_q = mepc_q;
|
||||
assign rvfi_csr_o.mcause_q = mcause_q;
|
||||
assign rvfi_csr_o.mtval_q = mtval_q;
|
||||
assign rvfi_csr_o.mtval_q = CVA6Cfg.TvalEn ? mtval_q : '0;
|
||||
assign rvfi_csr_o.fiom_q = fiom_q;
|
||||
assign rvfi_csr_o.mcountinhibit_q = mcountinhibit_q;
|
||||
assign rvfi_csr_o.cycle_q = cycle_q;
|
||||
|
|
134
core/cva6.sv
134
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
|
||||
|
@ -86,6 +86,11 @@ module cva6
|
|||
branchpredict_sbe_t branch_predict; // this field contains branch prediction information regarding the forward branch path
|
||||
exception_t ex; // this field contains exceptions which might have happened earlier, e.g.: fetch exceptions
|
||||
},
|
||||
//JVT struct{base,mode}
|
||||
localparam type jvt_t = struct packed {
|
||||
logic [CVA6Cfg.XLEN-7:0] base;
|
||||
logic [5:0] mode;
|
||||
},
|
||||
|
||||
// ID/EX/WB Stage
|
||||
localparam type scoreboard_entry_t = struct packed {
|
||||
|
@ -113,6 +118,7 @@ module cva6
|
|||
logic is_last_macro_instr; // is last decoded 32bit instruction of macro definition
|
||||
logic is_double_rd_macro_instr; // is double move decoded 32bit instruction of macro definition
|
||||
logic vfp; // is this a vector floating-point instruction?
|
||||
logic is_zcmt; //is a zcmt instruction
|
||||
},
|
||||
localparam type writeback_t = struct packed {
|
||||
logic valid; // wb data is valid
|
||||
|
@ -211,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;
|
||||
|
@ -412,9 +426,12 @@ module cva6
|
|||
// --------------
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] rs1_forwarding_id_ex; // unregistered version of fu_data_o.operanda
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] rs2_forwarding_id_ex; // unregistered version of fu_data_o.operandb
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rvfi_rs1;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rvfi_rs2;
|
||||
|
||||
fu_data_t [CVA6Cfg.NrIssuePorts-1:0] fu_data_id_ex;
|
||||
logic [CVA6Cfg.VLEN-1:0] pc_id_ex;
|
||||
logic zcmt_id_ex;
|
||||
logic is_compressed_instr_id_ex;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] tinst_ex;
|
||||
// fixed latency units
|
||||
|
@ -500,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;
|
||||
|
@ -560,9 +582,11 @@ 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;
|
||||
// ----------------------------
|
||||
// Performance Counters <-> *
|
||||
// ----------------------------
|
||||
|
@ -617,6 +641,8 @@ module cva6
|
|||
// ----------------
|
||||
dcache_req_i_t [2:0] dcache_req_ports_ex_cache;
|
||||
dcache_req_o_t [2:0] dcache_req_ports_cache_ex;
|
||||
dcache_req_i_t dcache_req_ports_id_cache;
|
||||
dcache_req_o_t dcache_req_ports_cache_id;
|
||||
dcache_req_i_t [1:0] dcache_req_ports_acc_cache;
|
||||
dcache_req_o_t [1:0] dcache_req_ports_cache_acc;
|
||||
logic dcache_commit_wbuffer_empty;
|
||||
|
@ -671,8 +697,11 @@ module cva6
|
|||
id_stage #(
|
||||
.CVA6Cfg(CVA6Cfg),
|
||||
.branchpredict_sbe_t(branchpredict_sbe_t),
|
||||
.dcache_req_i_t(dcache_req_i_t),
|
||||
.dcache_req_o_t(dcache_req_o_t),
|
||||
.exception_t(exception_t),
|
||||
.fetch_entry_t(fetch_entry_t),
|
||||
.jvt_t(jvt_t),
|
||||
.irq_ctrl_t(irq_ctrl_t),
|
||||
.scoreboard_entry_t(scoreboard_entry_t),
|
||||
.interrupts_t(interrupts_t),
|
||||
|
@ -716,7 +745,11 @@ module cva6
|
|||
.compressed_ready_i(x_compressed_ready),
|
||||
.compressed_resp_i (x_compressed_resp),
|
||||
.compressed_valid_o(x_compressed_valid),
|
||||
.compressed_req_o (x_compressed_req)
|
||||
.compressed_req_o (x_compressed_req),
|
||||
.jvt_i (jvt),
|
||||
// DCACHE interfaces
|
||||
.dcache_req_ports_i(dcache_req_ports_cache_id),
|
||||
.dcache_req_ports_o(dcache_req_ports_id_cache)
|
||||
);
|
||||
|
||||
logic [CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_ex_id;
|
||||
|
@ -744,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;
|
||||
|
@ -817,6 +851,7 @@ module cva6
|
|||
.rs2_forwarding_o (rs2_forwarding_id_ex),
|
||||
.fu_data_o (fu_data_id_ex),
|
||||
.pc_o (pc_id_ex),
|
||||
.is_zcmt_o (zcmt_id_ex),
|
||||
.is_compressed_instr_o (is_compressed_instr_id_ex),
|
||||
.tinst_o (tinst_ex),
|
||||
// fixed latency unit ready
|
||||
|
@ -879,7 +914,9 @@ module cva6
|
|||
.stall_issue_o (stall_issue),
|
||||
//RVFI
|
||||
.rvfi_issue_pointer_o (rvfi_issue_pointer),
|
||||
.rvfi_commit_pointer_o(rvfi_commit_pointer)
|
||||
.rvfi_commit_pointer_o(rvfi_commit_pointer),
|
||||
.rvfi_rs1_o (rvfi_rs1),
|
||||
.rvfi_rs2_o (rvfi_rs2)
|
||||
);
|
||||
|
||||
// ---------
|
||||
|
@ -898,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),
|
||||
|
@ -908,6 +947,7 @@ module cva6
|
|||
.rs2_forwarding_i(rs2_forwarding_id_ex),
|
||||
.fu_data_i(fu_data_id_ex),
|
||||
.pc_i(pc_id_ex),
|
||||
.is_zcmt_i(zcmt_id_ex),
|
||||
.is_compressed_instr_i(is_compressed_instr_id_ex),
|
||||
.tinst_i(tinst_ex),
|
||||
// fixed latency units
|
||||
|
@ -981,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),
|
||||
|
@ -1078,6 +1121,7 @@ module cva6
|
|||
csr_regfile #(
|
||||
.CVA6Cfg (CVA6Cfg),
|
||||
.exception_t (exception_t),
|
||||
.jvt_t (jvt_t),
|
||||
.irq_ctrl_t (irq_ctrl_t),
|
||||
.scoreboard_entry_t(scoreboard_entry_t),
|
||||
.rvfi_probes_csr_t (rvfi_probes_csr_t),
|
||||
|
@ -1154,6 +1198,7 @@ module cva6
|
|||
.pmpcfg_o (pmpcfg),
|
||||
.pmpaddr_o (pmpaddr),
|
||||
.mcountinhibit_o (mcountinhibit_csr_perf),
|
||||
.jvt_o (jvt),
|
||||
//RVFI
|
||||
.rvfi_csr_o (rvfi_csr)
|
||||
);
|
||||
|
@ -1258,15 +1303,29 @@ module cva6
|
|||
dcache_req_o_t [NumPorts-1:0] dcache_req_from_cache;
|
||||
|
||||
// D$ request
|
||||
assign dcache_req_to_cache[0] = dcache_req_ports_ex_cache[0];
|
||||
// Since ZCMT is only enable for embdeed class so MMU should be disable.
|
||||
// Cache port 0 is being ultilize in implicit read access in ZCMT extension.
|
||||
if (CVA6Cfg.RVZCMT & ~(CVA6Cfg.MmuPresent)) begin
|
||||
assign dcache_req_to_cache[0] = dcache_req_ports_id_cache;
|
||||
end else begin
|
||||
assign dcache_req_to_cache[0] = dcache_req_ports_ex_cache[0];
|
||||
end
|
||||
assign dcache_req_to_cache[1] = dcache_req_ports_ex_cache[1];
|
||||
assign dcache_req_to_cache[2] = dcache_req_ports_acc_cache[0];
|
||||
assign dcache_req_to_cache[3] = dcache_req_ports_ex_cache[2].data_req ? dcache_req_ports_ex_cache [2] :
|
||||
dcache_req_ports_acc_cache[1];
|
||||
|
||||
// D$ response
|
||||
assign dcache_req_ports_cache_ex[0] = dcache_req_from_cache[0];
|
||||
assign dcache_req_ports_cache_ex[1] = dcache_req_from_cache[1];
|
||||
// Since ZCMT is only enable for embdeed class so MMU should be disable.
|
||||
// Cache port 0 is being ultilized in implicit read access in ZCMT extension.
|
||||
if (CVA6Cfg.RVZCMT & ~(CVA6Cfg.MmuPresent)) begin
|
||||
assign dcache_req_ports_cache_id = dcache_req_from_cache[0];
|
||||
assign dcache_req_ports_cache_ex[0] = '0;
|
||||
end else begin
|
||||
assign dcache_req_ports_cache_ex[0] = dcache_req_from_cache[0];
|
||||
assign dcache_req_ports_cache_id = '0;
|
||||
end
|
||||
assign dcache_req_ports_cache_ex[1] = dcache_req_from_cache[1];
|
||||
assign dcache_req_ports_cache_acc[0] = dcache_req_from_cache[2];
|
||||
always_comb begin : gen_dcache_req_store_data_gnt
|
||||
dcache_req_ports_cache_ex[2] = dcache_req_from_cache[3];
|
||||
|
@ -1326,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),
|
||||
|
@ -1464,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),
|
||||
|
@ -1480,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),
|
||||
|
@ -1496,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),
|
||||
|
@ -1525,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;
|
||||
|
@ -1592,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),
|
||||
|
@ -1605,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),
|
||||
|
@ -1715,8 +1792,8 @@ module cva6
|
|||
.decoded_instr_valid_i (issue_entry_valid_id_issue),
|
||||
.decoded_instr_ack_i (issue_instr_issue_id),
|
||||
|
||||
.rs1_forwarding_i(rs1_forwarding_id_ex),
|
||||
.rs2_forwarding_i(rs2_forwarding_id_ex),
|
||||
.rs1_i(rvfi_rs1),
|
||||
.rs2_i(rvfi_rs2),
|
||||
|
||||
.commit_instr_i(commit_instr_id_commit),
|
||||
.commit_drop_i (commit_drop_id_commit),
|
||||
|
@ -1731,6 +1808,7 @@ module cva6
|
|||
.wdata_i (wdata_commit_id),
|
||||
|
||||
.csr_i(rvfi_csr),
|
||||
.irq_i(irq_i),
|
||||
|
||||
.rvfi_probes_o(rvfi_probes_o)
|
||||
|
||||
|
|
|
@ -77,13 +77,18 @@ module cva6_fifo_v3 #(
|
|||
read_pointer_n = read_pointer_q;
|
||||
write_pointer_n = write_pointer_q;
|
||||
status_cnt_n = status_cnt_q;
|
||||
data_ft_n = data_ft_q;
|
||||
first_word_n = first_word_q;
|
||||
if (FPGA_EN && FPGA_ALTERA) data_ft_n = data_ft_q;
|
||||
if (FPGA_EN && FPGA_ALTERA) first_word_n = first_word_q;
|
||||
if (FPGA_EN) begin
|
||||
fifo_ram_we = '0;
|
||||
fifo_ram_write_address = '0;
|
||||
fifo_ram_wdata = '0;
|
||||
data_o = (DEPTH == 0) ? data_i : (first_word_q ? data_ft_q : fifo_ram_rdata);
|
||||
if (DEPTH == 0) begin
|
||||
data_o = data_i;
|
||||
end else begin
|
||||
if (FPGA_ALTERA) data_o = first_word_q ? data_ft_q : fifo_ram_rdata;
|
||||
else data_o = fifo_ram_rdata;
|
||||
end
|
||||
end else begin
|
||||
data_o = (DEPTH == 0) ? data_i : mem_q[read_pointer_q];
|
||||
mem_n = mem_q;
|
||||
|
@ -96,7 +101,7 @@ module cva6_fifo_v3 #(
|
|||
fifo_ram_we = 1'b1;
|
||||
fifo_ram_write_address = write_pointer_q;
|
||||
fifo_ram_wdata = data_i;
|
||||
first_word_n = FPGA_ALTERA && first_word_q && pop_i;
|
||||
if (FPGA_ALTERA) first_word_n = first_word_q && pop_i;
|
||||
end else begin
|
||||
// push the data onto the queue
|
||||
mem_n[write_pointer_q] = data_i;
|
||||
|
@ -113,7 +118,7 @@ module cva6_fifo_v3 #(
|
|||
|
||||
if (pop_i && ~empty_o) begin
|
||||
data_ft_n = data_i;
|
||||
first_word_n = FPGA_EN && FPGA_ALTERA && first_word_q && push_i;
|
||||
if (FPGA_EN && FPGA_ALTERA) first_word_n = first_word_q && push_i;
|
||||
// read from the queue is a default assignment
|
||||
// but increment the read pointer...
|
||||
if (read_pointer_n == FifoDepth[ADDR_DEPTH-1:0] - 1) read_pointer_n = '0;
|
||||
|
@ -151,8 +156,8 @@ module cva6_fifo_v3 #(
|
|||
read_pointer_q <= '0;
|
||||
write_pointer_q <= '0;
|
||||
status_cnt_q <= '0;
|
||||
first_word_q <= '0;
|
||||
data_ft_q <= '0;
|
||||
if (FPGA_ALTERA) first_word_q <= '0;
|
||||
if (FPGA_ALTERA) data_ft_q <= '0;
|
||||
end else begin
|
||||
if (flush_i) begin
|
||||
read_pointer_q <= '0;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -64,8 +64,8 @@ module cva6_rvfi
|
|||
logic [CVA6Cfg.NrIssuePorts-1:0] decoded_instr_valid;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] decoded_instr_ack;
|
||||
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs1_forwarding;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs2_forwarding;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs1;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs2;
|
||||
|
||||
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] rvfi_intr;
|
||||
|
||||
|
@ -132,8 +132,8 @@ module cva6_rvfi
|
|||
assign decoded_instr_valid = instr.decoded_instr_valid;
|
||||
assign decoded_instr_ack = instr.decoded_instr_ack;
|
||||
|
||||
assign rs1_forwarding = instr.rs1_forwarding;
|
||||
assign rs2_forwarding = instr.rs2_forwarding;
|
||||
assign rs1 = instr.rs1;
|
||||
assign rs2 = instr.rs2;
|
||||
|
||||
assign commit_instr_pc = instr.commit_instr_pc;
|
||||
assign commit_instr_op = instr.commit_instr_op;
|
||||
|
@ -240,8 +240,8 @@ module cva6_rvfi
|
|||
for (int unsigned i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||
if (decoded_instr_valid[i] && decoded_instr_ack[i] && !flush_unissued_instr) begin
|
||||
mem_n[issue_pointer[i]] = '{
|
||||
rs1_rdata: rs1_forwarding[i],
|
||||
rs2_rdata: rs2_forwarding[i],
|
||||
rs1_rdata: rs1[i],
|
||||
rs2_rdata: rs2[i],
|
||||
lsu_addr: '0,
|
||||
lsu_rmask: '0,
|
||||
lsu_wmask: '0,
|
||||
|
@ -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)
|
||||
|
@ -418,7 +416,7 @@ module cva6_rvfi
|
|||
`CONNECT_RVFI_SAME(1'b1, icache)
|
||||
|
||||
`CONNECT_RVFI_SAME(CVA6Cfg.EnableAccelerator, acc_cons)
|
||||
|
||||
`CONNECT_RVFI_SAME(CVA6Cfg.RVZCMT, jvt)
|
||||
`CONNECT_RVFI_FULL(1'b1, pmpcfg0, csr.pmpcfg_q[CVA6Cfg.XLEN/8-1:0])
|
||||
`CONNECT_RVFI_FULL(CVA6Cfg.XLEN == 32, pmpcfg1, csr.pmpcfg_q[7:4])
|
||||
|
||||
|
@ -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
|
||||
;
|
||||
|
|
|
@ -35,8 +35,8 @@ module cva6_rvfi_probes
|
|||
input logic [CVA6Cfg.NrIssuePorts-1:0] decoded_instr_valid_i,
|
||||
input logic [CVA6Cfg.NrIssuePorts-1:0] decoded_instr_ack_i,
|
||||
|
||||
input logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] rs1_forwarding_i,
|
||||
input logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] rs2_forwarding_i,
|
||||
input logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs1_i,
|
||||
input logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs2_i,
|
||||
|
||||
input scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_i,
|
||||
input logic [CVA6Cfg.NrCommitPorts-1:0] commit_drop_i,
|
||||
|
@ -51,6 +51,7 @@ module cva6_rvfi_probes
|
|||
input logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] wdata_i,
|
||||
|
||||
input rvfi_probes_csr_t csr_i,
|
||||
input logic [1:0] irq_i,
|
||||
|
||||
output rvfi_probes_t rvfi_probes_o
|
||||
);
|
||||
|
@ -75,8 +76,8 @@ module cva6_rvfi_probes
|
|||
instr.decoded_instr_valid = decoded_instr_valid_i;
|
||||
instr.decoded_instr_ack = decoded_instr_ack_i;
|
||||
|
||||
instr.rs1_forwarding = rs1_forwarding_i;
|
||||
instr.rs2_forwarding = rs2_forwarding_i;
|
||||
instr.rs1 = rs1_i;
|
||||
instr.rs2 = rs2_i;
|
||||
|
||||
instr.ex_commit_cause = ex_commit_i.cause;
|
||||
instr.ex_commit_valid = ex_commit_i.valid;
|
||||
|
@ -109,6 +110,7 @@ module cva6_rvfi_probes
|
|||
instr.wdata = wdata_i;
|
||||
|
||||
csr = csr_i;
|
||||
csr.mip_q = csr_i.mip_q | ({{CVA6Cfg.XLEN - 1{1'b0}}, CVA6Cfg.RVS && irq_i[1]} << riscv::IRQ_S_EXT);
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -16,24 +16,24 @@ module cvxif_compressed_if_driver #(
|
|||
input logic clk_i,
|
||||
// Asynchronous reset active low - SUBSYSTEM
|
||||
input logic rst_ni,
|
||||
input logic flush_i,
|
||||
// CVA6 Hart id
|
||||
input logic [CVA6Cfg.XLEN-1:0] hart_id_i,
|
||||
|
||||
input logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_i,
|
||||
input logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_i,
|
||||
input logic [CVA6Cfg.NrIssuePorts-1:0] instruction_valid_i,
|
||||
input logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_i,
|
||||
input logic is_compressed_i,
|
||||
input logic is_illegal_i,
|
||||
input logic [31:0] instruction_i,
|
||||
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_o,
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_o,
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_o,
|
||||
input logic stall_i,
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0] stall_o,
|
||||
output logic is_compressed_o,
|
||||
output logic is_illegal_o,
|
||||
output logic [31:0] instruction_o,
|
||||
input logic stall_i,
|
||||
output logic stall_o,
|
||||
// CVXIF Compressed interface
|
||||
input logic compressed_ready_i,
|
||||
input x_compressed_resp_t compressed_resp_i,
|
||||
output logic compressed_valid_o,
|
||||
output x_compressed_req_t compressed_req_o
|
||||
input logic compressed_ready_i,
|
||||
input x_compressed_resp_t compressed_resp_i,
|
||||
output logic compressed_valid_o,
|
||||
output x_compressed_req_t compressed_req_o
|
||||
);
|
||||
|
||||
|
||||
|
@ -44,32 +44,22 @@ module cvxif_compressed_if_driver #(
|
|||
compressed_valid_o = 1'b0;
|
||||
compressed_req_o.instr = '0;
|
||||
compressed_req_o.hartid = hart_id_i;
|
||||
stall_o[0] = stall_i;
|
||||
stall_o[1] = 1'b0;
|
||||
if (is_illegal_i[0]) begin
|
||||
compressed_valid_o = is_illegal_i[0] && instruction_valid_i[0];
|
||||
compressed_req_o.instr = instruction_i[0][15:0];
|
||||
is_illegal_o[0] = ~compressed_resp_i.accept;
|
||||
instruction_o[0] = compressed_resp_i.accept ? compressed_resp_i.instr : instruction_i[0];
|
||||
is_compressed_o[0] = compressed_resp_i.accept ? 1'b0 : is_compressed_i[0];
|
||||
stall_o = stall_i;
|
||||
if (is_illegal_i) begin
|
||||
compressed_valid_o = is_illegal_i;
|
||||
compressed_req_o.instr = instruction_i[15:0];
|
||||
is_illegal_o = ~compressed_resp_i.accept;
|
||||
instruction_o = compressed_resp_i.accept ? compressed_resp_i.instr : instruction_i;
|
||||
is_compressed_o = compressed_resp_i.accept ? 1'b0 : is_compressed_i;
|
||||
if (~stall_i) begin
|
||||
// Propagate stall from macro decoder or wait for compressed ready if compressed transaction is happening.
|
||||
// Stall if both instruction are illegal
|
||||
stall_o[0] = (compressed_valid_o && ~compressed_ready_i);
|
||||
if (CVA6Cfg.SuperscalarEn) begin
|
||||
stall_o[1] = is_illegal_i[1];
|
||||
end
|
||||
stall_o = (compressed_valid_o && ~compressed_ready_i);
|
||||
end
|
||||
end
|
||||
if (CVA6Cfg.SuperscalarEn) begin
|
||||
if (~is_illegal_i[0] && is_illegal_i[1]) begin // 2nd instruction is illegal
|
||||
compressed_valid_o = is_illegal_i[1] && instruction_valid_i[1];
|
||||
compressed_req_o.instr = instruction_i[1][15:0];
|
||||
is_illegal_o[1] = ~compressed_resp_i.accept;
|
||||
instruction_o[1] = compressed_resp_i.accept ? compressed_resp_i.instr : instruction_i[1];
|
||||
is_compressed_o[1] = compressed_resp_i.accept ? 1'b0 : is_compressed_i[1];
|
||||
stall_o[1] = (compressed_valid_o && ~compressed_ready_i);
|
||||
end
|
||||
if (flush_i) begin
|
||||
compressed_valid_o = 1'b0;
|
||||
compressed_req_o.instr = '0;
|
||||
compressed_req_o.hartid = hart_id_i;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -88,8 +88,32 @@ module copro_alu
|
|||
rd_n = rd_i;
|
||||
we_n = 1'b1;
|
||||
end
|
||||
cvxif_instr_pkg::ADD_RS3_R4: begin
|
||||
result_n = NrRgprPorts == 3 ? registers_i[2] + registers_i[1] + registers_i[0] : registers_i[1] + registers_i[0];
|
||||
cvxif_instr_pkg::MADD_RS3_R4: begin
|
||||
result_n = NrRgprPorts == 3 ? (registers_i[0] + registers_i[1] + registers_i[2]) : (registers_i[0] + registers_i[1]);
|
||||
hartid_n = hartid_i;
|
||||
id_n = id_i;
|
||||
valid_n = 1'b1;
|
||||
rd_n = rd_i;
|
||||
we_n = 1'b1;
|
||||
end
|
||||
cvxif_instr_pkg::MSUB_RS3_R4: begin
|
||||
result_n = NrRgprPorts == 3 ? (registers_i[0] - registers_i[1] - registers_i[2]) : (registers_i[0] - registers_i[1]);
|
||||
hartid_n = hartid_i;
|
||||
id_n = id_i;
|
||||
valid_n = 1'b1;
|
||||
rd_n = rd_i;
|
||||
we_n = 1'b1;
|
||||
end
|
||||
cvxif_instr_pkg::NMADD_RS3_R4: begin
|
||||
result_n = NrRgprPorts == 3 ? ~(registers_i[0] + registers_i[1] + registers_i[2]) : ~(registers_i[0] + registers_i[1]);
|
||||
hartid_n = hartid_i;
|
||||
id_n = id_i;
|
||||
valid_n = 1'b1;
|
||||
rd_n = rd_i;
|
||||
we_n = 1'b1;
|
||||
end
|
||||
cvxif_instr_pkg::NMSUB_RS3_R4: begin
|
||||
result_n = NrRgprPorts == 3 ? ~(registers_i[0] - registers_i[1] - registers_i[2]) : ~(registers_i[0] - registers_i[1]);
|
||||
hartid_n = hartid_i;
|
||||
id_n = id_i;
|
||||
valid_n = 1'b1;
|
||||
|
|
|
@ -18,8 +18,11 @@ package cvxif_instr_pkg;
|
|||
DOUBLE_RS1 = 4'b0011,
|
||||
DOUBLE_RS2 = 4'b0100,
|
||||
ADD_MULTI = 4'b0101,
|
||||
ADD_RS3_R4 = 4'b0110,
|
||||
ADD_RS3_R = 4'b0111
|
||||
MADD_RS3_R4 = 4'b0110,
|
||||
MSUB_RS3_R4 = 4'b0111,
|
||||
NMADD_RS3_R4 = 4'b1000,
|
||||
NMSUB_RS3_R4 = 4'b1001,
|
||||
ADD_RS3_R = 4'b1111
|
||||
} opcode_t;
|
||||
|
||||
|
||||
|
@ -105,7 +108,7 @@ package cvxif_instr_pkg;
|
|||
32'b00000_00_00000_00000_0_00_00000_1000011, // MADD opcode
|
||||
mask: 32'b00000_11_00000_00000_1_11_00000_1111111,
|
||||
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}},
|
||||
opcode : ADD_RS3_R4
|
||||
opcode : MADD_RS3_R4
|
||||
},
|
||||
'{
|
||||
// Custom Add Multi rs1 : cus_add rd, rs1, rs1
|
||||
|
@ -113,7 +116,7 @@ package cvxif_instr_pkg;
|
|||
32'b00000_00_00000_00000_0_00_00000_1000111, // MSUB opcode
|
||||
mask: 32'b00000_11_00000_00000_1_11_00000_1111111,
|
||||
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}},
|
||||
opcode : ADD_RS3_R4
|
||||
opcode : MSUB_RS3_R4
|
||||
},
|
||||
'{
|
||||
// Custom Add Multi rs1 : cus_add rd, rs1, rs1
|
||||
|
@ -121,7 +124,7 @@ package cvxif_instr_pkg;
|
|||
32'b00000_00_00000_00000_0_00_00000_1001011, // NMSUB opcode
|
||||
mask: 32'b00000_11_00000_00000_1_11_00000_1111111,
|
||||
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}},
|
||||
opcode : ADD_RS3_R4
|
||||
opcode : NMSUB_RS3_R4
|
||||
},
|
||||
'{
|
||||
// Custom Add Multi rs1 : cus_add rd, rs1, rs1
|
||||
|
@ -129,7 +132,7 @@ package cvxif_instr_pkg;
|
|||
32'b00000_00_00000_00000_0_00_00000_1001111, // NMADD opcode
|
||||
mask: 32'b00000_11_00000_00000_1_11_00000_1111111,
|
||||
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}},
|
||||
opcode : ADD_RS3_R4
|
||||
opcode : NMADD_RS3_R4
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -56,7 +58,7 @@ module cvxif_fu
|
|||
|
||||
assign x_ready_o = 1'b1; // Readyness of cvxif_fu is determined in issue stage by CVXIF issue interface
|
||||
// Result signals
|
||||
assign x_valid_o = x_illegal_i && x_valid_i ? 1'b1 : result_valid_i;
|
||||
assign x_valid_o = x_illegal_i || result_valid_i;
|
||||
assign x_result_o = result_i.data;
|
||||
assign x_trans_id_o = x_illegal_i ? x_trans_id_i : result_i.id;
|
||||
assign x_we_o = result_i.we;
|
||||
|
@ -64,13 +66,14 @@ module cvxif_fu
|
|||
|
||||
// Handling of illegal instruction exception
|
||||
always_comb begin
|
||||
x_exception_o = '0; // No exception in this interface
|
||||
if (x_illegal_i && x_valid_i) begin
|
||||
x_exception_o.valid = '1;
|
||||
x_exception_o.cause = riscv::ILLEGAL_INSTR;
|
||||
if (CVA6Cfg.TvalEn)
|
||||
x_exception_o.tval = x_off_instr_i; // TODO Optimization : Set exception in IRO.
|
||||
end
|
||||
x_exception_o.valid = x_illegal_i;
|
||||
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
|
||||
|
|
|
@ -36,16 +36,14 @@ module cvxif_issue_register_commit_if_driver #(
|
|||
input logic [31:0] x_off_instr_i,
|
||||
input logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_i,
|
||||
input [(CVA6Cfg.NrRgprPorts/CVA6Cfg.NrIssuePorts)-1:0][CVA6Cfg.XLEN-1:0] register_i,
|
||||
input logic [(CVA6Cfg.NrRgprPorts/CVA6Cfg.NrIssuePorts)-1:0] rs_valid_i,
|
||||
output logic cvxif_busy_o
|
||||
input logic [(CVA6Cfg.NrRgprPorts/CVA6Cfg.NrIssuePorts)-1:0] rs_valid_i
|
||||
);
|
||||
// X_ISSUE_REGISTER_SPLIT = 0 : Issue and register transactions are synchrone
|
||||
// Mandatory assignement
|
||||
assign register_valid_o = issue_valid_o;
|
||||
assign register_o.hartid = issue_req_o.hartid;
|
||||
assign register_o.id = issue_req_o.id;
|
||||
// cvxif can not take any more instruction if issue transaction is still up.
|
||||
assign cvxif_busy_o = issue_valid_o && ~issue_ready_i;
|
||||
|
||||
always_comb begin
|
||||
issue_valid_o = valid_i && ~flush_i;
|
||||
issue_req_o.instr = x_off_instr_i;
|
||||
|
|
|
@ -48,6 +48,10 @@ module decoder
|
|||
input logic is_last_macro_instr_i,
|
||||
// Is mvsa01/mva01s macro instruction - macro_decoder
|
||||
input logic is_double_rd_macro_instr_i,
|
||||
// Zcmt instruction - FRONTEND
|
||||
input logic is_zcmt_i,
|
||||
// Jump address - zcmt_decoder
|
||||
input logic [CVA6Cfg.XLEN-1:0] jump_address_i,
|
||||
// Is a branch predict instruction - FRONTEND
|
||||
input branchpredict_sbe_t branch_predict_i,
|
||||
// If an exception occured in fetch stage - FRONTEND
|
||||
|
@ -178,9 +182,11 @@ module decoder
|
|||
instruction_o.use_zimm = 1'b0;
|
||||
instruction_o.bp = branch_predict_i;
|
||||
instruction_o.vfp = 1'b0;
|
||||
instruction_o.is_zcmt = is_zcmt_i;
|
||||
ecall = 1'b0;
|
||||
ebreak = 1'b0;
|
||||
check_fprm = 1'b0;
|
||||
tinst = 32'h0;
|
||||
|
||||
if (~ex_i.valid) begin
|
||||
case (instr.rtype.opcode)
|
||||
|
@ -812,10 +818,11 @@ module decoder
|
|||
unique case ({
|
||||
CVA6Cfg.RVB, CVA6Cfg.RVZiCond
|
||||
})
|
||||
2'b00: illegal_instr = illegal_instr_non_bm;
|
||||
2'b01: illegal_instr = illegal_instr_non_bm & illegal_instr_zic;
|
||||
2'b10: illegal_instr = illegal_instr_non_bm & illegal_instr_bm;
|
||||
2'b11: illegal_instr = illegal_instr_non_bm & illegal_instr_bm & illegal_instr_zic;
|
||||
2'b00: illegal_instr = illegal_instr_non_bm;
|
||||
2'b01: illegal_instr = illegal_instr_non_bm & illegal_instr_zic;
|
||||
2'b10: illegal_instr = illegal_instr_non_bm & illegal_instr_bm;
|
||||
2'b11: illegal_instr = illegal_instr_non_bm & illegal_instr_bm & illegal_instr_zic;
|
||||
default: ; // TODO: Check that default case is not synthesized.
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
@ -916,9 +923,18 @@ module decoder
|
|||
else if (instr.instr[24:20] == 5'b00000) instruction_o.op = ariane_pkg::CLZ;
|
||||
else if (instr.instr[24:20] == 5'b00001) instruction_o.op = ariane_pkg::CTZ;
|
||||
else illegal_instr_bm = 1'b1;
|
||||
end else if (instr.instr[31:26] == 6'b010010) instruction_o.op = ariane_pkg::BCLRI;
|
||||
else if (instr.instr[31:26] == 6'b011010) instruction_o.op = ariane_pkg::BINVI;
|
||||
else if (instr.instr[31:26] == 6'b001010) instruction_o.op = ariane_pkg::BSETI;
|
||||
end else if (CVA6Cfg.IS_XLEN64 && instr.instr[31:26] == 6'b010010)
|
||||
instruction_o.op = ariane_pkg::BCLRI;
|
||||
else if (CVA6Cfg.IS_XLEN32 && instr.instr[31:25] == 7'b0100100)
|
||||
instruction_o.op = ariane_pkg::BCLRI;
|
||||
else if (CVA6Cfg.IS_XLEN64 && instr.instr[31:26] == 6'b011010)
|
||||
instruction_o.op = ariane_pkg::BINVI;
|
||||
else if (CVA6Cfg.IS_XLEN32 && instr.instr[31:25] == 7'b0110100)
|
||||
instruction_o.op = ariane_pkg::BINVI;
|
||||
else if (CVA6Cfg.IS_XLEN64 && instr.instr[31:26] == 6'b001010)
|
||||
instruction_o.op = ariane_pkg::BSETI;
|
||||
else if (CVA6Cfg.IS_XLEN32 && instr.instr[31:25] == 7'b0010100)
|
||||
instruction_o.op = ariane_pkg::BSETI;
|
||||
else if (CVA6Cfg.ZKN && instr.instr[31:20] == 12'b000010001111)
|
||||
instruction_o.op = ariane_pkg::ZIP;
|
||||
else illegal_instr_bm = 1'b1;
|
||||
|
@ -929,8 +945,14 @@ module decoder
|
|||
instruction_o.op = ariane_pkg::REV8;
|
||||
else if (instr.instr[31:20] == 12'b011010011000)
|
||||
instruction_o.op = ariane_pkg::REV8;
|
||||
else if (instr.instr[31:26] == 6'b010_010) instruction_o.op = ariane_pkg::BEXTI;
|
||||
else if (instr.instr[31:26] == 6'b011_000) instruction_o.op = ariane_pkg::RORI;
|
||||
else if (CVA6Cfg.IS_XLEN64 && instr.instr[31:26] == 6'b010_010)
|
||||
instruction_o.op = ariane_pkg::BEXTI;
|
||||
else if (CVA6Cfg.IS_XLEN32 && instr.instr[31:25] == 7'b010_0100)
|
||||
instruction_o.op = ariane_pkg::BEXTI;
|
||||
else if (CVA6Cfg.IS_XLEN64 && instr.instr[31:26] == 6'b011_000)
|
||||
instruction_o.op = ariane_pkg::RORI;
|
||||
else if (CVA6Cfg.IS_XLEN32 && instr.instr[31:25] == 7'b011_0000)
|
||||
instruction_o.op = ariane_pkg::RORI;
|
||||
else if (CVA6Cfg.ZKN && instr.instr[31:20] == 12'b011010000111)
|
||||
instruction_o.op = ariane_pkg::BREV8;
|
||||
else if (CVA6Cfg.ZKN && instr.instr[31:20] == 12'b000010001111)
|
||||
|
@ -1484,13 +1506,18 @@ module decoder
|
|||
imm_u_type = {
|
||||
{CVA6Cfg.XLEN - 32{instruction_i[31]}}, instruction_i[31:12], 12'b0
|
||||
}; // JAL, AUIPC, sign extended to 64 bit
|
||||
imm_uj_type = {
|
||||
{CVA6Cfg.XLEN - 20{instruction_i[31]}},
|
||||
instruction_i[19:12],
|
||||
instruction_i[20],
|
||||
instruction_i[30:21],
|
||||
1'b0
|
||||
};
|
||||
// if zcmt then xlen jump address assign to immidiate
|
||||
if (CVA6Cfg.RVZCMT && is_zcmt_i) begin
|
||||
imm_uj_type = {{CVA6Cfg.XLEN - 32{jump_address_i[31]}}, jump_address_i[31:0]};
|
||||
end else begin
|
||||
imm_uj_type = {
|
||||
{CVA6Cfg.XLEN - 20{instruction_i[31]}},
|
||||
instruction_i[19:12],
|
||||
instruction_i[20],
|
||||
instruction_i[30:21],
|
||||
1'b0
|
||||
};
|
||||
end
|
||||
|
||||
// NOIMM, IIMM, SIMM, SBIMM, UIMM, JIMM, RS3
|
||||
// select immediate
|
||||
|
@ -1641,9 +1668,11 @@ module decoder
|
|||
if (irq_ctrl_i.mip[riscv::IRQ_M_TIMER] && irq_ctrl_i.mie[riscv::IRQ_M_TIMER]) begin
|
||||
interrupt_cause = INTERRUPTS.M_TIMER;
|
||||
end
|
||||
// Machine Mode Software Interrupt
|
||||
if (irq_ctrl_i.mip[riscv::IRQ_M_SOFT] && irq_ctrl_i.mie[riscv::IRQ_M_SOFT]) begin
|
||||
interrupt_cause = INTERRUPTS.M_SW;
|
||||
if (CVA6Cfg.SoftwareInterruptEn) begin
|
||||
// Machine Mode Software Interrupt
|
||||
if (irq_ctrl_i.mip[riscv::IRQ_M_SOFT] && irq_ctrl_i.mie[riscv::IRQ_M_SOFT]) begin
|
||||
interrupt_cause = INTERRUPTS.M_SW;
|
||||
end
|
||||
end
|
||||
// Machine Mode External Interrupt
|
||||
if (irq_ctrl_i.mip[riscv::IRQ_M_EXT] && irq_ctrl_i.mie[riscv::IRQ_M_EXT]) begin
|
||||
|
|
|
@ -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,
|
||||
|
@ -47,6 +49,8 @@ module ex_stage
|
|||
input fu_data_t [CVA6Cfg.NrIssuePorts-1:0] fu_data_i,
|
||||
// PC of the current instruction - ISSUE_STAGE
|
||||
input logic [CVA6Cfg.VLEN-1:0] pc_i,
|
||||
// Is_zcmt instruction - ISSUE_STAGE
|
||||
input logic is_zcmt_i,
|
||||
// Report whether instruction is compressed - ISSUE_STAGE
|
||||
input logic is_compressed_instr_i,
|
||||
// Report instruction encoding - ISSUE_STAGE
|
||||
|
@ -159,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
|
||||
|
@ -222,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
|
||||
|
@ -320,6 +327,7 @@ module ex_stage
|
|||
.debug_mode_i,
|
||||
.fu_data_i (one_cycle_data),
|
||||
.pc_i,
|
||||
.is_zcmt_i,
|
||||
.is_compressed_instr_i,
|
||||
.branch_valid_i (|branch_valid_i),
|
||||
.branch_comp_res_i (alu_branch_res),
|
||||
|
@ -526,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,
|
||||
|
@ -551,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,
|
||||
|
@ -609,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
|
|
@ -240,7 +240,7 @@ module frontend
|
|||
4'b0001: begin
|
||||
ras_pop = 1'b0;
|
||||
ras_push = 1'b0;
|
||||
if (CVA6Cfg.BTBEntries && btb_prediction_shifted[i].valid) begin
|
||||
if (CVA6Cfg.BTBEntries != 0 && btb_prediction_shifted[i].valid) begin
|
||||
predict_address = btb_prediction_shifted[i].target_address;
|
||||
cf_type[i] = ariane_pkg::JumpR;
|
||||
end
|
||||
|
@ -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
|
||||
|
|
|
@ -30,7 +30,7 @@ module instr_scan #(
|
|||
output logic rvi_jalr_o,
|
||||
// Unconditional jump instruction - FRONTEND
|
||||
output logic rvi_jump_o,
|
||||
// Instruction immediat - FRONTEND
|
||||
// Instruction immediate - FRONTEND
|
||||
output logic [CVA6Cfg.VLEN-1:0] rvi_imm_o,
|
||||
// Branch compressed instruction - FRONTEND
|
||||
output logic rvc_branch_o,
|
||||
|
@ -44,7 +44,7 @@ module instr_scan #(
|
|||
output logic rvc_jalr_o,
|
||||
// JAL compressed instruction - FRONTEND
|
||||
output logic rvc_call_o,
|
||||
// Instruction compressed immediat - FRONTEND
|
||||
// Instruction compressed immediate - FRONTEND
|
||||
output logic [CVA6Cfg.VLEN-1:0] rvc_imm_o
|
||||
);
|
||||
|
||||
|
@ -69,11 +69,8 @@ module instr_scan #(
|
|||
};
|
||||
endfunction
|
||||
|
||||
logic is_rvc;
|
||||
assign is_rvc = (instr_i[1:0] != 2'b11);
|
||||
|
||||
logic rv32_rvc_jal;
|
||||
assign rv32_rvc_jal = (CVA6Cfg.XLEN == 32) & ((instr_i[15:13] == riscv::OpcodeC1Jal) & is_rvc & (instr_i[1:0] == riscv::OpcodeC1));
|
||||
assign rv32_rvc_jal = (CVA6Cfg.XLEN == 32) & ((instr_i[15:13] == riscv::OpcodeC1Jal) & (instr_i[1:0] == riscv::OpcodeC1));
|
||||
|
||||
logic is_xret;
|
||||
assign is_xret = logic'(instr_i[31:30] == 2'b00) & logic'(instr_i[28:0] == 29'b10000001000000000000001110011);
|
||||
|
@ -90,22 +87,20 @@ module instr_scan #(
|
|||
assign rvi_jump_o = logic'(instr_i[6:0] == riscv::OpcodeJal) | is_xret;
|
||||
|
||||
// opcode JAL
|
||||
assign rvc_jump_o = ((instr_i[15:13] == riscv::OpcodeC1J) & is_rvc & (instr_i[1:0] == riscv::OpcodeC1)) | rv32_rvc_jal;
|
||||
assign rvc_jump_o = ((instr_i[15:13] == riscv::OpcodeC1J) & (instr_i[1:0] == riscv::OpcodeC1)) | rv32_rvc_jal;
|
||||
|
||||
// always links to register 0
|
||||
logic is_jal_r;
|
||||
assign is_jal_r = (instr_i[15:13] == riscv::OpcodeC2JalrMvAdd)
|
||||
& (instr_i[6:2] == 5'b00000)
|
||||
& (instr_i[1:0] == riscv::OpcodeC2)
|
||||
& is_rvc;
|
||||
& (instr_i[1:0] == riscv::OpcodeC2);
|
||||
assign rvc_jr_o = is_jal_r & ~instr_i[12];
|
||||
// always links to register 1 e.g.: it is a jump
|
||||
assign rvc_jalr_o = is_jal_r & instr_i[12];
|
||||
assign rvc_call_o = rvc_jalr_o | rv32_rvc_jal;
|
||||
|
||||
assign rvc_branch_o = ((instr_i[15:13] == riscv::OpcodeC1Beqz) | (instr_i[15:13] == riscv::OpcodeC1Bnez))
|
||||
& (instr_i[1:0] == riscv::OpcodeC1)
|
||||
& is_rvc;
|
||||
& (instr_i[1:0] == riscv::OpcodeC1);
|
||||
// check that rs1 is x1 or x5
|
||||
assign rvc_return_o = ((instr_i[11:7] == 5'd1) | (instr_i[11:7] == 5'd5)) & rvc_jr_o;
|
||||
|
||||
|
|
327
core/id_stage.sv
327
core/id_stage.sv
|
@ -16,8 +16,11 @@
|
|||
module id_stage #(
|
||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||
parameter type branchpredict_sbe_t = logic,
|
||||
parameter type dcache_req_i_t = logic,
|
||||
parameter type dcache_req_o_t = logic,
|
||||
parameter type exception_t = logic,
|
||||
parameter type fetch_entry_t = logic,
|
||||
parameter type jvt_t = logic,
|
||||
parameter type irq_ctrl_t = logic,
|
||||
parameter type scoreboard_entry_t = logic,
|
||||
parameter type interrupts_t = logic,
|
||||
|
@ -83,9 +86,15 @@ module id_stage #(
|
|||
// CVXIF Compressed interface
|
||||
input logic [CVA6Cfg.XLEN-1:0] hart_id_i,
|
||||
input logic compressed_ready_i,
|
||||
//JVT
|
||||
input jvt_t jvt_i,
|
||||
input x_compressed_resp_t compressed_resp_i,
|
||||
output logic compressed_valid_o,
|
||||
output x_compressed_req_t compressed_req_o
|
||||
output x_compressed_req_t compressed_req_o,
|
||||
// Data cache request ouput - CACHE
|
||||
input dcache_req_o_t dcache_req_ports_i,
|
||||
// Data cache request input - CACHE
|
||||
output dcache_req_i_t dcache_req_ports_o
|
||||
);
|
||||
// ID/ISSUE register stage
|
||||
typedef struct packed {
|
||||
|
@ -95,26 +104,51 @@ module id_stage #(
|
|||
logic is_ctrl_flow;
|
||||
} issue_struct_t;
|
||||
issue_struct_t [CVA6Cfg.NrIssuePorts-1:0] issue_n, issue_q;
|
||||
// stall required for ZCMP ZCMT CVXIF
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] stall_instr_fetch;
|
||||
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_control_flow_instr;
|
||||
scoreboard_entry_t [CVA6Cfg.NrIssuePorts-1:0] decoded_instruction;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] decoded_instruction_valid;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] orig_instr;
|
||||
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cmp;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cvxif;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] compressed_instr;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_cvxif;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cmp;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cvxif;
|
||||
// Compressed decoder signals
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_rvc;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_rvc;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_rvc;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_zcmt_instr;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_macro_instr;
|
||||
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_macro_instr_i;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] stall_instr_fetch;
|
||||
// CVXIF compressed interface driver signals
|
||||
// Inputs
|
||||
logic is_illegal_cvxif_i;
|
||||
logic [ 31:0] instruction_cvxif_i;
|
||||
logic is_compressed_cvxif_i;
|
||||
logic stall_macro_deco;
|
||||
logic is_last_macro_instr_o;
|
||||
logic is_double_rd_macro_instr_o;
|
||||
// Outputs
|
||||
logic is_illegal_cvxif_o;
|
||||
logic [ 31:0] instruction_cvxif_o;
|
||||
logic is_compressed_cvxif_o;
|
||||
|
||||
// ZCMP decoder signals
|
||||
logic is_illegal_zcmp;
|
||||
logic [ 31:0] instruction_zcmp;
|
||||
logic is_compressed_zcmp;
|
||||
logic stall_macro_deco_zcmp;
|
||||
logic is_last_macro_instr;
|
||||
logic is_double_rd_macro_instr;
|
||||
|
||||
// ZCMT decoder signals
|
||||
logic is_illegal_zcmt;
|
||||
logic [ 31:0] instruction_zcmt;
|
||||
logic is_compressed_zcmt;
|
||||
logic stall_macro_deco_zcmt;
|
||||
logic [ CVA6Cfg.XLEN-1:0] jump_address;
|
||||
|
||||
// Decoder signals
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_deco;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_deco;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_deco;
|
||||
|
||||
|
||||
if (CVA6Cfg.RVC) begin
|
||||
|
@ -126,104 +160,146 @@ module id_stage #(
|
|||
.CVA6Cfg(CVA6Cfg)
|
||||
) compressed_decoder_i (
|
||||
.instr_i (fetch_entry_i[i].instruction),
|
||||
.instr_o (compressed_instr[i]),
|
||||
.illegal_instr_o (is_illegal[i]),
|
||||
.is_compressed_o (is_compressed[i]),
|
||||
.is_macro_instr_o(is_macro_instr_i[i])
|
||||
.instr_o (instruction_rvc[i]),
|
||||
.illegal_instr_o (is_illegal_rvc[i]),
|
||||
.is_compressed_o (is_compressed_rvc[i]),
|
||||
.is_macro_instr_o(is_macro_instr[i]),
|
||||
.is_zcmt_instr_o (is_zcmt_instr[i])
|
||||
);
|
||||
end
|
||||
|
||||
if (CVA6Cfg.SuperscalarEn) begin
|
||||
assign stall_instr_fetch[1] = is_illegal_rvc[1] || is_macro_instr[1] || is_zcmt_instr[1];
|
||||
end
|
||||
|
||||
if (CVA6Cfg.RVZCMP) begin
|
||||
//sequencial decoder
|
||||
macro_decoder #(
|
||||
.CVA6Cfg(CVA6Cfg)
|
||||
) macro_decoder_i (
|
||||
.instr_i (compressed_instr[0]),
|
||||
.is_macro_instr_i (is_macro_instr_i[0]),
|
||||
.instr_i (instruction_rvc[0]),
|
||||
.is_macro_instr_i (is_macro_instr[0]),
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.instr_o (instruction_cvxif[0]),
|
||||
.illegal_instr_i (is_illegal[0]),
|
||||
.is_compressed_i (is_compressed[0]),
|
||||
.instr_o (instruction_zcmp),
|
||||
.illegal_instr_i (is_illegal_rvc[0]),
|
||||
.is_compressed_i (is_compressed_rvc[0]),
|
||||
.issue_ack_i (issue_instr_ack_i[0]),
|
||||
.illegal_instr_o (is_illegal_cvxif[0]),
|
||||
.is_compressed_o (is_compressed_cvxif[0]),
|
||||
.fetch_stall_o (stall_macro_deco),
|
||||
.is_last_macro_instr_o (is_last_macro_instr_o),
|
||||
.is_double_rd_macro_instr_o(is_double_rd_macro_instr_o)
|
||||
);
|
||||
if (CVA6Cfg.SuperscalarEn) begin
|
||||
assign instruction_cvxif[CVA6Cfg.NrIssuePorts-1] = '0;
|
||||
assign is_illegal_cvxif[CVA6Cfg.NrIssuePorts-1] = '0;
|
||||
assign is_compressed_cvxif[CVA6Cfg.NrIssuePorts-1] = '0;
|
||||
end
|
||||
cvxif_compressed_if_driver #(
|
||||
.CVA6Cfg(CVA6Cfg),
|
||||
.x_compressed_req_t(x_compressed_req_t),
|
||||
.x_compressed_resp_t(x_compressed_resp_t)
|
||||
) i_cvxif_compressed_if_driver_i (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.hart_id_i (hart_id_i),
|
||||
.is_compressed_i (is_compressed_cvxif),
|
||||
.is_illegal_i (is_illegal_cvxif),
|
||||
.instruction_i (instruction_cvxif),
|
||||
.instruction_valid_i(fetch_entry_valid_i),
|
||||
.is_compressed_o (is_compressed_cmp),
|
||||
.is_illegal_o (is_illegal_cmp),
|
||||
.instruction_o (instruction),
|
||||
.stall_i (stall_macro_deco),
|
||||
.stall_o (stall_instr_fetch),
|
||||
.compressed_ready_i (compressed_ready_i),
|
||||
.compressed_resp_i (compressed_resp_i),
|
||||
.compressed_valid_o (compressed_valid_o),
|
||||
.compressed_req_o (compressed_req_o)
|
||||
.illegal_instr_o (is_illegal_zcmp),
|
||||
.is_compressed_o (is_compressed_zcmp),
|
||||
.fetch_stall_o (stall_macro_deco_zcmp),
|
||||
.is_last_macro_instr_o (is_last_macro_instr),
|
||||
.is_double_rd_macro_instr_o(is_double_rd_macro_instr)
|
||||
);
|
||||
end else begin
|
||||
assign instruction_zcmp = instruction_rvc;
|
||||
assign is_illegal_zcmp = is_illegal_rvc;
|
||||
assign is_compressed_zcmp = is_compressed_rvc;
|
||||
assign stall_macro_deco_zcmp = '0;
|
||||
assign is_last_macro_instr = '0;
|
||||
assign is_double_rd_macro_instr = '0;
|
||||
end
|
||||
|
||||
if (CVA6Cfg.RVZCMT) begin
|
||||
zcmt_decoder #(
|
||||
.CVA6Cfg(CVA6Cfg),
|
||||
.dcache_req_i_t(dcache_req_i_t),
|
||||
.dcache_req_o_t(dcache_req_o_t),
|
||||
.jvt_t(jvt_t),
|
||||
.branchpredict_sbe_t(branchpredict_sbe_t)
|
||||
) zcmt_decoder_i (
|
||||
.instr_i (instruction_rvc[0]),
|
||||
.pc_i (fetch_entry_i[0].address),
|
||||
.is_zcmt_instr_i(is_zcmt_instr[0]),
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.instr_o (instruction_zcmt),
|
||||
.illegal_instr_i(is_illegal_rvc[0]),
|
||||
.is_compressed_i(is_compressed_rvc[0]),
|
||||
.illegal_instr_o(is_illegal_zcmt),
|
||||
.is_compressed_o(is_compressed_zcmt),
|
||||
.fetch_stall_o (stall_macro_deco_zcmt),
|
||||
.jvt_i (jvt_i),
|
||||
.req_port_i (dcache_req_ports_i),
|
||||
.req_port_o (dcache_req_ports_o),
|
||||
.jump_address_o (jump_address)
|
||||
);
|
||||
end else begin
|
||||
assign instruction_zcmt = instruction_rvc;
|
||||
assign is_illegal_zcmt = is_illegal_rvc;
|
||||
assign is_compressed_zcmt = is_compressed_rvc;
|
||||
assign stall_macro_deco_zcmt = '0;
|
||||
assign jump_address = '0;
|
||||
end
|
||||
|
||||
if (CVA6Cfg.RVZCMT) begin
|
||||
assign instruction_cvxif_i = is_zcmt_instr[0] ? instruction_zcmt : instruction_zcmp;
|
||||
assign is_illegal_cvxif_i = is_zcmt_instr[0] ? is_illegal_zcmt : is_illegal_zcmp;
|
||||
assign is_compressed_cvxif_i = is_zcmt_instr[0] ? is_compressed_zcmt : is_compressed_zcmp;
|
||||
assign stall_macro_deco = is_zcmt_instr[0] ? stall_macro_deco_zcmt : stall_macro_deco_zcmp;
|
||||
end else begin // Do not instantiate the mux which is not optimized cross-bondaries
|
||||
assign instruction_cvxif_i = instruction_zcmp;
|
||||
assign is_illegal_cvxif_i = is_illegal_zcmp;
|
||||
assign is_compressed_cvxif_i = is_compressed_zcmp;
|
||||
assign stall_macro_deco = stall_macro_deco_zcmp;
|
||||
end
|
||||
|
||||
if (CVA6Cfg.CvxifEn) begin
|
||||
cvxif_compressed_if_driver #(
|
||||
.CVA6Cfg(CVA6Cfg),
|
||||
.x_compressed_req_t(x_compressed_req_t),
|
||||
.x_compressed_resp_t(x_compressed_resp_t)
|
||||
) i_cvxif_compressed_if_driver_i (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.hart_id_i (hart_id_i),
|
||||
.is_compressed_i (is_compressed),
|
||||
.is_illegal_i (is_illegal),
|
||||
.instruction_valid_i(fetch_entry_valid_i),
|
||||
.instruction_i (compressed_instr),
|
||||
.is_compressed_o (is_compressed_cmp),
|
||||
.is_illegal_o (is_illegal_cmp),
|
||||
.instruction_o (instruction),
|
||||
.stall_i (1'b0),
|
||||
.stall_o (stall_instr_fetch),
|
||||
.compressed_ready_i (compressed_ready_i),
|
||||
.compressed_resp_i (compressed_resp_i),
|
||||
.compressed_valid_o (compressed_valid_o),
|
||||
.compressed_req_o (compressed_req_o)
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.flush_i (flush_i),
|
||||
.hart_id_i (hart_id_i),
|
||||
.is_compressed_i (is_compressed_cvxif_i),
|
||||
.is_illegal_i (is_illegal_cvxif_i),
|
||||
.instruction_i (instruction_cvxif_i),
|
||||
.is_compressed_o (is_compressed_cvxif_o),
|
||||
.is_illegal_o (is_illegal_cvxif_o),
|
||||
.instruction_o (instruction_cvxif_o),
|
||||
.stall_i (stall_macro_deco),
|
||||
.stall_o (stall_instr_fetch[0]),
|
||||
.compressed_ready_i(compressed_ready_i),
|
||||
.compressed_resp_i (compressed_resp_i),
|
||||
.compressed_valid_o(compressed_valid_o),
|
||||
.compressed_req_o (compressed_req_o)
|
||||
);
|
||||
assign is_last_macro_instr_o = '0;
|
||||
assign is_double_rd_macro_instr_o = '0;
|
||||
end else begin
|
||||
assign stall_instr_fetch[0] = stall_macro_deco;
|
||||
end
|
||||
end else begin
|
||||
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||
assign instruction[i] = fetch_entry_i[i].instruction;
|
||||
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
|
||||
assign is_illegal_cmp = '0;
|
||||
assign is_compressed_cmp = '0;
|
||||
assign is_macro_instr_i = '0;
|
||||
assign is_last_macro_instr_o = '0;
|
||||
assign is_double_rd_macro_instr_o = '0;
|
||||
if (CVA6Cfg.CvxifEn) begin
|
||||
assign compressed_valid_o = '0;
|
||||
assign compressed_req_o.instr = '0;
|
||||
assign compressed_req_o.hartid = hart_id_i;
|
||||
end // TODO Add else to map x_compressed_if outputs to '0 ?
|
||||
end
|
||||
|
||||
assign rvfi_is_compressed_o = is_compressed_cmp;
|
||||
// ---------------------------------------------------------
|
||||
// 2. Decode and emit instruction to issue stage
|
||||
// ---------------------------------------------------------
|
||||
|
||||
always_comb begin
|
||||
// No CVXIF, No ZCMP, No ZCMT => Connect directly compressed decoder to decoder
|
||||
is_illegal_deco = is_illegal_rvc;
|
||||
instruction_deco = instruction_rvc;
|
||||
is_compressed_deco = is_compressed_rvc;
|
||||
if (CVA6Cfg.CvxifEn) begin
|
||||
is_illegal_deco[0] = is_illegal_cvxif_o;
|
||||
instruction_deco[0] = instruction_cvxif_o;
|
||||
is_compressed_deco[0] = is_compressed_cvxif_o;
|
||||
end else if (!CVA6Cfg.CvxifEn && (CVA6Cfg.RVZCMP || CVA6Cfg.RVZCMT)) begin
|
||||
is_illegal_deco[0] = is_illegal_cvxif_i;
|
||||
instruction_deco[0] = instruction_cvxif_i;
|
||||
is_compressed_deco[0] = is_compressed_cvxif_i;
|
||||
end
|
||||
end
|
||||
|
||||
assign rvfi_is_compressed_o = is_compressed_rvc;
|
||||
|
||||
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||
decoder #(
|
||||
.CVA6Cfg(CVA6Cfg),
|
||||
|
@ -238,12 +314,14 @@ module id_stage #(
|
|||
.irq_ctrl_i,
|
||||
.irq_i,
|
||||
.pc_i (fetch_entry_i[i].address),
|
||||
.is_compressed_i (is_compressed_cmp[i]),
|
||||
.is_macro_instr_i (is_macro_instr_i[i]),
|
||||
.is_last_macro_instr_i (is_last_macro_instr_o),
|
||||
.is_double_rd_macro_instr_i(is_double_rd_macro_instr_o),
|
||||
.is_illegal_i (is_illegal_cmp[i]),
|
||||
.instruction_i (instruction[i]),
|
||||
.is_compressed_i (is_compressed_deco[i]),
|
||||
.is_macro_instr_i (is_macro_instr[i]),
|
||||
.is_zcmt_i (is_zcmt_instr[i]),
|
||||
.is_last_macro_instr_i (is_last_macro_instr),
|
||||
.is_double_rd_macro_instr_i(is_double_rd_macro_instr),
|
||||
.jump_address_i (jump_address),
|
||||
.is_illegal_i (is_illegal_deco[i]),
|
||||
.instruction_i (instruction_deco[i]),
|
||||
.compressed_instr_i (fetch_entry_i[i].instruction[15:0]),
|
||||
.branch_predict_i (fetch_entry_i[i].branch_predict),
|
||||
.ex_i (fetch_entry_i[i].ex),
|
||||
|
@ -266,7 +344,7 @@ module id_stage #(
|
|||
end
|
||||
|
||||
// ------------------
|
||||
// Pipeline Register
|
||||
// 3. Pipeline Register
|
||||
// ------------------
|
||||
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||
assign issue_entry_o[i] = issue_q[i].sbe;
|
||||
|
@ -280,6 +358,12 @@ module id_stage #(
|
|||
always_comb begin
|
||||
issue_n = issue_q;
|
||||
fetch_entry_ready_o = '0;
|
||||
// instruction is not valid if we stall due to ZCMT or CVXIF
|
||||
decoded_instruction_valid[0] = (CVA6Cfg.RVZCMT && is_zcmt_instr[0] && stall_macro_deco_zcmt) ||
|
||||
(CVA6Cfg.CvxifEn && is_illegal_cvxif_i && ~stall_macro_deco) && stall_instr_fetch[0]
|
||||
? 1'b0 : 1'b1;
|
||||
// Instruction on port 1 are always valid. It is either 32bits or legal 16bits.
|
||||
decoded_instruction_valid[1] = ~stall_instr_fetch[1];
|
||||
|
||||
// Clear the valid flag if issue has acknowledged the instruction
|
||||
if (issue_instr_ack_i[0]) begin
|
||||
|
@ -293,21 +377,36 @@ module id_stage #(
|
|||
if (issue_n[1].valid) begin
|
||||
issue_n[0] = issue_n[1];
|
||||
issue_n[1].valid = 1'b0;
|
||||
end else if (fetch_entry_valid_i[0] && !stall_instr_fetch[0]) begin
|
||||
fetch_entry_ready_o[0] = 1'b1;
|
||||
issue_n[0] = '{1'b1, decoded_instruction[0], orig_instr[0], is_control_flow_instr[0]};
|
||||
end else if (fetch_entry_valid_i[0]) begin
|
||||
fetch_entry_ready_o[0] = ~stall_instr_fetch[0];
|
||||
issue_n[0] = '{
|
||||
decoded_instruction_valid[0],
|
||||
decoded_instruction[0],
|
||||
orig_instr[0],
|
||||
is_control_flow_instr[0]
|
||||
};
|
||||
end
|
||||
end
|
||||
|
||||
if (!issue_n[1].valid) begin
|
||||
if (fetch_entry_ready_o[0]) begin
|
||||
if (fetch_entry_valid_i[1] && !stall_instr_fetch[1]) begin
|
||||
fetch_entry_ready_o[1] = 1'b1;
|
||||
issue_n[1] = '{1'b1, decoded_instruction[1], orig_instr[1], is_control_flow_instr[1]};
|
||||
if (fetch_entry_valid_i[1]) begin
|
||||
fetch_entry_ready_o[1] = ~stall_instr_fetch[1];
|
||||
issue_n[1] = '{
|
||||
decoded_instruction_valid[1],
|
||||
decoded_instruction[1],
|
||||
orig_instr[1],
|
||||
is_control_flow_instr[1]
|
||||
};
|
||||
end
|
||||
end else if (fetch_entry_valid_i[0] && !stall_instr_fetch[0]) begin
|
||||
fetch_entry_ready_o[0] = 1'b1;
|
||||
issue_n[1] = '{1'b1, decoded_instruction[0], orig_instr[0], is_control_flow_instr[0]};
|
||||
end else if (fetch_entry_valid_i[0]) begin
|
||||
fetch_entry_ready_o[0] = ~stall_instr_fetch[0];
|
||||
issue_n[1] = '{
|
||||
decoded_instruction_valid[0],
|
||||
decoded_instruction[0],
|
||||
orig_instr[0],
|
||||
is_control_flow_instr[0]
|
||||
};
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -318,22 +417,27 @@ module id_stage #(
|
|||
end
|
||||
end else begin
|
||||
always_comb begin
|
||||
issue_n = issue_q;
|
||||
issue_n = issue_q;
|
||||
fetch_entry_ready_o = '0;
|
||||
|
||||
// instruction is not valid if we stall due to ZCMT or CVXIF
|
||||
decoded_instruction_valid[0] = (CVA6Cfg.RVZCMT && is_zcmt_instr[0] && stall_macro_deco_zcmt) ||
|
||||
(CVA6Cfg.CvxifEn && is_illegal_cvxif_i && ~stall_macro_deco && stall_instr_fetch[0])
|
||||
? 1'b0 : 1'b1;
|
||||
// Clear the valid flag if issue has acknowledged the instruction
|
||||
if (issue_instr_ack_i[0]) issue_n[0].valid = 1'b0;
|
||||
|
||||
// TODO: refaire
|
||||
// if we have a space in the register and the fetch is valid, go get it
|
||||
// or the issue stage is currently acknowledging an instruction, which means that we will have space
|
||||
// for a new instruction
|
||||
if ((!issue_q[0].valid || issue_instr_ack_i[0]) && fetch_entry_valid_i[0]) begin
|
||||
if (stall_instr_fetch[0]) begin
|
||||
fetch_entry_ready_o[0] = 1'b0;
|
||||
end else begin
|
||||
fetch_entry_ready_o[0] = 1'b1;
|
||||
end
|
||||
issue_n[0] = '{1'b1, decoded_instruction[0], orig_instr[0], is_control_flow_instr[0]};
|
||||
if (!issue_n[0].valid && fetch_entry_valid_i[0]) begin
|
||||
fetch_entry_ready_o[0] = ~stall_instr_fetch[0];
|
||||
issue_n[0] = '{
|
||||
decoded_instruction_valid[0],
|
||||
decoded_instruction[0],
|
||||
orig_instr[0],
|
||||
is_control_flow_instr[0]
|
||||
};
|
||||
end
|
||||
|
||||
// invalidate the pipeline register on a flush
|
||||
|
@ -350,4 +454,5 @@ module id_stage #(
|
|||
issue_q <= issue_n;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -31,8 +31,6 @@ package ariane_pkg;
|
|||
// TODO: Slowly move those parameters to the new system.
|
||||
localparam BITS_SATURATION_COUNTER = 2;
|
||||
|
||||
localparam ISSUE_WIDTH = 1;
|
||||
|
||||
// depth of store-buffers, this needs to be a power of two
|
||||
localparam logic [2:0] DEPTH_SPEC = 'd4;
|
||||
|
||||
|
@ -809,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
|
||||
|
|
|
@ -70,9 +70,11 @@ package build_config_pkg;
|
|||
cfg.RVC = CVA6Cfg.RVC;
|
||||
cfg.RVH = CVA6Cfg.RVH;
|
||||
cfg.RVZCB = CVA6Cfg.RVZCB;
|
||||
cfg.RVZCMT = CVA6Cfg.RVZCMT;
|
||||
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;
|
||||
|
@ -95,12 +97,15 @@ package build_config_pkg;
|
|||
cfg.MmuPresent = CVA6Cfg.MmuPresent;
|
||||
cfg.RVS = CVA6Cfg.RVS;
|
||||
cfg.RVU = CVA6Cfg.RVU;
|
||||
cfg.SoftwareInterruptEn = CVA6Cfg.SoftwareInterruptEn;
|
||||
|
||||
cfg.HaltAddress = CVA6Cfg.HaltAddress;
|
||||
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 {
|
||||
|
@ -68,6 +80,8 @@ package config_pkg;
|
|||
bit RVZCB;
|
||||
// Zcmp RISC-V extension
|
||||
bit RVZCMP;
|
||||
// Zcmt RISC-V extension
|
||||
bit RVZCMT;
|
||||
// Zicond RISC-V extension
|
||||
bit RVZiCond;
|
||||
// Zicntr RISC-V extension
|
||||
|
@ -94,6 +108,8 @@ package config_pkg;
|
|||
bit RVS;
|
||||
// User mode
|
||||
bit RVU;
|
||||
// Software interrupts are enabled
|
||||
bit SoftwareInterruptEn;
|
||||
// Debug support
|
||||
bit DebugEn;
|
||||
// Base address of the debug module
|
||||
|
@ -136,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
|
||||
|
@ -202,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
|
||||
|
@ -256,8 +278,10 @@ package config_pkg;
|
|||
bit RVH;
|
||||
bit RVZCB;
|
||||
bit RVZCMP;
|
||||
bit RVZCMT;
|
||||
bit XFVec;
|
||||
bit CvxifEn;
|
||||
copro_type_t CoproType;
|
||||
bit RVZiCond;
|
||||
bit RVZicntr;
|
||||
bit RVZihpm;
|
||||
|
@ -277,14 +301,17 @@ package config_pkg;
|
|||
bit EnableAccelerator;
|
||||
bit PerfCounterEn;
|
||||
bit MmuPresent;
|
||||
bit RVS; //Supervisor mode
|
||||
bit RVU; //User mode
|
||||
bit RVS; //Supervisor mode
|
||||
bit RVU; //User mode
|
||||
bit SoftwareInterruptEn;
|
||||
|
||||
logic [63:0] HaltAddress;
|
||||
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;
|
||||
|
@ -386,9 +413,13 @@ package config_pkg;
|
|||
assert (Cfg.NrCachedRegionRules <= NrMaxRules);
|
||||
assert (Cfg.NrPMPEntries <= 64);
|
||||
assert (!(Cfg.SuperscalarEn && Cfg.RVF));
|
||||
assert (!(Cfg.SuperscalarEn && Cfg.RVZCMP));
|
||||
assert (Cfg.FETCH_WIDTH == 32 || Cfg.FETCH_WIDTH == 64)
|
||||
else $fatal(1, "[frontend] fetch width != not supported");
|
||||
// Support for disabling MIP.MSIP and MIE.MSIE in Hypervisor and Supervisor mode is not supported
|
||||
// Software Interrupt can be disabled when there is only M machine mode in CVA6.
|
||||
assert (!(Cfg.RVS && !Cfg.SoftwareInterruptEn));
|
||||
assert (!(Cfg.RVH && !Cfg.SoftwareInterruptEn));
|
||||
assert (!(Cfg.RVZCMT && ~Cfg.MmuPresent));
|
||||
// pragma translate_on
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -43,10 +43,12 @@ package cva6_config_pkg;
|
|||
RVV: bit'(0),
|
||||
RVC: bit'(1),
|
||||
RVH: bit'(0),
|
||||
RVZCMT: bit'(0),
|
||||
RVZCB: bit'(1),
|
||||
RVZCMP: bit'(1),
|
||||
RVZCMP: bit'(0),
|
||||
XFVec: bit'(0),
|
||||
CvxifEn: bit'(1),
|
||||
CoproType: config_pkg::COPRO_EXAMPLE,
|
||||
RVZiCond: bit'(0),
|
||||
RVZicntr: bit'(0),
|
||||
RVZihpm: bit'(0),
|
||||
|
@ -55,15 +57,18 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(0),
|
||||
RVS: bit'(0),
|
||||
RVU: bit'(0),
|
||||
SoftwareInterruptEn: bit'(0),
|
||||
HaltAddress: 64'h800,
|
||||
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,
|
||||
|
|
|
@ -43,10 +43,12 @@ package cva6_config_pkg;
|
|||
RVV: bit'(0),
|
||||
RVC: bit'(1),
|
||||
RVH: bit'(0),
|
||||
RVZCMT: bit'(0),
|
||||
RVZCB: bit'(1),
|
||||
RVZCMP: bit'(0),
|
||||
XFVec: bit'(0),
|
||||
CvxifEn: bit'(1),
|
||||
CoproType: config_pkg::COPRO_EXAMPLE,
|
||||
RVZiCond: bit'(0),
|
||||
RVZicntr: bit'(0),
|
||||
RVZihpm: bit'(0),
|
||||
|
@ -55,11 +57,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(0),
|
||||
RVS: bit'(0),
|
||||
RVU: bit'(0),
|
||||
SoftwareInterruptEn: bit'(0),
|
||||
HaltAddress: 64'h800,
|
||||
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;
|
||||
|
@ -42,6 +43,9 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigDcacheSetAssoc = 8;
|
||||
localparam CVA6ConfigDcacheLineWidth = 128;
|
||||
|
||||
localparam CVA6ConfigDcacheFlushOnFence = 1'b0;
|
||||
localparam CVA6ConfigDcacheInvalidateOnFlush = 1'b0;
|
||||
|
||||
localparam CVA6ConfigDcacheIdWidth = 1;
|
||||
localparam CVA6ConfigMemTidWidth = 2;
|
||||
|
||||
|
@ -84,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),
|
||||
|
@ -97,7 +101,9 @@ package cva6_config_pkg;
|
|||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
RVZCMT: bit'(0),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -106,11 +112,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(0),
|
||||
RVU: bit'(0),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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),
|
||||
|
@ -139,6 +148,8 @@ package cva6_config_pkg;
|
|||
DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize),
|
||||
DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc),
|
||||
DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth),
|
||||
DcacheFlushOnFence: bit'(CVA6ConfigDcacheFlushOnFence),
|
||||
DcacheInvalidateOnFlush: bit'(CVA6ConfigDcacheInvalidateOnFlush),
|
||||
DataUserEn: unsigned'(CVA6ConfigDataUserEn),
|
||||
WtDcacheWbufDepth: int'(CVA6ConfigWtDcacheWbufDepth),
|
||||
FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth),
|
||||
|
|
|
@ -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),
|
||||
|
@ -96,9 +97,11 @@ package cva6_config_pkg;
|
|||
RVC: bit'(CVA6ConfigCExtEn),
|
||||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -107,11 +110,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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),
|
||||
|
@ -140,6 +146,8 @@ package cva6_config_pkg;
|
|||
DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize),
|
||||
DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc),
|
||||
DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth),
|
||||
DcacheFlushOnFence: bit'(0),
|
||||
DcacheInvalidateOnFlush: bit'(0),
|
||||
DataUserEn: unsigned'(CVA6ConfigDataUserEn),
|
||||
WtDcacheWbufDepth: int'(CVA6ConfigWtDcacheWbufDepth),
|
||||
FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth),
|
||||
|
|
|
@ -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),
|
||||
|
@ -96,9 +97,11 @@ package cva6_config_pkg;
|
|||
RVC: bit'(CVA6ConfigCExtEn),
|
||||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -107,11 +110,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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),
|
||||
|
@ -140,6 +146,8 @@ package cva6_config_pkg;
|
|||
DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize),
|
||||
DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc),
|
||||
DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth),
|
||||
DcacheFlushOnFence: bit'(0),
|
||||
DcacheInvalidateOnFlush: bit'(0),
|
||||
DataUserEn: unsigned'(CVA6ConfigDataUserEn),
|
||||
WtDcacheWbufDepth: int'(CVA6ConfigWtDcacheWbufDepth),
|
||||
FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth),
|
||||
|
|
|
@ -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),
|
||||
|
@ -95,9 +96,11 @@ package cva6_config_pkg;
|
|||
RVC: bit'(CVA6ConfigCExtEn),
|
||||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -106,11 +109,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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),
|
||||
|
@ -97,8 +98,10 @@ package cva6_config_pkg;
|
|||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -107,11 +110,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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),
|
||||
|
@ -136,10 +142,12 @@ package cva6_config_pkg;
|
|||
IcacheByteSize: unsigned'(CVA6ConfigIcacheByteSize),
|
||||
IcacheSetAssoc: unsigned'(CVA6ConfigIcacheSetAssoc),
|
||||
IcacheLineWidth: unsigned'(CVA6ConfigIcacheLineWidth),
|
||||
DCacheType: CVA6ConfigDcacheType,
|
||||
DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize),
|
||||
DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc),
|
||||
DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth),
|
||||
DCacheType: CVA6ConfigDcacheType,
|
||||
DcacheFlushOnFence: bit'(0),
|
||||
DcacheInvalidateOnFlush: bit'(0),
|
||||
DataUserEn: unsigned'(CVA6ConfigDataUserEn),
|
||||
WtDcacheWbufDepth: int'(CVA6ConfigWtDcacheWbufDepth),
|
||||
FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth),
|
||||
|
|
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;
|
||||
|
@ -43,6 +44,9 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigDcacheSetAssoc = 8;
|
||||
localparam CVA6ConfigDcacheLineWidth = 128;
|
||||
|
||||
localparam CVA6ConfigDcacheFlushOnFence = 1'b0;
|
||||
localparam CVA6ConfigDcacheInvalidateOnFlush = 1'b0;
|
||||
|
||||
localparam CVA6ConfigDcacheIdWidth = 1;
|
||||
localparam CVA6ConfigMemTidWidth = 2;
|
||||
|
||||
|
@ -85,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),
|
||||
|
@ -97,8 +101,10 @@ package cva6_config_pkg;
|
|||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -107,11 +113,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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),
|
||||
|
@ -140,6 +149,8 @@ package cva6_config_pkg;
|
|||
DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize),
|
||||
DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc),
|
||||
DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth),
|
||||
DcacheFlushOnFence: bit'(CVA6ConfigDcacheFlushOnFence),
|
||||
DcacheInvalidateOnFlush: bit'(CVA6ConfigDcacheInvalidateOnFlush),
|
||||
DataUserEn: unsigned'(CVA6ConfigDataUserEn),
|
||||
WtDcacheWbufDepth: int'(CVA6ConfigWtDcacheWbufDepth),
|
||||
FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth),
|
||||
|
|
|
@ -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),
|
||||
|
@ -99,9 +100,11 @@ package cva6_config_pkg;
|
|||
RVC: bit'(CVA6ConfigCExtEn),
|
||||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -110,11 +113,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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),
|
||||
|
@ -107,8 +108,10 @@ package cva6_config_pkg;
|
|||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -117,11 +120,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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;
|
||||
|
@ -56,7 +57,7 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigDcacheIdWidth = 3;
|
||||
localparam CVA6ConfigMemTidWidth = CVA6ConfigAxiIdWidth;
|
||||
|
||||
localparam CVA6ConfigWtDcacheWbufDepth = 8;
|
||||
localparam CVA6ConfigWtDcacheWbufDepth = 7;
|
||||
|
||||
localparam CVA6ConfigNrScoreboardEntries = 8;
|
||||
|
||||
|
@ -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),
|
||||
|
@ -107,8 +108,10 @@ package cva6_config_pkg;
|
|||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -117,11 +120,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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;
|
||||
|
@ -43,6 +44,9 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigDcacheSetAssoc = 8;
|
||||
localparam CVA6ConfigDcacheLineWidth = 128;
|
||||
|
||||
localparam CVA6ConfigDcacheFlushOnFence = 1'b0;
|
||||
localparam CVA6ConfigDcacheInvalidateOnFlush = 1'b0;
|
||||
|
||||
localparam CVA6ConfigDcacheIdWidth = 1;
|
||||
localparam CVA6ConfigMemTidWidth = 2;
|
||||
|
||||
|
@ -85,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),
|
||||
|
@ -96,9 +100,11 @@ package cva6_config_pkg;
|
|||
RVC: bit'(CVA6ConfigCExtEn),
|
||||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -107,11 +113,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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),
|
||||
|
@ -140,6 +149,8 @@ package cva6_config_pkg;
|
|||
DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize),
|
||||
DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc),
|
||||
DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth),
|
||||
DcacheFlushOnFence: unsigned'(CVA6ConfigDcacheFlushOnFence),
|
||||
DcacheInvalidateOnFlush: unsigned'(CVA6ConfigDcacheInvalidateOnFlush),
|
||||
DataUserEn: unsigned'(CVA6ConfigDataUserEn),
|
||||
WtDcacheWbufDepth: int'(CVA6ConfigWtDcacheWbufDepth),
|
||||
FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth),
|
||||
|
|
|
@ -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),
|
||||
|
@ -99,9 +100,11 @@ package cva6_config_pkg;
|
|||
RVC: bit'(CVA6ConfigCExtEn),
|
||||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -110,11 +113,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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;
|
||||
|
@ -43,6 +44,9 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigDcacheSetAssoc = 8;
|
||||
localparam CVA6ConfigDcacheLineWidth = 128;
|
||||
|
||||
localparam CVA6ConfigDcacheFlushOnFence = 1'b0;
|
||||
localparam CVA6ConfigDcacheInvalidateOnFlush = 1'b0;
|
||||
|
||||
localparam CVA6ConfigDcacheIdWidth = 1;
|
||||
localparam CVA6ConfigMemTidWidth = 2;
|
||||
|
||||
|
@ -85,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),
|
||||
|
@ -96,9 +100,11 @@ package cva6_config_pkg;
|
|||
RVC: bit'(CVA6ConfigCExtEn),
|
||||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -107,11 +113,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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),
|
||||
|
@ -140,6 +149,8 @@ package cva6_config_pkg;
|
|||
DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize),
|
||||
DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc),
|
||||
DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth),
|
||||
DcacheFlushOnFence: unsigned'(CVA6ConfigDcacheFlushOnFence),
|
||||
DcacheInvalidateOnFlush: unsigned'(CVA6ConfigDcacheInvalidateOnFlush),
|
||||
DataUserEn: unsigned'(CVA6ConfigDataUserEn),
|
||||
WtDcacheWbufDepth: int'(CVA6ConfigWtDcacheWbufDepth),
|
||||
FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth),
|
||||
|
|
|
@ -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;
|
||||
|
@ -43,6 +44,9 @@ package cva6_config_pkg;
|
|||
localparam CVA6ConfigDcacheSetAssoc = 8;
|
||||
localparam CVA6ConfigDcacheLineWidth = 128;
|
||||
|
||||
localparam CVA6ConfigDcacheFlushOnFence = 1'b1;
|
||||
localparam CVA6ConfigDcacheInvalidateOnFlush = 1'b0;
|
||||
|
||||
localparam CVA6ConfigDcacheIdWidth = 1;
|
||||
localparam CVA6ConfigMemTidWidth = 2;
|
||||
|
||||
|
@ -85,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),
|
||||
|
@ -96,9 +100,11 @@ package cva6_config_pkg;
|
|||
RVC: bit'(CVA6ConfigCExtEn),
|
||||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -107,11 +113,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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),
|
||||
|
@ -140,6 +149,8 @@ package cva6_config_pkg;
|
|||
DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize),
|
||||
DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc),
|
||||
DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth),
|
||||
DcacheFlushOnFence: unsigned'(CVA6ConfigDcacheFlushOnFence),
|
||||
DcacheInvalidateOnFlush: unsigned'(CVA6ConfigDcacheInvalidateOnFlush),
|
||||
DataUserEn: unsigned'(CVA6ConfigDataUserEn),
|
||||
WtDcacheWbufDepth: int'(CVA6ConfigWtDcacheWbufDepth),
|
||||
FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth),
|
||||
|
|
|
@ -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,19 @@ 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;
|
||||
|
||||
localparam CVA6ConfigDcacheIdWidth = 1;
|
||||
localparam CVA6ConfigMemTidWidth = 2;
|
||||
|
@ -77,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),
|
||||
|
@ -85,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),
|
||||
|
@ -97,8 +103,10 @@ package cva6_config_pkg;
|
|||
RVH: bit'(CVA6ConfigHExtEn),
|
||||
RVZCB: bit'(CVA6ConfigZcbExtEn),
|
||||
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
|
||||
RVZCMT: bit'(0),
|
||||
XFVec: bit'(CVA6ConfigFVecEn),
|
||||
CvxifEn: bit'(CVA6ConfigCvxifEn),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(CVA6ConfigRVZiCond),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -107,11 +115,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(CVA6ConfigMmuPresent),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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),
|
||||
|
@ -139,6 +150,8 @@ package cva6_config_pkg;
|
|||
DcacheByteSize: unsigned'(CVA6ConfigDcacheByteSize),
|
||||
DcacheSetAssoc: unsigned'(CVA6ConfigDcacheSetAssoc),
|
||||
DcacheLineWidth: unsigned'(CVA6ConfigDcacheLineWidth),
|
||||
DcacheFlushOnFence: unsigned'(CVA6ConfigDcacheFlushOnFence),
|
||||
DcacheInvalidateOnFlush: unsigned'(CVA6ConfigDcacheInvalidateOnFlush),
|
||||
DataUserEn: unsigned'(CVA6ConfigDataUserEn),
|
||||
WtDcacheWbufDepth: int'(CVA6ConfigWtDcacheWbufDepth),
|
||||
FetchUserWidth: unsigned'(CVA6ConfigFetchUserWidth),
|
||||
|
|
|
@ -52,8 +52,10 @@ package cva6_config_pkg;
|
|||
RVH: bit'(0),
|
||||
RVZCB: bit'(1),
|
||||
RVZCMP: bit'(0),
|
||||
RVZCMT: bit'(0),
|
||||
XFVec: bit'(0),
|
||||
CvxifEn: bit'(1),
|
||||
CoproType: config_pkg::COPRO_NONE,
|
||||
RVZiCond: bit'(0),
|
||||
RVZicntr: bit'(1),
|
||||
RVZihpm: bit'(1),
|
||||
|
@ -62,11 +64,14 @@ package cva6_config_pkg;
|
|||
MmuPresent: bit'(1),
|
||||
RVS: bit'(1),
|
||||
RVU: bit'(1),
|
||||
SoftwareInterruptEn: bit'(1),
|
||||
HaltAddress: 64'h800,
|
||||
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),
|
||||
|
@ -95,6 +100,8 @@ package cva6_config_pkg;
|
|||
DcacheByteSize: unsigned'(32768),
|
||||
DcacheSetAssoc: unsigned'(8),
|
||||
DcacheLineWidth: unsigned'(128),
|
||||
DcacheFlushOnFence: bit'(0),
|
||||
DcacheInvalidateOnFlush: bit'(0),
|
||||
DataUserEn: unsigned'(0),
|
||||
WtDcacheWbufDepth: int'(2),
|
||||
FetchUserWidth: unsigned'(64),
|
||||
|
|
|
@ -385,6 +385,8 @@ package riscv;
|
|||
CSR_FFLAGS = 12'h001,
|
||||
CSR_FRM = 12'h002,
|
||||
CSR_FCSR = 12'h003,
|
||||
//jvt
|
||||
CSR_JVT = 12'h017,
|
||||
CSR_FTRAN = 12'h800,
|
||||
// Vector CSRs
|
||||
CSR_VSTART = 12'h008,
|
||||
|
@ -724,6 +726,8 @@ package riscv;
|
|||
localparam logic [63:0] SSTATUS_MXR = 'h00080000;
|
||||
localparam logic [63:0] SSTATUS_UPIE = 'h00000010;
|
||||
localparam logic [63:0] SSTATUS_UXL = 64'h0000000300000000;
|
||||
// CSR Bit Implementation Masks
|
||||
|
||||
function automatic logic [63:0] sstatus_sd(logic IS_XLEN64);
|
||||
return {IS_XLEN64, 31'h00000000, ~IS_XLEN64, 31'h00000000};
|
||||
endfunction
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
rvfi_csr_elmt_t fflags; \
|
||||
rvfi_csr_elmt_t frm; \
|
||||
rvfi_csr_elmt_t fcsr; \
|
||||
rvfi_csr_elmt_t jvt; \
|
||||
rvfi_csr_elmt_t ftran; \
|
||||
rvfi_csr_elmt_t dcsr; \
|
||||
rvfi_csr_elmt_t dpc; \
|
||||
|
@ -103,8 +104,8 @@
|
|||
logic [Cfg.NrIssuePorts-1:0] fetch_entry_valid; \
|
||||
logic [Cfg.NrIssuePorts-1:0][31:0] instruction; \
|
||||
logic [Cfg.NrIssuePorts-1:0] is_compressed; \
|
||||
logic [Cfg.NrIssuePorts-1:0][Cfg.VLEN-1:0] rs1_forwarding; \
|
||||
logic [Cfg.NrIssuePorts-1:0][Cfg.VLEN-1:0] rs2_forwarding; \
|
||||
logic [Cfg.NrIssuePorts-1:0][Cfg.XLEN-1:0] rs1; \
|
||||
logic [Cfg.NrIssuePorts-1:0][Cfg.XLEN-1:0] rs2; \
|
||||
logic [Cfg.NrCommitPorts-1:0][Cfg.VLEN-1:0] commit_instr_pc; \
|
||||
ariane_pkg::fu_op [Cfg.NrCommitPorts-1:0] commit_instr_op; \
|
||||
logic [Cfg.NrCommitPorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] commit_instr_rs1; \
|
||||
|
@ -130,6 +131,7 @@
|
|||
`define RVFI_PROBES_CSR_T(Cfg) struct packed { \
|
||||
riscv::fcsr_t fcsr_q; \
|
||||
riscv::dcsr_t dcsr_q; \
|
||||
logic [Cfg.XLEN-1:0] jvt_q; \
|
||||
logic [Cfg.XLEN-1:0] dpc_q; \
|
||||
logic [Cfg.XLEN-1:0] dscratch0_q; \
|
||||
logic [Cfg.XLEN-1:0] dscratch1_q; \
|
||||
|
|
|
@ -51,11 +51,13 @@ module issue_read_operands
|
|||
// FU data useful to execute instruction - EX_STAGE
|
||||
output fu_data_t [CVA6Cfg.NrIssuePorts-1:0] fu_data_o,
|
||||
// Unregistered version of fu_data_o.operanda - EX_STAGE
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs1_forwarding_o,
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] rs1_forwarding_o,
|
||||
// Unregistered version of fu_data_o.operandb - EX_STAGE
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs2_forwarding_o,
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.VLEN-1:0] rs2_forwarding_o,
|
||||
// Program Counter - EX_STAGE
|
||||
output logic [CVA6Cfg.VLEN-1:0] pc_o,
|
||||
// Is zcmt - EX_STAGE
|
||||
output logic is_zcmt_o,
|
||||
// Is compressed instruction - EX_STAGE
|
||||
output logic is_compressed_instr_o,
|
||||
// Fixed Latency Unit is ready - EX_STAGE
|
||||
|
@ -119,9 +121,13 @@ module issue_read_operands
|
|||
input logic [CVA6Cfg.NrCommitPorts-1:0] we_gpr_i,
|
||||
// FPR write enable - COMMIT_STAGE
|
||||
input logic [CVA6Cfg.NrCommitPorts-1:0] we_fpr_i,
|
||||
|
||||
// Issue stall - PERF_COUNTERS
|
||||
output logic stall_issue_o
|
||||
output logic stall_issue_o,
|
||||
// Information dedicated to RVFI - RVFI
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rvfi_rs1_o,
|
||||
// Information dedicated to RVFI - RVFI
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rvfi_rs2_o
|
||||
|
||||
);
|
||||
|
||||
localparam OPERANDS_PER_INSTR = CVA6Cfg.NrRgprPorts / CVA6Cfg.NrIssuePorts;
|
||||
|
@ -141,19 +147,22 @@ module issue_read_operands
|
|||
rs3_len_t operand_c_fpr;
|
||||
// output flipflop (ID <-> EX)
|
||||
fu_data_t [CVA6Cfg.NrIssuePorts-1:0] fu_data_n, fu_data_q;
|
||||
logic [ CVA6Cfg.XLEN-1:0] imm_forward_rs3;
|
||||
logic [CVA6Cfg.VLEN-1:0] pc_n;
|
||||
logic is_compressed_instr_n;
|
||||
branchpredict_sbe_t branch_predict_n;
|
||||
logic [CVA6Cfg.XLEN-1:0] imm_forward_rs3;
|
||||
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] alu_valid_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] mult_valid_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] fpu_valid_q;
|
||||
logic [ 1:0] fpu_fmt_q;
|
||||
logic [ 2:0] fpu_rm_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] alu2_valid_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] lsu_valid_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] csr_valid_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] branch_valid_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] cvxif_valid_q;
|
||||
logic [ 31:0] cvxif_off_instr_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] alu_valid_n, alu_valid_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] mult_valid_n, mult_valid_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] fpu_valid_n, fpu_valid_q;
|
||||
logic [1:0] fpu_fmt_n, fpu_fmt_q;
|
||||
logic [2:0] fpu_rm_n, fpu_rm_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] alu2_valid_n, alu2_valid_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] lsu_valid_n, lsu_valid_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] csr_valid_n, csr_valid_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] branch_valid_n, branch_valid_q;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] cvxif_valid_n, cvxif_valid_q;
|
||||
logic [31:0] cvxif_off_instr_n, cvxif_off_instr_q;
|
||||
logic cvxif_instruction_valid;
|
||||
|
||||
//fwd logic
|
||||
|
@ -197,7 +206,7 @@ module issue_read_operands
|
|||
|
||||
// CVXIF Signals
|
||||
logic cvxif_req_allowed;
|
||||
logic x_transaction_rejected;
|
||||
logic x_transaction_rejected, x_transaction_rejected_n;
|
||||
logic [OPERANDS_PER_INSTR-1:0] rs_valid;
|
||||
logic [OPERANDS_PER_INSTR-1:0][CVA6Cfg.XLEN-1:0] rs;
|
||||
|
||||
|
@ -225,8 +234,7 @@ module issue_read_operands
|
|||
.x_off_instr_i (orig_instr_i[0]),
|
||||
.x_trans_id_i (issue_instr_i[0].trans_id),
|
||||
.register_i (rs),
|
||||
.rs_valid_i (rs_valid),
|
||||
.cvxif_busy_o ()
|
||||
.rs_valid_i (rs_valid)
|
||||
);
|
||||
if (OPERANDS_PER_INSTR == 3) begin
|
||||
assign rs_valid = {~stall_rs3[0], ~stall_rs2[0], ~stall_rs1[0]};
|
||||
|
@ -250,6 +258,8 @@ module issue_read_operands
|
|||
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||
assign rs1_forwarding_o[i] = fu_data_n[i].operand_a[CVA6Cfg.VLEN-1:0]; //forwarding or unregistered rs1 value
|
||||
assign rs2_forwarding_o[i] = fu_data_n[i].operand_b[CVA6Cfg.VLEN-1:0]; //forwarding or unregistered rs2 value
|
||||
assign rvfi_rs1_o[i] = fu_data_n[i].operand_a;
|
||||
assign rvfi_rs2_o[i] = fu_data_n[i].operand_b;
|
||||
end
|
||||
|
||||
assign fu_data_o = fu_data_q;
|
||||
|
@ -284,7 +294,7 @@ module issue_read_operands
|
|||
|
||||
// after a multiplication was issued we can only issue another multiplication
|
||||
// otherwise we will get contentions on the fixed latency bus
|
||||
if (mult_valid_q) begin
|
||||
if (|mult_valid_q) begin
|
||||
fus_busy[0].alu = 1'b1;
|
||||
fus_busy[0].ctrl_flow = 1'b1;
|
||||
fus_busy[0].csr = 1'b1;
|
||||
|
@ -310,7 +320,7 @@ module issue_read_operands
|
|||
fus_busy[1].cvxif = 1'b1;
|
||||
|
||||
unique case (issue_instr_i[0].fu)
|
||||
NONE: fus_busy[1].none = 1'b1;
|
||||
NONE: fus_busy[1].none = 1'b1;
|
||||
CTRL_FLOW: begin
|
||||
if (CVA6Cfg.SpeculativeSb) begin
|
||||
// Issue speculative instruction, will be removed on BMISS
|
||||
|
@ -350,7 +360,7 @@ module issue_read_operands
|
|||
// Control hazard
|
||||
fus_busy[1] = '1;
|
||||
end
|
||||
MULT: fus_busy[1].mult = 1'b1;
|
||||
MULT: fus_busy[1].mult = 1'b1;
|
||||
FPU, FPU_VEC: begin
|
||||
fus_busy[1].fpu = 1'b1;
|
||||
fus_busy[1].fpu_vec = 1'b1;
|
||||
|
@ -360,6 +370,7 @@ module issue_read_operands
|
|||
fus_busy[1].store = 1'b1;
|
||||
end
|
||||
CVXIF: ;
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
@ -776,6 +787,64 @@ module issue_read_operands
|
|||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
alu_valid_n = '0;
|
||||
lsu_valid_n = '0;
|
||||
mult_valid_n = '0;
|
||||
fpu_valid_n = '0;
|
||||
fpu_fmt_n = '0;
|
||||
fpu_rm_n = '0;
|
||||
alu2_valid_n = '0;
|
||||
csr_valid_n = '0;
|
||||
branch_valid_n = '0;
|
||||
for (int unsigned i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||
if (!issue_instr_i[i].ex.valid && issue_instr_valid_i[i] && issue_ack_o[i]) begin
|
||||
case (issue_instr_i[i].fu)
|
||||
ALU: begin
|
||||
if (CVA6Cfg.SuperscalarEn && !fus_busy[i].alu2) begin
|
||||
alu2_valid_n[i] = 1'b1;
|
||||
end else begin
|
||||
alu_valid_n[i] = 1'b1;
|
||||
end
|
||||
end
|
||||
CTRL_FLOW: begin
|
||||
branch_valid_n[i] = 1'b1;
|
||||
end
|
||||
MULT: begin
|
||||
mult_valid_n[i] = 1'b1;
|
||||
end
|
||||
LOAD, STORE: begin
|
||||
lsu_valid_n[i] = 1'b1;
|
||||
end
|
||||
CSR: begin
|
||||
csr_valid_n[i] = 1'b1;
|
||||
end
|
||||
default: begin
|
||||
if (issue_instr_i[i].fu == FPU && CVA6Cfg.FpPresent) begin
|
||||
fpu_valid_n[i] = 1'b1;
|
||||
fpu_fmt_n = orig_instr.rftype.fmt; // fmt bits from instruction
|
||||
fpu_rm_n = orig_instr.rftype.rm; // rm bits from instruction
|
||||
end else if (issue_instr_i[i].fu == FPU_VEC && CVA6Cfg.FpPresent) begin
|
||||
fpu_valid_n[i] = 1'b1;
|
||||
fpu_fmt_n = orig_instr.rvftype.vfmt; // vfmt bits from instruction
|
||||
fpu_rm_n = {2'b0, orig_instr.rvftype.repl}; // repl bit from instruction
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
// if we got a flush request, de-assert the valid flag, otherwise we will start this
|
||||
// functional unit with the wrong inputs
|
||||
if (flush_i) begin
|
||||
alu_valid_n = '0;
|
||||
lsu_valid_n = '0;
|
||||
mult_valid_n = '0;
|
||||
fpu_valid_n = '0;
|
||||
alu2_valid_n = '0;
|
||||
csr_valid_n = '0;
|
||||
branch_valid_n = '0;
|
||||
end
|
||||
end
|
||||
// FU select, assert the correct valid out signal (in the next cycle)
|
||||
// This needs to be like this to make verilator happy. I know its ugly.
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
|
@ -790,91 +859,45 @@ module issue_read_operands
|
|||
csr_valid_q <= '0;
|
||||
branch_valid_q <= '0;
|
||||
end else begin
|
||||
alu_valid_q <= '0;
|
||||
lsu_valid_q <= '0;
|
||||
mult_valid_q <= '0;
|
||||
fpu_valid_q <= '0;
|
||||
fpu_fmt_q <= '0;
|
||||
fpu_rm_q <= '0;
|
||||
alu2_valid_q <= '0;
|
||||
csr_valid_q <= '0;
|
||||
branch_valid_q <= '0;
|
||||
// Exception pass through:
|
||||
// If an exception has occurred simply pass it through
|
||||
// we do not want to issue this instruction
|
||||
for (int unsigned i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||
if (!issue_instr_i[i].ex.valid && issue_instr_valid_i[i] && issue_ack_o[i]) begin
|
||||
case (issue_instr_i[i].fu)
|
||||
ALU: begin
|
||||
if (CVA6Cfg.SuperscalarEn && !fus_busy[i].alu2) begin
|
||||
alu2_valid_q[i] <= 1'b1;
|
||||
end else begin
|
||||
alu_valid_q[i] <= 1'b1;
|
||||
end
|
||||
end
|
||||
CTRL_FLOW: begin
|
||||
branch_valid_q[i] <= 1'b1;
|
||||
end
|
||||
MULT: begin
|
||||
mult_valid_q[i] <= 1'b1;
|
||||
end
|
||||
LOAD, STORE: begin
|
||||
lsu_valid_q[i] <= 1'b1;
|
||||
end
|
||||
CSR: begin
|
||||
csr_valid_q[i] <= 1'b1;
|
||||
end
|
||||
default: begin
|
||||
if (issue_instr_i[i].fu == FPU && CVA6Cfg.FpPresent) begin
|
||||
fpu_valid_q[i] <= 1'b1;
|
||||
fpu_fmt_q <= orig_instr.rftype.fmt; // fmt bits from instruction
|
||||
fpu_rm_q <= orig_instr.rftype.rm; // rm bits from instruction
|
||||
end else if (issue_instr_i[i].fu == FPU_VEC && CVA6Cfg.FpPresent) begin
|
||||
fpu_valid_q[i] <= 1'b1;
|
||||
fpu_fmt_q <= orig_instr.rvftype.vfmt; // vfmt bits from instruction
|
||||
fpu_rm_q <= {2'b0, orig_instr.rvftype.repl}; // repl bit from instruction
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
// if we got a flush request, de-assert the valid flag, otherwise we will start this
|
||||
// functional unit with the wrong inputs
|
||||
if (flush_i) begin
|
||||
alu_valid_q <= '0;
|
||||
lsu_valid_q <= '0;
|
||||
mult_valid_q <= '0;
|
||||
fpu_valid_q <= '0;
|
||||
alu2_valid_q <= '0;
|
||||
csr_valid_q <= '0;
|
||||
branch_valid_q <= '0;
|
||||
end
|
||||
alu_valid_q <= alu_valid_n;
|
||||
lsu_valid_q <= lsu_valid_n;
|
||||
mult_valid_q <= mult_valid_n;
|
||||
fpu_valid_q <= fpu_valid_n;
|
||||
fpu_fmt_q <= fpu_fmt_n;
|
||||
fpu_rm_q <= fpu_rm_n;
|
||||
alu2_valid_q <= alu2_valid_n;
|
||||
csr_valid_q <= csr_valid_n;
|
||||
branch_valid_q <= branch_valid_n;
|
||||
end
|
||||
end
|
||||
|
||||
if (CVA6Cfg.CvxifEn) begin
|
||||
always_comb begin
|
||||
cvxif_valid_n = '0;
|
||||
cvxif_off_instr_n = 32'b0;
|
||||
for (int unsigned i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||
if (!issue_instr_i[i].ex.valid && issue_instr_valid_i[i] && issue_ack_o[i]) begin
|
||||
case (issue_instr_i[i].fu)
|
||||
CVXIF: begin
|
||||
cvxif_valid_n[i] = 1'b1;
|
||||
cvxif_off_instr_n = orig_instr[i];
|
||||
end
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
if (flush_i) begin
|
||||
cvxif_valid_n = '0;
|
||||
cvxif_off_instr_n = 32'b0;
|
||||
end
|
||||
end
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
cvxif_valid_q <= '0;
|
||||
cvxif_off_instr_q <= 32'b0;
|
||||
end else begin
|
||||
cvxif_valid_q <= '0;
|
||||
cvxif_off_instr_q <= 32'b0;
|
||||
for (int unsigned i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||
if (!issue_instr_i[i].ex.valid && issue_instr_valid_i[i] && issue_ack_o[i]) begin
|
||||
case (issue_instr_i[i].fu)
|
||||
CVXIF: begin
|
||||
cvxif_valid_q[i] <= 1'b1;
|
||||
cvxif_off_instr_q <= orig_instr[i];
|
||||
end
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
if (flush_i) begin
|
||||
cvxif_valid_q <= '0;
|
||||
cvxif_off_instr_q <= 32'b0;
|
||||
end
|
||||
cvxif_valid_q <= cvxif_valid_n;
|
||||
cvxif_off_instr_q <= cvxif_off_instr_n;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1094,6 +1117,30 @@ module issue_read_operands
|
|||
// ----------------------
|
||||
// Registers (ID <-> EX)
|
||||
// ----------------------
|
||||
|
||||
always_comb begin
|
||||
pc_n = '0;
|
||||
is_compressed_instr_n = 1'b0;
|
||||
branch_predict_n = {cf_t'(0), {CVA6Cfg.VLEN{1'b0}}};
|
||||
if (CVA6Cfg.SuperscalarEn) begin
|
||||
if (issue_instr_i[1].fu == CTRL_FLOW) begin
|
||||
pc_n = issue_instr_i[1].pc;
|
||||
is_compressed_instr_n = issue_instr_i[1].is_compressed;
|
||||
branch_predict_n = issue_instr_i[1].bp;
|
||||
end
|
||||
end
|
||||
if (issue_instr_i[0].fu == CTRL_FLOW) begin
|
||||
pc_n = issue_instr_i[0].pc;
|
||||
is_compressed_instr_n = issue_instr_i[0].is_compressed;
|
||||
branch_predict_n = issue_instr_i[0].bp;
|
||||
end
|
||||
x_transaction_rejected_n = 1'b0;
|
||||
if (issue_instr_i[0].fu == CVXIF) begin
|
||||
x_transaction_rejected_n = x_transaction_rejected;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
fu_data_q <= '0;
|
||||
|
@ -1101,6 +1148,7 @@ module issue_read_operands
|
|||
tinst_q <= '0;
|
||||
end
|
||||
pc_o <= '0;
|
||||
is_zcmt_o <= '0;
|
||||
is_compressed_instr_o <= 1'b0;
|
||||
branch_predict_o <= {cf_t'(0), {CVA6Cfg.VLEN{1'b0}}};
|
||||
x_transaction_rejected_o <= 1'b0;
|
||||
|
@ -1120,6 +1168,8 @@ module issue_read_operands
|
|||
pc_o <= issue_instr_i[0].pc;
|
||||
is_compressed_instr_o <= issue_instr_i[0].is_compressed;
|
||||
branch_predict_o <= issue_instr_i[0].bp;
|
||||
if (CVA6Cfg.RVZCMT) is_zcmt_o <= issue_instr_i[0].is_zcmt;
|
||||
else is_zcmt_o <= '0;
|
||||
end
|
||||
x_transaction_rejected_o <= 1'b0;
|
||||
if (issue_instr_i[0].fu == CVXIF) begin
|
||||
|
|
|
@ -60,6 +60,8 @@ module issue_stage
|
|||
output fu_data_t [CVA6Cfg.NrIssuePorts-1:0] fu_data_o,
|
||||
// Program Counter - EX_STAGE
|
||||
output logic [CVA6Cfg.VLEN-1:0] pc_o,
|
||||
// Is zcmt instruction - EX_STAGE
|
||||
output logic is_zcmt_o,
|
||||
// Is compressed instruction - EX_STAGE
|
||||
output logic is_compressed_instr_o,
|
||||
// Transformed trap instruction - EX_STAGE
|
||||
|
@ -157,7 +159,11 @@ module issue_stage
|
|||
// Information dedicated to RVFI - RVFI
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_issue_pointer_o,
|
||||
// Information dedicated to RVFI - RVFI
|
||||
output logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_commit_pointer_o
|
||||
output logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_commit_pointer_o,
|
||||
// Information dedicated to RVFI - RVFI
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rvfi_rs1_o,
|
||||
// Information dedicated to RVFI - RVFI
|
||||
output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rvfi_rs2_o
|
||||
);
|
||||
// ---------------------------------------------------
|
||||
// Scoreboard (SB) <-> Issue and Read Operands (IRO)
|
||||
|
@ -170,19 +176,11 @@ module issue_stage
|
|||
scoreboard_entry_t [CVA6Cfg.NR_SB_ENTRIES-1:0] sbe;
|
||||
} forwarding_t;
|
||||
|
||||
forwarding_t fwd;
|
||||
scoreboard_entry_t [CVA6Cfg.NrIssuePorts-1:0] issue_instr_sb_iro;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][ 31:0] orig_instr_sb_iro;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] issue_instr_valid_sb_iro;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] issue_ack_iro_sb;
|
||||
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs1_forwarding_xlen;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs2_forwarding_xlen;
|
||||
|
||||
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||
assign rs1_forwarding_o[i] = rs1_forwarding_xlen[i][CVA6Cfg.VLEN-1:0];
|
||||
assign rs2_forwarding_o[i] = rs2_forwarding_xlen[i][CVA6Cfg.VLEN-1:0];
|
||||
end
|
||||
forwarding_t fwd;
|
||||
scoreboard_entry_t [CVA6Cfg.NrIssuePorts-1:0] issue_instr_sb_iro;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] orig_instr_sb_iro;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] issue_instr_valid_sb_iro;
|
||||
logic [CVA6Cfg.NrIssuePorts-1:0] issue_ack_iro_sb;
|
||||
|
||||
assign issue_instr_o = issue_instr_sb_iro[0];
|
||||
assign issue_instr_hs_o = issue_instr_valid_sb_iro[0] & issue_ack_iro_sb[0];
|
||||
|
@ -260,9 +258,10 @@ module issue_stage
|
|||
.issue_ack_o (issue_ack_iro_sb),
|
||||
.fwd_i (fwd),
|
||||
.fu_data_o (fu_data_o),
|
||||
.rs1_forwarding_o (rs1_forwarding_xlen),
|
||||
.rs2_forwarding_o (rs2_forwarding_xlen),
|
||||
.rs1_forwarding_o (rs1_forwarding_o),
|
||||
.rs2_forwarding_o (rs2_forwarding_o),
|
||||
.pc_o,
|
||||
.is_zcmt_o,
|
||||
.is_compressed_instr_o,
|
||||
.flu_ready_i (flu_ready_i),
|
||||
.alu_valid_o (alu_valid_o),
|
||||
|
@ -299,7 +298,9 @@ module issue_stage
|
|||
.wdata_i,
|
||||
.we_gpr_i,
|
||||
.we_fpr_i,
|
||||
.stall_issue_o
|
||||
.stall_issue_o,
|
||||
.rvfi_rs1_o (rvfi_rs1_o),
|
||||
.rvfi_rs2_o (rvfi_rs2_o)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -272,9 +272,9 @@ module macro_decoder #(
|
|||
|
||||
unique case (state_q)
|
||||
IDLE: begin
|
||||
if (is_macro_instr_i && issue_ack_i) begin
|
||||
if (is_macro_instr_i) begin
|
||||
reg_numbers_d = reg_numbers - 1'b1;
|
||||
state_d = INIT;
|
||||
state_d = issue_ack_i ? INIT : IDLE;
|
||||
case (macro_instr_type)
|
||||
PUSH: begin
|
||||
offset_d = 12'hFFC + 12'hFFC;
|
||||
|
@ -423,7 +423,7 @@ module macro_decoder #(
|
|||
end
|
||||
end
|
||||
INIT: begin
|
||||
fetch_stall_o = 1'b1; // stall inst fetch
|
||||
fetch_stall_o = is_macro_instr_i; // stall inst fetch
|
||||
if (issue_ack_i && is_macro_instr_i && macro_instr_type == PUSH) begin
|
||||
if (reg_numbers_q == 4'b0001) begin
|
||||
if (CVA6Cfg.XLEN == 64) begin
|
||||
|
|
|
@ -67,8 +67,7 @@ module mult
|
|||
.result_o (mul_result),
|
||||
.mult_valid_i (mul_valid_op),
|
||||
.mult_valid_o (mul_valid),
|
||||
.mult_trans_id_o(mul_trans_id),
|
||||
.mult_ready_o () // this unit is unconditionally ready
|
||||
.mult_trans_id_o(mul_trans_id)
|
||||
);
|
||||
|
||||
// ---------------------
|
||||
|
|
|
@ -38,8 +38,6 @@ module multiplier
|
|||
output logic [ CVA6Cfg.XLEN-1:0] result_o,
|
||||
// Mutliplier result is valid - Mult
|
||||
output logic mult_valid_o,
|
||||
// Multiplier FU is ready - Mult
|
||||
output logic mult_ready_o,
|
||||
// Multiplier transaction ID - Mult
|
||||
output logic [CVA6Cfg.TRANS_ID_BITS-1:0] mult_trans_id_o
|
||||
);
|
||||
|
@ -90,7 +88,6 @@ module multiplier
|
|||
// control signals
|
||||
assign mult_valid_o = mult_valid_q;
|
||||
assign mult_trans_id_o = trans_id_q;
|
||||
assign mult_ready_o = 1'b1;
|
||||
|
||||
assign mult_valid = mult_valid_i && (operation_i inside {MUL, MULH, MULHU, MULHSU, MULW, CLMUL, CLMULH, CLMULR});
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ module perf_counters
|
|||
input logic rst_ni,
|
||||
input logic debug_mode_i, // debug mode
|
||||
// SRAM like interface
|
||||
input logic [11:0] addr_i, // read/write address (up to 6 counters possible)
|
||||
input logic [11:0] addr_i, // read/write address (up to ariane_pkg::MHPMCounterNum counters possible)
|
||||
input logic we_i, // write enable
|
||||
input logic [CVA6Cfg.XLEN-1:0] data_i, // data to write
|
||||
output logic [CVA6Cfg.XLEN-1:0] data_o, // data to read
|
||||
|
@ -68,7 +68,7 @@ module perf_counters
|
|||
//internal signal to keep track of exception
|
||||
logic read_access_exception, update_access_exception;
|
||||
|
||||
logic events[6:1];
|
||||
logic events[MHPMCounterNum:1];
|
||||
//internal signal for MUX select line input
|
||||
logic [4:0] mhpmevent_d[MHPMCounterNum:1];
|
||||
logic [4:0] mhpmevent_q[MHPMCounterNum:1];
|
||||
|
@ -146,7 +146,7 @@ module perf_counters
|
|||
update_access_exception = 1'b0;
|
||||
|
||||
// Increment the non-inhibited counters with active events
|
||||
for (int unsigned i = 1; i <= 6; i++) begin
|
||||
for (int unsigned i = 1; i <= MHPMCounterNum; i++) begin
|
||||
if ((!debug_mode_i) && (!we_i)) begin
|
||||
if ((events[i]) == 1 && (!mcountinhibit_i[i+2])) begin
|
||||
generic_counter_d[i] = generic_counter_q[i] + 1'b1;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -85,7 +85,6 @@ module store_buffer
|
|||
speculative_status_cnt = speculative_status_cnt_q;
|
||||
|
||||
// default assignments
|
||||
speculative_status_cnt_n = speculative_status_cnt_q;
|
||||
speculative_read_pointer_n = speculative_read_pointer_q;
|
||||
speculative_write_pointer_n = speculative_write_pointer_q;
|
||||
speculative_queue_n = speculative_queue_q;
|
||||
|
@ -147,6 +146,7 @@ module store_buffer
|
|||
CVA6Cfg.DCACHE_INDEX_WIDTH-1 :
|
||||
CVA6Cfg.DCACHE_INDEX_WIDTH];
|
||||
assign req_port_o.data_wdata = commit_queue_q[commit_read_pointer_q].data;
|
||||
assign req_port_o.data_wuser = '0;
|
||||
assign req_port_o.data_be = commit_queue_q[commit_read_pointer_q].be;
|
||||
assign req_port_o.data_size = commit_queue_q[commit_read_pointer_q].data_size;
|
||||
|
||||
|
|
133
core/zcmt_decoder.sv
Normal file
133
core/zcmt_decoder.sv
Normal file
|
@ -0,0 +1,133 @@
|
|||
// Licensed under the Solderpad Hardware Licence, 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/
|
||||
//
|
||||
// Author: Farhan Ali Shah, 10xEngineers
|
||||
// Date: 15.11.2024
|
||||
// Description: ZCMT extension in the CVA6 core targeting the 32-bit embedded-class platforms (CV32A60x).
|
||||
// ZCMT is a code-size reduction feature that utilizes compressed table jump instructions (cm.jt and cm.jalt) to
|
||||
//reduce code size for embedded systems
|
||||
//
|
||||
module zcmt_decoder #(
|
||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||
parameter type dcache_req_i_t = logic,
|
||||
parameter type dcache_req_o_t = logic,
|
||||
parameter type jvt_t = logic,
|
||||
parameter type branchpredict_sbe_t = logic
|
||||
) (
|
||||
// Subsystem Clock - SUBSYSTEM
|
||||
input logic clk_i,
|
||||
// Asynchronous reset active low - SUBSYSTEM
|
||||
input logic rst_ni,
|
||||
// Instruction input - compressed_decoder
|
||||
input logic [ 31:0] instr_i,
|
||||
// current PC - FRONTEND
|
||||
input logic [CVA6Cfg.VLEN-1:0] pc_i,
|
||||
// Intruction is of ZCMT extension - compressed_decoder
|
||||
input logic is_zcmt_instr_i,
|
||||
// Instruction is illegal - compressed_decoder
|
||||
input logic illegal_instr_i,
|
||||
// Instruction is compressed - compressed_decoder
|
||||
input logic is_compressed_i,
|
||||
// JVT struct input - CSR
|
||||
input jvt_t jvt_i,
|
||||
// Data cache request output - CACHE
|
||||
input dcache_req_o_t req_port_i,
|
||||
// Instruction out - cvxif_compressed_if_driver
|
||||
output logic [ 31:0] instr_o,
|
||||
// Instruction is illegal out - cvxif_compressed_if_driver
|
||||
output logic illegal_instr_o,
|
||||
// Instruction is compressed out - cvxif_compressed_if_driver
|
||||
output logic is_compressed_o,
|
||||
// Fetch stall - cvxif_compressed_if_driver
|
||||
output logic fetch_stall_o,
|
||||
// Data cache request input - CACHE
|
||||
output dcache_req_i_t req_port_o,
|
||||
// jump_address
|
||||
output logic [CVA6Cfg.XLEN-1:0] jump_address_o
|
||||
);
|
||||
|
||||
// FSM States
|
||||
enum logic {
|
||||
IDLE, // if ZCMT instruction then request sent to fetch the entry from jump table
|
||||
TABLE_JUMP // Check the valid data from jump table and Calculate the offset for jump and create jal instruction
|
||||
}
|
||||
state_d, state_q;
|
||||
// Temporary registers
|
||||
// Physical address: jvt + (index <<2)
|
||||
logic [CVA6Cfg.VLEN-1:0] table_address;
|
||||
|
||||
always_comb begin
|
||||
state_d = state_q;
|
||||
illegal_instr_o = 1'b0;
|
||||
is_compressed_o = is_zcmt_instr_i || is_compressed_i;
|
||||
fetch_stall_o = '0;
|
||||
jump_address_o = '0;
|
||||
|
||||
// cache request port
|
||||
req_port_o.data_wdata = '0;
|
||||
req_port_o.data_wuser = '0;
|
||||
req_port_o.data_req = 1'b0;
|
||||
req_port_o.data_we = 1'b0;
|
||||
req_port_o.data_be = '0;
|
||||
req_port_o.data_size = 2'b10;
|
||||
req_port_o.data_id = 1'b1;
|
||||
req_port_o.kill_req = 1'b0;
|
||||
req_port_o.tag_valid = 1'b1;
|
||||
|
||||
unique case (state_q)
|
||||
IDLE: begin
|
||||
fetch_stall_o = 1'b0;
|
||||
if (is_zcmt_instr_i) begin
|
||||
if (CVA6Cfg.XLEN == 32) begin //It is only target for 32 bit targets in cva6 with No MMU
|
||||
table_address = {jvt_i.base, 6'b000000} + {24'h0, instr_i[7:2], 2'b00};
|
||||
req_port_o.address_index = table_address[9:0];
|
||||
req_port_o.address_tag = table_address[CVA6Cfg.VLEN-1:10]; // No MMU support
|
||||
state_d = TABLE_JUMP;
|
||||
req_port_o.data_req = 1'b1;
|
||||
fetch_stall_o = 1'b1;
|
||||
end else illegal_instr_o = 1'b1;
|
||||
// Condition may be extented for 64 bits embedded targets with No MMU
|
||||
end else begin
|
||||
illegal_instr_o = illegal_instr_i;
|
||||
instr_o = instr_i;
|
||||
state_d = IDLE;
|
||||
end
|
||||
end
|
||||
TABLE_JUMP: begin
|
||||
if (req_port_i.data_rvalid) begin
|
||||
// save the PC relative Xlen table jump address
|
||||
jump_address_o = $unsigned($signed(req_port_i.data_rdata) - $signed(pc_i));
|
||||
if (instr_i[9:2] < 32) begin // jal pc_offset, x0 for no return stack
|
||||
instr_o = {
|
||||
20'h0, 5'h0, riscv::OpcodeJal
|
||||
}; // immidiate assigned here (0) will be overwrite in decode stage with jump_address_o
|
||||
end else if ((instr_i[9:2] >= 32) & (instr_i[9:2] <= 255)) begin //- jal pc_offset, x1 for return stack
|
||||
instr_o = {
|
||||
20'h0, 5'h1, riscv::OpcodeJal
|
||||
}; // immidiate assigned here (0) will be overwrite in decode stage with jump_address_o
|
||||
end else begin
|
||||
illegal_instr_o = 1'b1;
|
||||
instr_o = instr_i;
|
||||
end
|
||||
state_d = IDLE;
|
||||
end else begin
|
||||
state_d = TABLE_JUMP;
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
state_d = IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
state_q <= IDLE;
|
||||
|
||||
end else begin
|
||||
state_q <= state_d;
|
||||
end
|
||||
end
|
||||
endmodule
|
|
@ -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
|
||||
|
|
|
@ -78,8 +78,14 @@ module rvfi_tracer #(
|
|||
// print the instruction information if the instruction is valid or a trap is taken
|
||||
if (rvfi_i[i].valid) begin
|
||||
// Instruction information
|
||||
$fwrite(f, "core 0: 0x%h (0x%h) DASM(%h)\n",
|
||||
pc64, rvfi_i[i].insn, rvfi_i[i].insn);
|
||||
if (rvfi_i[i].intr[2]) begin
|
||||
$fwrite(f, "core INTERRUPT 0: 0x%h (0x%h) DASM(%h)\n",
|
||||
pc64, rvfi_i[i].insn, rvfi_i[i].insn);
|
||||
end
|
||||
else begin
|
||||
$fwrite(f, "core 0: 0x%h (0x%h) DASM(%h)\n",
|
||||
pc64, rvfi_i[i].insn, rvfi_i[i].insn);
|
||||
end
|
||||
// Destination register information
|
||||
if (rvfi_i[i].insn[1:0] != 2'b11) begin
|
||||
$fwrite(f, "%h 0x%h (0x%h)",
|
||||
|
@ -129,8 +135,13 @@ module rvfi_tracer #(
|
|||
32'h5: cause = "LD_ACCESS_FAULT";
|
||||
32'h6: cause = "ST_ADDR_MISALIGNED";
|
||||
32'h7: cause = "ST_ACCESS_FAULT";
|
||||
32'hb: cause = "ENV_CALL_MMODE";
|
||||
endcase;
|
||||
$fwrite(f, "%s exception @ 0x%h\n", cause, pc64);
|
||||
if (rvfi_i[i].insn[1:0] != 2'b11) begin
|
||||
$fwrite(f, "%s exception @ 0x%h (0x%h)\n", cause, pc64, rvfi_i[i].insn[15:0]);
|
||||
end else begin
|
||||
$fwrite(f, "%s exception @ 0x%h (0x%h)\n", cause, pc64, rvfi_i[i].insn);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
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::[]
|
||||
|
|
|
@ -61,57 +61,71 @@ Supported Parameters
|
|||
|
||||
The following table presents CVXIF parameters supported by CVA6.
|
||||
|
||||
[cols=",,",options="header",]
|
||||
[cols=",a,a",options="header",]
|
||||
|=============================================
|
||||
|Signal |Value |Description
|
||||
|*X_NUM_RS* |int: 2 or 3 (configurable) a|
|
||||
|*X_NUM_RS* |
|
||||
int: 2 or 3 (configurable) +
|
||||
|
||||
* CV32A60X: 2
|
||||
* CV32A65X: 2
|
||||
|
|
||||
[verse]
|
||||
--
|
||||
Number of register file read ports that can
|
||||
be used by the eXtension interface
|
||||
--
|
||||
|
||||
|
|
||||
|*X_ID_WIDTH* |int: 3 a|
|
||||
|*X_ID_WIDTH* |
|
||||
int: 1 to 32 +
|
||||
|
||||
* CV32A60X: 2
|
||||
* CV32A65X: 3
|
||||
|
|
||||
[verse]
|
||||
--
|
||||
Identification width for the eXtension
|
||||
interface
|
||||
--
|
||||
|
||||
|
|
||||
|*X_MEM_WIDTH* |n/a (feature not supported) a|
|
||||
|*X_MEM_WIDTH* |n/a (feature not supported) |
|
||||
[verse]
|
||||
--
|
||||
Memory access width for loads/stores via the
|
||||
eXtension interface
|
||||
--
|
||||
|
||||
|
|
||||
|*X_RFR_WIDTH* |int: `XLEN` (32 or 64) a|
|
||||
|*X_RFR_WIDTH* |
|
||||
int: `XLEN` (32 or 64) +
|
||||
|
||||
* CV32A60X: 32
|
||||
* CV32A65X: 32
|
||||
|
|
||||
[verse]
|
||||
--
|
||||
Register file read access width for the
|
||||
eXtension interface
|
||||
--
|
||||
|
||||
|
|
||||
|*X_RFW_WIDTH* |int: `XLEN` (32 or 64) a|
|
||||
|*X_RFW_WIDTH* |
|
||||
int: `XLEN` (32 or 64) +
|
||||
|
||||
* CV32A60X: 32
|
||||
* CV32A65X: 32
|
||||
|
|
||||
[verse]
|
||||
--
|
||||
Register file write access width for the
|
||||
eXtension interface
|
||||
--
|
||||
|
||||
|
|
||||
|*X_MISA* |logic[31:0]: 0x0000_0000 a|
|
||||
|*X_MISA* |logic[31:0]: 0x0000_0000 |
|
||||
[verse]
|
||||
--
|
||||
MISA extensions implemented on the eXtension
|
||||
interface
|
||||
--
|
||||
|
||||
|
|
||||
|=============================================
|
||||
|
||||
[[cv-x-if-enabling]]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3,3 +3,9 @@ sphinx-rtd-theme
|
|||
recommonmark
|
||||
sphinxcontrib-svg2pdfconverter
|
||||
sphinx_github_changelog
|
||||
|
||||
# for gen_from_riscv_config
|
||||
mako
|
||||
mdutils
|
||||
pyyaml
|
||||
rstcloth
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 2c07aa2bcc02fd5fb2e53e42a32dc62a3eb0aa62
|
||||
Subproject commit 4f277ff8ea8c0fc9394dfccd1da0ace34b1aef68
|
|
@ -7,7 +7,7 @@
|
|||
This document describes the RISC-V unprivileged architecture tailored for
|
||||
OpenHW Group {ohg-config}.
|
||||
|
||||
[.big]*_Preface to Document Version 20241017_*
|
||||
[.big]*_Preface to Document Version 20241101_*
|
||||
|
||||
This document describes the RISC-V unprivileged architecture.
|
||||
|
||||
|
|
|
@ -226,10 +226,17 @@ supervisor modes respectively.
|
|||
|
||||
The "X" bit will be set if there are any non-standard extensions.
|
||||
|
||||
When "B" bit is 1, the implementation supports the instructions provided by the
|
||||
Zba, Zbb, and Zbs extensions. When "B" bit is 0, it indicates that the
|
||||
When the "B" bit is 1, the implementation supports the instructions provided by the
|
||||
Zba, Zbb, and Zbs extensions. When the "B" bit is 0, it indicates that the
|
||||
implementation may not support one or more of the Zba, Zbb, or Zbs extensions.
|
||||
|
||||
When the "M" bit is 1, the implementation supports all multiply and
|
||||
division instructions defined by the M extension. When the "M" bit
|
||||
is 0, it indicates that the implementation may not support those
|
||||
instructions. However if the Zmmul extension is supported then
|
||||
the multiply instructions it specifies are supported irrespective
|
||||
of the value of the "M" bit.
|
||||
|
||||
ifeval::[{note} == true]
|
||||
[NOTE]
|
||||
====
|
||||
|
@ -391,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.
|
||||
|
||||
|
@ -501,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::[]
|
||||
|
@ -1242,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
|
||||
|
@ -1554,7 +1561,7 @@ additional microarchitectural bits might be maintained in the extension
|
|||
to further reduce context save and restore overhead.
|
||||
|
||||
The SD bit is read-only and is set when either the FS, VS, or XS bits
|
||||
encode a Dirty state (i.e., SD=((FS==11) OR (XS==11) OR (VS==11))). This
|
||||
encode a Dirty state (i.e., `SD=(FS==0b11 OR XS==0b11 OR VS==0b11)`). This
|
||||
allows privileged code to quickly determine when no additional context
|
||||
save is required beyond the integer register set and `pc`.
|
||||
|
||||
|
@ -2108,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.
|
||||
|
@ -2211,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::[]
|
||||
|
@ -3502,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.
|
||||
|
@ -3865,7 +3872,9 @@ and I/O regions may be accessed with either _relaxed_ or _strong_
|
|||
ordering. Accesses to an I/O region with relaxed ordering are generally
|
||||
observed by other harts and bus mastering devices in a manner similar to
|
||||
the ordering of accesses to an RVWMO memory region, as discussed in
|
||||
Section A.4.2 in Volume I of this specification. By contrast, accesses
|
||||
the I/O Ordering section in the RVWMO Explanatory Material appendix
|
||||
of Volume I of this specification.
|
||||
By contrast, accesses
|
||||
to an I/O region with strong ordering are generally observed by other
|
||||
harts and bus mastering devices in program order.
|
||||
|
||||
|
@ -4059,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
|
||||
|
@ -4482,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::[]
|
||||
|
|
7
docs/riscv-isa/src/mm-formal.adoc
Normal file
7
docs/riscv-isa/src/mm-formal.adoc
Normal file
|
@ -0,0 +1,7 @@
|
|||
[appendix]
|
||||
== Formal Memory Model Specifications, Version 0.1
|
||||
[[mm-formal]]
|
||||
|
||||
ifdef::archi-CV32A60X,archi-CV32A65X[]
|
||||
{ohg-config}: No RVWMO memory model.
|
||||
endif::[]
|
1039
docs/riscv-isa/src/priv-csrs.adoc
Normal file
1039
docs/riscv-isa/src/priv-csrs.adoc
Normal file
File diff suppressed because it is too large
Load diff
|
@ -6,6 +6,98 @@
|
|||
This document describes the RISC-V privileged architecture tailored for
|
||||
OpenHW Group {ohg-config}.
|
||||
|
||||
[.big]*_Preface to Version 20241101_*
|
||||
|
||||
This document describes the RISC-V privileged architecture. This
|
||||
release, version 20241101, contains the following versions of the RISC-V ISA
|
||||
modules:
|
||||
|
||||
[%autowidth,float="center",align="center",cols="^,<,^",options="header",]
|
||||
|===
|
||||
|Module |Version |Status
|
||||
|_Machine ISA_ +
|
||||
*Smstateen Extension* +
|
||||
*Smcsrind/Sscsrind Extension* +
|
||||
*Smepmp Extension* +
|
||||
*Smcntrpmf Extension* +
|
||||
*Smrnmi Extension* +
|
||||
*Smcdeleg Extension* +
|
||||
*Smdbltrp Extension* +
|
||||
_Supervisor ISA_ +
|
||||
*Svade Extension* +
|
||||
*Svnapot Extension* +
|
||||
*Svpbmt Extension* +
|
||||
*Svinval Extension* +
|
||||
*Svadu Extension* +
|
||||
*Sstc Extension* +
|
||||
*Sscofpmf Extension* +
|
||||
*Ssdbltrp Extension* +
|
||||
*Ssqosid Extension* +
|
||||
*Hypervisor ISA* +
|
||||
*Shlcofideleg Extension* +
|
||||
*Svvptc Extension*
|
||||
|
||||
|_1.14_ +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
_1.14_ +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0* +
|
||||
*1.0*
|
||||
|
||||
|_Draft_ +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
_Draft_ +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified* +
|
||||
*Ratified*
|
||||
|===
|
||||
|
||||
The following changes have been made since version 1.13 of the Machine and
|
||||
Supervisor ISAs, which, while not strictly backwards compatible, are not
|
||||
anticipated to cause software portability problems in practice:
|
||||
|
||||
* (None yet)
|
||||
|
||||
Additionally, the following compatible changes have been
|
||||
made to the Machine and Supervisor ISAs since version 1.13:
|
||||
|
||||
* Defined the `mstateen0` P1P14 field.
|
||||
|
||||
Finally, the following clarifications and document improvements have been made
|
||||
since the last document release:
|
||||
|
||||
* (None yet)
|
||||
|
||||
[.big]*_Preface to Version 20241017_*
|
||||
|
||||
This document describes the RISC-V privileged architecture. This
|
||||
|
|
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