Skip to content

rocket: implement Zicbom, Zicboz, and Zicbop - #3818

Open
cyyself wants to merge 1 commit into
chipsalliance:masterfrom
cyyself:zicbom-zicboz-zicbop
Open

rocket: implement Zicbom, Zicboz, and Zicbop#3818
cyyself wants to merge 1 commit into
chipsalliance:masterfrom
cyyself:zicbom-zicboz-zicbop

Conversation

@cyyself

@cyyself cyyself commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Add RISC-V cache-block-operation extensions to the Rocket core and both L1 data caches:

  • Zicbom: cbo.clean / cbo.flush / cbo.inval, via new M_CBO_{CLEAN,FLUSH,INVAL} memory commands. On the blocking D$ they reuse the flush-line path; on the non-blocking D$ a small writeback+invalidate FSM handles them, fence- serialized in the core so it sees a quiescent cache; the FSM writes back under a fixed TileLink source id, so it starts only once all MSHRs are idle.
  • Zicboz: cbo.zero, via M_CBO_ZERO. Categorized as a full-block write for coherence. On a hit a zero engine writes one data-array row per cycle; a small flow queue lets back-to-back hits chain so the write port never idles. On the non-blocking D$ a miss allocates an MSHR that acquires write permission and zero-fills the block (s_refill_zero) before the line is made valid, so a half-zeroed block is never observed. cbo.zero is not fenced, but to avoid racing for a cache way its MSHR is kept isolated (no command merges into or out of it) and mutually exclusive with the hit-path zero engine, so back-to-back zeroing still overlaps.
  • Zicbop: prefetch.i/r/w are ISA-string/DT-only (Rocket executes them as NOPs).

Core plumbing:

  • useZicbom/useZicboz/useZicbop core params, WithZicbo*/WithCBO configs, and DefaultCBOConfig / DefaultCBONonblockingConfig.
  • menvcfg/senvcfg/henvcfg CBIE/CBCFE/CBZE become writable; CSR gating raises illegal- vs virtual-instruction exceptions per the CMO spec, and degrades cbo.inval to a flush when CBIE=01.
  • TLB permission checks: management ops need load-or-store permission, cbo.zero needs store permission plus a cacheable PMA; failures are reported as store faults. Effective addresses are block-aligned and the permission/PMP check spans the whole block, so a sub-block PMP boundary cannot be bypassed and no misaligned exceptions arise.
  • ISA string advertises zicbom/zicbop/zicboz and DT exposes the cbo*-block-size properties.

AcquirePerm (permission without fetch) is not used because the stock TLBroadcast hub answers it with GrantData; AcquireBlock is used and the fetched data is overwritten by the zero-fill.

Verified in Verilator (DefaultCBOConfig and DefaultCBONonblockingConfig): directed functional + envcfg-gating tests, an LR-created-Trunk cbo.zero regression, a sub-block-PMP fault regression, an MSHR store-merge regression, and a memory smoke test all pass.

cbo.zero vs an unrolled 8x sd zeroing loop, in cycles (Verilator, lower is better), reported as sd / cbo:

config size warm cold
blocking D$ 4 KiB 805 / 570 2589 / 2566
blocking D$ 64 KiB 47449 / 47470 44692 / 44878
non-blocking D$ 4 KiB 807 / 640 2187 / 1687
non-blocking D$ 64 KiB 38112 / 34563 36910 / 30896

cbo.zero matches or beats the sd loop in every case -- up to ~30% faster on L1-resident (warm) zeroing and ~16-23% faster cold on the non-blocking D$; the larger-than-L1 thrashing case is memory-bound and at parity.

Type of change: feature request
Impact: API addition (no impact on existing code)
Development Phase: implementation

Copilot AI review requested due to automatic review settings July 14, 2026 18:49
@linux-foundation-easycla

linux-foundation-easycla Bot commented Jul 14, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: cyyself / name: Yangyu Chen (7eab840)

Add RISC-V cache-block-operation extensions to the Rocket core and both L1
data caches:

- Zicbom: cbo.clean / cbo.flush / cbo.inval, via new M_CBO_{CLEAN,FLUSH,INVAL}
  memory commands. On the blocking D$ they reuse the flush-line path; on the
  non-blocking D$ a small writeback+invalidate FSM handles them, fence-
  serialized in the core so it sees a quiescent cache; the FSM writes back
  under a fixed TileLink source id, so it starts only once all MSHRs are idle.
- Zicboz: cbo.zero, via M_CBO_ZERO. Categorized as a full-block write for
  coherence. On a hit a zero engine writes one data-array row per cycle; a
  small flow queue lets back-to-back hits chain so the write port never idles.
  On the non-blocking D$ a miss allocates an MSHR that acquires write
  permission and zero-fills the block (s_refill_zero) before the line is made
  valid, so a half-zeroed block is never observed. cbo.zero is not fenced, but
  to avoid racing for a cache way its MSHR is kept isolated (no command merges
  into or out of it) and mutually exclusive with the hit-path zero engine, so
  back-to-back zeroing still overlaps.
