State machine definitions

S

Simon Watson

Hi all,

I am reading Pong P Chu's book RTL design using VHDL - and have a bit of a quandary.

I have always written my state machines (generally) in one process. However, in this book - the author suggests that this is bad practice due to the fact that any signals in the process will have additional registers placed on them.

The question breaks down quite nicely:

1) The author uses if (clk'event and clk='1') to trigger on the rising edge rather than rising_edge(clk) which is my normal use - is there a significant difference in these?

2) Is the extra registering on the output signals from the state machine necessarily a bad thing?

The author suggests that a "2-segment" or two process approach, with one process triggering on the signals / states in the state machine, and another clocked process updating the state register.

If anyone has the book the discussion is on 333 to 337.

Best regards,

Simon
 
K

KJ

Hi all,

I am reading Pong P Chu's book RTL design using VHDL - and have a bitof a quandary.

I have always written my state machines (generally) in one process. However, in this book - the author suggests that this is bad practice due to thefact that any signals in the process will have additional registers placedon them.

There will be no 'additional registers'. There is absolutely nothing wrongwith writing code as a single clocked process. Either the author is wrongor what you're stating was taken out of context. Maybe the author doesn'teven know about variables.
The question breaks down quite nicely:

1) The author uses if (clk'event and clk='1') to trigger onthe rising edge rather than rising_edge(clk) which is my normal use - is there a significant difference in these?

Yes...rising_edge is clearer about the intent and less typing. 'rising_edge' will also work if the clock goes from 'L' to 'H' rather than just '0' to'1', whereas "clk'event..." will not. Strike two for the author.
2) Is the extra registering on the output signals from the state machine necessarily a bad thing?

By stating 'extra registering' you imply that there is no way to avoid someextra baggage if you use a single clocked process as your model. That premise is wrong so any conclusions that are drawn from that premise are likely invalid as well.
The author suggests that a "2-segment" or two process approach,with one process triggering on the signals / states in the state machine, and another clocked process updating the state register.

There are those that do prefer this approach and it becomes almost a religion thing to them. There are no advantages to the two process approach, there are definite disadvantages. A search of the archives of this group willlikely give you all kinds of information. Bottom line is that the two process approach folks have never been able to post a single example demonstrating how that method is 'better' by any measurable metric...so the discussion devolves into "I've always done it that way..."

Kevin Jennings
 
S

Simon Watson

On Thursday, July 26, 2012 7:12:11 AM UTC-4, Simon Watson wrote:
> Hi all,
>
> I am reading Pong P Chu's book RTL design using VHDL - and have a bit of a quandary.
>
> I have always written my state machines (generally) in one process. However, in this book - the author suggests that this is bad practice due to the fact that any signals in the process will have additional registers placed on them.
>

There will be no 'additional registers'. There is absolutely nothing wrong with writing code as a single clocked process. Either the author is wrong or what you're stating was taken out of context. Maybe the author doesn't even know about variables.

Handily, the chapter I refer to is legally available online at the authors website. See page 24 here: http://academic.csuohio.edu/chu_p/rtl/chu_rtL_book/rtl_chap10_fsm.pdf

It is possible I've got the context wrong.

Best regards,

Simon

http://academic.csuohio.edu/chu_p/rtl/chu_rtL_book/rtl_chap10_fsm.pdf
 
M

Martin Thompson

Simon Watson said:
Hi all,

I am reading Pong P Chu's book RTL design using VHDL - and have a bit of a
quandary.

I have always written my state machines (generally) in one process. However, in
this book - the author suggests that this is bad practice due to the fact that
any signals in the process will have additional registers placed on them.

No additional registers will be placed on signals from using a single process.

If you want to "read the current value of some combinational logic" then
you can't do that in a single process using signals. But that's what
variables are for. Signals are for communicating with other processes.
The question breaks down quite nicely:

1) The author uses if (clk'event and clk='1') to trigger on the rising edge
rather than rising_edge(clk) which is my normal use - is there a significant
difference in these?

rising_edge() wins for me because
1) It's completely clear what it does even to very new readers of VHDL
2) It's a standard function rather than "ancient lore"
3) It catches edges which rise to 'H' as well (this is a minor issue in most cases)
2) Is the extra registering on the output signals from the state machine
necessarily a bad thing?

It is if it causes your state machine to wait an extra tick before seing
something change. Again (as you no doubt know if you ar already doing
1-process state machines) variable help this.
The author suggests that a "2-segment" or two process approach, with one process
triggering on the signals / states in the state machine, and another clocked
process updating the state register.

This usually ends up with more code, and one of them with a manually
updated (an therefore error-prone) sentivity list. Although the latter
can be mitigated by using process(all) these days if you tools support
it.

Various claims have been made in the past about the superiority of
results from 2-process designs (or even 3-process!) but I have yet to
see any science done with modern tools which shows any siginificant
difference.

So it tends to come down to "what coding style you prefer".

Cheers,
Martin
 
A

Andy

As has been noted, there is a lot of religion floating around this issue.

I prefer single, clocked processes to any method that requires a combinatorial process.

