please help! state machine

S

Simone Winkler

Guest
Hello!

I've got a strange problem that I don't know any solution for - up to now I
tried everything, but it didn't work.
I already posted a message here yesterday, it's still the same state machine
that I'm talking about - and it always stops to go to the next state - I
really don't understand why.

I've got a state machine with 5 states: SEL_EP, WRITE_INIT, WRITE_DATA,
VAL_BUF and IDLE. It gets stuck after the WRITE_INIT state, just remains in
the WRITE_INIT state all the time. WHY????
The 2nd (smaller) problem is, that the data at write_out comes one clock
cycle too late. I understand why, but how can i change this?

I don't know if it's a good idea to solve my problem with my kind of code,
i'm an "advanced beginner" and as I am used to program "sequential
programming languages" I've got big problems with doing sequential things in
vhdl. What is the easy way to do things one after the other, e.g. write one
byte after the other? (also to be synthesizable).

I put the code at http://members.liwest.at/simsi/stuff/usb.vhd, because it's
quite long to put it here. (don't be afraid - no virus!)

Please help me! I really don't know where to go on.

Thank you,
Simone
 
Simone Winkler wrote:

I've got a state machine with 5 states: SEL_EP, WRITE_INIT, WRITE_DATA,
VAL_BUF and IDLE. It gets stuck after the WRITE_INIT state, just remains in
the WRITE_INIT state all the time. WHY????
Probably because none of the covered conditions occur.
You can use breakpoint or single step to debug this.
Try recoding with if, elsif, elsif, else.

The 2nd (smaller) problem is, that the data at write_out comes one clock
cycle too late. I understand why, but how can i change this?
Consider registering the data on the same clock.

I don't know if it's a good idea to solve my problem with my kind of code,
i'm an "advanced beginner" and as I am used to program "sequential
programming languages" I've got big problems with doing sequential things in
vhdl. What is the easy way to do things one after the other, e.g. write one
byte after the other? (also to be synthesizable).
Consider using counter variables.

-- Mike Treseler
 
"Simone Winkler" <simone.winkler@gmx.at> wrote in message news:<1073153364.208362@news.liwest.at>...
Hello!

I've got a strange problem that I don't know any solution for - up to now I
tried everything, but it didn't work.
I already posted a message here yesterday, it's still the same state machine
that I'm talking about - and it always stops to go to the next state - I
really don't understand why.

I've got a state machine with 5 states: SEL_EP, WRITE_INIT, WRITE_DATA,
VAL_BUF and IDLE. It gets stuck after the WRITE_INIT state, just remains in
the WRITE_INIT state all the time. WHY????
The 2nd (smaller) problem is, that the data at write_out comes one clock
cycle too late. I understand why, but how can i change this?

I don't know if it's a good idea to solve my problem with my kind of code,
i'm an "advanced beginner" and as I am used to program "sequential
programming languages" I've got big problems with doing sequential things in
vhdl. What is the easy way to do things one after the other, e.g. write one
byte after the other? (also to be synthesizable).

I put the code at http://members.liwest.at/simsi/stuff/usb.vhd, because it's
quite long to put it here. (don't be afraid - no virus!)

Please help me! I really don't know where to go on.

Thank you,
Simone
Simone,

I looked at your code and I have no solution for your problem, but I
do have some suggestions. The process at the end of your architecture
uses state machine outputs to determine some of its actions, so why
not include the actions performed by that process in the state machine
itself? You would probably have to add a few more states, but you
would get the added advantage of having easier to follow code since
the major functions would all be in one place. You could also
eliminate some signals. You will need to synchronize all inputs to
the state machine (that are not synchronized in some other way) with
the state machine clock (a 2 d flip-flop synchronizer is the typical
way to do this, as discussed elsewhere in this forum). If you don't
do this you will have problems with the synthesized hardware due to
metastability even though your functional simulation works fine. I
don't think you need the procedure write_command. If you set the
value of write_out in a synchronous process, write_out is not needed.
In the state machine code you have some redundant logic for setting
sel_ep, etc. to '0'. I have put a snippet of the revised state
machine code below. I would like to help you more on this--I love
doing state machines, but I don't have the time right now.

Charles


PROCESS (reset,CLK, next_sreg)
BEGIN
IF CLK='1' AND CLK'event THEN
if RESET = '1' then
--state forced to IDLE on reset where sel_ep, valbuf, etc.
sreg <= IDLE;
else
sreg <= next_sreg;
end if ;
END IF;
END PROCESS;

write_stm: PROCESS (sreg,isr,RESET,wr_end,write_endp) is

BEGIN

CASE sreg IS
WHEN IDLE =>
sel_ep<='0';
valbuf<='0';
wr_data<='0';
wr_init<='0';
IF ( write_endp='0' ) OR ( isr='1' ) THEN
next_sreg<=IDLE;
ELSIF ( isr='0' AND write_endp='1' ) THEN
next_sreg<=SEL_ENDP;
END IF;
WHEN SEL_ENDP =>
valbuf<='0';
wr_data<='0';
wr_init<='0';
sel_ep<='1';
IF ( isr='0' ) THEN
write_out <= X"03";
next_sreg<=WRITE_INIT;
ELSE
--DON'T KNOW WHAT TO PUT HERE, BUT IT HAS TO BE SET TO
SOME VALUE
write_out <= X"??"; next_sreg<=IDLE;
END IF;
 
"Charles M. Elias" <charles.elias@wpafb.af.mil> wrote in message
news:35849667.0401050706.26cedcb4@posting.google.com...
"Simone Winkler" <simone.winkler@gmx.at> wrote in message
news:<1073153364.208362@news.liwest.at>...
Hello!

I've got a strange problem that I don't know any solution for - up to
now I
tried everything, but it didn't work.
I already posted a message here yesterday, it's still the same state
machine
that I'm talking about - and it always stops to go to the next state - I
really don't understand why.

I've got a state machine with 5 states: SEL_EP, WRITE_INIT, WRITE_DATA,
VAL_BUF and IDLE. It gets stuck after the WRITE_INIT state, just remains
in
the WRITE_INIT state all the time. WHY????
The 2nd (smaller) problem is, that the data at write_out comes one clock
cycle too late. I understand why, but how can i change this?

I don't know if it's a good idea to solve my problem with my kind of
code,
i'm an "advanced beginner" and as I am used to program "sequential
programming languages" I've got big problems with doing sequential
things in
vhdl. What is the easy way to do things one after the other, e.g. write
one
byte after the other? (also to be synthesizable).

I put the code at http://members.liwest.at/simsi/stuff/usb.vhd, because
it's
quite long to put it here. (don't be afraid - no virus!)

Please help me! I really don't know where to go on.

Thank you,
Simone

Simone,

I looked at your code and I have no solution for your problem, but I
do have some suggestions. The process at the end of your architecture
uses state machine outputs to determine some of its actions, so why
not include the actions performed by that process in the state machine
itself? You would probably have to add a few more states, but you
would get the added advantage of having easier to follow code since
the major functions would all be in one place. You could also
eliminate some signals. You will need to synchronize all inputs to
the state machine (that are not synchronized in some other way) with
the state machine clock (a 2 d flip-flop synchronizer is the typical
way to do this, as discussed elsewhere in this forum). If you don't
do this you will have problems with the synthesized hardware due to
metastability even though your functional simulation works fine. I
don't think you need the procedure write_command. If you set the
value of write_out in a synchronous process, write_out is not needed.
In the state machine code you have some redundant logic for setting
sel_ep, etc. to '0'. I have put a snippet of the revised state
machine code below. I would like to help you more on this--I love
doing state machines, but I don't have the time right now.

Charles


PROCESS (reset,CLK, next_sreg)
BEGIN
IF CLK='1' AND CLK'event THEN
if RESET = '1' then
--state forced to IDLE on reset where sel_ep, valbuf, etc.
sreg <= IDLE;
else
sreg <= next_sreg;
end if ;
END IF;
END PROCESS;

write_stm: PROCESS (sreg,isr,RESET,wr_end,write_endp) is

BEGIN

CASE sreg IS
WHEN IDLE =
sel_ep<='0';
valbuf<='0';
wr_data<='0';
wr_init<='0';
IF ( write_endp='0' ) OR ( isr='1' ) THEN
next_sreg<=IDLE;
ELSIF ( isr='0' AND write_endp='1' ) THEN
next_sreg<=SEL_ENDP;
END IF;
WHEN SEL_ENDP =
valbuf<='0';
wr_data<='0';
wr_init<='0';
sel_ep<='1';
IF ( isr='0' ) THEN
write_out <= X"03";
next_sreg<=WRITE_INIT;
ELSE
--DON'T KNOW WHAT TO PUT HERE, BUT IT HAS TO BE SET TO
SOME VALUE
write_out <= X"??"; next_sreg<=IDLE;
END IF;
Hi Charles,

I'm having a similar problems with a state machine, which I believe is due
to synchronization problems. You mentioned in your reply using 2 D-FipFlops
to overcome the syncing problems. Would you mind including some code to
demonstrate this, or pointing me in the direction of some? I've attempted
to code my own but with no success. Am I right in assuming you first code a
flip flop module and then use this?

Thank you for your time.
 
Hi,

For the state machine declaration try something like this:


type SREG is (IDLE, SEL_ENDP, WRITE_INIT, WRITE_DATA, VAL_BUF);
signal sigstSreg : SREG;

The next_sreg is not useful. I don't see the purpose.


procWriteStm : process (RESET, CLK) is
begin
--- reset
if (RESET = '1') then
.....

elsif (falling_edge(inCLK)) then

case sigstSreg is
when IDLE =>
.......
sigstSreg <= SEL_ENDP;

when SEL_ENDP =>
.......
sigstSreg <= WRITE_INIT;

when WRITE_INIT =>
.......
sigstSreg <= WRITE_DATA;

when WRITE_DATA =>
.......
sigstSreg <= VAL_BUF;

when VAL_BUF =>
.......
sigstSreg <= IDLE;
end case;
end if;

end process procWriteStm;

If you want to keep the same state (IDLE when IDLE) is not necessary to
specify that sigstSreg <= IDLE.

The last thing: If you try this on the real world, make sure that your in
port are synchronized with CLK. Read more about metastability.


I hope that help.
Dan.
 
"Mike" <Mike@noway.com> wrote in message news:<btc0rn$grb$1@newsg4.svr.pol.co.uk>...
"Charles M. Elias" <charles.elias@wpafb.af.mil> wrote in message
news:35849667.0401050706.26cedcb4@posting.google.com...
"Simone Winkler" <simone.winkler@gmx.at> wrote in message
news:<1073153364.208362@news.liwest.at>...
Hello!

I've got a strange problem that I don't know any solution for - up to
now I
tried everything, but it didn't work.
I already posted a message here yesterday, it's still the same state
machine
that I'm talking about - and it always stops to go to the next state - I
really don't understand why.

I've got a state machine with 5 states: SEL_EP, WRITE_INIT, WRITE_DATA,
VAL_BUF and IDLE. It gets stuck after the WRITE_INIT state, just remains
in
the WRITE_INIT state all the time. WHY????
The 2nd (smaller) problem is, that the data at write_out comes one clock
cycle too late. I understand why, but how can i change this?

I don't know if it's a good idea to solve my problem with my kind of
code,
i'm an "advanced beginner" and as I am used to program "sequential
programming languages" I've got big problems with doing sequential
things in
vhdl. What is the easy way to do things one after the other, e.g. write
one
byte after the other? (also to be synthesizable).

I put the code at http://members.liwest.at/simsi/stuff/usb.vhd, because
it's
quite long to put it here. (don't be afraid - no virus!)

Please help me! I really don't know where to go on.

Thank you,
Simone

Simone,

I looked at your code and I have no solution for your problem, but I
do have some suggestions. The process at the end of your architecture
uses state machine outputs to determine some of its actions, so why
not include the actions performed by that process in the state machine
itself? You would probably have to add a few more states, but you
would get the added advantage of having easier to follow code since
the major functions would all be in one place. You could also
eliminate some signals. You will need to synchronize all inputs to
the state machine (that are not synchronized in some other way) with
the state machine clock (a 2 d flip-flop synchronizer is the typical
way to do this, as discussed elsewhere in this forum). If you don't
do this you will have problems with the synthesized hardware due to
metastability even though your functional simulation works fine. I
don't think you need the procedure write_command. If you set the
value of write_out in a synchronous process, write_out is not needed.
In the state machine code you have some redundant logic for setting
sel_ep, etc. to '0'. I have put a snippet of the revised state
machine code below. I would like to help you more on this--I love
doing state machines, but I don't have the time right now.

Charles


PROCESS (reset,CLK, next_sreg)
BEGIN
IF CLK='1' AND CLK'event THEN
if RESET = '1' then
--state forced to IDLE on reset where sel_ep, valbuf, etc.
sreg <= IDLE;
else
sreg <= next_sreg;
end if ;
END IF;
END PROCESS;

write_stm: PROCESS (sreg,isr,RESET,wr_end,write_endp) is

BEGIN

CASE sreg IS
WHEN IDLE =
sel_ep<='0';
valbuf<='0';
wr_data<='0';
wr_init<='0';
IF ( write_endp='0' ) OR ( isr='1' ) THEN
next_sreg<=IDLE;
ELSIF ( isr='0' AND write_endp='1' ) THEN
next_sreg<=SEL_ENDP;
END IF;
WHEN SEL_ENDP =
valbuf<='0';
wr_data<='0';
wr_init<='0';
sel_ep<='1';
IF ( isr='0' ) THEN
write_out <= X"03";
next_sreg<=WRITE_INIT;
ELSE
--DON'T KNOW WHAT TO PUT HERE, BUT IT HAS TO BE SET TO
SOME VALUE
write_out <= X"??"; next_sreg<=IDLE;
END IF;

Hi Charles,

I'm having a similar problems with a state machine, which I believe is due
to synchronization problems. You mentioned in your reply using 2 D-FipFlops
to overcome the syncing problems. Would you mind including some code to
demonstrate this, or pointing me in the direction of some? I've attempted
to code my own but with no success. Am I right in assuming you first code a
flip flop module and then use this?

Thank you for your time.
Here is an excerpt from my flip-flops and registers library. These
components have been thoroughly tested and should work for you.
Please note that inputs that have default values may be omitted if not
needed. I did this when using the d flip-flop component to make a
synchronizer. Also, there is rarely a
need for the sclr input to the synchronizer so I virtually always omit
it
when instantiating the component.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
--===================================================================
package ffs_and_regs_pkg is
---------------------------------------------------------------------
--Single D-flop
---------------------------------------------------------------------
component d_ff
port ( data : in std_logic := '1';
clock : in std_logic;
enable : in std_logic := '1';
q : out std_logic;
aset : in std_logic := '0';
aclr : in std_logic := '0';
sclr : in std_logic := '0'
);
end component;
---------------------------------------------------------------------
--Standard 2 d-flop synchronizer. Synchronizes sig_in to clock in
--order to lessen effects of metastability on sig_out.
---------------------------------------------------------------------
component synchronizer

port( clock : in std_logic;
sclr : in std_logic := '0';
sig_in : in std_logic;
sig_out : out std_logic
);
end component;

end package ffs_and_regs_pkg;
--===================================================================
--Entity/Architecture for d_ff component
--===================================================================
library ieee;
use ieee.std_logic_1164.all;

use work.ffs_and_regs_pkg.all;
---------------------------------------------------------------------
--Single D-flop
---------------------------------------------------------------------
entity d_ff is
port ( data : in std_logic := '1';
clock : in std_logic;
enable : in std_logic := '1';
q : out std_logic;
aset : in std_logic := '0';
aclr : in std_logic := '0';
sclr : in std_logic := '0'
);
end d_ff;

architecture archd_ff of d_ff is

begin
pd_ff : process( clock, aset, aclr )
begin
if aclr = '1' then
q <= '0';
elsif aset = '1' then
q <= '1';
elsif rising_edge( clock ) then
if sclr = '1' then
q <= '0';
elsif enable = '1' then
q <= data;
end if; --sclr = '1'
end if ; --aclr = '1'
end process;
end archd_ff;
--*******************************************************************
-- Entity/Architecture for synchronizer
--*******************************************************************
library IEEE;
use IEEE.std_logic_1164.all;
use work.ffs_and_regs_pkg.all;
---------------------------------------------------------------------
entity synchronizer is

port( clock : in std_logic;
sclr : in std_logic := '0';
sig_in : in std_logic;
sig_out : out std_logic
);
end synchronizer;

architecture arch_synchronizer of synchronizer is

signal q_synch_a : std_logic;

begin
Usynch_a : d_ff
port map( data => sig_in,
clock => clock,
sclr => sclr,
q => q_synch_a
);

Usig_out : d_ff
port map( data => q_synch_a,
clock => clock,
sclr => sclr,
q => sig_out
);

end architecture arch_synchronizer;
---------------------------------------------------------------------
 
Try changing:

write_stm: PROCESS (sreg,isr,RESET,wr_end,write_endp) is

to

write_stm: PROCESS (sreg,isr,RESET,wr_end,write_endp, wr_init_end) is


Steve.
 

Welcome to EDABoard.com

Sponsor

Back
Top