Instruction Trace Interface (#2927)
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 support for Trace Interface or Trace Ingress Port (TIP) on CVA6

TIP is Interface between a RISC-V hart and the trace encoder

It generates information about the instruction retired.

The implementation is compliant with the Efficient Trace for RISC-V standard Version 2.0.2(https://github.com/riscv-non-isa/riscv-trace-spec/releases/download/v2.0.2/riscv-trace-spec-asciidoc.pdf), specifically:

Chapter 4.1: Instruction Trace Interface Requirements

Chapter 4.2: Instruction Trace Interface

The current implementation supports the following TIP signals: iretire, itype, cause, tval, priv, iaddr, and time. For Instruction Type (itype) encoding, it supports the following: Exception, Interrupt, Exception or interrupt return, Nontaken branch, Taken branch, Uninferable jump.

What I have been able to test so far:
Simulation: Executed C binaries and observed the waveform of TIP.

---------

Co-authored-by: root <darshak.sheladiya@sysgo.com>
Co-authored-by: CHAUVON Guillaume <guillaume.chauvon@thalesgroup.com>
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
This commit is contained in:
MaxCThales 2025-04-25 18:11:55 +02:00 committed by GitHub
parent c784fd9047
commit f314dcb136
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 834 additions and 13 deletions

View file

@ -225,6 +225,20 @@ smoke-hwconfig:
- when: manual
allow_failure: true
iti-test:
extends:
- .synthesis_test
variables:
DASHBOARD_JOB_TITLE: "ITI test"
DASHBOARD_JOB_DESCRIPTION: "Short test to challenge the Instuction Trace Interface"
DASHBOARD_SORT_INDEX: 0
DASHBOARD_JOB_CATEGORY: "Basic"
DV_SIMULATORS: "vcs-testharness"
script:
- bash verif/regress/iti_test.sh
- diff .gitlab-ci/iti_reference.trace .gitlab-ci/iti.trace
- python3 .gitlab-ci/scripts/report_pass.py
spyglass:
extends:
- .synthesis_test

View file

@ -0,0 +1,159 @@
i : 1 , val = 1 , iret = 12, ilast = 0x1 , itype = 6 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x00010000
i : 0 , val = 1 , iret = 39, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80000000
i : 0 , val = 1 , iret = 19, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80000058
i : 0 , val = 1 , iret = 76, ilast = 0x0 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000007e
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003f12
i : 0 , val = 1 , iret = 7, ilast = 0x0 , itype = 6 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003f52
i : 0 , val = 1 , iret = 35, ilast = 0x0 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003602
i : 0 , val = 1 , iret = 36, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003fc4
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 18, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003ffa
i : 0 , val = 1 , iret = 7, ilast = 0x0 , itype = 6 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000401e
i : 0 , val = 1 , iret = 5, ilast = 0x0 , itype = 6 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000362a
i : 0 , val = 1 , iret = 15, ilast = 0x0 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003662
i : 0 , val = 1 , iret = 5, ilast = 0x0 , itype = 6 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000359e
i : 1 , val = 1 , iret = 17, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000366c
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004266
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426a
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426e
i : 1 , val = 1 , iret = 7, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004272
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004280
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004284
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004288
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000428c
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004290
i : 0 , val = 1 , iret = 2, ilast = 0x0 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004294
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004262
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004266
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426a
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426e
i : 1 , val = 1 , iret = 7, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004272
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004280
i : 1 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004284
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004288
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000428c
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004290
i : 0 , val = 1 , iret = 2, ilast = 0x0 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004294
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004262
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004266
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426a
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426e
i : 1 , val = 1 , iret = 7, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004272
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004280
i : 1 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004284
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004288
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000428c
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004290
i : 0 , val = 1 , iret = 2, ilast = 0x0 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004294
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004262
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004266
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426a
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426e
i : 1 , val = 1 , iret = 7, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004272
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004280
i : 1 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004284
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004288
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000428c
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004290
i : 0 , val = 1 , iret = 2, ilast = 0x0 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004294
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004262
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004266
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426a
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426e
i : 1 , val = 1 , iret = 7, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004272
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004280
i : 1 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004284
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004288
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000428c
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004290
i : 0 , val = 1 , iret = 2, ilast = 0x0 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004294
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004262
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004266
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426a
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426e
i : 1 , val = 1 , iret = 7, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004272
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004280
i : 1 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004284
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004288
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000428c
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004290
i : 0 , val = 1 , iret = 2, ilast = 0x0 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004294
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004262
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004266
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426a
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426e
i : 1 , val = 1 , iret = 7, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004272
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004280
i : 1 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004284
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004288
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000428c
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004290
i : 0 , val = 1 , iret = 2, ilast = 0x0 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004294
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004262
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004266
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426a
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426e
i : 1 , val = 1 , iret = 7, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004272
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004280
i : 1 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004284
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004288
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000428c
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004290
i : 0 , val = 1 , iret = 2, ilast = 0x0 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004294
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004262
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004266
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426a
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426e
i : 1 , val = 1 , iret = 7, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004272
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004280
i : 1 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004284
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004288
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000428c
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004290
i : 0 , val = 1 , iret = 2, ilast = 0x0 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004294
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004262
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004266
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426a
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000426e
i : 1 , val = 1 , iret = 7, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004272
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004280
i : 1 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004284
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004288
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x8000428c
i : 0 , val = 1 , iret = 2, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004290
i : 0 , val = 1 , iret = 2, ilast = 0x0 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004294
i : 0 , val = 1 , iret = 1, ilast = 0x0 , itype = 6 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80004298
i : 0 , val = 1 , iret = 6, ilast = 0x0 , itype = 6 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003014
i : 0 , val = 1 , iret = 12, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003672
i : 0 , val = 1 , iret = 9, ilast = 0x0 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003680
i : 0 , val = 1 , iret = 10, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x800036d8
i : 0 , val = 1 , iret = 9, ilast = 0x0 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x80003680
i : 0 , val = 1 , iret = 10, ilast = 0x1 , itype = 4 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x800036d8
i : 0 , val = 1 , iret = 4, ilast = 0x1 , itype = 5 , cause = 0x00 , tval= 0x00000000 , priv = 0x3 , iadd= 0x800036ec

View file

@ -169,7 +169,7 @@ src := $(if $(spike-tandem),verif/tb/core/uvma_core_cntrl_pkg.sv)
$(wildcard corev_apu/fpga/src/axi_slice/src/*.sv) \
$(wildcard corev_apu/src/axi_riscv_atomics/src/*.sv) \
$(wildcard corev_apu/axi_mem_if/src/*.sv) \
$(wildcard corev_apu/riscv-dbg/src/*.sv) \
$(wildcard corev_apu/riscv-dbg/src/*.sv) \
corev_apu/rv_plic/rtl/rv_plic_target.sv \
corev_apu/rv_plic/rtl/rv_plic_gateway.sv \
corev_apu/rv_plic/rtl/plic_regmap.sv \
@ -201,12 +201,16 @@ src := $(if $(spike-tandem),verif/tb/core/uvma_core_cntrl_pkg.sv)
vendor/pulp-platform/tech_cells_generic/src/deprecated/cluster_clk_cells.sv \
vendor/pulp-platform/tech_cells_generic/src/deprecated/pulp_clk_cells.sv \
vendor/pulp-platform/tech_cells_generic/src/rtl/tc_clk.sv \
core/include/iti_pkg.sv \
corev_apu/tb/ariane_testharness.sv \
corev_apu/tb/ariane_peripherals.sv \
corev_apu/tb/rvfi_tracer.sv \
corev_apu/tb/common/uart.sv \
corev_apu/tb/common/SimDTM.sv \
corev_apu/tb/common/SimJTAG.sv
corev_apu/tb/common/SimJTAG.sv \
core/cva6_iti/instr_to_trace.sv \
core/cva6_iti/iti.sv \
core/cva6_iti/itype_detector.sv
src := $(addprefix $(root-dir), $(src))

View file

@ -1774,6 +1774,7 @@ module cva6
.exception_t (exception_t),
.scoreboard_entry_t (scoreboard_entry_t),
.lsu_ctrl_t (lsu_ctrl_t),
.bp_resolve_t (bp_resolve_t),
.rvfi_probes_instr_t(rvfi_probes_instr_t),
.rvfi_probes_csr_t (rvfi_probes_csr_t),
.rvfi_probes_t (rvfi_probes_t)
@ -1809,7 +1810,8 @@ module cva6
.csr_i(rvfi_csr),
.irq_i(irq_i),
.resolved_branch_i(resolved_branch),
.flu_trans_id_ex_id_i(flu_trans_id_ex_id),
.rvfi_probes_o(rvfi_probes_o)
);

View file

@ -0,0 +1,95 @@
// Copyright (c) 2025 Thales DIS design services SAS
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
// Author: Maxime Colson - Thales
// Date: 20/03/2025
// Contributors:
// Darshak Sheladiya, SYSGO GmbH
// Umberto Laghi, UNIBO
//Systollic module used to determines the iaddr, ilastsize, iretire for Encoder Module
module instr_to_trace #(
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter type uop_entry_t = logic,
parameter type itt_out_t = logic,
parameter CAUSE_LEN = 5, //Size is ecause_width_p in the E-Trace SPEC
parameter ITYPE_LEN = 3, //Size is itype_width_p in the E-Trace SPEC (3 or 4)
parameter IRETIRE_LEN = 32 //Size is iretire_width_p in the E-Trace SPEC
) (
input uop_entry_t uop_entry_i,
input logic [ CAUSE_LEN-1:0] cause_i,
input logic [CVA6Cfg.XLEN-1:0] tval_i,
input logic [ IRETIRE_LEN-1:0] counter_i,
input logic [CVA6Cfg.XLEN-1:0] iaddr_i,
input logic was_special_i,
output itt_out_t itt_out_o,
output logic [ IRETIRE_LEN-1:0] counter_o,
output logic [CVA6Cfg.XLEN-1:0] iaddr_o,
output logic is_special_o
);
logic special_inst;
logic exception;
logic interrupt;
assign special_inst = !(uop_entry_i.itype inside {iti_pkg::INT, iti_pkg::EXC, iti_pkg::STANDARD}) && uop_entry_i.valid ;
assign exception = (uop_entry_i.itype == iti_pkg::EXC) ? 1'b1 : 1'b0;
assign interrupt = (uop_entry_i.itype == iti_pkg::INT) ? 1'b1 : 1'b0;
always_comb begin
counter_o = counter_i;
is_special_o = was_special_i;
iaddr_o = iaddr_i;
itt_out_o = '0;
if (uop_entry_i.valid) begin
counter_o = uop_entry_i.compressed ? counter_i + 1 : counter_i + 2;
if (was_special_i) begin
counter_o = 0;
iaddr_o = uop_entry_i.pc;
is_special_o = 1'b0;
end
if (special_inst) begin
itt_out_o.valid = 1'b1;
itt_out_o.iretire = uop_entry_i.compressed ? counter_o + 1 : counter_o + 2;
itt_out_o.itype = uop_entry_i.itype;
itt_out_o.ilastsize = ~uop_entry_i.compressed;
itt_out_o.iaddr = iaddr_o;
itt_out_o.priv = uop_entry_i.priv;
itt_out_o.cycles = uop_entry_i.cycles;
itt_out_o.cause = '0;
itt_out_o.tval = '0;
is_special_o = 1'b1;
end
if (interrupt) begin
itt_out_o.valid = 1'b1;
itt_out_o.iretire = uop_entry_i.compressed ? 1 : 2;
itt_out_o.itype = uop_entry_i.itype;
itt_out_o.ilastsize = ~uop_entry_i.compressed;
itt_out_o.iaddr = uop_entry_i.pc;
itt_out_o.priv = uop_entry_i.priv;
itt_out_o.cycles = uop_entry_i.cycles;
itt_out_o.cause = cause_i;
itt_out_o.tval = '0;
is_special_o = 1'b1;
end
if (exception) begin
itt_out_o.valid = 1'b1;
itt_out_o.iretire = uop_entry_i.compressed ? 1 : 2;
itt_out_o.itype = uop_entry_i.itype;
itt_out_o.ilastsize = ~uop_entry_i.compressed;
itt_out_o.iaddr = uop_entry_i.pc;
itt_out_o.priv = uop_entry_i.priv;
itt_out_o.cycles = uop_entry_i.cycles;
itt_out_o.cause = cause_i;
itt_out_o.tval = tval_i;
is_special_o = 1'b1;
end
end
end
endmodule

187
core/cva6_iti/iti.sv Normal file
View file

@ -0,0 +1,187 @@
// Copyright (c) 2025 Thales DIS design services SAS
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
// Author: Maxime Colson - Thales
// Date: 20/03/2025
// Contributors:
// Darshak Sheladiya, SYSGO GmbH
// Umberto Laghi, UNIBO
// For reference : See Section 4.2 Intruction Trace Inteface from Efficient Trace for RISC-V v2.0 (may 5 2022)
// iti stand for Instruction Trace Interface, changing because tip (Trace Ingress Port) and "type" are too similar creating confusion
module cva6_iti #(
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter CAUSE_LEN = 5, //Size is ecause_width_p in the E-Trace SPEC
parameter ITYPE_LEN = 3, //Size is itype_width_p in the E-Trace SPEC (3 or 4)
parameter IRETIRE_LEN = 32, //Size is iretire_width_p in the E-Trace SPEC
parameter type rvfi_to_iti_t = logic,
parameter type iti_to_encoder_t = logic
) (
input logic clk_i,
input logic rst_ni,
input logic [CVA6Cfg.NrCommitPorts-1:0] valid_i,
input rvfi_to_iti_t rvfi_to_iti_i,
output logic [CVA6Cfg.NrCommitPorts-1:0] valid_o,
output iti_to_encoder_t iti_to_encoder_o
);
// pragma translate_off
int f;
initial begin
f = $fopen("iti.trace", "w");
end
final $fclose(f);
// pragma translate_on
/* Structure used for each instr*/
localparam type uop_entry_t = struct packed {
logic valid;
logic [CVA6Cfg.XLEN-1:0] pc;
iti_pkg::itype_t itype;
logic compressed;
riscv::priv_lvl_t priv;
logic [63:0] cycles;
};
/* Structure used to output trace_signals if special instr */
localparam type itt_out_t = struct packed {
logic valid;
logic [IRETIRE_LEN-1:0] iretire;
iti_pkg::itype_t itype;
logic ilastsize;
logic [CVA6Cfg.XLEN-1:0] iaddr;
riscv::priv_lvl_t priv;
logic [CAUSE_LEN-1:0] cause;
logic [CVA6Cfg.XLEN-1:0] tval;
logic [63:0] cycles;
};
logic interrupt;
iti_pkg::itype_t [CVA6Cfg.NrCommitPorts-1:0] itype;
logic [IRETIRE_LEN-1:0] counter_d, counter_q;
logic [CVA6Cfg.XLEN-1:0] addr_d, addr_q;
logic special_d, special_q;
uop_entry_t [CVA6Cfg.NrCommitPorts-1:0] uop_entry;
itt_out_t [CVA6Cfg.NrCommitPorts-1:0] itt_out;
logic [CVA6Cfg.NrCommitPorts-1:0][IRETIRE_LEN-1:0] counter_itt;
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] addr_itt;
logic [CVA6Cfg.NrCommitPorts-1:0] special_itt;
logic [CVA6Cfg.NrCommitPorts-1:0][CAUSE_LEN-1:0] cause_itt;
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] tval_itt;
logic [CVA6Cfg.NrCommitPorts-1:0][IRETIRE_LEN-1:0] counter;
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] addr;
logic [CVA6Cfg.NrCommitPorts-1:0] special;
assign interrupt = rvfi_to_iti_i.cause[CVA6Cfg.XLEN-1]; // determinated based on the MSB of cause
for (genvar i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
itype_detector #(
.ITYPE_LEN(ITYPE_LEN)
) i_itype_detector (
.valid_i (valid_i[i]),
.exception_i (rvfi_to_iti_i.ex_valid),
.interrupt_i (interrupt),
.op_i (rvfi_to_iti_i.op[i]),
.branch_taken_i(rvfi_to_iti_i.is_taken[i]),
.itype_o (itype[i])
);
// Adding this to ensure that interuption/exception happen only in commit port 0 of cva6
assign cause_itt[i] = i == 0 ? rvfi_to_iti_i.cause[CAUSE_LEN-1:0] : '0;
assign tval_itt[i] = i == 0 ? rvfi_to_iti_i.tval : '0;
// Systolic logic (First itt is connected to D Flip-Flop to continue computation if needed)
assign counter_itt[i] = i == 0 ? counter_q : counter[i-1];
assign addr_itt[i] = i == 0 ? addr_q : addr[i-1];
assign special_itt[i] = i == 0 ? special_q : special[i-1];
instr_to_trace #(
.CVA6Cfg(CVA6Cfg),
.uop_entry_t(uop_entry_t),
.itt_out_t(itt_out_t),
.CAUSE_LEN(CAUSE_LEN),
.ITYPE_LEN(ITYPE_LEN),
.IRETIRE_LEN(IRETIRE_LEN)
) i_instr_to_trace (
.uop_entry_i(uop_entry[i]),
.cause_i(cause_itt[i]),
.tval_i(tval_itt[i]),
.counter_i(counter_itt[i]),
.iaddr_i(addr_itt[i]),
.was_special_i(special_itt[i]),
.itt_out_o(itt_out[i]),
.counter_o(counter[i]),
.iaddr_o(addr[i]),
.is_special_o(special[i])
);
end
always_comb begin
iti_to_encoder_o.cause = '0;
iti_to_encoder_o.tval = '0;
for (int i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
uop_entry[i].valid = valid_i[i];
uop_entry[i].pc = rvfi_to_iti_i.pc[i];
uop_entry[i].itype = itype[i];
uop_entry[i].compressed = rvfi_to_iti_i.is_compressed[i];
uop_entry[i].priv = rvfi_to_iti_i.priv_lvl;
uop_entry[i].cycles = rvfi_to_iti_i.cycles;
iti_to_encoder_o.valid[i] = 1'b0;
iti_to_encoder_o.iretire[i] = '0;
iti_to_encoder_o.ilastsize[i] = '0;
iti_to_encoder_o.itype[i] = '0;
iti_to_encoder_o.iaddr[i] = '0;
if (itt_out[i].valid) begin
valid_o[i] = itt_out[i].valid;
iti_to_encoder_o.valid[i] = itt_out[i].valid;
iti_to_encoder_o.iretire[i] = itt_out[i].iretire;
iti_to_encoder_o.ilastsize[i] = itt_out[i].ilastsize;
iti_to_encoder_o.itype[i] = itt_out[i].itype;
iti_to_encoder_o.iaddr[i] = itt_out[i].iaddr;
iti_to_encoder_o.priv = itt_out[i].priv; // privilege don't change between 2 instr comitted in the same cycle
iti_to_encoder_o.cycles = itt_out[i].cycles; // Same here (same time at same cycle)
end
end
if (itt_out[0].valid) begin // interrupt & exception only in port 0
iti_to_encoder_o.cause = itt_out[0].cause;
iti_to_encoder_o.tval = itt_out[0].tval;
end
end
assign counter_d = counter[CVA6Cfg.NrCommitPorts-1];
assign addr_d = addr[CVA6Cfg.NrCommitPorts-1];
assign special_d = special[CVA6Cfg.NrCommitPorts-1];
always_ff @(posedge clk_i, negedge rst_ni) begin
if (!rst_ni) begin
counter_q <= '0;
addr_q <= '0;
special_q <= 1'b1;
end else begin
counter_q <= counter_d;
addr_q <= addr_d;
special_q <= special_d;
end
//pragma translate_off
for (int i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
if (itt_out[i].valid) begin
$fwrite(
f,
"i :%d , val = %d , iret = %d, ilast = 0x%d , itype = %d , cause = 0x%h , tval= 0x%h , priv = 0x%d , iadd= 0x%h \n",
i, itt_out[i].valid, itt_out[i].iretire, itt_out[i].ilastsize, itt_out[i].itype,
itt_out[i].cause, itt_out[i].tval, itt_out[i].priv, itt_out[i].iaddr);
end
end
//pragma translate_on
end
endmodule

92
core/cva6_iti/itype_detector.sv Executable file
View file

@ -0,0 +1,92 @@
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
// https://solderpad.org/licenses/SHL-2.1/
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions and
// limitations under the License.
// Author: Umberto Laghi
// Contact: umberto.laghi@studio.unibo.it
// Github: @ubolakes
// Contributors:
// Darshak Sheladiya, SYSGO GmbH
// Maxime COLSON, Thales CDI France
/* ITYPE DETECTOR */
/*
it produces the type of the instruction
*/
module itype_detector #(
parameter ITYPE_LEN = 3 //Size is itype_width_p in the E-Trace SPEC (3 or 4)
) (
input logic valid_i,
input logic exception_i,
input logic interrupt_i,
input ariane_pkg::fu_op op_i,
input logic branch_taken_i,
output iti_pkg::itype_t itype_o
);
// internal signals
logic exception;
logic interrupt;
logic eret;
logic nontaken_branch;
logic taken_branch;
logic updiscon;
// assignments
assign exception = exception_i;
assign interrupt = interrupt_i; // no need to have an inst committed
assign eret = op_i inside {ariane_pkg::MRET, ariane_pkg::SRET, ariane_pkg::DRET};
assign nontaken_branch = ( op_i == ariane_pkg::EQ ||
op_i == ariane_pkg::NE ||
op_i == ariane_pkg::LTS ||
op_i == ariane_pkg::GES ||
op_i == ariane_pkg::LTU ||
op_i == ariane_pkg::GEU) &&
~branch_taken_i;
assign taken_branch = ( op_i == ariane_pkg::EQ ||
op_i == ariane_pkg::NE ||
op_i == ariane_pkg::LTS ||
op_i == ariane_pkg::GES ||
op_i == ariane_pkg::LTU ||
op_i == ariane_pkg::GEU) &&
branch_taken_i;
assign updiscon = op_i == ariane_pkg::JALR;
// assigning the itype
always_comb begin
// initialization
itype_o = iti_pkg::STANDARD;
if (exception) begin // exception
itype_o = iti_pkg::EXC;
end else if (interrupt) begin // interrupt
itype_o = iti_pkg::INT;
end else if (valid_i) begin
if (eret) begin // exception or interrupt return
itype_o = iti_pkg::ERET;
end else if (nontaken_branch) begin // nontaken branch
itype_o = iti_pkg::NON_TAKEN_BR;
end else if (taken_branch) begin // taken branch
itype_o = iti_pkg::TAKEN_BR;
end else if (ITYPE_LEN == 3 && updiscon) begin // uninferable discontinuity
itype_o = iti_pkg::UNINF_JMP;
end
end
end
endmodule

View file

@ -17,7 +17,8 @@ module cva6_rvfi
parameter type rvfi_csr_t = logic,
parameter type rvfi_probes_instr_t = logic,
parameter type rvfi_probes_csr_t = logic,
parameter type rvfi_probes_t = logic
parameter type rvfi_probes_t = logic,
parameter type rvfi_to_iti_t = logic
) (
@ -26,8 +27,8 @@ module cva6_rvfi
input rvfi_probes_t rvfi_probes_i,
output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_instr_o,
output rvfi_to_iti_t rvfi_to_iti_o,
output rvfi_csr_t rvfi_csr_o
);
localparam logic [CVA6Cfg.XLEN-1:0] IsaCode =
@ -81,6 +82,14 @@ module cva6_rvfi
logic [CVA6Cfg.XLEN-1:0] ex_commit_cause;
logic ex_commit_valid;
logic [CVA6Cfg.NrCommitPorts-1:0] valid_iti;
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.VLEN-1:0] pc_iti;
ariane_pkg::fu_op [CVA6Cfg.NrCommitPorts-1:0] op_iti;
logic branch_valid_iti;
logic is_taken_iti;
logic [CVA6Cfg.XLEN-1:0] tval_iti;
logic [63:0] time_iti;
riscv::priv_lvl_t priv_lvl;
logic [CVA6Cfg.VLEN-1:0] lsu_ctrl_vaddr;
@ -99,6 +108,8 @@ module cva6_rvfi
logic [(CVA6Cfg.XLEN/8)-1:0] lsu_wmask;
logic [CVA6Cfg.TRANS_ID_BITS-1:0] lsu_addr_trans_id;
logic [CVA6Cfg.TRANS_ID_BITS-1:0] branch_trans_id;
riscv::pmpcfg_t [15:0] pmpcfg_q, pmpcfg_d;
rvfi_probes_csr_t csr;
@ -147,6 +158,14 @@ module cva6_rvfi
assign ex_commit_cause = instr.ex_commit_cause;
assign ex_commit_valid = instr.ex_commit_valid;
assign valid_iti = instr.commit_ack;
assign pc_iti = instr.commit_instr_pc;
assign op_iti = instr.commit_instr_op;
assign branch_valid_iti = instr.branch_valid;
assign is_taken_iti = instr.is_taken;
assign tval_iti = instr.tval;
assign time_iti = rvfi_probes_i.csr.cycle_q;
assign priv_lvl = instr.priv_lvl;
assign wbdata = instr.wbdata;
@ -159,6 +178,8 @@ module cva6_rvfi
assign lsu_rmask = instr.lsu_ctrl_fu == LOAD ? instr.lsu_ctrl_be : '0;
assign lsu_wmask = instr.lsu_ctrl_fu == STORE ? instr.lsu_ctrl_be : '0;
assign lsu_addr_trans_id = instr.lsu_ctrl_trans_id;
assign branch_trans_id = instr.branch_trans_id;
//ID STAGE
@ -170,6 +191,7 @@ module cva6_rvfi
typedef struct packed {
logic valid;
logic [31:0] instr;
logic is_compressed;
} issue_struct_t;
issue_struct_t [CVA6Cfg.NrIssuePorts-1:0] issue_n, issue_q;
logic took0;
@ -187,6 +209,7 @@ module cva6_rvfi
if (!issue_n[CVA6Cfg.NrIssuePorts-1].valid) begin
issue_n[CVA6Cfg.NrIssuePorts-1].valid = fetch_entry_valid[0];
issue_n[CVA6Cfg.NrIssuePorts-1].instr = truncated[0];
issue_n[CVA6Cfg.NrIssuePorts-1].is_compressed = is_compressed[0];
took0 = 1'b1;
end
@ -199,9 +222,11 @@ module cva6_rvfi
if (took0) begin
issue_n[CVA6Cfg.NrIssuePorts-1].valid = fetch_entry_valid[CVA6Cfg.NrIssuePorts-1];
issue_n[CVA6Cfg.NrIssuePorts-1].instr = truncated[CVA6Cfg.NrIssuePorts-1];
issue_n[CVA6Cfg.NrIssuePorts-1].is_compressed = is_compressed[CVA6Cfg.NrIssuePorts-1];
end else begin
issue_n[CVA6Cfg.NrIssuePorts-1].valid = fetch_entry_valid[0];
issue_n[CVA6Cfg.NrIssuePorts-1].instr = truncated[0];
issue_n[CVA6Cfg.NrIssuePorts-1].is_compressed = is_compressed[0];
end
end
@ -231,6 +256,9 @@ module cva6_rvfi
logic [(CVA6Cfg.XLEN/8)-1:0] lsu_wmask;
logic [CVA6Cfg.XLEN-1:0] lsu_wdata;
logic [31:0] instr;
logic branch_valid;
logic is_taken;
logic is_compressed;
} sb_mem_t;
sb_mem_t [CVA6Cfg.NR_SB_ENTRIES-1:0] mem_q, mem_n;
@ -246,11 +274,17 @@ module cva6_rvfi
lsu_rmask: '0,
lsu_wmask: '0,
lsu_wdata: '0,
instr: issue_q[i].instr
instr: issue_q[i].instr,
branch_valid: 1'b0,
is_taken: 1'b0,
is_compressed: issue_q[i].is_compressed
};
end
end
if (branch_valid_iti) begin
mem_n[branch_trans_id].branch_valid = branch_valid_iti;
mem_n[branch_trans_id].is_taken = is_taken_iti;
end
if (lsu_rmask != 0) begin
mem_n[lsu_addr_trans_id].lsu_addr = lsu_addr;
mem_n[lsu_addr_trans_id].lsu_rmask = lsu_rmask;
@ -317,7 +351,18 @@ module cva6_rvfi
rvfi_instr_o[i].mem_rdata <= commit_instr_result[i];
rvfi_instr_o[i].rs1_rdata <= mem_q[commit_pointer[i]].rs1_rdata;
rvfi_instr_o[i].rs2_rdata <= mem_q[commit_pointer[i]].rs2_rdata;
rvfi_to_iti_o.branch_valid[i] <= mem_q[commit_pointer[i]].branch_valid;
rvfi_to_iti_o.is_taken[i] <= mem_q[commit_pointer[i]].is_taken;
rvfi_to_iti_o.is_compressed[i] <= mem_q[commit_pointer[i]].is_compressed;
rvfi_to_iti_o.valid[i] <= valid_iti[i];
rvfi_to_iti_o.pc[i] <= pc_iti[i];
rvfi_to_iti_o.op[i] <= op_iti[i];
end
rvfi_to_iti_o.ex_valid <= ex_commit_valid;
rvfi_to_iti_o.cycles <= time_iti;
rvfi_to_iti_o.cause <= ex_commit_cause;
rvfi_to_iti_o.tval <= tval_iti;
rvfi_to_iti_o.priv_lvl <= priv_lvl;
end

