Compare commits

..

78 commits

Author SHA1 Message Date
Mike Thompson
733743da0f
Fix URLs to point to CV32A60X-specific files on RTDs. (#2938)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
This fixes the paths for the CV32A60X-specific documentation (from the cv32a60x branch). Whenever the cv32a60x branch is updated, the documentation will be regenerated by RTD.
2025-04-16 23:00:33 +02:00
André Sintzoff
30811d1e7e
docs: link to CV32A60X design documentation (#2931)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
2025-04-15 11:36:38 +02:00
Mike Thompson
8bcb14a2df
CV32A60X ISA (#2922)
* Bring in CV32A60X ISA from the cv32a60x branch
2025-04-15 09:40:35 +02:00
AngelaGonzalezMarino
f7fae486ff
Fix https://github.com/openhwgroup/cva6/issues/2912 (#2916)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
Fix the wrong connection of ASID in MMU. Should solve #2912
2025-04-11 17:21:29 +02:00
Enrico Zelioli
b9da1d9e2d
Fix instruction tracer for superscalar mode (#2901)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
This PR adapts the instr_tracer module to support superscalar mode.
2025-04-06 13:30:18 +02:00
Côme
7b3054156e
Add CVA6 performance model (#2880)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
2025-03-28 14:50:12 +01:00
Florian Zaruba
4a1bffa87a
CODEOWNERS: remove zarubaf from global owners (#2869)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
2025-03-27 00:05:15 +01:00
Côme
1342bc960b
remove useless COMMA macro (#2850)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
This macro is not required and makes the file harder to parse.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-03-20 19:01:12 +01:00
Valentin Thomazic
75bc12d01b
ci: fix pmp tests (#2851)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
Run PMP tests on cv32a65x since PMP has been disabled on cv32a60x by #2848
2025-03-20 17:43:56 +01:00
André Sintzoff
a165a2bb50
cv32a60x_config_pkg.sv: set NrPMPEntries to 0 (#2848)
to build correct RISC-V ISA privilege manual
2025-03-20 12:23:22 +01:00
Guillaume Chauvon
b258d27816
[CVXIF] Initialize exception fields for RVH (#2844)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
Following what was done in branch_unit, I set up a default value for hypervisor exception fields in cvxif_fu.
Should fix issue #2831

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-03-19 17:31:29 +01:00
André Sintzoff
79c7c2c681
docs: add HTML generation for cv32a60x (followup PR2838) (#2845)
update global doc Makefile

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-03-19 12:00:13 +01:00
Valentin Thomazic
d94db10fb1
Minor dashboard-related adjustement (#2841)
* wait for dashboard generation before commenting PRs with pipeline report link.
* change dashboard link and badge

---------

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-03-19 11:14:10 +01:00
André Sintzoff
21506e4c66
docs: add CV32A60X configuration in RISC-V ISA manual (#2838)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
* docs: spec_builder.py: add missing extensions
* docs: fix unpriv manual (opcode map, Zcmop)
* in opcode map, write not used when corresponding extension is disabled
* use correct condition for Zcmop extension
* docs: remove PMP chapter when no PMP
* docs: add tailored RISC-V ISA manual for CV32A60X configuration

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-03-19 00:03:00 +01:00
Guillaume Chauvon
b38c259c8c
Initialize compressed related signals in id_stage when RVC is disabled (#2833)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
Add else case to initialize signals going into decoder.
Should fix #2819
2025-03-17 17:35:43 +01:00
Katharina
0e2e5128b2
Assign a default value to tinst in decoder (#2830)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
This PR assigns 0 to tinst by default.
Even though tinst is only used when CVA6Cfg.RVH is enabled, I chose to assign it a default value in all configurations, since the signal is defined for all configurations.

Fixes #2803

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-03-14 22:42:29 +01:00
Jonathan Balkind
2b1f45cad9
Update CODEOWNERS with jbalkind and cfuguet (#2829)
Updating @Jbalkind and adding @cfuguet to CODEOWNERS
2025-03-14 22:39:36 +01:00
Valentin Thomazic
45e845d165
ci: test PMP with CV32A60X (#2825)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
Bring the tests added by #2648 in Gitlab CI:
* Rename PMP tests with generic names
* Add a CV32A60X PMP testlist
* Adapt PMP test script to run the testlist
* Add a CI job running said test script
2025-03-12 23:21:10 +01:00
khandelwaltanuj
3a389af151
added correct reset val (#2823)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
For cv64a60ax configuration
2025-03-12 15:19:15 +01:00
OlivierBetschi
c3fe25aeda
PMP Verif Plan and tests (#2648)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
Verification Plan provided in VP_TOOL for the PMP. The verification plan should be complete, however only a partial set of the tests is available. This is not included in the CI but a bash script is available to run the test.
2025-03-12 13:17:40 +01:00
MaxCThales
f984dc347f
Granularity .3f only in report for kGates (#2820)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
Changing the type of Kgates from int to float in order to add more granularity on the report (usefull when the difference is under 1k Gates)

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-03-11 21:39:51 +01:00
Riccardo Tedeschi
028ce43fce
docs: add bht2lvl image (#2814)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
2025-03-07 22:01:28 +01:00
Geza Lore
c511b21911
Workaround for Verilator ordering issue in OpenPiton cache adapter (#2809)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
This code hits verilator/verilator#5829 due to the use of partial assignments to dcache_rtrn_o in this always block, while reading other bits of the same packed struct elsewhere in the block.

The actual effect of this is that with a Verilator simulation, invalidation requests incoming from the coherence network are sometimes ignored breaking AMOs.

Moving the assignments to the bits read in the always block into the same always block avoids this issue.

---------

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-06 17:16:13 +01:00
Riccardo Tedeschi
aae9b2eb66
bp: add BHT with private history (#2793)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
This PR adds a new two-level BHT predictor with private history. The new BPType parameters allow choosing between the original BHT and the new one.

Co-authored-by: Gianmarco Ottavi <ottavig91@gmail.com>
2025-03-06 09:45:45 +01:00
Nils Wistoff
d971232cd7
mmu: Use latched value to determine if misaligned exception occurred (#2802)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
Adds to #2798. Sorry for noticing this only now. Together with #2798, this reverts a bug that was introduced in #2528.

Signed-off-by: Nils Wistoff <nwistoff@iis.ee.ethz.ch>
2025-02-28 23:50:35 +01:00
khandelwaltanuj
ab89beaebb
Adding a new configuration file for cv64a60ax and dv target RV64IMAFDC (#2761)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
A new configuration file and core v target is added to start working on a 64 bit CVA6 core.

---------

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-02-28 07:55:13 +01:00
Nils Wistoff
14ef741bae
mmu: Latch misaligned exception to fix misattribution (#2798)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
The load and store units sample the MMU exception one cycle after
`dtlb_hit` is asserted. However, misaligned exceptions are currently fed
through the MMU, potentially attributing a misaligned exception to the
*preceding* instruction. Fix this by latching the misaligned exception.

Signed-off-by: Nils Wistoff <nwistoff@iis.ee.ethz.ch>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-02-27 23:08:22 +01:00
Matteo Perotti
3e73712c3e
cva6_ptw: fix latch when RVH is disabled (#2795)
Fix a small latch created when RVH is off.
2025-02-27 23:05:25 +01:00
AngelaGonzalezMarino
6e0cf8d730
Altera fpga update (#2790)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
Update Altera APU design to support linux in both 32 and 64 bits
* Move JTAG UART inside peripherals to properly connect the interruput request to PLIC
* Reduce the frequency of operation to 100MHz to avoid timing issues in 64bit version
* Update UART read and write operation in bootrom to allow keyboard interrupt
2025-02-25 22:12:55 +01:00
Riccardo Tedeschi
bac134b7b5
cv*_config_pkg.sv: separately parametrize RVF and RVD (#2786)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
Use separate parametrization for RVF and RVD support. In the cv32a6_imafc_sv32 configuration RVD is currently enabled, leading to compilation errors.

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-02-25 07:13:29 +01:00
Valentin Thomazic
dfdc72cb5a
Enable gdb on toolchain builder (#2789)
As discussed in #2775 (comment) , this pr enables gdb back on the toolchain build scripts. It also updates the README to use the current toolchain name for the gdb section.
2025-02-25 07:09:27 +01:00
Nils Wistoff
2d411b2dc8
instr_tracer.sv: Fix double sampling (#2782)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
Currently, the instruction trace update logic is triggered on both clock
edges, leading to double entries in the instruction trace and a wrong
cycle count. Fix this by updating the trace only on positive clock edges.

Signed-off-by: Nils Wistoff <nwistoff@iis.ee.ethz.ch>
2025-02-20 07:18:59 +01:00
Nils Wistoff
a55db35bd1
Makefile: Fix FPGA bootrom path (#2774)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
`src/bootrom/bootrom_$(XLEN).sv` does not exist relative to the Makefile
and is not built by the recipe. Like all other FPGA source files, prefix
the full path to `bootrom_$(XLEN).sv`.

Signed-off-by: Nils Wistoff <nwistoff@iis.ee.ethz.ch>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-02-19 23:21:09 +01:00
JeanRochCoulon
e4c28b0b03
Simplify the Verilog "inside" (from @flaviens) (#2776)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
Hi! Some tools like morty struggle with this expression. I suggest this very simple rewrite. No need for fancy constructs here.
Thanks @flaviens for this contribution
2025-02-19 09:45:30 +01:00
Guillaume Chauvon
be7c8746c6
Add parameter type to define which coprocessor is instantiated on CVXIF (#2772)
Add parameter CoproType to select which coprocessor to instantiate when CvxifEn == 1
---------

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-02-19 08:52:17 +01:00
Jérôme Quévremont
373401537e
[Skip CI] Update to CONTRIBUTING.md (#2769)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
Writing some rules that were previously implicit.

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-02-13 21:27:35 +01:00
Côme
07bb91f5a2
ci: require correct formatting (#2771)
let CI fail if verible catches mismatches to prevent them from being accidentally merged

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-02-13 21:25:37 +01:00
Nils Wistoff
abf21ee221
cva6_icache: Fix formatting (#2770)
Run verible verilog format to fix upstream formatting.

Signed-off-by: Nils Wistoff <nwistoff@iis.ee.ethz.ch>
2025-02-13 21:24:31 +01:00
dependabot[bot]
7b759a8b71
Bump verif/sim/dv from f0c570d to 7e54b67 (#2763)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
Bumps [verif/sim/dv](https://github.com/google/riscv-dv) from `f0c570d` to `7e54b67`.
- [Commits](f0c570d112...7e54b678ab)

---
updated-dependencies:
- dependency-name: verif/sim/dv
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-02-11 10:48:31 +01:00
Matteo Perotti
1bc415391a
[RVV] CVA6 re-parametrization and MMU interface (#2652)
Follow-up to the discussion on extending Linux support to the Ara vector processor.

* Main changes:
Add:
Add external MMU interface to share the MMU with the external accelerator.
Add avoid_neg() function used to clip negative numbers to zero. Useful for parametric array sizes and vector multipliers.

Modifications:
2 commit ports by default in cv64a6_imafdcv_config_pkg.
Change exception_t from localparam to param in cva6.sv.
Add parameters accelerator_req_t, accelerator_resp_t, acc_mmu_req_t, and acc_mmu_resp_t to cva6.sv.
Replace the fall-through register with a spill register in acc_dispatcher to decouple timing with the accelerator.
Decrease cache sizes in cv64a6_imafdcv_sv39_config_pkg.
Modify Bender.yml package name from ariane to cva6.
Add harmless code to prevent synthesizer tool from crashing when compiling csr_regfile.

* Collateral changes:
Fixes:
Guard some X-IF code lines with correct parameter in cva6.sv.
Parametrize the tracer interface with NrCommitPorts.
Add missing local dependencies to Bender.yml.

---------

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-02-11 07:22:31 +01:00
Guillaume Chauvon
2ef1c1b1fc
Update ID stage to support ZCMP, ZCMT and CVXIF with Superscalar (#2756)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
Add support for Superscalar with ZCMP, ZCMT and CVXIF.
ZCMP decoder, ZCMT decoder and CVXIF interface driver are using port 0.
Standard RVC and 32 bits instruction can take port 0 or 1.
2025-02-03 13:40:02 +01:00
Jalali
fd8c890def
Makefile : Add target to generate functional coverage using verdi tool (#2755)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
Co-authored-by: André Sintzoff <61976467+ASintzoff@users.noreply.github.com>
2025-01-31 14:13:36 +01:00
Jalali
70972dad54
Update rvfi_tracer and cva6.py (#2684)
* RVFI Tracer : Update tracer to support interrupts

* Randomize sv_seed by default

* Change pc64 to pc

* Fixes

* cva6.py : add the capability to create a log for sv_seed

* Tracer : keep pc64 64 targets failed

* Fix UVM seed for performance tests

---------

Co-authored-by: André Sintzoff <61976467+ASintzoff@users.noreply.github.com>
2025-01-31 13:10:27 +01:00
André Sintzoff
10fced1c99
csr_regfile.sv: move CVA6Cfg.DebugEn to improve code coverage (#2753)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
Use CVA6Cfg.DebugEn in an outer test instead of in inner tests
Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-31 05:46:24 +01:00
André Sintzoff
0ec65198bc
doc: fix description of signals in instr_scan.sv (#2752)
as use in design document (automatically generated part)

Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
2025-01-31 05:44:24 +01:00
André Sintzoff
a3372c51f0
cva6_rvfi_probes.sv: fix be5ac20e4 (PR 2749) (#2751)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
rs1_i and rs2_i have XLEN width

Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
2025-01-29 15:50:34 +01:00
André Sintzoff
07f19ea319
decoder.sv: add condition CVA6Cfg.SoftwareInterruptEn (#2747)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
to improve conditional coverage
Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-29 11:46:34 +01:00
André Sintzoff
59822e7ad1
instr_scan.sv: remove useless condition (#2748)
is_rvc is redundant with riscv::OpcodeC1, riscv::OpcodeC2

Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-29 11:45:47 +01:00
JeanRochCoulon
be5ac20e46
Fix RVFI rs1/rs2 len from VLEN to XLEN (#2749)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
RVFI rs1 and rs2 operands were VLEN, it has been fixed to be XLEN.
2025-01-28 18:37:07 +01:00
Jalali
3e8eb88e88
Fix UVM scoreboard check VLEN bits only (#2742)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
2025-01-28 00:07:58 +01:00
Farhan Ali Shah
542fe39adc
Adding support for ZCMT Extension for Code-Size Reduction in CVA6 (#2659)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
## Introduction
This PR implements the ZCMT extension in the CVA6 core, targeting the 32-bit embedded-class platforms. 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
**Note:** Due to implementation complexity, ZCMT extension is primarily targeted at embedded class CPUs. Additionally, it is not compatible with architecture class profiles.(Ref. [Unprivilege spec 27.20](https://drive.google.com/file/d/1uviu1nH-tScFfgrovvFCrj7Omv8tFtkp/view))

## Key additions

- Added zcmt_decoder module for compressed table jump instructions: cm.jt (jump table) and cm.jalt (jump-and-link table)

- Implemented the Jump Vector Table (JVT) CSR to store the base address of the jump table in csr_reg module

- Implemented a return address stack, enabling cm.jalt to behave equivalently to jal ra (jump-and-link with return address), by pushing the return address onto the stack in zcmt_decoder module

## Implementation in CVA6
The implementation of the ZCMT extension involves the following major modifications:

### compressed decoder 
The compressed decoder scans and identifies the cm.jt and cm.jalt instructions, and generates signals indicating that the instruction is both compressed and a ZCMT instruction.

### zcmt_decoder
A new zcmt_decoder module was introduced to decode the cm.jt and cm.jalt instructions, fetch the base address of the JVT table from JVT CSR, extract the index and construct jump instructions to ensure efficient integration of the ZCMT extension in embedded platforms. Table.1 shows the IO port connection of zcmt_decoder module. High-level block diagram of zcmt implementation in CVA6 is shown in Figure 1.

_Table. 1 IO port connection with zcmt_decoder module_
Signals | IO | Description | Connection | Type
-- | -- | -- | -- | --
clk_i | in | Subsystem Clock | SUBSYSTEM | logic
rst_ni | in | Asynchronous reset active low | SUBSYSTEM | logic
instr_i | in | Instruction in | compressed_decoder | logic [31:0]
pc_i | in | Current PC | PC from FRONTEND | logic [CVA6Cfg.VLEN-1:0]
is_zcmt_instr_i | in | Is instruction a zcmt instruction | compressed_decoder | logic
illegal_instr_i | in | Is instruction a illegal instruction | compressed_decoder | logic
is_compressed_i | in | Is instruction a compressed instruction | compressed_decoder | logic
jvt_i | in | JVT struct from CSR | CSR | jvt_t
req_port_i | in | Handshake between CACHE and FRONTEND (fetch) | Cache | dcache_req_o_t
instr_o | out | Instruction out | cvxif_compressed_if_driver | logic [31:0]
illegal_instr_o | out | Is the instruction is illegal | cvxif_compressed_if_driver | logic
is_compressed_o | out | Is the instruction is compressed | cvxif_compressed_if_driver | logic
fetch_stall_o | out | Stall siganl | cvxif_compressed_if_driver | logic
req_port_o | out | Handshake between CACHE and FRONTEND (fetch) | Cache | dcache_req_i_t

### branch unit condition
A condition is implemented in the branch unit to ensure that ZCMT instructions always cause a misprediction, forcing the program to jump to the calculated address of the newly constructed jump instruction.

### JVT CSR
A new JVT csr is implemented in csr_reg which holds the base address of the JVT table. The base address is fetched from the JVT CSR, and combined with the index value to calculate the effective address.

### No MMU
Embedded platform does not utilize the MMU, so zcmt_decoder is connected with cache through port 0 of the Dcache module for implicit read access from the memory.

![zcmt_block drawio](https://github.com/user-attachments/assets/ac7bba75-4f56-42f4-9f5e-0c18f00d4dae)
_Figure. 1 High level block diagram of ZCMT extension implementation_

## Known Limitations
The implementation targets 32-bit instructions for embedded-class platforms without an MMU. Since the core does not utilize an MMU, it is leveraged to connect the zcmt_decoder to the cache via port 0.

## Testing and Verification

- Developed directed test cases to validate cm.jt and cm.jalt instruction functionality
- Verified correct initialization and updates of JVT CSR

### Test Plan 
A test plan is developed to test the functionality of ZCMT extension along with JVT CSR. Directed Assembly test executed to check the functionality. 

_Table. 2 Test plan_
S.no | Features | Description | Pass/Fail Criteria | Test Type | Test status
-- | -- | -- | -- | ---- | --
1 | cm.jt | Simple assembly test to validate the working of cm.jt instruction in  CV32A60x. | Check against Spike's ref. model | Directed | Pass
2 | cm.jalt | Simple assembly test to validate the working of cm.jalt instruction in both CV32A60x. | Check against Spike's ref. model | Directed | Pass
3 | cm.jalt with return address stack | Simple assembly test to validate the working of cm.jalt instruction with return address stack in both CV32A60x. It works as jump and link ( j ra, imm) | Check against Spike's ref. model | Directed | Pass
4 | JVT CSR | Read and write base address of Jump table to JVT CSR | Check against Spike's ref. model | Directed | Pass


**Note**: Please find the test under CVA6_REPO_DIR/verif/tests/custom/zcmt"
2025-01-27 13:23:26 +01:00
Riccardo Tedeschi
fb4a8d4472
Fix missing parametrization in performance counters (#2740)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
2025-01-26 21:51:25 +01:00
André Sintzoff
3ebb510374
dvplan_csr-access.md: remove file in VerifPlans/csr_access (#2739)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
as the file is also located in VerifPlans/source

Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
2025-01-24 13:56:24 +01:00
Pascal Cotret
9d039197d1
update smoke tests file names (#2736)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
Related to issue #2715

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-23 17:54:21 +01:00
Riccardo Tedeschi
024b8eada8
config_pkg: fix HPDCache related parameter (#2731)
The AXI AW channel in the HPDcache is shared by three components:

Write Buffer
Flush Controller
Uncached Controller
The ID for each transaction is generated based on its source as follows:

Write Buffer: {1'b0, write_buffer_entry_index}
Flush Controller: {1'b1, flush_controller_index}
Uncached Controller: '1
To distinguish between flush transactions and uncached transactions, the flush transaction ID must include at least one 0.

Currently, the AXI ID is limited to 4 bits, while the flush controller supports 8 entries. As a result, when a transaction is sent from the 8th entry of the flush controller, all bits of the ID are set to 1. This causes the HPDcache to misroute the response to the uncached controller instead of the flush controller.

The parameter CVA6ConfigWtDcacheWbufDepth is used in the WB cache to set the number of flush entries. To avoid modifying the ID width, the number of flush entries must be less than 8. Non-power-of-two values are supported.

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-23 17:53:07 +01:00
André Sintzoff
cbb08e8d19
docs: clarify WLRL CSR fields on CVA6 (fix #1053) (#2733)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
as priv-csrs.adoc was not yet tailored for CVA6, the file is copied
and tailored

Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
2025-01-23 16:48:13 +01:00
Guillaume Chauvon
3ce44b1b4e
Spyglass clean up: multiple change to remove Spyglass warnings (#2727)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
Multiple changes to clean up code and remove Spyglass warnings.

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-23 08:32:31 +01:00
Guillaume Chauvon
664c515b22
Fix decoding of CLRI, BINVI, BSETI, BEXTI and RORI where bit 25 is reserved in RV32 (#2728)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
Fix decoding of some bitmanip instruction where decoding differs between rv32 and rv64.
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-22 23:45:09 +01:00
Jalali
c19a3c1ace
Spike : mtvec doesn't support vectored mode for cv32a65x (#2729)
This is a spike fix for cv32a65x config.
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-22 23:42:47 +01:00
André Sintzoff
45aa060b5c
docs: regenerate dvplan_csr-access.md (#2625) (#2714)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
Previous fix was not correct (PR 2627)
Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-22 10:51:14 +01:00
dependabot[bot]
14998fc161
Bump verif/core-v-verif from 19b5a3f to 60e5724 (#2724)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-22 09:11:11 +01:00
André Sintzoff
f80c507aea
docs/requirements.txt: add missing packages for RTD (#2726)
this should fix build of design documents

Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
2025-01-22 09:07:01 +01:00
Mike Thompson
b9886a27a2
Clean up table (#2725) 2025-01-22 08:29:35 +01:00
André Sintzoff
02092dbcf0
riscv-isa-manual: ignore mm-formal.adoc (#2723)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
as this appendix requires Java and as it is not relevant for CV32A65X

Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-21 17:42:39 +01:00
Guillaume Chauvon
24c6a891b8
Docs: define values for CVXIF in 60x and 65x configuration (#2721)
Set values for X_NUM_RS in embedded configurations to 2.

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-21 17:06:26 +01:00
André Sintzoff
fb899feec1
fix 023e67e9 (define PATH variable and make in one command) (#2722)
to avoid PATH export, define it in the same command with make

Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
2025-01-21 17:04:24 +01:00
André Sintzoff
b6b259914a
fix 8e5872c03 (add missing smctr.adoc file) (#2720)
Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
2025-01-21 16:25:18 +01:00
André Sintzoff
023e67e9be
.readthedocs.yaml: add node modules to PATH environment variable (#2719)
Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
2025-01-21 16:00:13 +01:00
Guillaume Chauvon
98604b5920
csr_regfile: SEIP is read only 0 (fix #2056) (#2716)
Fix #2056

---------

Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-21 14:53:37 +01:00
André Sintzoff
7bdfa5f63e
.readthedocs.yaml: clone submodule recursively (#2718)
as riscv-isa-manual has a submodule, clone it

Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
2025-01-21 14:34:40 +01:00
André Sintzoff
8e5872c03b
update riscv-isa-manual to riscv-isa-release-4f277ff-2025-01-17 (#2717)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
Since last riscv-isa-manual update (CVA6 commit 67a6ae966):
	- minor documentation changes
	- new unsupported Zsmctr extension
	- add missing asciidoctor-lists gem in dependencies/Gemfile

Gemfile update is needed for ReadTheDocs

Signed-off-by: André Sintzoff <andre.sintzoff@thalesgroup.com>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
2025-01-21 09:56:51 +01:00
Guillaume Chauvon
3d2ff00b1c
Modify MSUB, NMADD, NMSUB behaviour to differs from other instructions. (#2712)
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled
MSUB = rs1 - rs2 - rs3
NMADD = ~(rs1 + rs2 + rs3)
NMSUB = ~(rs1 - rs2 - rs3)
2025-01-17 14:12:08 +01:00
OlivierBetschi
e840a61e80
Rewrite assert to avoid multi assertion (#2713)
This should fix github CI failing with verilator due to the assert combination
2025-01-17 12:39:05 +01:00
Côme
7af0f2e4d1
ariane_pkg: remove unused localparam ISSUE_WIDTH (#2710)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
This localparam is not needed anymore.
2025-01-16 23:12:33 +01:00
Guillaume Chauvon
41c22069a0
Add parameter to disable software interrupt. Fix issue #2500 (#2711)
Fix issue #2500
Add parameter to disable software interrupt.
MIP.MSIP and MIE.MSIE are now read only when this parameter is disabled.
2025-01-16 23:09:57 +01:00
dependabot[bot]
5518a41c08
Bump verif/core-v-verif from 464bf7a to 19b5a3f (#2703)
Some checks are pending
bender-up-to-date / bender-up-to-date (push) Waiting to run
ci / build-riscv-tests (push) Waiting to run
ci / execute-riscv64-tests (push) Blocked by required conditions
ci / execute-riscv32-tests (push) Blocked by required conditions
2025-01-15 19:57:00 +01:00
Guillaume Chauvon
21b247dca7
CI: copy seeds in artifacts for generated tests (#2708)
Save seeds in artifacts for generated tests. It will help to reproduce the test in case of failure.
2025-01-15 17:48:01 +01:00
Nils Wistoff
86c53c5334
config_pkg: Update configurations with new flush parameter (#2704)
#2691 extended the cva6_user_cfg_t struct by two new parameters to control the cache's flush behaviour. Add these new parameters to all configs to fix compilation errors due to incomplete struct literals.
2025-01-15 17:47:07 +01:00
186 changed files with 42629 additions and 1974 deletions

View file

@ -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
View file

@ -1,3 +1,5 @@
*.swp
*.swo
site/*
*.ucdb
covhtmlreport/*

View file

@ -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"

View file

@ -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):

View file

@ -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

View file

@ -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:

View file

@ -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:

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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)

View file

@ -1,9 +1,12 @@
# CVA6 RISC-V CPU [![Build Status](https://github.com/openhwgroup/cva6/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/openhwgroup/cva6/actions/workflows/ci.yml) [![CVA6 dashboard](https://riscv-ci.pages.thales-invia.fr/dashboard/badge.svg)](https://riscv-ci.pages.thales-invia.fr/dashboard/) [![Documentation Status](https://readthedocs.com/projects/openhw-group-cva6-user-manual/badge/?version=latest)](https://docs.openhwgroup.org/projects/cva6-user-manual/?badge=latest) [![GitHub release](https://img.shields.io/github/release/openhwgroup/cva6?include_prereleases=&sort=semver&color=blue)](https://github.com/openhwgroup/cva6/releases/)
# CVA6 RISC-V CPU [![Build Status](https://github.com/openhwgroup/cva6/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/openhwgroup/cva6/actions/workflows/ci.yml) [![CVA6 dashboard](https://riscv-ci.pages.thales-invia.fr/dashboard/badge_master.svg)](https://riscv-ci.pages.thales-invia.fr/dashboard/dashboard_cva6.html) [![Documentation Status](https://readthedocs.com/projects/openhw-group-cva6-user-manual/badge/?version=latest)](https://docs.openhwgroup.org/projects/cva6-user-manual/?badge=latest) [![GitHub release](https://img.shields.io/github/release/openhwgroup/cva6?include_prereleases=&sort=semver&color=blue)](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

View file

@ -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
// --------------------

View file

@ -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

View 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

View 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

File diff suppressed because it is too large Load diff

View 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

View file

@ -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

View file

@ -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)

View file

@ -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.

View file

@ -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

View file

@ -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),

View file

@ -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),

View file

@ -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

View file

@ -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 = {

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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
;

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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
}
};

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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
View 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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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,

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View 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

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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

View file

@ -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; \

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)
);
// ---------------------

View file

@ -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});

View file

@ -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;

View file

@ -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
);

View file

@ -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;

View file

@ -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
View 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

View file

@ -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}

View file

@ -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

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

View 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>`_

View 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

View 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

View 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

View file

@ -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

View file

@ -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::[]

View file

@ -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]]

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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::[]

View 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::[]

File diff suppressed because it is too large Load diff

View file

@ -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