Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20705 Discussions

is VHDL unsafe with state machine?

Altera_Forum
Honored Contributor II
2,902 Views

Typical VHDL state machine is to define a type that consist of states, then use that type in a signal. But if someone (not me, no way! ;-)) forget to put a reset state, the state machine continues to work starting from the first state declared in type. This is wrong! It should go to undefined state. But since the state definition does not include undefined state, it never goes there. Below is an example code. 

 

type state_type is (S0, S1, S2, S3, STARTUPSTATE); 

signal currState, nextState : state_type; 

begin 

 

process(currState) begin 

case currState is 

when S0 => blah0; nextState <= findNextState(blah0); 

when S1 => blah1; nextState <= findNextState(blah1); 

when S2 => blah2; nextState <= findNextState(blah2); 

when S3 => blah3; nextState <= findNextState(blah3); 

when STARTUPSTATE => nextState <= findNextState(someCondition); 

when others => -- never goes here 

end case; 

end process; 

 

process(reset, clk) begin 

if reset='1' then 

-- currState <= STARTUPSTATE; somebody forgot this reset!!! 

elsif rising_edge(clk) then 

currState <= nextState; 

end if; 

end process; 

 

 

Note that the state machine starts at S0, not STARTUPSTATE as intended. One could argue that STARTUPSTATE should be the first item in state type, but that's not the point; the problem arose out of error, and VHDL did not flag it as "X". Also, that still doesn't fix the problem: after P&R, flop is not reset property, and one doesn't know what state the flop will take. But functional simulation will work just fine. It seems coding state machine like this is going to mask problems that may come up in hardware after P&R. 

 

One way to circumvent this is to use std_logic_vector to explicitly encode that states. But doing that means one has to binary code the states and more decoding is needed as opposed to more efficient methods such as one-hot. And doing one-hot in VHDL means if-else rather than case, which could incur unnecessary logic. 

 

If FPGA always take on some value, that might be fine. But flops without reset must take on undefined values upon power up until valid inputs (D + CK) are present. This becomes especially problematic for ASIC emulation where ASIC behaves differently than FPGA due to coding error that was masked by VHDL. 

 

So what are the options other than going to Verilog for safe coding of state machine in VHDL that will catch errors like this without explicitly specifying the state values? Thank you.
0 Kudos
10 Replies
Altera_Forum
Honored Contributor II
1,686 Views

no they shouldnt. By default ALL registers in an FPGA powerup to '0' unless specified. Whether you code in Verilog or VHDL it wont be any different. There is no such thing as undefined in real hardware. Even more interesting, a state machine like this with more than 3 states has the states encoded as 1 hot by default, so there are actually many illegal states. 

 

As for the VHDL, all types, if left uninitialised, will initialise to the left most state, which in this case is S0. It cannot go to 'X' in simulation because you have not defined an 'X' state. This is not a std_logic (which would default to 'U', not 'X'). If you really want the specifics, then yes, you have to define the states yourself using std_logic_vector or similar. Even if you did this, without the reset, its likely to power up to all zeros, regardless of what youir first state should be. 

 

The solution: have your powerup/reset state as the left most state.
0 Kudos
Altera_Forum
Honored Contributor II
1,686 Views

I think your question confuses several unrelated points. In functional simulation, the initial state of a signal will follow general VHDL rules, not an assumed behaviour of FFs. For enumerations, the first member is the initial state. 

 

In synthesized code, there's no thing like unknown state. Safe coding of state machine doesn't mean to enter an 'X' state for a missing reset. It means that any illegal states will automatically cause a transition to a defined, usually the initial state. That's important to prevent locking of a FSM in case of unexpected events, e.g. clock glitches or timing violation of input signals. 

 

A functional simulation however does neither show nor handles illegal states, you have to refer to a gate level simulation to check for these effects. 

 

In my opinion, there's no principle difference between VHDL and Verilog implementation of state machines, except for some syntax details. But although you'll define e.g. a state encoding in Verilog, it will be usually translated in a one state hot design by the synthesis tool.
0 Kudos
Altera_Forum
Honored Contributor II
1,686 Views