View file

@ -16,6 +16,7 @@ module cva6_rvfi_probes
parameter type exception_t = logic,
parameter type scoreboard_entry_t = logic,
parameter type lsu_ctrl_t = logic,
parameter type bp_resolve_t = logic,
parameter type rvfi_probes_instr_t = logic,
parameter type rvfi_probes_csr_t = logic,
parameter type rvfi_probes_t = logic
@ -52,6 +53,8 @@ module cva6_rvfi_probes
input rvfi_probes_csr_t csr_i,
input logic [1:0] irq_i,
input bp_resolve_t resolved_branch_i,
input [CVA6Cfg.TRANS_ID_BITS-1:0] flu_trans_id_ex_id_i,
output rvfi_probes_t rvfi_probes_o
);
@ -81,6 +84,11 @@ module cva6_rvfi_probes
instr.ex_commit_cause = ex_commit_i.cause;
instr.ex_commit_valid = ex_commit_i.valid;
if (CVA6Cfg.TvalEn) begin
instr.tval = ex_commit_i.tval;
end else begin
instr.tval = '0;
end
instr.priv_lvl = priv_lvl_i;
@ -109,6 +117,10 @@ module cva6_rvfi_probes
instr.commit_ack = commit_ack_i;
instr.wdata = wdata_i;
instr.branch_valid = resolved_branch_i.valid;
instr.is_taken = resolved_branch_i.is_taken;
instr.branch_trans_id = flu_trans_id_ex_id_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);

