Electronic – One-hot fsm in vhdl

state-machinesvhdl

I'd like to code a one-hot fsm in vhdl. I've done many in verilog but my current employer prefers vhdl. In verilog I'd use the "inverse case statement" (case 1'b1) to compare each bit in the state vector in parallel. Then with a parallel-case pragma, or a "unique" declaration in system verilog, we synthesize to the right result.

But… Vhdl doesn't seem to allow a reverse case statement. There's no need for parallel_case since case is always parallel in vhdl. The best example I found, from Steve Golson's paper (in 1994!) uses cascaded if statements. There's no "else" but it seems to me these should become priority encoders and not parallel state checking. So I'm kind of at a loss.

Asking co-workers won't help, nobody uses this coding style and I'm trying to show them how well it works. But maybe there's a reason these vhdl guys don't use it…

Best Answer

In VHDL you describe the FSM states with an enumeration type like this:

type T_STATE is (ST_IDLE, ST_READING, ST_WRITING, ST_FINISHED, ST_ERROR);

This type has no meaning on how to represent the enumeration literals (the state names) as binary values in you target device. It can be: * sequential * gray code * johnson code * one-hot code * ...

You can even specify your own user-defined encoding.

The synthesis tool will chose based on: * number of states * number of transitions * transition patterns, e.g. parallel paths in your FSM * need output format * timing requirements * optimization strategy

what will be the best encoding. For example if you enable speed optimization, it might chose one-hot more often, because it's easier to check, and can handle higher frequencies. If you optimize for area, it will decide for more compact codes like gray or sequential (binary numbers).

I have seen one-hot encoded FSM with up to 31 registers (states) in Xilinx synthesis tools.

You can specify a default FSM encoding globally by synthesizer options or per FSM or per enum type with VHDL attributes.


An enumeration type is a discrete type. All enumeration literals have a position number (T_STATE'pos(ST_ERROR) is 4). Because of that, the tools can handle enumeration literals internally as integers, because a position on the number-scale is an integer value. But this fact does not mean, that each state will be encoded as the binary format of it's position number.