Combinatorial processes are subject to latches.

Combinatorial processes are not subject to the performance optimizations that clocked processes are (in simulation). Lots of combinatorial processes will slow your RTL simulation down.

Controlling the scope of signals requires an additional block statement to limit the scope to only those processes driving or reading the signal.

Combinatorial outputs are subject to decoding glitches.

If required, combinatorial outputs can be created from a synchronous process if variables are used for the registers that drive the combinatorial logic. (note that latches can also be created with this method if common latch avoidance techniques are not used).

Single processes allow the use of variables, which are always private to the process, and can be used for combinatorial and/or registered logic.

There are others, but these are at the top of my list.

Andy
 
J

jim

Hi Simon,
How can the conflicting views possibly both be right? - because they are. It really comes down to coding approach. Some like coding a design in a single large process with everything in it. Some like coding piece wise.

Lets assume you are coding piece wise where you code your statemachine and the datapath logic in one more more separate processes. Under these conditions, if you use a one process statemachine, then every output from it is asignal with a register on it. If you use these outputs to control datapath logic (that is in a separate process), such as a load enable, then that load enable has a flip-flop on it and potentially has an extra clock cycle of latency on it that it may not need (timing wise, you are connecting the output of one register to the load enable input of another). Of course you can code around this by writing separate logic outside of the statemachine to generate the load enable signal - but then you are writing a informal multiprocess statemachine that may end up being harder to debug (and read andreview). I suspect this is what Pong was thinking of a piece wise approach when he said there would be an extra register.

Another way is to code is lump all of the logic in an architecture into onelarge clocked process. Use variables for combinational logic values. In this case, the load enable signal, if broken out is a variable that is thenused later in the process to control the register.

What is better, one, two, or three? From a quality of result perspective, I expect all are similar. There was a contest that John Cooley ran - not the V vs. V one, but the statemachine one. The way I interpreted the results is that if you enabled all statemachine optimizations (now on by default - then on by settings), most statemachines coding styles are within 10% of each other - this included statemachines generated by the block diagram tools.

At the end of the day, the most important thing about your code is readability and reviewability. Either approach (statemachine or coding approach) can be made readable. To make reviews easier your group may wish to adopt a coding practice document that documents what it expects as the more similarthe code is to expectations, the easier it is to review.

Personally I like coding piece wise and use a two process statemachine. For me this forces a practice of code separability and locality, which makes it easy to see the hardware within the software. From a philosophical perspective, when I deliver code to a customer, I want them to be able to modify it when they make the next generation of the device without my help. Hence I consider seeing the hardware within the code and separability and locality important to readability.

I would bet someone coding carefully with a single large process can get the same degree of readability.

From a readability stand point, I like rising_edge. Potentially clk='1' and clk'event is more simulation efficient (faster in sim due to less checks), but I would hope that the simulators optimize these in a similar fashion - as readability is important.

If you like two process statemachines (like I do), here are a few tips:
1) Be careful with your sensitivity lists. If your synthesis vendor supports the VHDL-2008 keyword all in the sensitivity list use it, or if they don't submit a bug report against their tool. Using "all" removes what I would consider the number one issue with two process statemachines.
2) Be careful about latches on outputs. To do this, give all statemachine outputs a default value at the top of the next state process to the non-driving value (typically 0). This also means to make an output a 1 during a particular state, you must set it to a 1 (which increases readability).
When I code a one process statemachine, I follow this same rule. From a _reviewability_ standpoint, I hate when someone retains a value on an output from a previous state.
3) Be careful about latches on the state variable. To do this, assign the NextState signal to the State signal at the top of the next state process. This happens automatically with one process statemachines.
The alternative is to tediously make sure that the NextState signal receives a value in every branch of every state - typically by having every if statement end with an else branch.

Following these steps, results in little difference in length of code.

As a consultant and trainer, the religion around this issue is a non-starter. The coding styles I use must be consistent with the customer's coding guidelines. The code must be readable.

My personal opinion is that most hardware designers learn fastest thinking in smaller chunks and coding piece wise. Getting the hardware done and correct is the first job. My expectation is that as designers grow in experience that their code will think in bigger chunks and also become more efficient software. Some will make this transition faster than others - for some the design size and simulation speeds will demand it. However, as they progress, the code must remain readable and reviewable.

Best Regards,
Jim
SynthWorks
 
J

jim

Hi Andy,
....
Combinatorial outputs are subject to decoding glitches.
Glitches are an inherent part of all combinatorial logic, even that produced by one process statemachines. As long as one is going from one FF to another (in the same clock domain), then glitches are part of path delays.

Were you trying to say: chip integration goes smoother when major blocks of the design have FF on their outputs - and one gets this for free when coding a single large clocked process.

Best,
Jim
 
P

pault.eg

I have always written my state machines (generally) in one process. However, in this book - the author suggests that this is bad practice due to thefact that any signals in the process will have additional registers placedon them.

I'd go with single process state machines to start with, _normally_ it is painful to use two processes. I can give you some examples.

