State machine with control outputs

J

john

Hi,

I have the following problem with the control statment generated by the
state machine to control the counter. In the code mentioned below, I am
trying to increment a counter when trigger = '1' and at the same time,
I want to change the state to CONTROL. Can anyone advice a better
solution to solve this problem? So, "incr" should get updated (
change from 0 to 1 ) in CONTROL state before the state machine switches
to state "Stop".

type State is (
INIT,
CONTROL,
STOP
);
signal state_r, incr, state_x : State
begin
case state_r is
when INIT =>
incr <= '0';
state_x <= CONTROL;

when CONTROL =>
if Trigger = '1' the
incr <= '1';
state_x <= STOP
else
incr<='0';
state_x <= CONTROL;
end if;

When STOP=>
................

When others =>
--some code--


if clk'event and clk = '1' then
if rst = YES then
state_r <=INIT;
else
state_r <=state_x;
end if;
end if;
end process;

Process ( rst , clock)
Begin
if (rst = '1') then
elsif ( if clk='1' and clk'event ) then
if ( inc ='1') then
addr_r <= addr_r + 1;
End If;

Regards,
John
 
A

Andy

I usually find it much easier to control the (cycle-cycle) timing by
just putting the counter in the state machine code. I also use single
processes for state machines, so here is how I would do it:

process (rst, clk) is
type state_t is ....
variable state : state_t;
begin
if rising_edge(clk) then
if rst = '1' then
state := init;
addr <= ...
else
case state is
when ...
when control =>
if trigger = '1' then
addr <= addr + 1;
state := stop;
end if; -- (else state is unchanged)
when ...
end case;
end if;
end if;
end process;

Andy
 
J

john

Hello,

Would you please explain a little bit that why is it better to
increment the counter inside the state machine?

John
 
M

Mike Treseler

john said:
Would you please explain a little bit that why is it better to
increment the counter inside the state machine?

1. Easier to read.
2. Easier to write.

-- Mike Treseler
 
J

john

Hello,

Would you advice that where will

state_r :=state_x;
addr_r <= addr_x;

go in your code?

Regards
John
 
A

Andy

Hello,

Would you advice that where will

state_r :=state_x;
addr_r <= addr_x;

go in your code?

Regards
John

That's the beauty of single, clocked processes over the traditional,
separate, clocked and combinatorial processes: There is no separate
state_r & state_x, just state. Same with addr.

Variable (not signal!) references that occur before the variable is
written in the same clock cycle are references to the registered
version of that data. So, "case state" is a reference to the
registered version of state.

Andy
 
J

john

Hello,

So, the value of state_r will change before the change of the value of
signal "addr". But i want to change the value of addr before any
change in the
variable state_r.

John
 
A

Andy

Hello,

So, the value of state_r will change before the change of the value of
signal "addr". But i want to change the value of addr before any
change in the
variable state_r.

John

In my example, there is no difference in behavior or implied circuitry
whether state is coded as a signal or a variable, since the "case
state" is always a reference to the registered state, the same as it
would be for a signal.

In your initial example, after the state machine was @ CONTROL and
received trigger, it set a flag (registered on the next clock), and
then the counter advanced addr on the next clock after that. In my
example I have taken out the clock delay from registering the flag,
and the counter will increment addr in the next clock after the
trigger is seen while in control, or one clock earlier than before. If
you want addr to increment at the same time you go to control, you'd
have to code the increment (and the check for trigger) in the state(s)
that lead to control. The fact that a variable updates immediately
(i.e. the combinatorial value updates immediately) is moot if the only
reference(s) to it are a clock later, meaning they are to the
registered value. Just remember that variables work just like
software.

Andy
 
J

john

Hi,

In my example I have taken out the clock delay from registering the
flag,
and the counter will increment addr in the next clock after the
trigger is seen while in control, or one clock earlier than before

So, the increment of the addr and the setting of the incr signal is
happening
at the same rising edge of the clock.

If you want addr to increment at the same time you go to control,
you'd
have to code the increment (and the check for trigger) in the state(s)
that lead to control.

you meant that if I need to increment the addr in the CONTROL state
then I need to update it in state that is prior to CONTROL state.

How can detect trigger =1 and increment the addr. in the same state.
Is it possible?

Thanks
John
 
A

Andy

Hi,

In my example I have taken out the clock delay from registering the
flag,
and the counter will increment addr in the next clock after the
trigger is seen while in control, or one clock earlier than before

So, the increment of the addr and the setting of the incr signal is
happening
at the same rising edge of the clock.

If you want addr to increment at the same time you go to control,
you'd
have to code the increment (and the check for trigger) in the state(s)
that lead to control.

you meant that if I need to increment the addr in the CONTROL state
then I need to update it in state that is prior to CONTROL state.
Yes.


How can detect trigger =1 and increment the addr. in the same state.
Is it possible?

It depends on what your definition of "in the same state" is. You can
increment the addr on the same clock edge on which the trigger was
detected, assuming trigger is synchronous (generated by circuitry
running from the same clock your state machine and counter are running
from). That's what my example does.

Andy
 
J

john

Hi,

The trigger is asynchronous. and its coming from some external source
to FPGA.

John
 
A

Andy

The trigger is asynchronous. and its coming from some external source

Then the trigger input will have to be synchronized, which will take a
minimum of one clock delay before the state machine can react to it.
The state machine should never use an input that is not properly
synchronized.

Andy
 
J

john

Then the trigger input will have to be synchronized, which will take a
minimum of one clock delay before the state machine can react to it.
The state machine should never use an input that is not properly
synchronized.

Andy

Hi,

1. Did you mean something like this

if (trigger_in = '1' ) then
trigger_1 <= '1';
trigger_2 <= '1';

elsif rising_edge ( clk ) then

trigger_1 <= '0';
trigger_2 <= trigger_1;

end if;

Final_trigger <= trigger_2;

ans then the state machine will be detecting the " Final trigger ".

2. Would you please that

process (rst, clk) is
type state_t is ....
variable state : state_t;
begin
if rising_edge(clk) then
if rst = '1' then
state := init;
addr <= ...
else
case state is
when ...
when control =>
if trigger = '1' then
addr <= addr + 1;
state := stop;
end if; -- (else state is unchanged)
when ...
end case;
end if;
end if;
end process;


the state machine will detect the trigger ( lets suppose trigger is
synchronize with the clock) at clock cycle 1 but the "addr" will
update in the clock cycle 2 not 1 though it is present in the same
state control or it will update in the next state not in state
"control" . Same with the signal "inc" as mentioned in my posted code.
But if the addr was a variable then it will update in the same state
"control" Am I right?

John
 
K

KJ

Same with the signal "inc" as mentioned in my posted code.
But if the addr was a variable then it will update in the same state
"control" Am I right?

Use a simulator to get your answer.

Kevin Jennings
 

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,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top