Skip to content

Commit 52ca0dd

Browse files
committed
[RTL] Avoid synthesis optimizations for DCLS feature
Depending on synthesis constraints and synthesis tools, some synthesis tools could potentially remove the shadow core of the DCLS feature as it always should be an identical copy of the main core. To prevent this optimiziation, use the prim_buf module on the core IOs. Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
1 parent 1a6d471 commit 52ca0dd

2 files changed

Lines changed: 47 additions & 2 deletions

File tree

design/el2_veer_lockstep.sv

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,26 @@ module el2_veer_lockstep
401401
veer_outputs_t delayed_main_core_outputs;
402402
veer_outputs_t shadow_core_outputs;
403403

404-
assign shadow_core_inputs = delay_input_d[LockstepDelayPipeStages];
405-
assign delayed_main_core_outputs = delay_output_d[LockstepDelayPipeStages];
404+
// Insert optimization barriers (el2_prim_buf) at the shadow-core IOs so that
405+
// synthesis tools cannot prove the shadow core / comparison redundant and
406+
// optimize them away.
407+
veer_inputs_t shadow_core_inputs_pre;
408+
veer_outputs_t delayed_main_core_outputs_pre;
409+
assign shadow_core_inputs_pre = delay_input_d[LockstepDelayPipeStages];
410+
assign delayed_main_core_outputs_pre = delay_output_d[LockstepDelayPipeStages];
411+
412+
el2_prim_buf #(
413+
.Width($bits(veer_inputs_t))
414+
) u_shadow_inputs_buf (
415+
.in_i (shadow_core_inputs_pre),
416+
.out_o(shadow_core_inputs)
417+
);
418+
el2_prim_buf #(
419+
.Width($bits(veer_outputs_t))
420+
) u_main_outputs_buf (
421+
.in_i (delayed_main_core_outputs_pre),
422+
.out_o(delayed_main_core_outputs)
423+
);
406424

407425
// Capture input
408426
assign main_core_inputs.rst_vec = rst_vec;

docs/source/dual-core-lock-step.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,33 @@ There are two configuration options:
11831183

11841184
The configuration options are ignored and their macros are not generated if the Dual Core Lockstep feature is disabled.
11851185

1186+
## Synthesis: optimization barriers (`el2_prim_buf`)
1187+
1188+
For the DCLS to be effective, the Shadow Core and the Main/Shadow comparison logic must *not* be merged or removed by synthesis.
1189+
Logic-equivalence-aware tools can otherwise recognize the Shadow Core as redundant duplicate logic and optimize it away.
1190+
1191+
To prevent this, `el2_veer_lockstep` inserts optimization barriers (`el2_prim_buf`) on the IOs of the Shadow Core:
1192+
1193+
* the Shadow Core input bus (`shadow_core_inputs`),
1194+
* the delayed Main Core outputs used in the comparison (`delayed_main_core_outputs`).
1195+
1196+
The register-file comparison (when `lockstep_regfile_enable=1`) is covered by the `shadow_core_inputs` barrier: the Shadow Core's internal register file is driven from the buffered inputs, so the comparison cannot be proven constant and optimized away.
1197+
1198+
`el2_prim_buf` is an abstract wrapper that selects its implementation through the `RV_PRIM_BUF_IMPL` macro.
1199+
By default, it resolves to `el2_prim_generic_buf`, which is a plain buffer provided such that the core builds and simulates standalone.
1200+
1201+
**Warning**
1202+
The default `el2_prim_generic_buf` shipped in this repository is **functionally** a buffer but is **not constrained for synthesis**, i.e., it carries no `keep` / `size_only` / `dont_touch` attribute.
1203+
With the generic buffer alone, a synthesis tool is free to optimize the barrier - and therefore the redundant Shadow Core and comparison logic it protects - away.
1204+
1205+
An integrator targeting silicon (or fault-injection / safety hardening) **must** do one of the following:
1206+
1207+
* Apply the appropriate synthesis constraints to `el2_prim_generic_buf` in their flow (e.g. `size_only` or `KEEP` / `DONT_TOUCH` in) so the buffer survives optimization; **or**
1208+
* Override `RV_PRIM_BUF_IMPL` to point at a primitive that already carries those constraints. For example, Caliptra builds pass `+define+RV_PRIM_BUF_IMPL=caliptra_prim_buf`, whose generic/Xilinx implementations are constrained `size_only` / `keep` by the Caliptra synthesis flow.
1209+
1210+
Failing to do either leaves the DCLS protection unverified against logic-optimization removal.
1211+
```
1212+
11861213
## Validation Plan
11871214
11881215
The DCLS feature will be tested within:

0 commit comments

Comments
 (0)