Firstly, see the code here https://github.com/pdt/spcis/blob/master/rtl/slave_controller.vhdl. There's a fairly simple state machine in that file. Just after the state machine there is the code:

next_phase <= '1' when state = STATE3 and (ack = '1' or
timeout_count = "11") else '0';
data_out <= ad;
byte_en <= not c_n_be;

At one point with that design, those two lines were in the state machine. By pulling them out, I saved 33 registers, which perhaps you could argue is neither here nor there with the number of registers that come with modern FPGAs. I also saved a clock cycle, which again in this case isn't critical. I also could have saved those 33 registers by going to a two process state machine, but generally I try and avoid that - it's too much typing.
 
P

pault.eg

Sorry I need to get my mouse under control...

Trying again...



Wrt to the state machine in this file:

https://github.com/pdt/spcis/blob/master/rtl/slave_controller.vhdl

this code just under the state machine

next_phase <= '1' when state = STATE3 and (ack = '1' or
timeout_count = "11") else '0';
data_out <= ad;
byte_en <= not c_n_be;

used to be in the state machine, but I pulled it out saving 37 registers and also one clock cycle.

Also see here:

https://github.com/pdt/spcim/blob/master/rtl/master_controller.vhdl.

There is a two process state machine in that file. It started out as a single process state machine, but while I was working on it I fairly quickly changed it, because I didn't want the extra clock delay on control signals, and I found that the two process state machine was the thing to do in this case.

In that second example, there is also a single process state machine in that file as well. Go for what you think is best is my advice, but I'd always look to a single process state machine first.

Actually, sometimes you can get away with not using a state machine as in the above examples. For example, there are a lot of UARTs out on the internet that use state machines. See the VHDL UART TX and UART RX examples below as an altenative style of implementation:

http://pdt.github.com/script-tb_uart_tx_ex.html

http://pdt.github.com/script-tb_uart_rx_ex.html
 
T

Thomas Stanka

Hi Andy,
...> Combinatorial outputs are subject to decoding glitches.

Glitches are an inherent part of all combinatorial logic, even that produced by one process statemachines.  As long as one is going from one FF toanother (in the same clock domain), then glitches are part of path delays.

While it is true for the netlist, that glitches are not depending
wheter you use 1 process or 2 (or even 3) process style, you can
clearly say, that rtl simulations of combinatorial process are subject
to glitches leading to potential longer simulation time than without
combinatorial process.
My experience is, that 2 process style allows the designer to
implement more pitfalls like latches, but an experienced designer used
to 2 process style will have equivalent results to a 1 process style
designer.

bye Thomas
 
G

Gabor

While it is true for the netlist, that glitches are not depending
wheter you use 1 process or 2 (or even 3) process style, you can
clearly say, that rtl simulations of combinatorial process are subject
to glitches leading to potential longer simulation time than without
combinatorial process.
My experience is, that 2 process style allows the designer to
implement more pitfalls like latches, but an experienced designer used
to 2 process style will have equivalent results to a 1 process style
designer.

bye Thomas

I think that "experience" is the important word, here. I would suggest
looking through the Xilinx forums to see the kind of mess beginners
get into with a 2-process state machine. The usual response to "why
are you using two processes?" is "I read it in a book." The most
common response to that is "burn that book." I am amazed at the number
of books on HDL coding for synthesis (or otherwise) that seem to be
written by someone with no clue on how to actually design logic.

For a beginner, the single process FSM is easier to stay out of
trouble with. And once he learns that one can avoid additional
delay in the outputs by assigning them at the state transitions
instead of in the following states, he is generally happy to
stick with this method.

As for glitches on the outputs, defining the code such that
the outputs are registered would appear to fix this, but as
soon as you allow the tools to do "register balancing" all
bets are off. Properly optimized, I would expect very little
difference between methods in terms of resource usage. The
real difference is in the ease of design.

Personally I find that any method that places more of the code
within one screen of view is easier to follow, and easier to
come back to later when changes are needed.

Just my $.02 (call it "religion" if you want)

-- Gabor
 
Joined
Jun 3, 2010
Messages
14
Reaction score
0
On Wednesday, August 1, 2012 10:41:31 PM UTC+1, (unknown) wrote:
> On Wednesday, August 1, 2012 10:04:00 PM UTC+1, (unknown) wrote:
>
> > On Thursday, July 26, 2012 12:12:11 PM UTC+1, Simon Watson wrote:

>
>
>
> Sorry I need to get my mouse under control...



Actually, sometimes you can get away with not using a state machine as in the above examples. For example, there are a lot of UARTs out on the internet that use state machines. See the VHDL UART TX and UART RX examples below as an altenative style of implementation:

Is there really an advantage using that style over a state machine? I would have to assume a state machine would only make things more readable (i.e. the PCI code). That block diagram tool is pretty neat btw.:)

OP, the pong book isn't that bad, his style is a little verbose at times but compared to most books it's less Q&A and more designing a real application, which is kind of nice. Also if you're just starting out, Enoch Hwang's book on digital design is quite good imo.
 
Last edited:

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top