Skip to content

cv32e40s#1129

Draft
karabambus wants to merge 49 commits intoriscv:act4from
karabambus:cv32e40s
Draft

cv32e40s#1129
karabambus wants to merge 49 commits intoriscv:act4from
karabambus:cv32e40s

Conversation

@karabambus
Copy link
Copy Markdown
Contributor

Configuration files for cv32e40s

Configuration for CV32E40P core (Phase 1 CTP research) with all
parameters documented and verified against manual.

Baseline configuration: COREV_PULP=0, FPU=0, NUM_MHPMCOUNTERS=1

ISA Extensions:
- Base: I, M, C
- Standard: Zca, Zicsr, Zifencei, Zicntr
- Supervisor: Sm, Smhpm

Parameters: 44 documented with verification status
- 21 VERIFIED (with manual citations)
- 7 FROM MANUAL
- 13 ASSUMED (reasonable defaults)
- 2 QUESTIONABLE (flagged for review)
- 1 UNKNOWN

Research notes and atomic concepts in separate Obsidian vault.
CV32E40P configuration updates based on detailed RTL source code investigation:

Key Changes:
- Removed C extension from implemented_extensions (C = Zca + floating-point, FPU=0 means only Zca)
- TRAP_ON_UNIMPLEMENTED_CSR: Updated from false to true
  * RTL cv32e40p_decoder.sv line 2978 has 'default : csr_illegal = 1'b1'
  * Any CSR not in decoder whitelist causes IllegalInstruction exception
  * Config assumption (silent 0 return) contradicts actual RTL behavior

- TRAP_ON_ILLEGAL_WLRL: Verified false (no changes needed)
  * Decoder (ID stage) validates CSR addresses, not write data values
  * Write data only available at EX stage (too late for trap)
  * cs_registers.sv silently masks WLRL field writes (lines 954-1023)
  * Architecture constraint: masking is only viable option

- Commented out incomplete parameters (MTVAL, misaligned, IDs, MTVEC, Sm, HPM)

Investigation Sources:
- CV32E40P manual: intro.rst, control_status_registers.rst, exceptions_interrupts.rst
- RISC-V Unified DB: extension definitions, parameter schemas
- CV32E40P RTL: decoder.sv (CSR validation), cs_registers.sv (field masking)
NUM_PMP_ENTRIES is defined by Smpmp extension which CV32E40P does not
implement; remove it. Add TIME_CSR_IMPLEMENTED: false (defined by Zicntr,
which CV32E40P does implement); verified via perf_counters.rst:130-133.
Add F extension (v2.2.0) to implemented_extensions. Update description
to RV32IMCF. Update IMP_ID_VALUE 0x0->0x1 (cs_registers.sv:511-513:
FPU==1 sets mimpid=0x1). Add MUTABLE_MISA_F: false (F bit is RO,
control_status_registers.rst:1444,1457). Add HW_MSTATUS_FS_DIRTY_UPDATE:
imprecise and MSTATUS_FS_LEGAL_VALUES: [0,1,2,3] (cs_registers.sv:964,1034;
control_status_registers.rst:448-456,483).
… RV32IMC (FPU=0) config

Move cv32e40p.yaml into cv32e40p_v1.8.3_rv32imcf/ subfolder and rename to match
versioned naming convention (core/version-variant/file). Follows same structure as
cve2 and cvw configs.

Add cv32e40p_v1.8.3_rv32imc.yaml (FPU=0, mimpid=0) recovered from git history
as the baseline RV32IMC certified configuration (RTL Freeze v1.8.3, mimpid=0).
Add two architecture configuration yamls for CV32E40P v1.0.0 (RTL Freeze 2020-12-10):

- cv32e40p_v1.0.0_rv32imc: FPU=0 baseline, the only certified/frozen config for v1.0.0
  (mimpid=0, events 0-10 only)

