newby: eliminating excess flipflops from simple state machine

Discussion in 'VHDL' started by Paul Guy, May 24, 2004.

  1. Paul Guy

    Paul Guy Guest

    I have been puzzled by the fact that two implementations have such
    drastic differences in synthesized circuits. I know that I have failed
    to cover all the if-then-else possibilities (that's required to
    generate SOME of the flipflops). I am really at my wit's end trying to
    get my head around the "why" and the "howto get around it" of the
    following situation:

    first program, it is compiled under Lattice & Synplify, and it
    works just fine, it's a 4 bit counter, described as a finite state
    machine, using an asynch reset and synchronous preset (the chips we're
    using do not allow asynch preset). This one synthesizes nicely to 4
    flipflops.
    The 2nd program is the same as the first, except the lines with
    ##### in them are removed.
    ........................................................................
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    use ieee.std_logic_arith.all;

    entity counter is
    PORT(clock :IN STD_LOGIC;
    barreset :IN STD_LOGIC;
    barpreset :IN STD_LOGIC;
    q :OUT STD_LOGIC_VECTOR (3 downto 0));

    attribute LOC : string;
    ATTRIBUTE LOC of clock: signal is "P2";
    ATTRIBUTE LOC of barreset: signal is "P3";
    ATTRIBUTE LOC of barpreset: signal is "P4";
    ATTRIBUTE LOC of q: signal is "P27 P26 P25 P24";
    end;


    --this one works


    architecture howitcounts of counter is
    TYPE statemachine IS (s0,s1,s2,s3,s4,s5,s6,s7,s8,s9);
    begin
    PROCESS (clock,barreset)
    VARIABLE state: statemachine;
    begin
    if (barreset = '0') then
    state := s0;
    elsif rising_edge(clock) then
    if (barpreset = '0') then --########
    state := s8; --########
    end if; --########
    CASE state IS
    WHEN s0 => state := s1;
    WHEN s1 => state := s2;
    WHEN s2 => state := s3;
    WHEN s3 => state := s4;
    WHEN s4 => state := s5;
    WHEN s5 => state := s6;
    WHEN s6 => state := s7;
    WHEN s7 => state := s8;
    WHEN s8 => state := s9;
    WHEN s9 => state := s0;
    WHEN OTHERS => state := s0;
    END CASE;
    end if;

    CASE state is
    WHEN s0 => q <= "0000";
    WHEN s1 => q <= "0001";
    WHEN s2 => q <= "0010";
    WHEN s3 => q <= "0011";
    WHEN s4 => q <= "0100";
    WHEN s5 => q <= "0101";
    WHEN s6 => q <= "0110";
    WHEN s7 => q <= "0111";
    WHEN s8 => q <= "1000";
    WHEN s9 => q <= "1001";
    WHEN OTHERS => q <= "0000";
    END CASE;
    END PROCESS;

    end howitcounts;
    ............................................................

    this next program DOES NOT work nicely. It requires about 13 flipflops
    and thus fails miserably when using a GAL22V10C (10 flipflops). The
    ONLY diference between the two, is 3 lines removed that control the
    synchronous preset (I have shown #####'s on the 1st program where that
    code is).
    Hopefully your newsreader will preserve tabs.... otherwise this code
    will be a mess to read.
    The implementation is rather clunky for a 4 bit counter, because I
    will use this program as a template for much more complicated state
    machines.
    I suspect that the compiler thinks that the circuit will remember
    the states in one case, and won't remember then in the other case,
    hence it needs a flipflop for every state. The "prefit equations"
    suggest that there is a shift register synthesized for the "bad
    circuit". I am not very comfortable with FSM details, but it would
    appear that it might be trying to create a "one-hot" implementation.
    Am I totally misled? Why should there be such a difference in
    implementation? Would I be better off to break this program up into
    more processes? Did I screw up in the if-else blocks?
    Thanks for any help......

    -Paul
    Paul Guy, May 24, 2004
    #1
    1. Advertising

  2. A few comments:
    The two USE statements,
    use ieee.std_logic_unsigned.all;
    use ieee.std_logic_arith.all;
    are not needed.

    The WHEN OTHERS clauses of the two CASE statements are not needed since
    all possible values of "state" are already covered by the other WHEN
    clauses.

    Also, are you trying to preset the state machine to s8 or s9?
    Charles Bailey, May 25, 2004
    #2
    1. Advertising

  3. Paul Guy

    Jim Lewis Guest

    Paul,
    It is surprising that you have different synthesis results.
    Since your "CASE state is" fully covers all possibilities,
    the lines marked with "--########" have no synthesis semantic.

    I agree that the second implementation seems to be implemented as
    one-hot. The synthesis tool probably will not do this by
    default. I suspect that some how when you were synthesizing
    the second design that you accidentally selected one-hot.
    You might check your constraints and try again. If that does
    not work, try selecting binary/sequentical encoding (not gray)
    to try to get it closer to what you want.

    If that does not work, you might try using Synplicity's
    "syn_encoding" to force the coding to something exactly the
    values you expect for Q.


    Alternately, if you want to stop fooling around with synthesis
    tool switches, use use a counter. I do this for ring
    counters like you show:

    architecture howitcounts of counter is
    signal StateReg : unsigned(3 downto 0) ;
    begin
    StateProc : PROCESS (clock,barreset)
    begin
    if (barreset = '0') then
    StateReg <= "0000" ;
    elsif rising_edge(clock) then
    If StateReg = 9 then
    StateReg <= "0000" ;
    else
    StateReg <= StateReg + 1 ;
    end if ;
    end if ;
    end process ;

    Q <= std_logic_vector(StateReg) ;


    Cheers,
    Jim
    P.S.
    I recommend the use of the package numeric_std rather
    than std_logic_arith for all new designs.
    --
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Jim Lewis
    Director of Training mailto:
    SynthWorks Design Inc. http://www.SynthWorks.com
    1-503-590-4787

    Expert VHDL Training for Hardware Design and Verification
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    Paul Guy wrote:
    > I have been puzzled by the fact that two implementations have such
    > drastic differences in synthesized circuits. I know that I have failed
    > to cover all the if-then-else possibilities (that's required to
    > generate SOME of the flipflops). I am really at my wit's end trying to
    > get my head around the "why" and the "howto get around it" of the
    > following situation:
    >
    > first program, it is compiled under Lattice & Synplify, and it
    > works just fine, it's a 4 bit counter, described as a finite state
    > machine, using an asynch reset and synchronous preset (the chips we're
    > using do not allow asynch preset). This one synthesizes nicely to 4
    > flipflops.
    > The 2nd program is the same as the first, except the lines with
    > ##### in them are removed.
    > .......................................................................
    > library ieee;
    > use ieee.std_logic_1164.all;
    > use ieee.std_logic_unsigned.all;
    > use ieee.std_logic_arith.all;
    >
    > entity counter is
    > PORT(clock :IN STD_LOGIC;
    > barreset :IN STD_LOGIC;
    > barpreset :IN STD_LOGIC;
    > q :OUT STD_LOGIC_VECTOR (3 downto 0));
    >
    > attribute LOC : string;
    > ATTRIBUTE LOC of clock: signal is "P2";
    > ATTRIBUTE LOC of barreset: signal is "P3";
    > ATTRIBUTE LOC of barpreset: signal is "P4";
    > ATTRIBUTE LOC of q: signal is "P27 P26 P25 P24";
    > end;
    >
    >
    > --this one works
    >
    >
    > architecture howitcounts of counter is
    > TYPE statemachine IS (s0,s1,s2,s3,s4,s5,s6,s7,s8,s9);
    > begin
    > PROCESS (clock,barreset)
    > VARIABLE state: statemachine;
    > begin
    > if (barreset = '0') then
    > state := s0;
    > elsif rising_edge(clock) then
    > if (barpreset = '0') then --########
    > state := s8; --########
    > end if; --########
    > CASE state IS
    > WHEN s0 => state := s1;
    > WHEN s1 => state := s2;
    > WHEN s2 => state := s3;
    > WHEN s3 => state := s4;
    > WHEN s4 => state := s5;
    > WHEN s5 => state := s6;
    > WHEN s6 => state := s7;
    > WHEN s7 => state := s8;
    > WHEN s8 => state := s9;
    > WHEN s9 => state := s0;
    > WHEN OTHERS => state := s0;
    > END CASE;
    > end if;
    >
    > CASE state is
    > WHEN s0 => q <= "0000";
    > WHEN s1 => q <= "0001";
    > WHEN s2 => q <= "0010";
    > WHEN s3 => q <= "0011";
    > WHEN s4 => q <= "0100";
    > WHEN s5 => q <= "0101";
    > WHEN s6 => q <= "0110";
    > WHEN s7 => q <= "0111";
    > WHEN s8 => q <= "1000";
    > WHEN s9 => q <= "1001";
    > WHEN OTHERS => q <= "0000";
    > END CASE;
    > END PROCESS;
    >
    > end howitcounts;
    > ...........................................................
    >
    > this next program DOES NOT work nicely. It requires about 13 flipflops
    > and thus fails miserably when using a GAL22V10C (10 flipflops). The
    > ONLY diference between the two, is 3 lines removed that control the
    > synchronous preset (I have shown #####'s on the 1st program where that
    > code is).
    > Hopefully your newsreader will preserve tabs.... otherwise this code
    > will be a mess to read.
    > The implementation is rather clunky for a 4 bit counter, because I
    > will use this program as a template for much more complicated state
    > machines.
    > I suspect that the compiler thinks that the circuit will remember
    > the states in one case, and won't remember then in the other case,
    > hence it needs a flipflop for every state. The "prefit equations"
    > suggest that there is a shift register synthesized for the "bad
    > circuit". I am not very comfortable with FSM details, but it would
    > appear that it might be trying to create a "one-hot" implementation.
    > Am I totally misled? Why should there be such a difference in
    > implementation? Would I be better off to break this program up into
    > more processes? Did I screw up in the if-else blocks?
    > Thanks for any help......
    >
    > -Paul
    Jim Lewis, May 25, 2004
    #3
  4. Paul Guy

    Paul Guy Guest

    On Tue, 25 May 2004 10:08:44 -0700, Jim Lewis <>
    wrote:

    >Paul,
    >It is surprising that you have different synthesis results.
    >Since your "CASE state is" fully covers all possibilities,
    >the lines marked with "--########" have no synthesis semantic.
    >
    >I agree that the second implementation seems to be implemented as
    >one-hot. The synthesis tool probably will not do this by
    >default. I suspect that some how when you were synthesizing
    >the second design that you accidentally selected one-hot.
    >You might check your constraints and try again. If that does
    >not work, try selecting binary/sequentical encoding (not gray)
    >to try to get it closer to what you want.
    >
    >If that does not work, you might try using Synplicity's
    >"syn_encoding" to force the coding to something exactly the
    >values you expect for Q.
    >
    >
    >Alternately, if you want to stop fooling around with synthesis
    >tool switches, use use a counter. I do this for ring
    >counters like you show:
    >
    >architecture howitcounts of counter is
    > signal StateReg : unsigned(3 downto 0) ;
    >begin
    > StateProc : PROCESS (clock,barreset)
    > begin
    > if (barreset = '0') then
    > StateReg <= "0000" ;
    > elsif rising_edge(clock) then
    > If StateReg = 9 then
    > StateReg <= "0000" ;
    > else
    > StateReg <= StateReg + 1 ;
    > end if ;
    > end if ;
    > end process ;
    >
    > Q <= std_logic_vector(StateReg) ;
    >
    >
    >Cheers,
    >Jim
    >P.S.
    >I recommend the use of the package numeric_std rather
    >than std_logic_arith for all new designs.





    I later tried setting a constraint ("syn_encoding") and it yielded
    more consistent results, but in this case both versions ended up as a
    one-hot. My guess is that when I use an asynchronous reset, because
    the state machine definition is bypassed in the "if" statement, the
    states must be memorized, and that requires all 10 states to require
    their own registers.
    You are correct about modelling it as a counter..... it boils down
    to the minimum 4 registers. The synthesis part of the package must
    somehow realize that a counter is best done sequentially, and a state
    machine is best done by one-hot, despite the constraints. The code I
    finally chose looks remarkably like that you have shown above.
    Originally this whole query came about as a result of trying to put
    a 2 decade counter with reset, preset and carryout onto a 10 register
    GALV2210. I was demonstrating the similiarities between a behavioural
    representation as a counter (adding the counts), and a state machine.
    The statemachine failed miserably - it required far too many
    flipflops. Students are always quite interested in seeing how an
    instructor "gets off the hook" in such a case. Both them and I did
    learn something about the trade-offs between sequential and one-hot
    implementations of state machines. Next year for this course I must
    invest in chips with higher complexity - more gates and registers!
    -Thanks for your help......

    -Paul
    Paul Guy, May 27, 2004
    #4
    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. Martin Bammer
    Replies:
    0
    Views:
    611
    Martin Bammer
    Nov 17, 2003
  2. MattC

    Event Log Entry - excess info

    MattC, Jan 7, 2005, in forum: ASP .Net
    Replies:
    7
    Views:
    6,038
    MattC
    Jan 10, 2005
  3. =?Utf-8?B?Y2xpY2tvbg==?=

    Removing excess white space

    =?Utf-8?B?Y2xpY2tvbg==?=, Apr 6, 2006, in forum: ASP .Net
    Replies:
    5
    Views:
    17,779
    visserj
    Feb 3, 2011
  4. KSR
    Replies:
    13
    Views:
    1,264
    jeppe
    Nov 6, 2009
  5. Thomas Heller

    Flipflops

    Thomas Heller, Jun 22, 2012, in forum: VHDL
    Replies:
    4
    Views:
    698
Loading...

Share This Page