Strange problem with very simple state machine

Discussion in 'VHDL' started by Roger Dahl, Nov 16, 2004.

  1. Roger Dahl

    Roger Dahl Guest

    Dear group,

    I'm teaching myself VHDL and to that end, I got a prototype board with
    a Xilinx Spartan 2 and WebPack 6.3.02 plus service packs.

    I was working on a small design when I started having some strange
    problems with a state machine. To locate the problem, I separated out
    the state machine and simplified it as much as I could while still
    retaining the problem. So I now have a complete design with an
    extremely simple state machine that exhibits the problem, but I still
    can't see that I made any mistakes. I've included that design in VHDL
    below.

    The state machine has two states. The first state sets a signal to 0,
    and the second state inverts the signal. From everything I've read
    about state machines and processes, the signal should turn to 1 when
    the state machine goes to the second state and stay at 1 until the
    state machine goes back to the first state. Instead, what happens is
    that while the state machine is in the second state, the signal keeps
    inverting as quickly as the chip can manage.

    When I view the RTL schematic for the design, it is apparent why this
    happens. While the state machine is in the second state, the signal is
    simply run in a loop through a NOT gate.

    I would much appreciate it if someone that knows more about VHDL than
    I could take a look at the code below and see if I have missed
    something fundamental about VHDL or state machines, or if this is a
    bug in the Xilinx tools.

    Thank you for any help!

    Roger Dahl

    --

    library ieee;
    use ieee.std_logic_1164.all;

    entity sigtest is
    port (
    mclk : in std_logic;
    d: out std_logic
    );
    end sigtest;

    architecture behavioral of sigtest is

    type state is (
    write_a,
    write_b
    );

    signal d_ctl : std_logic := '0';

    signal cur_st : state := write_a;
    signal next_st : state := write_b;

    begin

    d <= d_ctl;

    process (mclk)
    begin
    if rising_edge(mclk) then
    cur_st <= next_st;
    end if;
    end process;

    process (cur_st)
    begin
    case cur_st is
    when write_a =>
    d_ctl <= '0';
    next_st <= write_b;

    when write_b =>
    d_ctl <= not d_ctl;
    next_st <= write_a;
    end case;
    end process;

    end behavioral;
    Roger Dahl, Nov 16, 2004
    #1
    1. Advertising

  2. Roger Dahl wrote:

    > Instead, what happens is that while the state machine
    > is in the second state, the signal keeps
    > inverting as quickly as the chip can manage.


    I expect that you are toggling back and forth
    from a to b to a etc.

    Your code specifies that

    a: d_ctl gets '0'; go to b
    b: d_ctl gets inverted to '1'; go to a

    and I expect that is exactly what is happening.
    Next time consider running a simulation to
    debug your code.

    -- Mike Treseler
    mike_treseler, Nov 16, 2004
    #2
    1. Advertising

  3. Roger Dahl

    Roger Dahl Guest

    "mike_treseler" <tres@fl_ke_networks.com> wrote in message

    > I expect that you are toggling back and forth
    > from a to b to a etc.
    >
    > Your code specifies that
    >
    > a: d_ctl gets '0'; go to b
    > b: d_ctl gets inverted to '1'; go to a
    >
    > and I expect that is exactly what is happening.
    > Next time consider running a simulation to
    > debug your code.


    Thank you for your reply, Mike.

    Actually, the frequency that is output when the state machine is in
    the second state is much higher than the clock frequency. It displays
    only as a voltage of around 0.1V on my 20MHz oscilloscope. When the
    state machine is in the first state, I get GND on the output.

    The result I see is also consistent with the RTL schematic, but to me,
    the RTL schematic is not consistent with my code.

    Finally, the VHDL code seems to work when I simulate it in ModelSim.

    Thanks again,

    Roger
    Roger Dahl, Nov 17, 2004
    #3
  4. Roger Dahl

    Neo Guest

    > The state machine has two states. The first state sets a signal to 0,
    > and the second state inverts the signal. From everything I've read
    > about state machines and processes, the signal should turn to 1 when
    > the state machine goes to the second state and stay at 1 until the
    > state machine goes back to the first state. Instead, what happens is
    > that while the state machine is in the second state, the signal keeps
    > inverting as quickly as the chip can manage.
    >


    > Thank you for any help!
    >
    > Roger Dahl
    >
    > --
    >
    > library ieee;
    > use ieee.std_logic_1164.all;
    >
    > entity sigtest is
    > port (
    > mclk : in std_logic;
    > d: out std_logic
    > );
    > end sigtest;
    >
    > architecture behavioral of sigtest is
    >
    > type state is (
    > write_a,
    > write_b
    > );
    >
    > signal d_ctl : std_logic := '0';
    >
    > signal cur_st : state := write_a;
    > signal next_st : state := write_b;
    >
    > begin
    >
    > d <= d_ctl;
    >
    > process (mclk)
    > begin
    > if rising_edge(mclk) then
    > cur_st <= next_st;
    > end if;
    > end process;
    >
    > process (cur_st)
    > begin
    > case cur_st is
    > when write_a =>
    > d_ctl <= '0';
    > next_st <= write_b;
    >
    > when write_b =>
    > d_ctl <= not d_ctl;
    > next_st <= write_a;
    > end case;
    > end process;
    >
    > end behavioral;

    The behaviour you observe is correct as per hardware but wont show in
    simulation because the process sensitivity list is for simulator
    only(it would have shown if you had as required included the d_ctl in
    the sensitivity list) , the hardware is not dictated by it, so for all
    practical purposes the hardware comb logic triggers everytime the
    d_ctl changes which is nothing but a not gate fed to itself. So to
    accurately model your requirement you have to specifically state that
    d_ctl <= '1' in the write_b state. but you present assignment is
    modelling a clock.
    Neo, Nov 17, 2004
    #4
  5. Hi Roger,

    What Mike said was correct . The output is switching with half the
    frequency of 'mclk'.

    some other comments on your code....
    1) Dont Initialize the signals when you write code for synthesis
    2) All FSMs should have a reset signal.(otherwise system starts from
    a unknow state). Hence your First process should be like this...

    process (mclk,reset)
    begin
    if (reset='0')then
    cur_st <= write_a; -- If write_a is the initial state
    elsif rising_edge(mclk) then
    cur_st <= next_st;
    end if;
    end process;
    Mohammed khader, Nov 17, 2004
    #5
  6. Roger Dahl

    Roger Dahl Guest

    (Neo) wrote in message news:<>...

    > The behaviour you observe is correct as per hardware but wont show in
    > simulation because the process sensitivity list is for simulator
    > only(it would have shown if you had as required included the d_ctl in
    > the sensitivity list) , the hardware is not dictated by it, so for all
    > practical purposes the hardware comb logic triggers everytime the
    > d_ctl changes which is nothing but a not gate fed to itself. So to
    > accurately model your requirement you have to specifically state that
    > d_ctl <= '1' in the write_b state. but you present assignment is
    > modelling a clock.


    Neo,

    That explains it. I appreciate that you took the time to enlighten me. Thanks!

    Roger
    Roger Dahl, Nov 18, 2004
    #6
  7. Roger Dahl

    Roger Dahl Guest

    (Mohammed khader) wrote in message news:<>...
    > Hi Roger,
    >
    > What Mike said was correct . The output is switching with half the
    > frequency of 'mclk'.
    >
    > some other comments on your code....
    > 1) Dont Initialize the signals when you write code for synthesis
    > 2) All FSMs should have a reset signal.(otherwise system starts from
    > a unknow state). Hence your First process should be like this...
    >
    > process (mclk,reset)
    > begin
    > if (reset='0')then
    > cur_st <= write_a; -- If write_a is the initial state
    > elsif rising_edge(mclk) then
    > cur_st <= next_st;
    > end if;
    > end process;


    Hi Mohammed,

    Thank you for your reply.

    Actually, the output is switching as fast as the hardware can manage
    while the state machine is in the second state. See Neo's post for the
    explanation as to why this happens.

    Thanks for the coding tips. Those things were in my original design
    but I had shaved them off to make the example as brief as possible for
    the group.

    Roger
    Roger Dahl, Nov 18, 2004
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. brewman
    Replies:
    0
    Views:
    1,433
    brewman
    Aug 28, 2003
  2. Raymond Arthur St. Marie II of III

    very Very VERY dumb Question About The new Set( ) 's

    Raymond Arthur St. Marie II of III, Jul 23, 2003, in forum: Python
    Replies:
    4
    Views:
    452
    Raymond Hettinger
    Jul 27, 2003
  3. Kenneth McDonald

    Very, very strange problem with properties

    Kenneth McDonald, May 4, 2004, in forum: Python
    Replies:
    2
    Views:
    254
    Kenneth McDonald
    May 4, 2004
  4. olivier.melcher

    Help running a very very very simple code

    olivier.melcher, May 12, 2008, in forum: Java
    Replies:
    8
    Views:
    2,247
  5. fenster
    Replies:
    3
    Views:
    1,149
    jeppe
    Dec 23, 2011
Loading...

Share This Page