- cv32e40p_v1.0.0_rv32imcf: FPU=1 path for completeness (not RTL-frozen in v1.0.0)
  Key differences vs v1.8.3 FPU=1: mimpid always 0x0 (hardwired), mstatus.FS not
  implemented (bits[16:13] hardwired 0, MSTATUS_FS_LEGAL_VALUES=[0]), HPM events
  12-15 active via internal APU dispatcher (cv32e40p_core.sv APU localparam).
Verified RTL (cv32e40p_compressed_decoder.sv) expands 16-bit
FP load/store (3'b001/3'b111) to 32-bit F-ext ops when FPU=1.
Required for ACT compatibility on RV32IMCF.
- .align 8 -> .align 2 (direct mode needs 4-byte alignment only)
- la x2, tohost -> li x2, 0x20000000 (symbol ref caused test failures)
- remove stale TODO and fix comment
Add stub CTP config directory for CV32E40S (CORE-V security-hardened,
RV32IMC + Smepmp + U-mode). RTL pinned to 103056f0 from core-v-verif.

Generated cv32e40s_rv32imc.yaml via scaffold_config.py (41 UDB params
scaffolded; Sm/Smhpm/Zicsr/Zifencei/Zicntr/I/M/Zca extensions). All
7 companion stub files created from cv32e40p templates with cv32e40s-
specific adjustments (marchid=0x15, U-mode support, PMP_NUM_REGIONS
noted as 16 for Smepmp). Config validates: 'Config cv32e40s_rv32imc
is valid'.

Params and rvmodel macros marked STUB -- to be verified against RTL
in the next phase before running tests.
Replace stub values with RTL-verified parameters for the cv32e40s
default configuration (ZC_EXT=0, B_EXT=NONE, PMP=0, PMA=0).
Key changes: MARCHID=0x15, 16 HPM events, Zkt always enabled,
MTVEC 256-byte aligned, MUTABLE_MISA_C added, MTVAL_WIDTH=32,
PMP regions set to 0, sail.json Zkt enabled.
Copy link
Copy Markdown
Collaborator

@davidharrishmc davidharrishmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good with minor feedback. It should get feedback from Jordan too.

MARCHID_IMPLEMENTED: true
MIMPID_IMPLEMENTED: true
PMA_GRANULARITY: 2 # Schema minimum (= 4 bytes); PMA_NUM_REGIONS=0 by default → entire memory is main
# PMP/PMA: defaults are PMP_NUM_REGIONS=0, PMA_NUM_REGIONS=0 (cv32e40s_core.sv lines 42,45)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider setting PMP_NUM_REGIONS to 0 explicitly rather than relying on default.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UDB schema minimum is 2.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The minimum granularity is 2. The minimum number of entries is 0.

Copy link
Copy Markdown
Contributor Author

@karabambus karabambus Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a problem:

Setting NUM_PMP_ENTRIES: 0 in a UDB config requires Smpmp in implemented_extensions. Without it:

Parameter is not defined by this config: 'NUM_PMP_ENTRIES'.
Needs: (Smpmp=1.11.0 || Smpmp=1.12.0 || Smpmp=1.13.0)

I can add smpmp in extension list but I cant find any information on this parameter except:

The MC100 CRD (docs/crd/src/mc100_crd.adoc:30) says:

Don't use Smpmp term which is a made-up UDB extension name for the original PMP.

The CTP param summary (docs/ctp/src/param/summary.adoc:556) lists NUM_PMP_ENTRIES and PMP_GRANULARITY as defined by Smpmp, but CTP test plans (PMPSm, PMPS, PMPU) never reference Smpmp as something to declare.

Should I add smpmp as well into extension list @davidharrishmc @jordancarlin ? I think it would correctly define our hardware as having PMP is present but with 0 configured regions.

I will make issue of this if I get clarification on this parameter.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smpmp and Smhpm were removed from UDB earlier today (they are not real extensions). NUM_PMP_ENTRIES will always be required when Sm is supported once we update the version of UDB we are using (planning to do that soon).

# cv32e40s supports both direct (MODE=0) and vectored (MODE=1) mtvec.
# Direct mode (MODE=0) requires 4-byte alignment only — use .align 2 before handler.
#define RVMODEL_BOOT \
.option push ; \
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of setting up this trap handler? Don't the priv tests immediately replace it with the ACT trap handler?