36
core/include/iti_pkg.sv Normal file
View file

@ -0,0 +1,36 @@
// Copyright (c) 2025 Thales DIS design services SAS
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
// Author: Maxime Colson - Thales
// Date: 20/03/2025
// Contributors:
// Darshak Sheladiya, SYSGO GmbH
// Umberto Laghi, UNIBO
// This package is temporary, the idea is to have it directly in the encoder later
package iti_pkg;
localparam CAUSE_LEN = 5; //Size is ecause_width_p in the E-Trace SPEC
localparam ITYPE_LEN = 3; //Size is itype_width_p in the E-Trace SPEC (3 or 4)
localparam IRETIRE_LEN = 32; //Size is iretire_width_p in the E-Trace SPEC
typedef enum logic [ITYPE_LEN-1:0] {
STANDARD = 0, // none of the other named itype codes
EXC = 1, // exception
INT = 2, // interrupt
ERET = 3, // exception or interrupt return
NON_TAKEN_BR = 4, // nontaken branch
TAKEN_BR = 5, // taken branch
UNINF_JMP = 6, // uninferable jump if ITYPE_LEN == 3, otherwise reserved
RES = 7 /*, // reserved
UC = 8, // uninferable call
IC = 9, // inferable call
UIJ = 10, // uninferable jump
IJ = 11, // inferable jump
CRS = 12, // co-routine swap
RET = 13, // return
OUIJ = 14, // other uninferable jump
OIJ = 15*/ // other inferable jump
} itype_t;
endpackage

