frontend: Clear 'speculative' flag on replay
Created by: niwis
Prevent deadlock when replaying speculative instruction from nonidempotent memory region.
Consider the following scenario while executing from nonidempotent memory:
- A branch instruction is fetched =>
speculative_d = 1'b1
- The instruction queue is full,
replay
is asserted - Once the instruction queue is
ready
again, the frontend sends a request to the icache to refetch the branch instruction - The icache blocks as
dreq.spec == 1'b1
(and we do not fetch speculatively from nonidempotent memory) - Deadlock
Hence, the speculative
register needs to be rolled back if the corresponding speculative instruction is not accepted by the instruction queue. Since the speculative instruction should always be the most recently fetched instruction (the icache stalls until the speculative instruction is resolved), clearing speculative
on a replay
should be accurate.
(Alternatively we could set speculative
only if the instruction queue is ready, but I think this might be less accurate as the underlying assumption "!instr_queue_ready
=> instr
will not enter the instruction queue" might not hold.)