I'm trying to design a processor in VHDL. While the base instruction set is done, I'm having trouble building on top of it.

Specifically, I'm implementing control and status registers (CSRs), which allows the system to be controlled to a greater degree.

These CSRs do not need an instruction to be altered, they can change based on the state of the machine. This comes with a set of data hazards that I have been trying to solve. There are not many existing resources that offer solutions to these hazards.

All instructions which associate with these registers are atomic instructions which are meant to swap the CSR value with a general purpose value.

Hazard 1: RAW
The register is read from, and the CSR are read from on one clock cycle of the pipeline. On the next clock cycle, the values are written. During this time, the CSR may have changed.

Hazard 2: interrupt WAW Something in the processor triggers an interrupt, And changes a whole bunch of registers at once. In the pipeline, however, there is an instruction which writes to a CSR which has been modified. This corrupts the register.

What are some common ways to remedy these hazards?

  • 2
    \$\begingroup\$ related, not 100% sure if it describes your problem: Are you aware of shadow registers? \$\endgroup\$ Jun 1, 2020 at 18:34
  • \$\begingroup\$ @MarcusMüller I am not. \$\endgroup\$
    – tuskiomi
    Jun 1, 2020 at 18:35
  • 1
    \$\begingroup\$ Also, in some cases you can remove hazards by not detecting them or dealing with them. For example, in the MIPS R2000 (and to a still greater degree, the DEC Alpha) they removed a read-after-write register hazard by simply not detecting them. It was the programmer's problem. If you cared, you inserted a NOP or some other back-filled instruction. Frankly, I like this method better as it also provides more opportunities for faster clocking as you haven't inserted still more logic that lengthens combinatorial paths. Compiler tools aren't so happy, though. \$\endgroup\$
    – jonk
    Jun 1, 2020 at 18:45
  • \$\begingroup\$ What can modify the CSRs? You say the state of the machine, but if "machine" means "processor", then the state of the machine only changes synchronously with the clock, not asynchronously. \$\endgroup\$
    – user253751
    Jun 1, 2020 at 18:49
  • 1
    \$\begingroup\$ I think, typically, writing to a rarely modified register will simply flush the pipeline. The extra delay is considered acceptable because it doesn't happen very often. \$\endgroup\$
    – user253751
    Jun 1, 2020 at 18:54

2 Answers 2


In general any asynchronous inputs to the system (such as from peripherals) would be synchronized with a dual rank register to make it synchronous to the processor clock before it is used by any processor state machine.

Dual rank synchronizer

From: Synchronization in digital logic cercuits


I'm not sure about your question. Register updates are usually committed in the write state, that includes normal registers, the program counter and system registers.

If an exception is triggered (for example after a memory access), the updates can be cancelled. For example the program counter that is always in advance for fetches, this register has several copies along the pipeline with different "ages".

For things that affect performances, like NZVC flags in CPUs that use them, these flags will be bypassed like integer registers around the ALU. For less performance sensitive system flags and registers, the pipeline can stall after one of the instructions controlling these flags is decoded, until the pipeline is empty, for example instructions that controls interrupt masking flags.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.