View file

@ -0,0 +1,24 @@
// Copyright (c) 2025 Thales DIS design services SAS
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
// Author: Maxime Colson - Thales
// Date: 20/03/2025
// Contributors:
// Darshak Sheladiya, SYSGO GmbH
// Umberto Laghi, UNIBO
`ifndef ITI_TYPES_SVH
`define ITI_TYPES_SVH
`define ITI_TO_ENCODER_T(Cfg) struct packed { \
logic [Cfg.NrCommitPorts-1:0] valid; \
logic [Cfg.NrCommitPorts-1:0][iti_pkg::IRETIRE_LEN-1:0] iretire; \
logic [Cfg.NrCommitPorts-1:0] ilastsize; \
iti_pkg::itype_t [Cfg.NrCommitPorts-1:0][iti_pkg::ITYPE_LEN-1:0] itype; \
logic [iti_pkg::CAUSE_LEN-1:0] cause; \
logic [Cfg.XLEN-1:0] tval; \
riscv::priv_lvl_t priv; \
logic [Cfg.NrCommitPorts-1:0][Cfg.XLEN-1:0] iaddr; \
logic [63:0] cycles; \
}
`endif // ITI_TYPES_SVH

View file

@ -126,6 +126,10 @@
logic [Cfg.PLEN-1:0] mem_paddr; \
logic debug_mode; \
logic [Cfg.NrCommitPorts-1:0][Cfg.XLEN-1:0] wdata; \
logic branch_valid; \
logic is_taken; \
logic [Cfg.XLEN-1:0] tval; \
logic [Cfg.TRANS_ID_BITS-1:0] branch_trans_id; \
}
`define RVFI_PROBES_CSR_T(Cfg) struct packed { \
@ -164,4 +168,18 @@
logic [63:0][Cfg.PLEN-3:0] pmpaddr_q; \
}
`define RVFI_TO_ITI_T(Cfg) struct packed { \
logic [Cfg.NrCommitPorts-1:0] valid; \
logic [Cfg.NrCommitPorts-1:0][Cfg.VLEN-1:0] pc; \
ariane_pkg::fu_op [Cfg.NrCommitPorts-1:0] op; \
logic [Cfg.NrCommitPorts-1:0] is_compressed; \
logic [Cfg.NrCommitPorts-1:0] branch_valid; \
logic [Cfg.NrCommitPorts-1:0] is_taken; \
logic ex_valid; \
logic [Cfg.XLEN-1:0] tval; \
logic [Cfg.XLEN-1:0] cause; \
riscv::priv_lvl_t priv_lvl; \
logic [63:0] cycles; \
}
`endif // RVFI_TYPES_SVH

View file

@ -15,6 +15,7 @@
`include "axi/assign.svh"
`include "rvfi_types.svh"
`include "iti_types.svh"
`ifdef VERILATOR
`include "custom_uvm_macros.svh"
@ -46,6 +47,8 @@ module ariane_testharness #(
localparam type rvfi_instr_t = `RVFI_INSTR_T(CVA6Cfg);
localparam type rvfi_csr_elmt_t = `RVFI_CSR_ELMT_T(CVA6Cfg);
localparam type rvfi_csr_t = `RVFI_CSR_T(CVA6Cfg, rvfi_csr_elmt_t);
localparam type rvfi_to_iti_t = `RVFI_TO_ITI_T(CVA6Cfg);
localparam type iti_to_encoder_t = `ITI_TO_ENCODER_T(CVA6Cfg);
// RVFI PROBES
localparam type rvfi_probes_instr_t = `RVFI_PROBES_INSTR_T(CVA6Cfg);
@ -625,6 +628,8 @@ module ariane_testharness #(
rvfi_probes_t rvfi_probes;
rvfi_csr_t rvfi_csr;
rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_instr;
rvfi_to_iti_t rvfi_to_iti;
iti_to_encoder_t iti_to_encoder;
ariane #(
.CVA6Cfg ( CVA6Cfg ),
@ -672,6 +677,23 @@ module ariane_testharness #(
end
end
cva6_iti #(
.CVA6Cfg (CVA6Cfg),
.CAUSE_LEN (iti_pkg::CAUSE_LEN),
.ITYPE_LEN (iti_pkg::ITYPE_LEN),
.IRETIRE_LEN (iti_pkg::IRETIRE_LEN),
.rvfi_to_iti_t(rvfi_to_iti_t),
.iti_to_encoder_t(iti_to_encoder_t)
) i_iti (
.clk_i (clk_i),
.rst_ni (ndmreset_n),
// inputs from rvfi
.valid_i(rvfi_to_iti.valid),
.rvfi_to_iti_i(rvfi_to_iti),
// outputs for the encoder module TODO
.valid_o(),
.iti_to_encoder_o(iti_to_encoder)
);
cva6_rvfi #(
@ -680,13 +702,15 @@ module ariane_testharness #(
.rvfi_csr_t(rvfi_csr_t),
.rvfi_probes_instr_t(rvfi_probes_instr_t),
.rvfi_probes_csr_t(rvfi_probes_csr_t),
.rvfi_probes_t(rvfi_probes_t)
.rvfi_probes_t(rvfi_probes_t),
.rvfi_to_iti_t(rvfi_to_iti_t)
) i_cva6_rvfi (
.clk_i (clk_i),
.rst_ni (rst_ni),
.clk_i (clk_i),
.rst_ni (rst_ni),
.rvfi_probes_i(rvfi_probes),
.rvfi_instr_o(rvfi_instr),
.rvfi_csr_o(rvfi_csr)
.rvfi_instr_o (rvfi_instr),
.rvfi_to_iti_o (rvfi_to_iti),
.rvfi_csr_o (rvfi_csr)
);
rvfi_tracer #(