Do you need
csrwi mcountinhibit, 0
as in CV32E40P?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidharrishmc i will try to apply it as @jordancarlin suggested in #1031

kind: architecture configuration
type: fully configured
name: cv32e40s_rv32imc
description: CV32E40S (CORE-V secure) - RV32IMC default configuration (ZC_EXT=0, B_EXT=NONE, PMP=0, PMA=0)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does ZC_EXT=0 mean? Seems inconsistent with RV32IMC.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ZC_EXT is register in rtl, it enables optional Zc? subextensions. Removed since I was looking at older version of core, in latest version of core it is enabled by default.

Initial config was based on old RTL (103056f0, Feb 2022) where ZC_EXT
was a parameter defaulting to 0. Upstream master (Oct 2024) hardcodes
ZC_EXT=1 and NUM_MHPMCOUNTERS=0. Changes:

- Add Zcb, Zcmp, Zcmt extensions (ZC_EXT=1 always enabled)
- Add JVT params (JVT_BASE_TYPE, JVT_READ_ONLY, JVT_BASE_MASK)
- Update HPM: NUM_MHPMCOUNTERS=0, NUM_HPM_EVENTS=2
- Replace trap handler in RVMODEL_BOOT with mcountinhibit clear
- Update sail.json: Zcb=true, writable_hpm_counters=0

Note: JVT_BASE_MASK uses 0x7FFFFFC0 as workaround for UDB constraint
bug (requires < 0xFFFFFFC0 but RTL mask is exactly 0xFFFFFFC0).
# Zcmt params (VERIFIED — cv32e40s_pkg.sv: CSR_JVT_MASK=0xFFFFFFC0, JVT_RESET_VAL=0)
JVT_BASE_TYPE: mask # VERIFIED — upper 26 bits writable via mask
JVT_READ_ONLY: false # VERIFIED — jvt is writable
JVT_BASE_MASK: 0x7FFFFFC0 # RTL mask is 0xFFFFFFC0 but UDB requires < 0xFFFFFFC0 for RV32; bit 31 excluded
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is UDB issue. I submitted PR

SECURE=1 is hardcoded in cv32e40s, so PMP CSRs are always accessible
(no illegal instruction trap). PMP_NUM_REGIONS=0 by default means all
PMP CSRs are read-only-zero. Smpmp is a UDB placeholder extension
that gates PMP parameter visibility.
@davidharrishmc
Copy link
Copy Markdown
Collaborator

davidharrishmc commented Mar 25, 2026 via email

Add two new CTP configurations:
- cv32e40s_rv32imc_PMA: PMA-only (PMP_NUM_REGIONS=0)
- cv32e40s_rv32imc_PMA-PMP: PMA + PMP enabled (PMP_NUM_REGIONS=16, G=0)

Remove Zicntr extension and TIME_CSR param from base config since
cv32e40s does not implement user time CSRs.
@karabambus
Copy link
Copy Markdown
Contributor Author

karabambus commented Apr 1, 2026

Okay this is almost done. I have tested all three configs both on DUT and sail (it passes signature comparison for RVI20 profile).

Notes on needed changes before ready for review:

  1. how do you want this @MikeOpenHWGroup , can we flatten this in one config?
  2. adding config with B_EXT enabled (bit manipulation extensions)
  3. redundant files with symlink (depending on 1 and 2)
  4. sail.json config changes for PMP, this I would like reviewed @jordancarlin
  5. comments check
  6. PMP PMA is not really documented - see if I can open any issues on CTP concerning PMP PMA
  7. final README.md change (depends on 1., and after 2)

@karabambus
Copy link
Copy Markdown
Contributor Author

karabambus commented Apr 8, 2026

