synthesizing 'rightof or 'succ

Discussion in 'VHDL' started by Neha, Nov 10, 2007.

  1. Neha

    Neha Guest

    Hi.
    I have an FSM with 32 states. States 0, 1 and 31 are unique, and the
    rest are basically doing the same thing.
    ...so I wrote the code using case statements like this:

    case state is

    when t0=>--somecode....
    state<=t1;

    when t1=>--somecode....
    state<=t2;

    when t2 to t30=>
    state<=state_type'succ(state) --or state<=state_type'rightof(state)
    --somecode

    when t31=>
    state<=t0;
    --somecode

    However, Xilinx ISE doesn't synthesize 'rightof or 'succ. Is there any
    way to overcome this? I don't want to copy the same code for each
    state.

    Thanx.
    Neha
     
    Neha, Nov 10, 2007
    #1
    1. Advertising

  2. Neha wrote:

    > when t2 to t30=>
    > state<=state_type'succ(state) --or state<=state_type'rightof(state)
    > --somecode
    >
    > when t31=>
    > state<=t0;
    > --somecode
    >
    > However, Xilinx ISE doesn't synthesize 'rightof or 'succ. Is there any
    > way to overcome this? I don't want to copy the same code for each
    > state.


    Consider using a counter rather
    than a case.

    -- Mike Treseler
     
    Mike Treseler, Nov 10, 2007
    #2
    1. Advertising

  3. Neha

    Neha Guest

    Okay. Thanks.
     
    Neha, Nov 10, 2007
    #3
  4. On Sat, 10 Nov 2007 03:37:30 -0800, Neha <>
    wrote:

    >I have an FSM with 32 states. States 0, 1 and 31 are unique, and the
    >rest are basically doing the same thing.


    As Mike said, it's probably best to use a counter to cope
    with this kind of thing.

    I usually prefer to have a downcounter and leave it counting
    unconditionally, synchronously loading it with a timeout value
    whenever necessary. This commonly gives rise to more compact
    and cleaner logic than a FSM that decrements the counter in
    various different places - although these days the tools are
    pretty good at recognising such shareable increment/decrement
    operations.

    My code would look something like this. Note the use of a
    variable (even though it's not terribly convenient) to
    hide away the downcounter entirely within the process
    that needs it.

    ...
    process (clock, reset)
    variable timer, next_timer: unsigned(...);
    begin
    if reset = '1' then
    --- do all your resets, including...
    state <= t0;
    timer := to_unsigned(0, timer'length);
    elsif rising_edge(clock) then
    next_timer := timer - 1; -- count down, by default
    case state is
    when t0 =>
    .....
    state <= t1;
    when t1 =>
    ..... make decision to go into timed state tt
    state <= tt;
    next_timer := to_unsigned(DELAY, timer'length);
    when tt =>
    if timer = 0 then
    -- timer has run to completion
    state <= t31;
    end if;
    when t31 =>
    ...
    end case;
    timer := next_timer;
    end if;
    end process;

    An alternative would be to write your own SUCCESSOR() function
    and use that in place of 'SUCC. This function would be quite
    clunky, but it would at least hide away all the messy detail
    so that you can get the desired effect in your FSM.
    --
    Jonathan Bromley, Consultant

    DOULOS - Developing Design Know-how
    VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

    Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK

    http://www.MYCOMPANY.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
     
    Jonathan Bromley, Nov 10, 2007
    #4
  5. Neha

    Neha Guest

    Thanx :)
     
    Neha, Nov 10, 2007
    #5
  6. Neha

    Neha Guest

    Just a question: If i were to go on and type the same code for each
    state, will the synthesized logic be lesser than if I had a counter?
    The tool is doing one-hot encoding for this FSM
    *Why is the encoding one-hot most of the times and rarely
    binary?

    Thanks,
    Neha
    (M.Tech Student)
     
    Neha, Nov 10, 2007
    #6
  7. Neha wrote:
    > Just a question: If i were to go on and type the same code for each
    > state, will the synthesized logic be lesser than if I had a counter?


    No, the code is just easier to read.
    Counters, shifters, states etc
    as just variables that are updated
    on every rising edge using different procedures.
    See Amit's recent postings regarding
    coding a shift register as a case.

    > The tool is doing one-hot encoding for this FSM
    > *Why is the encoding one-hot most of the times and rarely
    > binary?


    Quartus and ISE default to "AUTO" encoding
    which usually means binary for up to 4 states
    and one-hot otherwise. There is only a very
    small advantage for one-hot in the large cases
    I have tested. On the rare occasion when I have
    to encode a case, I use binary as
    it is easier to keep track of.
    But synthesis does a good job at this, so
    I usually just leave it set to AUTO.

    -- Mike Treseler
     
    Mike Treseler, Nov 10, 2007
    #7
  8. Neha

    KJ Guest

    "Neha" <> wrote in message
    news:...
    >
    > However, Xilinx ISE doesn't synthesize 'rightof or 'succ. Is there any
    > way to overcome this? I don't want to copy the same code for each
    > state.
    >

    Besides the work arounds that have been suggested, you should probably open
    a web case to Xilinx to fix their tool to properly support this. Work
    arounds are fine to get one going where the tool falls flat so your design
    is not halted by this failure, but Xilinx should be held to task for not
    supporting this perfectly valid language construct....and like all suppliers
    they respond to complaints so even if there fix isn't in time for you on
    this project, you'll be doing your part to help them improve their tool.
    Down the road it will be helping others and maybe yourself in the future.

    KJ
     
    KJ, Nov 10, 2007
    #8
  9. Neha

    Andy Guest

    I wholeheartedly agree with Jonathan's use of a variable to hide/
    protect the counter in the process that uses it. I would extend that
    to the state as well if it is not accessed outside the process (which
    I would consider poor design if it was).

    Another approach to the timer/next_timer pair is to have a timer and a
    timeout variable instead (note that timeout does not become a
    register, it just uses a registered reference to timer).

    And if you are having to load the timer from an integer constant, just
    go ahead and make the timer an integer itself.

    variable timeout : boolean;
    variable timer : integer range 0 to MAX_TIME - 1;
    ....
    elsif rising_edge(clk) then
    timeout := timer - 1 < 0; -- reuse carry bit
    timer := (timer - 1) mod MAX_TIME; -- rollover
    end if;
    case state is
    when t0 =>
    .....
    state <= t1;
    when t1 =>
    ..... make decision to go into timed state tt
    state <= tt;
    timer := DELAY;
    when tt =>
    if timeout then
    -- timer has run to completion
    state <= t31;
    end if;
    when t31 =>
    ...
    end case;
    end if;
     
    Andy, Nov 12, 2007
    #9
  10. Neha wrote:

    > I have an FSM with 32 states. States 0, 1 and 31 are unique, and the
    > rest are basically doing the same thing.
    > ..so I wrote the code using case statements like this:
    > case state is
    > when t0=>--somecode....
    > state<=t1;
    > when t1=>--somecode....
    > state<=t2;
    > when t2 to t30=>
    > state<=state_type'succ(state) --or state<=state_type'rightof(state)
    > --somecode
    > when t31=>
    > state<=t0;
    > --somecode


    After seeing the other examples, and
    rereading your original question above,
    It sounds to me that you might be able
    to decode a rollover counter directly,
    something like this:

    http://home.comcast.net/~mike_treseler/cnt_decode.vhd


    -- Mike Treseler
     
    Mike Treseler, Nov 12, 2007
    #10
  11. Mike Treseler wrote:


    > After seeing the other examples, and
    > rereading your original question above,
    > It sounds to me that you might be able
    > to decode a rollover counter directly,
    > something like this:
    >
    > http://home.comcast.net/~mike_treseler/cnt_decode.vhd


    Which says:
    cnt_v := cnt_v + 1;
    case cnt_v is
    when 0 | 1 =>
    somecode;
    when 31 =>
    somecode;
    cnt_v := 0;
    when others => null;
    end case;

    Why not:
    cnt_v := cnt_v + 1;
    case cnt_v is
    when 0 | 1 | 31 =>
    somecode;
    when others => null;
    end case;
    if cnt_v = 31 then
    cnt_v := 0;
    end if;

    I would prefer that because "somecode" is not duplicated.

    --
    Paul Uiterlinden
    www.aimvalley.nl
    e-mail addres: remove the not.
     
    Paul Uiterlinden, Nov 12, 2007
    #11
  12. Paul Uiterlinden wrote:

    >
    > Which says:
    > cnt_v := cnt_v + 1;
    > case cnt_v is
    > when 0 | 1 =>
    > somecode;
    > when 31 =>
    > somecode;
    > cnt_v := 0;
    > when others => null;
    > end case;
    >
    > Why not:
    > cnt_v := cnt_v + 1;
    > case cnt_v is
    > when 0 | 1 | 31 =>
    > somecode;
    > when others => null;
    > end case;
    > if cnt_v = 31 then
    > cnt_v := 0;
    > end if;
    >
    > I would prefer that because "somecode" is not duplicated.


    Very clean on the when line.
    Oh, but now case 31 is duplicated.
    I can't decide :)

    Back to the salt mines.

    -- Mike Treseler
     
    Mike Treseler, Nov 12, 2007
    #12
  13. Mike Treseler wrote:

    >> I would prefer that because "somecode" is not duplicated.

    >
    > Very clean on the when line.
    > Oh, but now case 31 is duplicated.
    > I can't decide :)


    I can. Didn't you see that "somecode" is actually 42 lines? ;-)

    > Back to the salt mines.


    :)

    --
    Paul Uiterlinden
    www.aimvalley.nl
    e-mail addres: remove the not.
     
    Paul Uiterlinden, Nov 13, 2007
    #13
  14. Paul Uiterlinden wrote:

    > I can. Didn't you see that "somecode" is actually 42 lines? ;-)


    Unless it is a procedure id in a single process entity.
    This may look inefficient, but it makes no difference
    to synthesis.

    -- Mike Treseler
     
    Mike Treseler, Nov 13, 2007
    #14
  15. Mike Treseler wrote:

    > Paul Uiterlinden wrote:
    >
    >> I can. Didn't you see that "somecode" is actually 42 lines? ;-)

    >
    > Unless it is a procedure id in a single process entity.


    I don't want to play with you anymore. You are cheating.
    Go back into your salt mines. ;-P

    > This may look inefficient, but it makes no difference
    > to synthesis.


    Yep, even not for simulation.

    --
    Paul Uiterlinden
    www.aimvalley.nl
    e-mail addres: remove the not.
     
    Paul Uiterlinden, Nov 13, 2007
    #15
  16. Neha

    Neha Guest

    On Nov 12, 9:03 pm, Andy <> wrote:
    > I wholeheartedly agree with Jonathan's use of a variable to hide/
    > protect the counter in the process that uses it. I would extend that
    > to the state as well if it is not accessed outside the process (which
    > I would consider poor design if it was).
    >


    *** Why is it poor design to declare state as signal instead of
    variable? It won't necessarily lead to better synthesis...and I
    wouldn't be able to observe the state in simulation waveforms.
     
    Neha, Nov 14, 2007
    #16
  17. Neha wrote:

    > *** Why is it poor design to declare state as signal instead of
    > variable?
    >

    It isn't poor design, it is a different style of design.
    It is easier for me to write sequential code
    using functions and procedures.
    For this style, variables are essential.
    Many designers don't care about this at all,
    and design with a netlist-oriented style.
    This works fine also.

    > It won't necessarily lead to better synthesis...and I
    > wouldn't be able to observe the state in simulation waveforms.


    This is not true. All of the waveforms labeled with _v
    in the pdf below are modelsim waveforms.
    http://home.comcast.net/~mike_treseler/uart_zoom.pdf

    -- Mike Treseler
     
    Mike Treseler, Nov 14, 2007
    #17
  18. Neha

    KJ Guest

    On Nov 14, 9:43 am, Neha <> wrote:
    > On Nov 12, 9:03 pm, Andy <> wrote:
    >
    > > I wholeheartedly agree with Jonathan's use of a variable to hide/
    > > protect the counter in the process that uses it. I would extend that
    > > to the state as well if it is not accessed outside the process (which
    > > I would consider poor design if it was).

    >
    > *** Why is it poor design to declare state as signal instead of
    > variable? It won't necessarily lead to better synthesis...and I
    > wouldn't be able to observe the state in simulation waveforms.


    It's a matter of opinion whether or not hiding things within the
    architecture of a given entity is 'poor design' or not. In my
    opinion, the VHDL notion of design hierarchy is the entity, when a
    particular entity/architecture has grown to be 'too big' or 'too
    complicated' it should be re-factored and broken down into sub-
    entities. Within a given entity/architecture though, my opinion is
    that individual processes are all working towards the same goal and
    should have access to everything so the notion of hiding things by
    virtue of the scoping rules (i.e. variables are not accessible outside
    that process) is counterproductive to getting a design task completed
    because of the loss of visibility in the debug process. Hiding
    signals by not making them available to sub-entities in a hierarchical
    design (unless they are needed of course) accomplishes the same thing
    without getting persnickety about the whole idea of localizing usage
    of signals/variables.

    The obvious downside (as you've already noticed) to variables is that
    they can not be observed in wave windows, list windows, whatever after
    the fact (i.e. you're trying to debug a problem and are working back
    in time). They can be added and viewed going forward, but not going
    back in time (at least not with Modelsim). That to me is a big
    drawback, others don't mind recomputing (possibly incorrectly) the
    value that a variable must have had based on the signals that can be
    viewed. Again, that to me seems counterproductive to getting a task
    completed. I do use variables, but not as extensively as others in
    this group but my reason for using a variable has never been just
    because I didn't want some other process in that same entity/
    architecture to be able to access it.

    KJ
     
    KJ, Nov 14, 2007
    #18
  19. Neha

    KJ Guest

    On Nov 14, 10:29 am, Mike Treseler <> wrote:
    > Neha wrote:
    >
    > > It won't necessarily lead to better synthesis...and I
    > > wouldn't be able to observe the state in simulation waveforms.

    >
    > This is not true. All of the waveforms labeled with _v
    > in the pdf below are modelsim waveforms.http://home.comcast.net/~mike_treseler/uart_zoom.pdf
    >


    But only if you wave the variables ahead of time. There is no
    equivalent that I know of to "log -r /*" that will pick up variables
    so that they can be waved at some later sim time and see the complete
    history of that variable up to that sim time.

    KJ
     
    KJ, Nov 14, 2007
    #19
  20. KJ wrote:

    > But only if you wave the variables ahead of time. There is no
    > equivalent that I know of to "log -r /*" that will pick up variables
    > so that they can be waved at some later sim time and see the complete
    > history of that variable up to that sim time.


    That is true.
    log -r /*
    covers the uut and testbench port only.
    I have to log the process of interest to see the variables.

    For your example I would have to say:
    log /test_uart/dut/main/*
    to cover the variables then
    add wave test_uart/dut/main/*
    to see the history.

    I actually just add all the waves in a do file like this
    http://home.comcast.net/~mike_treseler/uart.do
    any time I run a sim.

    -- Mike Treseler
     
    Mike Treseler, Nov 14, 2007
    #20
    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. Hal Fulton

    Time#succ ?

    Hal Fulton, Nov 23, 2003, in forum: Ruby
    Replies:
    7
    Views:
    129
    Niklas Frykholm
    Nov 28, 2003
  2. illocutionist
    Replies:
    3
    Views:
    137
    Mauricio Fernández
    Mar 6, 2004
  3. Jeff Mitchell

    Propose Range.new(..., &succ)

    Jeff Mitchell, Apr 24, 2004, in forum: Ruby
    Replies:
    2
    Views:
    107
    Tim Sutherland
    Apr 26, 2004
  4. trans.  (T. Onoma)

    reverse #succ ?

    trans. (T. Onoma), Oct 27, 2004, in forum: Ruby
    Replies:
    8
    Views:
    353
    illocutionist
    Nov 10, 2004
  5. paul
    Replies:
    10
    Views:
    203
    Tom Werner
    Nov 10, 2006
Loading...

Share This Page