49
verif/regress/iti_test.sh Normal file
View file

@ -0,0 +1,49 @@
# 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
# where are the tools
if ! [ -n "$RISCV" ]; then
echo "Error: RISCV variable undefined"
return
fi
if ! [ -n "$DV_SIMULATORS" ]; then
DV_SIMULATORS=vcs-testharness,spike
fi
# install the required tools
if [[ "$DV_SIMULATORS" == *"veri-testharness"* ]]; then
source ./verif/regress/install-verilator.sh
fi
source ./verif/regress/install-spike.sh
# setup sim env
source ./verif/sim/setup-env.sh
echo "$SPIKE_INSTALL_DIR$"
if ! [ -n "$UVM_VERBOSITY" ]; then
export UVM_VERBOSITY=UVM_NONE
fi
export DV_OPTS="$DV_OPTS --issrun_opts=+debug_disable=1+UVM_VERBOSITY=$UVM_VERBOSITY"
CC_OPTS="-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S ../tests/custom/ITI/iti_asm.S -I../tests/custom/env -I../tests/custom/common -lgcc"
cd verif/sim/
make -C ../.. clean
make clean_all
python3 cva6.py --elf_tests ../tests/custom/ITI/test_iti_asm.o --target cv32a65x --iss_yaml cva6.yaml --iss=$DV_SIMULATORS --linker=../../config/gen_from_riscv_config/cv32a65x/linker/link.ld $DV_OPTS
#python3 cva6.py --c_tests ../tests/custom/ITI/test_iti_asm.c --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS --linker=../../config/gen_from_riscv_config/cv32a65x/linker/link.ld --gcc_opts="$CC_OPTS" $DV_OPTS
cp iti.trace ../../.gitlab-ci
make -C ../.. clean
make clean_all
cd -