Concerning #1187 :

  1. cv32e40s_rv32imc (no PMA, no PMP) - no access fault possible for any address, any access type
  2. cv32e40s_rv32imc_PMA
  • rvmodel_macros.h: RVMODEL_ACCESS_FAULT_ADDRESS 0x80000000 (correct value, but overridden by sail_test.h)
  • 0x80000000 is outside all configured PMA regions - falls to PMA_R_DEFAULT: main=0 (I/O)
  • cv32e40s_pma.sv:103-116: pma_err_o=1 only for:
    • instruction fetch to non-main region
    • misaligned or modified access to non-main region
    • PUSH/POP to non-main region
    • normal aligned load or store to non-main region → pma_err_o=0
  • Result: fetch access fault at 0x80000000 possible via PMA; load/store access faults not possible
  1. cv32e40s_rv32imc_PMA-PMP
  • Same as PMA config for PMA-generated faults
  • PMP adds the ability to generate access faults via locked PMP entries
  • Whether this is exploitable for RVMODEL_ACCESS_FAULT_ADDRESS depends on PMP configuration at runtime

Workaround fo PMA-PMP config

  • Since the PMA-PMP sail.json has count: 16, Sail simulates PMP fully. Both Sail and DUT run the same binary, so if the startup/boot code writes a locked PMP entry covering 0x0 (alternative set sail.json memory region to start from 0x4, and instantiate core with 0x0 locked)

Will try this workaround so we dont get blocked by this issue.

@MikeOpenHWGroup
Copy link
Copy Markdown
Contributor

The rvmodel_macros.h files have entries such as:

##### Interrupt Latency #####

#define RVMODEL_INTERRUPT_LATENCY 10

##### Machine Timer #####

#define RVMODEL_MTIME_ADDRESS    0x0200BFF8
#define RVMODEL_MTIMECMP_ADDRESS 0x02004000
#define RVMODEL_TIMER_INT_SOON_DELAY 100

As is the situation with the other e40 cores, the MTIME and MTIMECMP are Platform CSRs that are not implemented in our testbenches.

I should probably RTFM before asking this, but how are the RVMODEL_INTERRUPT_LATENCY and RVMODEL_TIMER_INT_SOON_DELAY intended to be used? Is it assumed that a quasi-standard Interrupt Controller exists in the testbench?

@karabambus
Copy link
Copy Markdown
Contributor Author

karabambus commented Apr 15, 2026

As is the situation with the other e40 cores, the MTIME and MTIMECMP are Platform CSRs that are not implemented in our testbenches.

yes this was addressed by #1248 it should be removed now

I should probably RTFM before asking this, but how are the RVMODEL_INTERRUPT_LATENCY and RVMODEL_TIMER_INT_SOON_DELAY intended to be used? Is it assumed that a quasi-standard Interrupt Controller exists in the testbench?

Both RVMODEL_INTERRUPT_LATENCY and RVMODEL_TIMER_INT_SOON_DELAY are also present in cv32e20 and cv32e40p. They should be modified accordingly in these configs also.
I just copied them over for testing, I am using this branch for running tests on DUT.

RVMODEL_INTERRUPT_LATENCY

  • Expected latency (in cycles/NOPs) for interrupt trap processing. Ensures interrupt is received and can be processed before test continues.Can be 0 if interrupt controller adds no delay.

This must me verified. I assume it is set to high number because it doesn't hurt. I am not sure how to find this should i look at RTL or waveform?

RVMODEL_TIMER_INT_SOON_DELAY

  • The delay (in cycles) before a timer interrupt fires when using set_mtimer_int_soon(). Sets mtimecmp = mtime + delay. Can be empty

I will be removing this , since we dont have mtime

- Bump Sm to version 1.12.0; remove Smpmp/Smhpm from base config (no PMP in default build)
- Add CONFIG_PTR_ADDRESS, MCOUNTENABLE_EN; remove PMP_GRANULARITY/HPM_EVENTS
- Comment out RVMODEL_ACCESS_FAULT_ADDRESS (all addresses valid in Sail memory map)
- Comment out RVMODEL_MTIME_ADDRESS/MTIMECMP_ADDRESS (no CLINT timer in this config)
- rvmodel_boot
- ACCESS_FAULT_ADDRESS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants