state machine reset

Guest
Hi all,

I'm new to vhdl and trying to reset a state machine to state 0 when
the incoming signal x changes state. How can I combine the two
processes below and not resulting in multiple sources error?

process (clk, rst)
begin
if rst = '1' then
state <= s0;
elsif rising_edge (clk) then
state <= next_state;
end if;
end process;

process (x0, x1)
begin
state <= s0;
end process;

Thanks...
 
yiipee@gmail.com wrote:
process (x0, x1)
begin
state <= s0;
end process;
process (x0, x1)
begin
next_state <= s0;
end process;

Presumably there is other logic in your process you're not showing us.

-Jeff
 
well... I didn't show the part of state assignment. I need to design a
2-bit counter that will reset to s0 if x0 and x1 change their state.
Here is the complete code what I have but it's not working.

process (clk, rst)
begin
if rst = '1' then
state <= s0;
elsif rising_edge (clk) then
state <= next_state;
end if;
end process;

process (sel0, sel1)
begin
state <= s0;
end process;

process (state)
begin
case state is
when s0 =>
y <= '1';
next_state <= s1;
when s1 =>
y <= '1';
next_state <= s2;
when s2 =>
y <= '1';
next_state <= s3;
when s3 =>
y <= '0';
next_state <= s3;
end case;
end process;
 
corrected the code as below:

well... I didn't show the part of state assignment. I need to design a
2-bit counter that will reset to s0 if x0 and x1 change their state.
Here is the complete code what I have but it's not working.

process (clk, rst)
begin
   if rst = '1' then
      state <= s0;
   elsif rising_edge (clk) then
      state <= next_state;
   end if;
end process;

process (x0, x1)
begin
   state <= s0;
end process;

process (state)
begin
   case state is
      when s0 =
         y <= '1';
         next_state <= s1;
      when s1 =
         y <= '1';
         next_state <= s2;
      when s2 =
         y <= '1';
         next_state <= s3;
      when s3 =
         y <= '0';
         next_state <= s3;
   end case;
end process;
 
On Aug 14, 12:16 pm, yii...@gmail.com wrote:
corrected the code as below:



well... I didn't show the part of state assignment. I need to design a
2-bit counter that will reset to s0 if x0 and x1 change their state.
Here is the complete code what I have but it's not working.

process (clk, rst)
begin
   if rst = '1' then
      state <= s0;
   elsif rising_edge (clk) then
      state <= next_state;
   end if;
end process;

process (x0, x1)
begin
   state <= s0;
end process;

process (state)
begin
   case state is
      when s0 =
         y <= '1';
         next_state <= s1;
      when s1 =
         y <= '1';
         next_state <= s2;
      when s2 =
         y <= '1';
         next_state <= s3;
      when s3 =
         y <= '0';
         next_state <= s3;
   end case;
end process;- Hide quoted text -

- Show quoted text -
Hi
Still in above code, many things are missing... what is sel0/1? in
state s3 again next state is s3..
any way i guess u can write
process (clk, rst)
begin
if rst = '1' then
state <= s0;
elsif rising_edge (clk) then
if change_state(sel0/sel1) then --not sure what you mean by
change state ..whether 0-> or 1-->
state <= s0;
else
state <= next_state;
endif;
end if;
end process;

regards
Sandeep
 
On Aug 13, 6:03 pm, yii...@gmail.com wrote:
Hi all,

I'm new to vhdl and trying to reset a state machine to state 0 when
the incoming signal x changes state. How can I combine the two
processes below and not resulting in multiple sources error?

process (clk, rst)
begin
if rst = '1' then
state <= s0;
elsif rising_edge (clk) then
state <= next_state;
end if;
end process;

process (x0, x1)
begin
state <= s0;
end process;

Thanks...
I think one of the things that is confusing you is the way you
separate the sequential process from the combinatorial process. There
is no real reason to do that. It seems that this is a coding style
that is often taught in school, but seldom used in practice. I have
never found a reason to code this way and this is the way I started
out coding. It didn't take me long to change to using a single
process to describe state machines, counters and such.

So instead of using logic to define next_state, just replace
next_state in the sequential process with the statements from the
combinatorial process. It should look like this...

process (clk, rst)
begin
if rst = '1' then
state <= s0;
elsif rising_edge (clk) then
state <= s0;
if change(sel0, sel1) then
state <= s0;
else
case state is
when s0 =>
y <= '1';
next_state <= s1;
when s1 =>
y <= '1';
next_state <= s2;
when s2 =>
y <= '1';
next_state <= s3;
when s3 =>
y <= '0';
next_state <= s3;
end case;
end if;
end process;

Your code won't work because you are assigning state in two
processes. That is like tying the output of a flip-flop and a gate
together. You can't have two outputs on the same signal (unless one
is tri-stated).

This is a counter that can be reset at any point in the cycle. It
will count up to three and wait. But it can be reset in state 1, 2 or
3. Is that your intent or do you mean for it to count to 3 and *then*
wait for a reset? If the reset comes early when the machine is in one
of the other states, do you still want it to reset or continue to
state 3?

Rick
 
On Aug 14, 7:22 am, rickman <gnu...@gmail.com> wrote:
On Aug 13, 6:03 pm, yii...@gmail.com wrote:



Hi all,

I'm new to vhdl and trying to reset a state machine to state 0 when
the incoming signal x changes state. How can I combine the two
processes below and not resulting in multiple sources error?

process (clk, rst)
begin
if rst = '1' then
state <= s0;
elsif rising_edge (clk) then
state <= next_state;
end if;
end process;

process (x0, x1)
begin
state <= s0;
end process;

Thanks...
Put the inputs in the sensivity list of the third process and delete
the second process. Then you have one sequential process for the
states that only depends on clk and rst and one combinational process
that depends on the current state and the inputs. Also called 2-
process FSM in my textbook.

I think one of the things that is confusing you is the way you
separate the sequential process from the combinatorial process. There
is no real reason to do that. It seems that this is a coding style
that is often taught in school, but seldom used in practice. I have
never found a reason to code this way and this is the way I started
out coding. It didn't take me long to change to using a single
process to describe state machines, counters and such.
Yes, 2-process state machines are very popular in teaching. Things get
structured and it is probably easier to correct the student works this
way :) Maybe it is also more correctly reflecting the formal
definitions of Moore and Mealy machines and academic work must always
be of high academic quality regardless of its industrial usefulness.
Do professors actually write code?

The textbook that I have for reference does give tribute to the 1-
process FSM as it is quicker in simulation, but the designer has to
take care in which state outputs are asserted.

--
Svenn
 
Svenn Are Bjerkem wrote:

Yes, 2-process state machines are very popular in teaching.
Maybe it is too much trouble to update
those lecture notes on the yellowed parchment ;)

Things get
structured and it is probably easier to correct the student works this
way :)
It does provide a wider range of errors to correct.

Maybe it is also more correctly reflecting the formal
definitions of Moore and Mealy machines and academic work must always
be of high academic quality regardless of its industrial usefulness.
Either model could be demonstrated on one process.
The question is, why demonstrate such a small
subset of what is possible?

Like mechanical cash register theory,
these models should be presented as a historical footnote,
not as a viable standard for logic description.

The textbook that I have for reference does give tribute to the 1-
process FSM as it is quicker in simulation, but the designer has to
take care in which state outputs are asserted.
I have to do that in any case.

-- Mike Treseler
 
rickman schrieb:
process (clk, rst)
begin
if rst = '1' then
state <= s0;
elsif rising_edge (clk) then
state <= s0;
if change(sel0, sel1) then
state <= s0;
else
case state is
when s0 =
y <= '1';
next_state <= s1;
when s1 =
y <= '1';
next_state <= s2;
when s2 =
y <= '1';
next_state <= s3;
when s3 =
y <= '0';
next_state <= s3;
end case;
end if;
end process;

Oha, this should pose some problems with synthesis. change(sel0, sel1)
can't be synthesized, and y converts maybe to a latch if you don't
reset. An "end if" is missing and next_state should be better a variable ;)

My proposal:

process (clk, rst)
variable next_state : <sx_type>;

begin
if rst = '1' then
next_state := s0;
state <= s0;

elsif rising_edge (clk) then
if sel0 != sel0_old or
sel1 != sel1_old then
next_state := s0;

else
next_state := state;

case state is
when s0 =>
y <= '1';
next_state := s1;

when s1 =>
y <= '1';
next_state := s2;

when s2 =>
y <= '1';
next_state := s3;

when s3 =>
y <= '0';
next_state := s3;

when others =>
Null;

end case;
end if;

state <= next_state
end if;
end process;

Best regards

Wolfgang
 
KJ wrote:

If this is the extent of the state machine, then a simple counter
would be cleaner than a state machine approach ...
Nice example Kevin.
This makes the point that the textbooks don't cover.
To my simulator and synthesizer, there
is no fundamental difference between:

1. Updating an unsigned register named "cnt" using '+'
in an IF statement and

2. Updating an enumerated register named "state" using '<='
in an CASE statement.

As long as I match the clocked template,
the tools don't care if I update one, two or
all of the registers in a process.
This is the designer's call,
not Mr. Mealy's.

-- Mike Treseler
 
On Aug 14, 3:48 am, Svenn Are Bjerkem <svenn.bjer...@googlemail.com>
wrote:
On Aug 14, 7:22 am, rickman <gnu...@gmail.com> wrote:

Put the inputs in the sensivity list of the third process and delete
the second process. Then you have one sequential process for the
states that only depends on clk and rst and one combinational process
that depends on the current state and the inputs. Also called 2-
process FSM in my textbook.
That still leaves the logic in the second process out of the
equation. Textbooks are for teaching, but often they don't teach the
best approach. FSM design is a very good example. Very few engineers
code a 2 process FSM in HDL. In the real world there is virtually no
advantage.


I think one of the things that is confusing you is the way you
separate the sequential process from the combinatorial process. There
is no real reason to do that. It seems that this is a coding style
that is often taught in school, but seldom used in practice. I have
never found a reason to code this way and this is the way I started
out coding. It didn't take me long to change to using a single
process to describe state machines, counters and such.

Yes, 2-process state machines are very popular in teaching. Things get
structured and it is probably easier to correct the student works this
way :) Maybe it is also more correctly reflecting the formal
definitions of Moore and Mealy machines and academic work must always
be of high academic quality regardless of its industrial usefulness.
Do professors actually write code?

The textbook that I have for reference does give tribute to the 1-
process FSM as it is quicker in simulation, but the designer has to
take care in which state outputs are asserted.

--
Svenn
On Aug 14, 3:48 am, Svenn Are Bjerkem <svenn.bjer...@googlemail.com>
wrote:
On Aug 14, 7:22 am, rickman <gnu...@gmail.com> wrote:



On Aug 13, 6:03 pm, yii...@gmail.com wrote:

Hi all,

I'm new to vhdl and trying to reset a state machine to state 0 when
the incoming signal x changes state. How can I combine the two
processes below and not resulting in multiple sources error?

process (clk, rst)
begin
if rst = '1' then
state <= s0;
elsif rising_edge (clk) then
state <= next_state;
end if;
end process;

process (x0, x1)
begin
state <= s0;
end process;

Thanks...

Put the inputs in the sensivity list of the third process and delete
the second process. Then you have one sequential process for the
states that only depends on clk and rst and one combinational process
that depends on the current state and the inputs. Also called 2-
process FSM in my textbook.



I think one of the things that is confusing you is the way you
separate the sequential process from the combinatorial process. There
is no real reason to do that. It seems that this is a coding style
that is often taught in school, but seldom used in practice. I have
never found a reason to code this way and this is the way I started
out coding. It didn't take me long to change to using a single
process to describe state machines, counters and such.

Yes, 2-process state machines are very popular in teaching. Things get
structured and it is probably easier to correct the student works this
way :) Maybe it is also more correctly reflecting the formal
definitions of Moore and Mealy machines and academic work must always
be of high academic quality regardless of its industrial usefulness.
Do professors actually write code?

The textbook that I have for reference does give tribute to the 1-
process FSM as it is quicker in simulation, but the designer has to
take care in which state outputs are asserted.
Anyone who understands both HDL and state machines will find it
trivial to implement both Mealy and Moore FSMs. The one is just a
clocked process with outputs assigned only on state transitions and
the other is a clocked process for the state transitions and
combinatorial logic (either a process or concurrent statements) for
the outputs.

Many people use a modified Mealy (or is it Moore?) machine because it
is the simplest to code and all outputs are registered giving highest
clock speed.

Like I said, I don't typically use any of these. Being rooted in the
days of twiddling bits with a soldering iron and SSI logic, I tend to
think in terms of the logic and then code the HDL to describe the
logic. After all, that's what the D in HDL is for, right? So my FSMs
tend to be ad hoc and vary a lot. Often they are just counters.

Rick
 
On Aug 14, 11:28 am, Wolfgang Grafen <wolfgang.gra...@ericsson.com>
wrote:
rickman schrieb:
end process;

and y converts maybe to a latch if you don't reset.
No, in both rickman's and your code, 'y' will come out as a flip flop,
not a latch. Just because y is not reset asynchronously and other
output signals in the process are reset won't turn 'y' into a latch.

and next_state should be better a variable ;)
Personally, I would dispense completely with next_state and simply do
a signal assignment to 'state'. Most times the only time 'next_state'
is needed would be handled inside the case statement anyway. Less
typing, less objects to track, etc.

My proposal:
If this is the extent of the state machine, then a simple counter
would be cleaner than a state machine approach. If tomorrow you need
another state or two, you've got to muck with several lines of code to
change the state machine to the new requirement, using a counter or
shift register approach you would only change one line of code (the
value of the constant 'MAX_CNT' in the sample below). The odds of
screwing something up are much lower that way.

But as an exercise in learning about state machines what you have is
OK.

constant MAX_CNT: natural := 3;
signal cnt: natural range 0 to MAX_CNT;
...
process(clk,rst)
begin
if rising_edge(clk) then
if (sel0 != sel0_old) or (sel1 != sel1_old) then
cnt <= 0;
elsif (cnt < MAX_CNT) then
cnt <= cnt + 1;
end if;
if (cnt = MAX_CNT) then
y <= '0';
else
y <= '1';
end if;
end if;
if (rst='1') then
cnt <= 0;
end if;
end process;

KJ
 
casey wrote:
Thanks to all you guys there for the great discussion. I wrote up
something last night that's similar to Wolfgang's and it's working
now. In the past, somehow I worked with two always block state machine
in Verilog and thought that VHDL would work in the same way...
Actually, a single clocked block works fine in verilog too.
If you are not offended by the appropriate use of '=' assignments
for the local variables, you may look at this example:
http://mysite.verizon.net/miketreseler/count_enable.v

-- Mike Treseler
 
On Aug 14, 11:28 am, Wolfgang Grafen <wolfgang.gra...@ericsson.com>
wrote:
Oha, this should pose some problems with synthesis. change(sel0, sel1)
can't be synthesized, and y converts maybe to a latch if you don't
reset. An "end if" is missing and next_state should be better a variable ;)
Yes, I didn't run this through any tools, so I had a couple of typos.
next_state was intended to be replace with state. I would have thought
that was obvious from the context, not that it needed to be a
variable. After all, next_state was not used anywhere.

The missing end if; is trivial.

You are incorrect about "change(sel0, sel1)" not being synthesizable.
It is a function that needs to be defined. Since the OP did not
difine what the function should do, I left it as a function to be
coded.

Is this better?

process (clk, rst)
begin
if rst = '1' then
state <= s0;
elsif rising_edge (clk) then
state <= s0; -- superfluous - remove
if change(sel0, sel1) then
state <= s0;
else
case state is
when s0 =>
y <= '1';
state <= s1;
when s1 =>
y <= '1';
state <= s2;
when s2 =>
y <= '1';
state <= s3;
when s3 =>
y <= '0';
state <= s3;
end case;
end if;
end if;
end process;

There is absolutely no reason to introduce a dummy variable to
calculate the value for next_state rather than just assigning the same
values to state. Not using the variable in this case is simpler,
cleaner and is less work and less chance for error. I think some
people don't understand the nature of a clocked process compared to a
C program and so have trouble with signal assignments in a process.

Actually, I can spot one issue now. The initial assignment to state
is superfluous. The structure of if and case assign a value to state
for all input conditions, so the initial assignment will be
overwritten. But that was the original code. If the logic were being
done with incomplete if statements, then you could have unspecified
conditions and a default might be useful. But then it most likely is
a hold over from the combinatorial logic to prevent the creation of
latches. No need for it in a sequential process.

Rick
 
Thanks to all you guys there for the great discussion. I wrote up
something last night that's similar to Wolfgang's and it's working
now. In the past, somehow I worked with two always block state machine
in Verilog and thought that VHDL would work in the same way...

Nevertheless... thanks to eveyone here. Have a good day
 
KJ schrieb:

Personally, I would dispense completely with next_state and simply do
a signal assignment to 'state'. Most times the only time 'next_state'
is needed would be handled inside the case statement anyway. Less
typing, less objects to track, etc.

There is a problem with assigning to state as a signal directly:
- you see a change only in the next clock cycle but as signal transition
depends on that value you can't debug you state machine easily
- It is less readable. Where do you modify state? Easy by looking for
next_state.
- Of course in some situations a counter can be a typing lazy
alternative BUT don't do that, you will not understand what you were
thinking a month after, and for a code review you have to talk your
mouth fuzzy that other designers will understand your work, more worse
you will have to document where plain code could be documentation
enough...
- The way I showed worked perfectly for designing complex state
machines in some very large ASICS, including debug and verification.

=> Lazy is not always best IMO.

Best regards

Wolfgang
 
rickman schrieb:

There is absolutely no reason to introduce a dummy variable to
calculate the value for next_state rather than just assigning the same
values to state. Not using the variable in this case is simpler,
cleaner and is less work and less chance for error. I think some
people don't understand the nature of a clocked process compared to a
C program and so have trouble with signal assignments in a process.
You are right, this example is so easy that next_state could be omitted.
Please look at my other answer, there are very good and proved reasons
using it, though, e.g. for debug and understanding reasons.

Best regards

Wolfgang
 
On 14 Aug, 16:26, Mike Treseler <mtrese...@gmail.com> wrote:
Svenn Are Bjerkem wrote:
Yes, 2-process state machines are very popular in teaching.

Maybe it is too much trouble to update
those lecture notes on the yellowed parchment ;)
LOL :)

Things get
structured and it is probably easier to correct the student works this
way :)

It does provide a wider range of errors to correct.
Yes I think multiple assignments can be quite confusing, even though
if all possible paths can be shown to ever give just 1 at most
assignment, then what looks like a double assignment is not.

Maybe it is also more correctly reflecting the formal
definitions of Moore and Mealy machines and academic work must always
be of high academic quality regardless of its industrial usefulness.
Yes moore macines are prefered, http://nibz.googlecode.com is a mealy
machine at present, but the signal which makes it so would be driven
by synchronous logic in a full design, making it finalize as a moore
machine.

cheers
jacko

Either model could be demonstrated on one process.
The question is, why demonstrate such a small
subset of what is possible?

Like mechanical cash register theory,
these models should be presented as a historical footnote,
not as a viable standard for logic description.

The textbook that I have for reference does give tribute to the 1-
process FSM as it is quicker in simulation, but the designer has to
take care in which state outputs are asserted.

I have to do that in any case.

   -- Mike Treseler
 
On Aug 15, 8:34 am, Wolfgang Grafen <wolfgang.gra...@ericsson.com>
wrote:
KJ schrieb:

Personally, I would dispense completely with next_state and simply do
a signal assignment to 'state'.  Most times the only time 'next_state'
is needed would be handled inside the case statement anyway.  Less
typing, less objects to track, etc.

There is a problem with assigning to state as a signal directly:
- you see a change only in the next clock cycle
Exactly as it should be, the clock causes state transitions, flip
flops to update, etc.

