# One-hot fsm in vhdl

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...

• Synthesis tools are (mostly) able to recognize the state machine pattern and choose the optimal encoding method. So in VHDL you usually use enumerations for states without explicitly stating the encoding. And let the tool to optimize it for you. This would likely be true for Verilog as well. – Eugene Sh. Dec 4 '18 at 19:23
• Good point about synth tools. I think I'll email our AE to see what they recommend. – Matt Dec 4 '18 at 19:35
• I'm also not quite sure how enumerations work with logic types in vhdl. In system verilog you can declare an enum of type logic. That doesn't work in vhdl, so you lose Z and X states. Maybe that modeling is unnecessary with enumerated states. – Matt Dec 4 '18 at 19:36
• Also, would formal equivalence be able to compare tool-optimized encodings? It's interesting how some of the high-end chip designs are very regressive about tool flows, probably because they know what has worked and are scared to make changes. – Matt Dec 4 '18 at 19:38
• On further thought there won't be a priority encoder inferred. This completely captures the intended logic, which I only realized after writing out a long message to my AE, before hitting send. I'll think about this a bit more, but it appears to be a non-issue. – Matt Dec 4 '18 at 19:49

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.

• But that isn't so good when you know that you want one-hot (for example, for eco-friendliness, and the fact that we are high frequency, low voltage, and every picosecond counts) and there doesn't seem to be a tool-indepedent way to specify the encoding. Unfortunately I've gone the way that I mentioned in my initial post, as described in the paper from 1994. Then again, my team normally doesn't allow "process" for combinational logic so it might get shot down anyways... – Matt Dec 4 '18 at 21:14
• At first, the tools knows about your timing restrictions (that's why you have SDC/XDC/LDC, ... files). At second, you can set global options for all FSMs to use a specify encoding (synthesizer option). And finally, you can define the encoding with design constraints, or VHDL attributes. Search for the FSM_ENCODING and ENUM_ENCODING attributes in your vendors synthesis user manuals. – Paebbels Dec 4 '18 at 21:20
• How portable is ENUM_ENCODING? If we switch vendors, does it need to get rewritten? And if I do it this way, when I compare to see if we are in a specific state, I would compare to the enum value... it would get synthesized to just a single bit comparison (if one-hot)? – Matt Dec 4 '18 at 21:31
• The vendors rejected the VHDL synthesis standard time time ago. But as far as I remember, the attribute name is the same, while some encoding names are different. Xilinx calls it "sequential", Intel calls it "binary". You can write a function (which can be called in attribute statements) to handle this. – Paebbels Dec 4 '18 at 21:38