- Zicbop: prefetch.i/r/w are ISA-string/DT-only (Rocket executes them as NOPs).

Core plumbing:
- useZicbom/useZicboz/useZicbop core params, WithZicbo*/WithCBO configs, and
  DefaultCBOConfig / DefaultCBONonblockingConfig.
- menvcfg/senvcfg/henvcfg CBIE/CBCFE/CBZE become writable; CSR gating raises
  illegal- vs virtual-instruction exceptions per the CMO spec, and degrades
  cbo.inval to a flush when CBIE=01.
- TLB permission checks: management ops need load-or-store permission, cbo.zero
  needs store permission plus a cacheable PMA; failures are reported as store
  faults. Effective addresses are block-aligned and the permission/PMP check
  spans the whole block, so a sub-block PMP boundary cannot be bypassed and no
  misaligned exceptions arise.
- ISA string advertises zicbom/zicbop/zicboz and DT exposes the cbo*-block-size
  properties.

AcquirePerm (permission without fetch) is not used because the stock TLBroadcast
hub answers it with GrantData; AcquireBlock is used and the fetched data is
overwritten by the zero-fill.

Verified in Verilator (DefaultCBOConfig and DefaultCBONonblockingConfig):
directed functional + envcfg-gating tests, an LR-created-Trunk cbo.zero
regression, a sub-block-PMP fault regression, an MSHR store-merge regression,
and a memory smoke test all pass.

cbo.zero vs an unrolled 8x sd zeroing loop, in cycles (Verilator, lower is
better), reported as sd / cbo:

  config            size    warm           cold
  blocking D$       4 KiB   805 / 570      2589 / 2566
  blocking D$       64 KiB  47449 / 47470  44692 / 44878
  non-blocking D$   4 KiB   807 / 640      2187 / 1687
  non-blocking D$   64 KiB  38112 / 34563  36910 / 30896

cbo.zero matches or beats the sd loop in every case -- up to ~30% faster on
L1-resident (warm) zeroing and ~16-23% faster cold on the non-blocking D$; the
larger-than-L1 thrashing case is memory-bound and at parity.
@cyyself
cyyself force-pushed the zicbom-zicboz-zicbop branch from 6234a16 to 7eab840 Compare July 14, 2026 18:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds RISC-V cache-block-operation extension support to Rocket by plumbing new CBO memory commands through decode/CSR gating, the TLB permission model, and both the blocking and non-blocking L1 data caches (with Zicbop advertised but executed as NOPs).

Changes:

  • Add core parameters/config fragments for Zicbom/Zicboz/Zicbop and expose them via ISA string + device tree properties.
  • Implement CSR envcfg-based gating (illegal vs virtual instruction behavior) and extend TLB permission/PMP checking to cover whole cache blocks for CBO operations.
  • Implement D$ behaviors for CBO operations (blocking: reuse flush-line path + add hit-path zeroing engine; non-blocking: add a hit-path zeroing engine plus MSHR-based miss-path zero-fill and a management-op flush/inval FSM).

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/main/scala/tilelink/Metadata.scala Classifies cbo.zero as an actual write for coherence/metadata purposes.
src/main/scala/tile/Core.scala Adds Zicbo* feature params and derived usingCBO flag.
src/main/scala/tile/BaseTile.scala Advertises zicbo* extensions in ISA string and adds DT cbo*-block-size properties.
src/main/scala/system/Configs.scala Adds default configs enabling CBO and a non-blocking D$ CBO config.
src/main/scala/rocket/TLB.scala Extends PMP/permission checking semantics for block-granular CBO operations.
src/main/scala/rocket/RocketCore.scala Adds decode-time CBO gating, management-op serialization, and block-aligned effective addresses.
src/main/scala/rocket/NBDcache.scala Implements non-blocking D$ support for CBO management ops and cbo.zero (hit engine + miss zero-fill).
src/main/scala/rocket/IDecode.scala Adds instruction decode tables for Zicbom and Zicboz CBO instructions.
src/main/scala/rocket/HellaCache.scala Adds parameter-time requirements for enabling Zicbom/Zicboz with the chosen cache setup.
src/main/scala/rocket/DCache.scala Implements blocking D$ support for Zicbom management ops and a cbo.zero hit-path zeroing engine.
src/main/scala/rocket/CSR.scala Makes CBIE/CBCFE/CBZE writable (when enabled) and provides decode-time CBO gating signals.
src/main/scala/rocket/Consts.scala Adds new memory command encodings and helpers for identifying CBO ops.
src/main/scala/rocket/Configs.scala Adds WithZicbom/WithZicboz/WithZicbop and WithCBO config fragments.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

2 participants