but as signal transition
   depends on that value you can't debug you state machine easily
You only have difficulty if you compute other signals based on
'next_state', rather than 'state'. Personally I haven't had any
difficulty debugging without the 'next_state' signal.

Typically other signals/variable that are a function of the state
machine's state I compute based on the current state (i.e. the signal
'state' in this example) not on what the next state is going to be.
Typically this leads to higher clock cycle performance of the design
since the combinatorial logic that is needed to compute 'next_state'
does not roll into the logic needed to compute the output (or other
signal).

- It is less readable.
Readability would not necessarily be a function of whether there was
an explicit 'next_state' signal/variable or not. Either form can be
just as readable. For those cases, where duplication of code would
have to take place, I would have a variable 'next_state' for assigning
to those signals that would benefit from it. That's why I said "Most
times the only time..." 'most times' does not mean 'all times', it
means 'usually the case'.

Where do you modify state?
I modify state in the state machine. There is no need to have an
intermediate signal/variable to compute the 'next_state', just so that
it can be synchronously assigned to a signal called 'state'. There is
one clocked process of the following general form:

process(clk)
begin
if rising_edge(clk) then
if (reset = '1') then
current_state <= idle;
else
case current_state is
when idle => current_state <= Michigan;
when Michigan => current_state <= California;
when California => current_state <= Hawaii;
end case;
end if;
end if;
end process;

Easy by looking for next_state.
Just as easy looking for 'current_state'.

- Of course in some situations a counter can be a typing lazy
   alternative BUT don't do that, you will not understand what you were
   thinking a month after, and for a code review you have to talk your
   mouth fuzzy that other designers will understand your work, more worse
   you will have to document where plain code could be documentation
   enough...
Actually you'll likely have more trouble explaining the state machine
then the counter. For example, let's say this design is for some form
of memory controller. Let's say that after issuing a read command to
the memory device you need to wait 40 ns for the data to be valid,
let's also assume that the clock period is 10 ns. One might be
tempted to make a state machine that has the proper number of states
so that 4 clock cycles after the read command is issued that data gets
sampled. Your design will be very fragile (in my opinion) because of
the implicit constants (i.e. the number of states) that are really a
function of the following parameters:
- Clock period
- Memory access time
Using a counter approach, one would have constants (actually I'd use
generic inputs on the entity) for both of these and they would be
defined in units of time and I'd define the upper end of the counter
to be the ceil() of the ratio of memory access time divided by clock
period. So it would be painfully clear where the design error is that
needs fixing when I find that the board was built with 60ns access
time parts instead of 40ns, the 'fix' would be to simply change the
generic parameter input to the entiy from 40ns to 60ns and rebuild.
With the state machine approach you'd have to modify a bunch more than
that and have a much higher risk of getting it wrong the first time.

Linking parameters that you have no control over in your design (in
this case the memory access time) so that they properly parameterize
the design will naturally lead to using counters. Hard coding in a
calculated number of states that depends on this uncontrolled
parameter (or pulse time requirement) in the form of states in a state
machine is a mistake. Although both designs will work, one will be
much more fragile and less likely to be able to be modified correctly
in the future...but that's just my 2 cents.

- The way I showed worked perfectly for designing complex state
   machines in some very large ASICS, including debug and verification.
And my method has worked just as perfectly.

=> Lazy is not always best IMO.
You're the one who brought up lazy, not me.

KJ
 
KJ schrieb:
On Aug 15, 8:34 am, Wolfgang Grafen <wolfgang.gra...@ericsson.com
wrote:
KJ schrieb:

Personally, I would dispense completely with next_state and simply do
a signal assignment to 'state'. Most times the only time 'next_state'
is needed would be handled inside the case statement anyway. Less
typing, less objects to track, etc.
There is a problem with assigning to state as a signal directly:
- you see a change only in the next clock cycle

Exactly as it should be, the clock causes state transitions, flip
flops to update, etc.

but as signal transition
depends on that value you can't debug you state machine easily