As FvM points out, the VHDL language is essentially changing your code to: 

 

signal currState, nextState : state_type := S0; 

 

Which is a synthesizeable construct; whatever Quartus decides is the state width, and the encoding for S0, the registers will be initialized to at power-on. 

 

If STARTUPSTATE should be first, then either the enumeration can be changed, or the code changed to  

 

signal currState, nextState : state_type := STARTUPSTATE; 

 

or, explicitly use a reset signal and initialize the state in the process as you have shown. However, even in that case, if you never assert reset in the simulation, the state variables will be assigned to either S0 or whatever you explicitly assign to. 

 

Personally I prefer the explicit use of a reset signal. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
1,686 Views

I don't want to drag discussion back to some posts in 2008. But, an issue was raised that "when others" is ignored by most tools by default unless you override it, because it takes too much logic. Thus a reset is essential for power up case. For critical applications it must be safe in real time as well and so when others must be there fitted. 

 

Does that mean "when others" of state machines only or any case statement, I don't know and I don't think so.
0 Kudos
Altera_Forum
Honored Contributor II
1,686 Views

Hi, I think both replies miss the point that there is discrepancy of hardware behavior and RTL functional simulation. If one assume this only relate to flops that always reset to some value as I discussed in original post, this is not a problem. But the real flop in ASIC or may not behave this way. Correct behavior is undefined output from flops (sometimes 0, sometime 1, never known a priori). Therefore, coding this way with left most entry as default state does not address the issue of undefined output from real flop causing the post place and route and hardware behavior to not match RTL functional. 

 

Granted, one can say this is reset bug, so that should be fixed. But functional simulation will not catch this kind of bug when all states are defined. I supposed one can go a step further and define and undefined state as left most in type declaration just to catch not properly resetted state machine, but that's so kludgy... 

 

As for HW, I was testing an FPGA hardware in lab long ago, and it would only work after dozen or so power cycles. Now I think of it, I suspect the guy who did RTL did not reset his state machine written in VHDL.
0 Kudos
Altera_Forum
Honored Contributor II
1,686 Views

I think the original question is sensible as there is some ambiguity here (though it is tool related issue) that even if fpga guarantees zero power up state of most flips, then that does not means guaranteeing start up state registers which could be encoded as some nonzero value. 

 

So, yes power reset is essential and your circuit will not start same otherwise.
0 Kudos
Altera_Forum
Honored Contributor II
1,686 Views

 

--- Quote Start ---  

Hi, I think both replies miss the point that there is discrepancy of hardware behavior and RTL functional simulation.  

 

--- Quote End ---  

 

The 'HD' in VHDL stands for hardware description...all you're saying with your point is that the source code that was written does not describe the hardware that is built...don't blame VHDL for an incorrect description. At best, you could blame the synthesis tool for not synthesizing exactly what was described, but you probably won't get much support on 'fixing' that problem. 

 

 

--- Quote Start ---  

 

If one assume this only relate to flops that always reset to some value as I discussed in original post, this is not a problem. But the real flop in ASIC or may not behave this way. Correct behavior is undefined output from flops (sometimes 0, sometime 1, never known a priori). Therefore, coding this way with left most entry as default state does not address the issue of undefined output from real flop causing the post place and route and hardware behavior to not match RTL functional. 

 

--- Quote End ---  

 

Many things can be coded that cannot be synthesized and built reliably. Synthesis tools will accept the following statement, but not actually implement it. 

a <= b after 10 ns; 

Again, it's not the language that is the problem. 

 

 

--- Quote Start ---  

 

Granted, one can say this is reset bug, so that should be fixed. But functional simulation will not catch this kind of bug when all states are defined. 

 

--- Quote End ---  

 

The functional simulation will catch it. If it doesn't, this implies that your testbench was not adequate in coverage to catch it. 

 

 

--- Quote Start ---  

 

