state machine reset

Y

yiipee

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

Jeff Cunningham

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
 
Y

yiipee

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;
 
S

sandeep

corrected the code as below:







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

rickman

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
 
S

Svenn Are Bjerkem

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

Mike Treseler

Svenn said:
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
 
W

Wolfgang Grafen

rickman said:
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
 
R

rickman

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.

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


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.




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
 
K

KJ

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
 
R

rickman

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
 
M

Mike Treseler

KJ said:
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
 
C

casey

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
 
M

Mike Treseler

casey said:
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
 
W

Wolfgang Grafen

KJ said:
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
 
W

Wolfgang Grafen

rickman said:
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
 
J

jacko

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

LOL :)
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.

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
 
K

KJ

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
 
R

rickman

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

I would dispute that. The value that you would see on the
"next_state" signal is the value that will appear on the "state"
signal after the clock. What does "next_state" tell you that "state"
won't?

Are you saying that you can look at the values of "next_state" other
than at the clock edge and see what input changes are causing the
output change? I don't think I have ever done that with a registered
signal, even when I did have the input value available. I think the
tools for analyzing the logic of code are pretty good and I don't see
the need for an extra variable to get this sort of insight. That
would be like using multiple signals and assignments just to be able
to see smaller pieces of the logic. Yes, I suppose that for some
people this can be a help, but I don't recall ever having a logic
problem where this was really helpful. I don't have trouble seeing
what the logic of my code is. My issue is making sure I understand
the problem enough to have selected the right logic to be coded.

- It is less readable. Where do you modify state? Easy by looking for
next_state.

That is almost silly. Where do you modify state? Easy, look for
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...

Hmmm... if you think a counter as a FSM is hard to understand, then I
think maybe you need the extra crutch of superfluous signals. If the
design of the FSM is that it gets a trigger and goes through states,
1, 2, 3, 4, 5, ... until it reaches state N and then waits for the
trigger... this will be coded as a loadable counter, not as an FSM
with enumerated states.

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

There is lazy and there is making extra work. Is there some reason
that you think adding extra signals makes non-working code work? I
don't see how adding the signal for the *input* to the register in
addition to the signal for the output of the register makes anything
easier to debug. It can lead to the usage of extra logic resources.
It is common for the tool to use the clock enable of registers. If
you code the register input separately like this, it is conceivable
that it may fold the enable that would otherwise be used, into the
data input instead of the clock enable input potentially using extra
LUTs.

I just don't see an advantage to creating this extra code and logic.

Rick
 

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