Why 4 regs to control a FSM? Verilog

I'm studying an SDRAM controller (in Verilog), which uses 4 reg to control a FSM. I couldn't understand why they use 4 regs instead of 2 (state and next_state).

Here's the piece of code:

reg [STATE_SIZE-1:0] state_d, state_q = INIT;
reg [STATE_SIZE-1:0] next_state_d, next_state_q;


• It looks like it's tracking previous states after some delay -- see line 240. I did not look hard, and I am not a digital logic expert, which is why this isn't an answer! Feb 5, 2019 at 2:01

First of all, there are *_d and *_q versions of each variable because the designer follows the practice of using two separate always blocks for his state machine.

The state machine requires timed waits at various stages of its operation, and instead of having a separate state for each one, he wrote just a single common WAIT state. The next_state_* variables tell the machine what to do when the WAIT is over.

The first thing to remember is that a Verilog "reg" doesn't always represent a register, whether or not it represents a register depends on how it is used.

The author of this code has implemented the state machine using two separate always blocks. The state machine logic is represented by a combinatorial always block while a sequential always block represents the registers. This structure means he needs Verilog regs to represent both the inputs "_d" and the outputs "_q" of his registers.

The advantage of this structure is that it allows the state machine to have combinatorial outputs. If you put the state machine logic in a sequential always block then all outputs from that logic must be registered.

Now in this particular case it looks like all outputs are registered, so he could have just put the logic in a sequential always block, but I suspect some people find it easier to stick to a consistent style even if said style is more verbose than necessary in most cases. Translating a single always block state machine to a two always block style because you found you did in-fact need a combinatorial output is no fun.

He has two state registers so he can have a single "wait" state that can lead to multiple different next states after the wait is over.

Two state registers, each with a separate Verilog "reg" for it's input and output makes four Verilog "reg"s.