I supposed one can go a step further and define and undefined state as left most in type declaration just to catch not properly resetted state machine, but that's so kludgy... 

 

--- Quote End ---  

 

True...also keep this in mind if you ever use integers where the leftmost value is a big negative number...the list goes on. 

 

I'm not trying to rake you over the coals, but just pointing out that VHDL as a language is a tool that can be used for design. It does not guarantee a correct design no more than a hammer guarantees correctly fastened 2x4s used to build a house. Use your tools properly, but don't expect them to catch your every error, even if you think it is something 'simple'. Instead, you need to know the limitations of your tools in order to now how to apply them correctly. 

 

 

--- Quote Start ---  

 

As for HW, I was testing an FPGA hardware in lab long ago, and it would only work after dozen or so power cycles. Now I think of it, I suspect the guy who did RTL did not reset his state machine written in VHDL. 

 

--- Quote End ---  

 

Or it could be an unsynchronized asynchronous reset input...or lots of things. 

 

Kevin Jennings
0 Kudos
Altera_Forum
Honored Contributor II
1,686 Views

Nice thread. One comment to Tricky's post that registers will power-up to 0 unless otherwise stated. Note that they always power-up to 0. If you have a reset that says it should come up as 1, then a not gate is put before and after the register. So the register still powers up to 0, but it immediately gets inverted so it looks like a 1 to the rest of the world. As data goes through, it is inverted coming in and going out, so the rest of the design is unaware. Not gates are free in most conditions, as they can be absorbed into the LUT.  

So for a one-hot state machine, it actually comes up as all 0s. You'll see it like so: 

000 

011 

101 

As you can see, the LSB is basically inverted. Most users are never aware of this, but the two places it comes up are timing simulations and signaltap, where in both cases you are looking at the register between the not gates, so it will look like its acting the opposite of what you'd expect. This really doesn't have a whole lot to do with the thread, but hopefully interesting.
0 Kudos
Altera_Forum
Honored Contributor II
1,686 Views

We trust the fpga will start up with zeros on all flips. No problem here. For nonzero power up then the issue Rysc raised is just implementation for cases when register must startup with 1. 

 

The problem is that vendors themselves say don't trust our power up. Not that they can't do it but they can't guarantee what happens at intrinsic reset release after configuration. You may for example have an active external clock that upsets timing...etc. 

The solution is quite simple. Use your own reset and it should be safe. With your own reset you will have better control of recovery/removal etc.than device wide reset release.
0 Kudos
Altera_Forum
Honored Contributor II
1,686 Views

 

--- Quote Start ---  

If one assume this only relate to flops that always reset to some value as I discussed in original post, this is not a problem. But the real flop in ASIC or may not behave this way. Correct behavior is undefined output from flops (sometimes 0, sometime 1, never known a priori). Therefore, coding this way with left most entry as default state does not address the issue of undefined output from real flop causing the post place and route and hardware behavior to not match RTL functional. 

--- Quote End ---  

 

As many contributors explained, the initialization behaviour with FPGA hardware is compeletey defined. The Quartus synthesis tool also achieves consistency between functional simulation and hardware behaviour, because it codes the initial FSM state with all zero state FFs. 

 

 

--- Quote Start ---  

As for HW, I was testing an FPGA hardware in lab long ago, and it would only work after dozen or so power cycles. Now I think of it, I suspect the guy who did RTL did not reset his state machine written in VHDL. 

--- Quote End ---  

 

I agree with K_J, that the reason is more likely a timing violation by an asynchronously released reset than a missing reset. Clock glitches can have a similar effect. Unfortunately, these effects can't be catched in a functional simulation. 

 

If I understand right, your question can be reduced to "how to achieve a FSM simulation consistent with an ASIC hardware target". I'm convinced, that both VHDL and Verilog HDL have adequate means for this purpose, but probably not in an automatic manner. I assume, that similar to the FPGA target, missing reset is only one of the simple cases, that may cause design failure.
0 Kudos
Reply