View file

@ -452,6 +452,7 @@ clean_all: vcs_clean_all
rm -f trace*.log
rm -f trace*.dasm
rm -f *.vpd *.fsdb *.vcd *.fst
rm -f *.trace
help:
@echo "Shell environment:"

View file

@ -48,6 +48,7 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
parameter type rvfi_probes_instr_t = logic,
parameter type rvfi_probes_csr_t = logic,
parameter type rvfi_probes_t = logic,
parameter type rvfi_to_iti_t = logic,
// CVXIF Types
localparam type readregflags_t = `READREGFLAGS_T(CVA6Cfg),
localparam type writeregflags_t = `WRITEREGFLAGS_T(CVA6Cfg),
@ -88,6 +89,7 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_instr;
rvfi_probes_t rvfi_probes;
rvfi_to_iti_t rvfi_to_iti;
rvfi_csr_t rvfi_csr;
assign rvfi_o = rvfi_instr;
assign rvfi_csr_o = rvfi_csr;
@ -126,12 +128,14 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
.rvfi_csr_t(rvfi_csr_t),
.rvfi_probes_instr_t(rvfi_probes_instr_t),
.rvfi_probes_csr_t(rvfi_probes_csr_t),
.rvfi_probes_t(rvfi_probes_t)
.rvfi_probes_t(rvfi_probes_t),
.rvfi_to_iti_t(rvfi_to_iti_t)
) i_cva6_rvfi (
.clk_i (clk_i),
.rst_ni (rst_ni),
.rvfi_probes_i(rvfi_probes),
.rvfi_instr_o(rvfi_instr),
.rvfi_to_iti_o (rvfi_to_iti),
.rvfi_csr_o(rvfi_csr)
);

