Identifying Register Write-back Hazard when using eXtension Interface

Placeholder Abraham Steenhoek
2026-02-10T06:20:56Z

It appears that the CPU pipeline does not properly preserve the writeback state for custom instructions through the eXt interface in

Consider the following disassembly, where my custom instruction at pc==`1000030a` is a writeback instruction through the eXt interface.
```
10000300: 0002a503 lw a0,0(t0)
10000304: 00a2a023 sw a0,0(t0)
10000308: 0001 nop
1000030a: 0a65150b .insn 4, 0x0a65150b // custom instruction here, writing value back to reg 0xA
1000030e: 00a2a023 sw a0,0(t0)
:
: "r"(&val1), "r"(val2)
: "a0", "a1", "memory"
);
```

With the coprocessor communicating that this is a writeback during the "issue response", it appears to get received properly at the decode stage, and the pipeline seems to preserve the writeback flag at the writeback stage, as circled.

However, if I run the following disassembly, where the `nop` has been removed between `sw` and `insn`
```
100002fc: 08800313 li t1,136
10000300: 0002a503 lw a0,0(t0)
10000304: 00a2a023 sw a0,0(t0)
10000308: 0a65150b .insn 4, 0x0a65150b // SAME custom instruction here, writing value back to reg 0xA
1000030c: 00a2a023 sw a0,0(t0)
```

It appears that the writeback flag never gets preserved in the decode stage, which results in it never getting preserved at the writeback stage. Notice that the coprocessor still communicates the writeback flag at the eXt interface.

However, it seems like the `rf_we` signal coming from the decoder_ctrl_mux in `cv32e40x_id_stage` might not be preserving the wb flag properly
```
// Mux control outputs from decoders
always_comb
begin
unique case (1'b1)
!decoder_m_ctrl.illegal_insn : decoder_ctrl_mux = decoder_m_ctrl; // M decoder got a match
!decoder_a_ctrl.illegal_insn : decoder_ctrl_mux = decoder_a_ctrl; // A decoder got a match
!decoder_i_ctrl.illegal_insn : decoder_ctrl_mux = decoder_i_ctrl; // I decoder got a match
!decoder_b_ctrl.illegal_insn : decoder_ctrl_mux = decoder_b_ctrl; // B decoder got a match
default : decoder_ctrl_mux = DECODER_CTRL_ILLEGAL_INSN; // No match from decoders, illegal instruction
endcase
end
```