While running the RISC-V architectural PMP tests, we observed a behavioral difference between Spike and the Sail reference model for misaligned memory accesses that cross PMP region boundaries (e.g., ld/sd straddling an NA4/TOR/NAPOT region).
This appears to be related to how misaligned accesses are handled internally by the implementation.
The RISC-V Privileged Specification (Section 3.7.1.3) states that on some implementations, misaligned loads, stores, and instruction fetches may also be decomposed into multiple accesses. Because of this allowance, there are two possible valid behaviors.
Spike
Spike treats the misaligned access as a single memory access.
Example:
If the access width crosses a PMP region boundary (e.g., an NA4 region), Spike checks the entire access width against the matching PMP entry.
If the entry does not match all bytes of the access, Spike raises:
Sail
Sail appears to decompose misaligned accesses into multiple aligned accesses.
For example, an ld or sd that straddles a PMP boundary is executed as two smaller accesses, each of which independently passes PMP checks.
As a result, no exception is raised.
Because the privileged spec explicitly allows implementations to either
- Treat the misaligned access as a single access, or
- Decompose it into multiple accesses
both Spike and Sail behaviors are architecturally allowed.
However, this difference causes problems when using Sail as a reference model for DUT comparison, because different implementations may follow either behavior. This difference currently causes mismatches in PMP architectural tests involving misaligned accesses that straddle PMP boundaries, including:
The DUT may match either Spike-style behavior or Sail-style behavior depending on how misaligned accesses are implemented.
Introduce a configuration option in Sail controlling how misaligned accesses are handled during PMP checking.
Example:
pmp_misaligned_access_behavior = {single_access | decomposed_access}
Where:
single_access
- Treat the misaligned load/store as one access
- Check the entire access width against PMP
- If any byte falls outside the matching PMP entry → raise fault
- Matches Spike behavior
decomposed_access
- Decompose misaligned access into multiple aligned accesses
- Perform PMP checks per sub-access
- Matches current Sail behavior
While running the RISC-V architectural PMP tests, we observed a behavioral difference between Spike and the Sail reference model for misaligned memory accesses that cross PMP region boundaries (e.g.,
ld/sdstraddling an NA4/TOR/NAPOT region).This appears to be related to how misaligned accesses are handled internally by the implementation.
The RISC-V Privileged Specification (Section 3.7.1.3) states that on some implementations, misaligned loads, stores, and instruction fetches may also be decomposed into multiple accesses. Because of this allowance, there are two possible valid behaviors.
Spike
Spike treats the misaligned access as a single memory access.
Example:
If the access width crosses a PMP region boundary (e.g., an NA4 region), Spike checks the entire access width against the matching PMP entry.
If the entry does not match all bytes of the access, Spike raises:
Sail
Sail appears to decompose misaligned accesses into multiple aligned accesses.
For example, an
ldorsdthat straddles a PMP boundary is executed as two smaller accesses, each of which independently passes PMP checks.As a result, no exception is raised.
Because the privileged spec explicitly allows implementations to either
both Spike and Sail behaviors are architecturally allowed.
However, this difference causes problems when using Sail as a reference model for DUT comparison, because different implementations may follow either behavior. This difference currently causes mismatches in PMP architectural tests involving misaligned accesses that straddle PMP boundaries, including:
misaligned_na4misaligned_tormisaligned_napotThe DUT may match either Spike-style behavior or Sail-style behavior depending on how misaligned accesses are implemented.
Introduce a configuration option in Sail controlling how misaligned accesses are handled during PMP checking.
Example:
Where:
single_accessdecomposed_access