View file

@ -22,6 +22,7 @@ module uvmt_cva6_dut_wrap # (
parameter type rvfi_probes_instr_t = logic,
parameter type rvfi_probes_csr_t = logic,
parameter type rvfi_probes_t = logic,
parameter type rvfi_to_iti_t = logic,
//
parameter int unsigned AXI_USER_EN = 0,
parameter int unsigned NUM_WORDS = 2**25
@ -52,6 +53,7 @@ module uvmt_cva6_dut_wrap # (
.rvfi_probes_instr_t(rvfi_probes_instr_t),
.rvfi_probes_csr_t ( rvfi_probes_csr_t ),
.rvfi_probes_t ( rvfi_probes_t ),
.rvfi_to_iti_t ( rvfi_to_iti_t ),
//
.AXI_USER_EN (AXI_USER_EN),
.NUM_WORDS (NUM_WORDS)

View file

@ -41,6 +41,7 @@ module uvmt_cva6_tb;
localparam type rvfi_instr_t = `RVFI_INSTR_T(CVA6Cfg);
localparam type rvfi_csr_elmt_t = `RVFI_CSR_ELMT_T(CVA6Cfg);
localparam type rvfi_csr_t = `RVFI_CSR_T(CVA6Cfg, rvfi_csr_elmt_t);
localparam type rvfi_to_iti_t = `RVFI_TO_ITI_T(CVA6Cfg);
// RVFI PROBES
localparam type rvfi_probes_instr_t = `RVFI_PROBES_INSTR_T(CVA6Cfg);
@ -120,6 +121,7 @@ module uvmt_cva6_tb;
.rvfi_probes_instr_t(rvfi_probes_instr_t ),
.rvfi_probes_csr_t ( rvfi_probes_csr_t ),
.rvfi_probes_t ( rvfi_probes_t ),
.rvfi_to_iti_t ( rvfi_to_iti_t ),
//
.AXI_USER_EN (CVA6Cfg.AXI_USER_EN),
.NUM_WORDS (NUM_WORDS)

View file

@ -0,0 +1,35 @@
// Copyright (c) 2025 Thales DIS design services SAS
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
// Author: Maxime Colson - Thales
// Date: 20/03/2025
// Contributors:
// Darshak Sheladiya, SYSGO GmbH
// Umberto Laghi, UNIBO
.section .text
.align 1
.align 4
.global branch_test
.type branch_test, @function
branch_test:
c.li x12,10
loop:
bne x13,x13, branch_test
bne x13,x13, branch_test
bne x13,x13, branch_test
bne x13,x13, branch_test
la x11, branch_test
lw x10, 0(x11)
bne x13,x13, branch_test
bne x13,x13, branch_test
bne x13,x13, branch_test
bne x13,x13, branch_test
bne x13,x13, branch_test
bne x13,x13, branch_test
c.addi x12, -1
c.bnez x12, loop
c.jr ra

View file

@ -0,0 +1,16 @@
// Copyright (c) 2025 Thales DIS design services SAS
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
// Author: Maxime Colson - Thales
// Date: 20/03/2025
// Contributors:
// Darshak Sheladiya, SYSGO GmbH
// Umberto Laghi, UNIBO
//This test will be improved by taking into account other scenarios
void branch_test();
int main(int argc, char* arg[]) {
branch_test();
return 0;
}

Binary file not shown.