Code of Conduct
CVA6 commit affected
6cb200105fb9441d170e45786125a737fab98e91
Bug Description
Bug Description
The WT DCache accepts a three-way associativity configuration, but its replacement index has two bits and can encode value 3. The one-hot conversion then indexes a three-element vector with an out-of-range value and produces an empty replacement mask.
Steps to reproduce
From this issue directory, run bash test/run.sh.
The test uses three ways as the trigger and four ways as the baseline:
WT assoc=3 rnd=11 repl_way_oh=000
WT assoc=4 rnd=11 repl_way_oh=1000
BUG_CONFIRMED: WT DCache assoc=3 can select no replacement way
test.zip
Expected behavior
Every accepted associativity must produce exactly one valid replacement way. If non-power-of-two associativities are unsupported, the configuration should be rejected with a clear diagnostic.
Observed behavior
The three-way witness reaches binary replacement index 11, which is outside ways 0–2. The resulting repl_way_oh=000 selects no way. The four-way baseline produces a valid one-hot mask.
A full CPU replay was also run with test/cva6_wt_dcache_assoc3_cpu.S using the three-way WT configuration. The program completed its four same-set loads successfully, but an internal trace of the production WT miss unit reported:
WT_DYNAMIC repl_way=1 cycle=1863
WT_DYNAMIC repl_way=2 cycle=1874
WT_DYNAMIC repl_way=3 cycle=1887
WT_DYNAMIC repl_way=0 cycle=1888
The repl_way=3 event is the dynamic RTL symptom: a three-way cache only has valid way indices 0, 1, and 2. The software test passing does not disprove the issue; this particular sequence does not require the invalidly selected line to be observed architecturally.
Root cause analysis
The replacement logic uses $clog2(3) bits for the random index and directly applies that value to the way one-hot vector. The width can represent four values, but the cache has only three ways. There is no modulo, rejection, or range assertion before the one-hot conversion.
Reproduction test case
test/cva6_wt_dcache_assoc3_tb.sv instantiates the actual common-cells LFSR and the same binary-index-to-one-hot operation used by wt_dcache_missunit.sv.
test/run.sh runs the three-way trigger against a four-way baseline.
test/cva6_wt_dcache_assoc3_cpu.S is the bare-metal full-CPU replay that creates four misses in one cache set.
test/link.ld places the test code, tohost, and all four data words in one loadable image.
The full-CPU replay was run with the CVA6 Verilator harness and the internal repl_way trace shown above. The focused run.sh remains useful as a small RTL regression for the exact replacement expression.
This is a focused replacement-path RTL test; it does not claim a complete DCache miss/refill software regression.
Possible fix
Either restrict DcacheSetAssoc to power-of-two values, or make replacement selection range-safe by rejecting/re-rolling an out-of-range index and asserting $onehot(repl_way_oh) for every accepted request.
Environment and source
- Target: CVA6 WT DCache replacement path.
- Verilator: 5.020.
- Relevant RTL:
core/cache_subsystem/wt_dcache_missunit.sv and the common-cells lfsr module.
I can work on this issue; please assign it to me.
Code of Conduct
CVA6 commit affected
6cb200105fb9441d170e45786125a737fab98e91Bug Description
Bug Description
The WT DCache accepts a three-way associativity configuration, but its replacement index has two bits and can encode value 3. The one-hot conversion then indexes a three-element vector with an out-of-range value and produces an empty replacement mask.
Steps to reproduce
From this issue directory, run
bash test/run.sh.The test uses three ways as the trigger and four ways as the baseline:
test.zip
Expected behavior
Every accepted associativity must produce exactly one valid replacement way. If non-power-of-two associativities are unsupported, the configuration should be rejected with a clear diagnostic.
Observed behavior
The three-way witness reaches binary replacement index
11, which is outside ways 0–2. The resultingrepl_way_oh=000selects no way. The four-way baseline produces a valid one-hot mask.A full CPU replay was also run with
test/cva6_wt_dcache_assoc3_cpu.Susing the three-way WT configuration. The program completed its four same-set loads successfully, but an internal trace of the production WT miss unit reported:The
repl_way=3event is the dynamic RTL symptom: a three-way cache only has valid way indices 0, 1, and 2. The software test passing does not disprove the issue; this particular sequence does not require the invalidly selected line to be observed architecturally.Root cause analysis
The replacement logic uses
$clog2(3)bits for the random index and directly applies that value to the way one-hot vector. The width can represent four values, but the cache has only three ways. There is no modulo, rejection, or range assertion before the one-hot conversion.Reproduction test case
test/cva6_wt_dcache_assoc3_tb.svinstantiates the actual common-cells LFSR and the same binary-index-to-one-hot operation used bywt_dcache_missunit.sv.test/run.shruns the three-way trigger against a four-way baseline.test/cva6_wt_dcache_assoc3_cpu.Sis the bare-metal full-CPU replay that creates four misses in one cache set.test/link.ldplaces the test code,tohost, and all four data words in one loadable image.The full-CPU replay was run with the CVA6 Verilator harness and the internal
repl_waytrace shown above. The focusedrun.shremains useful as a small RTL regression for the exact replacement expression.This is a focused replacement-path RTL test; it does not claim a complete DCache miss/refill software regression.
Possible fix
Either restrict
DcacheSetAssocto power-of-two values, or make replacement selection range-safe by rejecting/re-rolling an out-of-range index and asserting$onehot(repl_way_oh)for every accepted request.Environment and source
core/cache_subsystem/wt_dcache_missunit.svand the common-cellslfsrmodule.I can work on this issue; please assign it to me.