We are working on a pipelined processor written in VHDL, and we have some issues with timing, synchronization and registers on the simulator (the code does not need to be synthesizable, because we going to run it only on the simulator).
Imagine we have two processor stages, A and B, with a pipeline register in the middle:
- Processor stage A is combinatorial and does not depend on clock
- The pipeline register R, is a register, and therefor, changes its state at clock rising edge.
- Processor stage B is a complex stage and has its own state machine, and, therefor, changes its state and does operations inside a VHDL process, governed by clock rising edge.
The configuration would be as follows
_______ ___ _______
| | | | | |
---| A |---|R|---| B |---
|_____| |_| |_____|
With this configuration, there is a timing problem:
- t = 0: A gets data, and does its operations
- t = 1: At rising edge, R updates its data with the output of A.
- t = 2: At rising edge, B gets the values of R, and updates its status and gives an output.
We would like to have B changing its state and generating an output at t = 1, but we also need the register in the middle to make the pipeline work.
A solution would be to update the R register on falling edge. But then, we are assuming that all processor stages run in half a clock cycle, and the other half is a bit useless.
How is this problem usually solved in pipelines?