You only have difficulty if you compute other signals based on
'next_state', rather than 'state'. Personally I haven't had any
difficulty debugging without the 'next_state' signal.

Typically other signals/variable that are a function of the state
machine's state I compute based on the current state (i.e. the signal
'state' in this example) not on what the next state is going to be.
Typically this leads to higher clock cycle performance of the design
since the combinatorial logic that is needed to compute 'next_state'
does not roll into the logic needed to compute the output (or other
signal).
next_state will not generate logic, though :)

- It is less readable.
Readability would not necessarily be a function of whether there was
an explicit 'next_state' signal/variable or not. Either form can be
just as readable. For those cases, where duplication of code would
have to take place, I would have a variable 'next_state' for assigning
to those signals that would benefit from it. That's why I said "Most
times the only time..." 'most times' does not mean 'all times', it
means 'usually the case'.
Well, the interesting thing is when you change a state for the next
transition. Allowing only one assignment to state and using next_state
for searching and looking over the text makes it more readable and
useable IMO.

state <= s8;
if state == s1 then
state <= s2;
elsif state = s2 then
state <= s3;
elsif state <= s3 then
state = s4;

or

next_state := s8;
if state == s1 then
next_state := s2;
elsif state = s2 then
next_state := s3;
elsif state = s3 then
next_state := s4;
.
.
state <= next_state;

Where do you modify state?
I modify state in the state machine. There is no need to have an
intermediate signal/variable to compute the 'next_state', just so that
it can be synchronously assigned to a signal called 'state'. There is
one clocked process of the following general form:

process(clk)
begin
if rising_edge(clk) then
if (reset = '1') then
current_state <= idle;
else
case current_state is
when idle => current_state <= Michigan;
when Michigan => current_state <= California;
when California => current_state <= Hawaii;
end case;
end if;
end if;
end process;
This is a super simple state machine. Read over state machines filling
several pages, and lots of calculations within every state...
Easy by looking for next_state.
Just as easy looking for 'current_state'.

- Of course in some situations a counter can be a typing lazy
alternative BUT don't do that, you will not understand what you were
thinking a month after, and for a code review you have to talk your
mouth fuzzy that other designers will understand your work, more worse
you will have to document where plain code could be documentation
enough...

Actually you'll likely have more trouble explaining the state machine
then the counter. For example, let's say this design is for some form
of memory controller. Let's say that after issuing a read command to
the memory device you need to wait 40 ns for the data to be valid,
let's also assume that the clock period is 10 ns. One might be
tempted to make a state machine that has the proper number of states
so that 4 clock cycles after the read command is issued that data gets
sampled. Your design will be very fragile (in my opinion) because of
the implicit constants (i.e. the number of states) that are really a
function of the following parameters:
- Clock period
- Memory access time
Using a counter approach, one would have constants (actually I'd use
generic inputs on the entity) for both of these and they would be
defined in units of time and I'd define the upper end of the counter
to be the ceil() of the ratio of memory access time divided by clock
period. So it would be painfully clear where the design error is that
needs fixing when I find that the board was built with 60ns access
time parts instead of 40ns, the 'fix' would be to simply change the
generic parameter input to the entiy from 40ns to 60ns and rebuild.
With the state machine approach you'd have to modify a bunch more than
that and have a much higher risk of getting it wrong the first time.

Linking parameters that you have no control over in your design (in
this case the memory access time) so that they properly parameterize
the design will naturally lead to using counters. Hard coding in a
calculated number of states that depends on this uncontrolled
parameter (or pulse time requirement) in the form of states in a state
machine is a mistake. Although both designs will work, one will be
much more fragile and less likely to be able to be modified correctly
in the future...but that's just my 2 cents.
It depends on the problem. Where a counter is more readable use a
counter, otherwise use a state machine ...
- The way I showed worked perfectly for designing complex state
machines in some very large ASICS, including debug and verification.


And my method has worked just as perfectly.

=> Lazy is not always best IMO.


You're the one who brought up lazy, not me.

I am lazy I know :)

Best regards

Wolfgang
 

Welcome to EDABoard.com

Sponsor

Back
Top