Variable vs. Signal on indexing

Discussion in 'VHDL' started by ALuPin@web.de, Jan 16, 2007.

  1. Guest

    Hi newsgroup,

    I have the two following approaches in combinational processes:

    SIGNAL ls_idx : integer RANGE 0 TO 127;
    SIGNAL ls_wlist_copy_cache_q : std_logic_vector(63 DOWNTO 0);
    SIGNAL ls_rlist_cache_q : std_logic_vector(63 DOWNTO 0);
    SIGNAL ls_ba_checked_wlistc, ls_ba_checked_rlist : std_logic_vector(1
    DOWNTO 0);
    SIGNAL ls_pos_col_in_cache : std_logic_vector(5 DOWNTO 0);

    1. approach:

    CHECKCACHES_comb: PROCESS(ls_check_w_wc_r_list, ls_pos_col_in_cache,
    ls_wlist_copy_cache_q,
    ls_rlist_cache_q, ls_idx)
    VARIABLE idx : integer RANGE 0 TO 127;
    BEGIN
    ls_ba_checked_wlistc <= "00";
    ls_ba_checked_rlist <= "00";

    IF ls_check_w_wc_r_list='1' THEN
    idx := 2 * to_integer(unsigned(ls_pos_col_in_cache)) - 1;

    ls_ba_checked_wlistc <= ls_wlist_copy_cache_q(idx DOWNTO idx-1);
    ls_ba_checked_rlist <= ls_rlist_cache_q(idx DOWNTO idx-1);
    ls_idx <= idx;

    END IF;
    END PROCESS CHECKCACHES_comb;

    2. approach:

    CHECKCACHES_comb: PROCESS(ls_check_w_wc_r_list, ls_pos_col_in_cache,
    ls_wlist_copy_cache_q,
    ls_rlist_cache_q, ls_idx)
    BEGIN
    ls_ba_checked_wlistc <= "00";
    ls_ba_checked_rlist <= "00";
    ls_idx <= 0;

    IF ls_check_w_wc_r_list='1' THEN
    ls_idx <= 2 * to_integer(unsigned(ls_pos_col_in_cache)) - 1;

    ls_ba_checked_wlistc <= ls_wlist_copy_cache_q(ls_idx DOWNTO
    ls_idx-1);
    ls_ba_checked_rlist <= ls_rlist_cache_q(ls_idx DOWNTO ls_idx-1);


    END IF;
    END PROCESS CHECKCACHES_comb;

    When using the second approach I get the following fatal error when
    performing functional simulation
    (with ModelsimDesigner 6.1f):


    # ** Fatal: (vsim-3471) Slice range (0 downto -1) does not belong to
    the prefix index range (63 downto 0).


    Note that the signal "ls_pos_col_in_cache" NEVER gets "000000" when
    "ls_check_w_wc_r_list"
    is active.
    So where is the difference in both descriptions causing Modelsim to
    complain ?

    Is it a simulation problem or will the indexing cause problems during
    synthesis ?

    Thank you for your opinion.

    Rgds
    Andre
     
    , Jan 16, 2007
    #1
    1. Advertising

  2. Jim Lewis Guest

    wrote:
    Variables get updated immediately so the process sees the new value.
    Signals get updated at the beginning of the next delta cycle,
    and hence it has a previous value on it. The previous value
    at start-up is 0, the left-most value of the constrained type
    (since you range it to be 0 t0 127).

    Cheers,
    Jim

    > Hi newsgroup,
    >
    > I have the two following approaches in combinational processes:
    >
    > SIGNAL ls_idx : integer RANGE 0 TO 127;
    > SIGNAL ls_wlist_copy_cache_q : std_logic_vector(63 DOWNTO 0);
    > SIGNAL ls_rlist_cache_q : std_logic_vector(63 DOWNTO 0);
    > SIGNAL ls_ba_checked_wlistc, ls_ba_checked_rlist : std_logic_vector(1
    > DOWNTO 0);
    > SIGNAL ls_pos_col_in_cache : std_logic_vector(5 DOWNTO 0);
    >
    > 1. approach:
    >
    > CHECKCACHES_comb: PROCESS(ls_check_w_wc_r_list, ls_pos_col_in_cache,
    > ls_wlist_copy_cache_q,
    > ls_rlist_cache_q, ls_idx)
    > VARIABLE idx : integer RANGE 0 TO 127;
    > BEGIN
    > ls_ba_checked_wlistc <= "00";
    > ls_ba_checked_rlist <= "00";
    >
    > IF ls_check_w_wc_r_list='1' THEN
    > idx := 2 * to_integer(unsigned(ls_pos_col_in_cache)) - 1;
    >
    > ls_ba_checked_wlistc <= ls_wlist_copy_cache_q(idx DOWNTO idx-1);
    > ls_ba_checked_rlist <= ls_rlist_cache_q(idx DOWNTO idx-1);
    > ls_idx <= idx;
    >
    > END IF;
    > END PROCESS CHECKCACHES_comb;
    >
    > 2. approach:
    >
    > CHECKCACHES_comb: PROCESS(ls_check_w_wc_r_list, ls_pos_col_in_cache,
    > ls_wlist_copy_cache_q,
    > ls_rlist_cache_q, ls_idx)
    > BEGIN
    > ls_ba_checked_wlistc <= "00";
    > ls_ba_checked_rlist <= "00";
    > ls_idx <= 0;
    >
    > IF ls_check_w_wc_r_list='1' THEN
    > ls_idx <= 2 * to_integer(unsigned(ls_pos_col_in_cache)) - 1;
    >
    > ls_ba_checked_wlistc <= ls_wlist_copy_cache_q(ls_idx DOWNTO
    > ls_idx-1);
    > ls_ba_checked_rlist <= ls_rlist_cache_q(ls_idx DOWNTO ls_idx-1);
    >
    >
    > END IF;
    > END PROCESS CHECKCACHES_comb;
    >
    > When using the second approach I get the following fatal error when
    > performing functional simulation
    > (with ModelsimDesigner 6.1f):
    >
    >
    > # ** Fatal: (vsim-3471) Slice range (0 downto -1) does not belong to
    > the prefix index range (63 downto 0).
    >
    >
    > Note that the signal "ls_pos_col_in_cache" NEVER gets "000000" when
    > "ls_check_w_wc_r_list"
    > is active.
    > So where is the difference in both descriptions causing Modelsim to
    > complain ?
    >
    > Is it a simulation problem or will the indexing cause problems during
    > synthesis ?
    >
    > Thank you for your opinion.
    >
    > Rgds
    > Andre
    >
     
    Jim Lewis, Jan 16, 2007
    #2
    1. Advertising

  3. Guest

    Hi Jim,
    thank you for your response:

    Yes, it is clear now for simulation.

    But what about synthesis ? When using variables as shown in the first
    approach, do I have to define the ELSE condition for the variable ?

    CHECKCACHES_comb: PROCESS(ls_check_w_wc_r_list, ls_pos_col_in_cache,
    ls_wlist_copy_cache_q,
    ls_rlist_cache_q, ls_idx)
    VARIABLE idx : integer RANGE 0 TO 127;
    BEGIN
    ls_ba_checked_wlistc <= "00";
    ls_ba_checked_rlist <= "00";
    idx := 0; -- ??? necessary


    IF ls_check_w_wc_r_list='1' THEN
    idx := 2 * to_integer(unsigned(ls_pos_col_in_cache)) - 1;


    ls_ba_checked_wlistc <= ls_wlist_copy_cache_q(idx DOWNTO idx-1);
    ls_ba_checked_rlist <= ls_rlist_cache_q(idx DOWNTO idx-1);
    ls_idx <= idx;

    END IF;
    END PROCESS CHECKCACHES_comb;

    Rgds
    Andre
     
    , Jan 16, 2007
    #3
  4. wrote:

    > Yes, it is clear now for simulation.
    > But what about synthesis ?


    If the design simulates ok,
    synthesis should be a detail.

    The design process is that same
    with or without variables.

    With reasonable code design rules, the
    simulation waveforms at the ports
    matches what I see on the bench.

    -- Mike Treseler
     
    Mike Treseler, Jan 16, 2007
    #4
  5. Jim Lewis Guest

    Mike Treseler wrote:
    > If the design simulates ok,
    > synthesis should be a detail.
    >
    > The design process is that same
    > with or without variables.

    I agree. The functionality will be correct,
    however sometimes with variables the synthesis
    tool will be a little generous with registers.
    For example if a variable is read before it is
    written, it may create a register even when
    that register is redundant. In the process below
    sometimes VAR will create a register eventhough
    that register has the same inputs as the Count
    register:

    VarProc : Process
    begin
    wait until Clk = '1' ;
    VAR := VAR + 1 ;
    Count <= VAR ;
    end process ;


    > But what about synthesis ? When using variables as shown in the first
    > approach, do I have to define the ELSE condition for the variable ?
    >
    > CHECKCACHES_comb: PROCESS(ls_check_w_wc_r_list, ls_pos_col_in_cache,
    > ls_wlist_copy_cache_q,
    > ls_rlist_cache_q, ls_idx)
    > VARIABLE idx : integer RANGE 0 TO 127;
    > BEGIN
    > ls_ba_checked_wlistc <= "00";
    > ls_ba_checked_rlist <= "00";
    > idx := 0; -- ??? necessary
    >
    >
    > IF ls_check_w_wc_r_list='1' THEN
    > idx := 2 * to_integer(unsigned(ls_pos_col_in_cache)) - 1;
    >
    >
    > ls_ba_checked_wlistc <= ls_wlist_copy_cache_q(idx DOWNTO idx-1);
    > ls_ba_checked_rlist <= ls_rlist_cache_q(idx DOWNTO idx-1);
    > ls_idx <= idx;
    >
    > END IF;
    > END PROCESS CHECKCACHES_comb;


    Good question. First this process does create latches for
    ls_ba_checked_wlistc, ls_ba_checked_rlist, and ls_idx.
    If it did create a latch for idx, that latch would be redundant
    with the latch for ls_idx.

    Without an assignment outside of the if condition, it is possible
    that it would create a latch for idx - not very logical though,
    but remember synthesis tools are algorithmic - not logical.

    I would not assign idx to 0 outside the if statement as that
    would imply a multiplexer for idx. Instead if I were worried,
    I would move the assignment to idx outside of the if statement.

    Cheers,
    Jim Lewis
    SynthWorks
     
    Jim Lewis, Jan 16, 2007
    #5
  6. Jim Lewis wrote:

    > For example if a variable is read before it is
    > written, it may create a register even when
    > that register is redundant.


    The implication is that using variables
    wastes flops, and this simply is not true.

    If the register is not intended,
    that is a design error like any
    other that would be picked up and corrected
    during the edit-sim-edit cycle.
    Is the wave correct or is it delayed by a tick?

    The simulation results are what matters.
    Synthesis tools are very efficient with
    signals or variables.

    > In the process below
    > sometimes VAR will create a register even though
    > that register has the same inputs as the Count
    > register:
    >
    > VarProc : Process
    > begin
    > wait until Clk = '1' ;
    > VAR := VAR + 1 ;
    > Count <= VAR ;
    > end process ;


    The error here is that the port
    assignment is inside a clocked clause.
    This infers an output pipeline register.

    If I put the port assignment
    outside of the clocked clause,
    no pipeline register is inferred.

    clked : process(clk)
    variable cnt_v : count_t;
    begin
    if rising_edge(clk) then
    cnt_v := cnt_v + 1; -- increment on rising edge
    end if;
    cnt <= cnt_v; -- wire assignment outside of clocked clause
    end process clked;

    see synthesis results here:
    http://home.comcast.net/~mike_treseler/rollover.pdf

    see full design here:
    http://home.comcast.net/~mike_treseler/rollover.vhd


    -- Mike Treseler
     
    Mike Treseler, Jan 16, 2007
    #6
  7. Andy Guest

    Synplicity has always done a good job of optimizing out redundant
    flops, so long as they really are redundant (i.e. both have same async
    reset, etc.)!

    I've found Mike's method of making the port/signal assignment
    outside/after the clock clause to be more efficient, since it avoids
    creating the redundant flop in the first place. Inside the clock clause
    creates a count register with the combinatorial var as input, outside
    the clock clause creates a combinatorial count signal from the
    registered var. Sixes either way.

    Interestingly, when I ran a test with two functionally (on a
    clock-clock basis) identical output signals (one inside, one outside
    the clock clause), synplicity did figure out that they were both
    identical, and optimized one out. This was even when the LHS was an
    expression of variables, as in:

    if rising_edge(clk) then
    vara := vara + 1;
    varb := varb + 1;
    siga <= vara + varb; -- register of combo values for a,b
    end if; -- rising_edge
    sigb <= vara + varb; -- combo of registered values for a,b

    Andy


    Mike Treseler wrote:
    > Jim Lewis wrote:
    >
    > > For example if a variable is read before it is
    > > written, it may create a register even when
    > > that register is redundant.

    >
    > The implication is that using variables
    > wastes flops, and this simply is not true.
    >
    > If the register is not intended,
    > that is a design error like any
    > other that would be picked up and corrected
    > during the edit-sim-edit cycle.
    > Is the wave correct or is it delayed by a tick?
    >
    > The simulation results are what matters.
    > Synthesis tools are very efficient with
    > signals or variables.
    >
    > > In the process below
    > > sometimes VAR will create a register even though
    > > that register has the same inputs as the Count
    > > register:
    > >
    > > VarProc : Process
    > > begin
    > > wait until Clk = '1' ;
    > > VAR := VAR + 1 ;
    > > Count <= VAR ;
    > > end process ;

    >
    > The error here is that the port
    > assignment is inside a clocked clause.
    > This infers an output pipeline register.
    >
    > If I put the port assignment
    > outside of the clocked clause,
    > no pipeline register is inferred.
    >
    > clked : process(clk)
    > variable cnt_v : count_t;
    > begin
    > if rising_edge(clk) then
    > cnt_v := cnt_v + 1; -- increment on rising edge
    > end if;
    > cnt <= cnt_v; -- wire assignment outside of clocked clause
    > end process clked;
    >
    > see synthesis results here:
    > http://home.comcast.net/~mike_treseler/rollover.pdf
    >
    > see full design here:
    > http://home.comcast.net/~mike_treseler/rollover.vhd
    >
    >
    > -- Mike Treseler
     
    Andy, Jan 16, 2007
    #7
  8. Jim Lewis Guest

    Mike,
    >> For example if a variable is read before it is
    >> written, it may create a register even when
    >> that register is redundant.

    >
    > The implication is that using variables
    > wastes flops, and this simply is not true.

    Touchy are we :)

    It only takes one counter case to prove this
    statement wrong and I just showed you one.

    > If the register is not intended,
    > that is a design error like any
    > other that would be picked up and corrected
    > during the edit-sim-edit cycle.
    > Is the wave correct or is it delayed by a tick?


    The wave is correct - only one register in simulation.
    Gate and RTL simulation match, yet the synthesis results
    have 2 registers. If you look at the synthesis
    results, you will see that both registers (VAR and Count)
    have the same input - hence the tool did waste registers.

    > The simulation results are what matters.
    > Synthesis tools are very efficient with
    > signals or variables.


    With respect to registers, some synthesis tools
    seem to be more generous producing registers than
    others.

    >> In the process below
    >> sometimes VAR will create a register even though
    >> that register has the same inputs as the Count
    >> register:
    >>
    >> VarProc : Process
    >> begin
    >> wait until Clk = '1' ;
    >> VAR := VAR + 1 ;
    >> Count <= VAR ;
    >> end process ;

    >
    > The error here is that the port
    > assignment is inside a clocked clause.
    > This infers an output pipeline register.


    Nope. No extra pipeline delay.
    BTW, this code is 1076.6-1999 and 1076.6-2004
    compliant. As are results that produce either
    one or two registers (the standard is about producing
    results and not optimization).

    > If I put the port assignment
    > outside of the clocked clause,
    > no pipeline register is inferred.
    >
    > clked : process(clk)
    > variable cnt_v : count_t;
    > begin
    > if rising_edge(clk) then
    > cnt_v := cnt_v + 1; -- increment on rising edge
    > end if;
    > cnt <= cnt_v; -- wire assignment outside of clocked clause
    > end process clked;
    >


    The fact that you can fix the code is not the point.
    The point is there is some code (not good code) that
    looks fine, but will produce area inefficient results.

    Also although you got results, is your code style portable?
    In particular, does it work on Synopsys? I know they
    did not support it in the past. Also it is not 1076.6-1999
    compliant, it may not be 1076.6-2004 compliant either
    (it certainly was not intended to be).

    Cheers,
    Jim

    OTOH, so what if variables are inefficient with respect to
    registers? Would you notice? Not unless you did not
    fit in the chip.
     
    Jim Lewis, Jan 16, 2007
    #8
  9. Andy wrote:
    > Synplicity has always done a good job of optimizing out redundant
    > flops, so long as they really are redundant (i.e. both have same async
    > reset, etc.)!


    Quartus and ISE also take out the duplicate flops, post-fit.
    However they can show up in the pre-fit RTL view.

    > I've found Mike's method of making the port/signal assignment
    > outside/after the clock clause to be more efficient, since it avoids
    > creating the redundant flop in the first place.


    This also gives me a clean RTL schematic
    without running a full synthesis.

    -- Mike Treseler
     
    Mike Treseler, Jan 17, 2007
    #9
  10. Jim Lewis wrote:

    > It only takes one counter case to prove this
    > statement wrong and I just showed you one.


    The duplicate flops only show up in the RTL view,
    not in the tech view. The removal is also
    noted in the log file.

    > The wave is correct - only one register in simulation.
    > Gate and RTL simulation match, yet the synthesis results
    > have 2 registers. If you look at the synthesis
    > results, you will see that both registers (VAR and Count)
    > have the same input - hence the tool did waste registers.


    Yes, sorry, it is a duplication,
    not a pipe at the RTL level.
    But synthesis removes it, post-fit.

    > With respect to registers, some synthesis tools
    > seem to be more generous producing registers than
    > others.
    > The fact that you can fix the code is not the point.
    > The point is there is some code (not good code) that
    > looks fine, but will produce area inefficient results.


    Hmmm. Synplicity, Quartus and ISE get it right,
    even for the "not good code".
    What synthesis should I use to duplicate
    these inefficient results?

    > Also although you got results, is your code style portable?
    > In particular, does it work on Synopsys? I know they
    > did not support it in the past. Also it is not 1076.6-1999
    > compliant, it may not be 1076.6-2004 compliant either
    > (it certainly was not intended to be).


    I have one email reporting that my reference design produces
    an error on an unspecified version of Synopsys, but it involves my use
    of procedures, not variables. But without the use
    of a license it is impossible for me to narrow it down,
    and I have no interest in buying one.
    Other than that, the style is portable, as far as I know.

    > OTOH, so what if variables are inefficient with respect to
    > registers? Would you notice? Not unless you did not
    > fit in the chip.


    I'm sure I wouldn't notice even if it were true.
    But it isn't true for any of the tools that I use,
    and I cringe when new users are frightened away
    from perfectly useful synthesis concepts like
    variable assignments.

    -- Mike Treseler
     
    Mike Treseler, Jan 17, 2007
    #10
  11. Jim Lewis Guest

    Mike
    > The duplicate flops only show up in the RTL view,
    > not in the tech view. The removal is also
    > noted in the log file.

    Good to hear.


    > I have one email reporting that my reference design produces
    > an error on an unspecified version of Synopsys, but it involves my use
    > of procedures, not variables. But without the use
    > of a license it is impossible for me to narrow it down,
    > and I have no interest in buying one.
    > Other than that, the style is portable, as far as I know.


    ???
    I would definitely need to see it working under
    Synopsys before I would claim any portability.
    I know for a fact that old versions did not
    support this.

    > I'm sure I wouldn't notice even if it were true.
    > But it isn't true for any of the tools that I use,
    > and I cringe when new users are frightened away
    > from perfectly useful synthesis concepts like
    > variable assignments.


    This is where our opinion differs.
    There are enough issues with design, verification,
    and HDL coding that new users must deal with and
    master. As a result, I don't think a new user
    needs to bother with variables in an RTL design.

    OTOH, as one grows in experience, I don't see any
    reason not to start to use variables.

    Cheers,
    Jim
     
    Jim Lewis, Jan 17, 2007
    #11
  12. > Mike wrote:
    >> I have one email reporting that my reference design produces
    >> an error on an unspecified version of Synopsys, but it involves my use
    >> of procedures, not variables. But without the use
    >> of a license it is impossible for me to narrow it down,
    >> and I have no interest in buying one.
    >> Other than that, the style is portable, as far as I know.


    Jim Lewis wrote:

    > I would definitely need to see it working under
    > Synopsys before I would claim any portability.


    I made no such claim.
    In fact I have always disclaimed Synopsys
    on my web page like this:

    "Examples have been used successfully on Quartus, ISE, Leonardo,
    Synplify, Modelsim, and NC-Sim. Examples are not compatible with
    Synopsys tools. Reports for other tools are appreciated."

    > I know for a fact that old versions did not
    > support this.


    Thanks for the report.

    > This is where our opinion differs.
    > There are enough issues with design, verification,
    > and HDL coding that new users must deal with and
    > master. As a result, I don't think a new user
    > needs to bother with variables in an RTL design.


    I will agree that we disagree.

    -- Mike Treseler
     
    Mike Treseler, Jan 18, 2007
    #12
  13. Guest

    Hi Mike, hi Jim,

    thank you for your opinions. I think in my case it does make sense
    to use variables because if I use the second approach (which is fine
    for synthesis) I will always get that fatal error when simulating. So
    it is somehow
    paradox that a construct can be synthesized but not simulated, my
    experience
    always shows the other way around.

    Rgds
    Andre
     
    , Jan 18, 2007
    #13
  14. Guest

    I have to correct myself:

    When using approach one, and defining the else tree for the variable
    assignment, the synthesis tool (Synplicity) gives out the
    warning that a combinational loop has been found.
    I cannot understand that, all cases are defined.

    Rgds
    Andres
     
    , Jan 18, 2007
    #14
  15. jandecaluwe Guest

    Jim Lewis wrote:

    > There are enough issues with design, verification,
    > and HDL coding that new users must deal with and
    > master. As a result, I don't think a new user
    > needs to bother with variables in an RTL design.



    Certainly a widely held opinion, but that doesn't make it
    logical as I hope to show with the following two arguments.

    First, for essential skills such as verification, you need to
    learn about variables. You'll need them immediately, for
    example to write a for loop or a function. At the same time,
    we know that variables are useful and work fine with RTL
    design also. So why should we prevent users from using them
    in RTL design, while they'll need them for verification
    anyway? That seems arbitrary and artificial. Surely it
    complicates matters more than it simplifies them.

    Secondly, consider trying to explain variable versus signal
    semantics to a junior software engineer. What will be the most
    difficult? Obviously, variables are the easy stuff. In contrast,
    signals are complex objects with pretty complicated semantics,
    requiring a considerable amount of learning. Still, many
    hardware designers have a tendency to label signals as
    "basic" and variables as "advanced". It should really be the
    other way around. Odd, isn'it?

    Jan

    --
    Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com
    Losbergenlaan 16, B-3010 Leuven, Belgium
    From Python to silicon:
    http://myhdl.jandecaluwe.com
     
    jandecaluwe, Jan 18, 2007
    #15
  16. On 18 Jan 2007 07:47:25 -0800, "jandecaluwe"
    <> wrote:

    >hardware designers have a tendency to label signals as
    >"basic" and variables as "advanced". It should really be the
    >other way around. Odd, isn'it?


    Yes; but then, many things about simulation and synthesis
    are odd.

    For example: it's odd that, in a discrete-event simulator,
    all the simulator's time is spent processing activity that
    occurs in zero simulated time; the passage of simulated
    time costs the simulator essentially nothing (merely
    replacing the current value of NOW with the value
    at which the next event occurs).

    Given the usual RTL paradigm, the relationship between
    VHDL signals and the hardware they represent can be
    explained rather easily. The relationship between VHDL
    variables and the hardware they represent (or don't!)
    is much subtler.

    It's difficult to get hardware folk to think in terms of
    functionality, when they (quite properly) need to
    spend much of their working lives worrying about
    structure and timing.

    I have huge sympathy for the position held by Mike
    Treseler and others - that you should use variables
    in fairly complicated synchronous processes to describe
    the functionality you want, and let the synthesis tool
    fuss about the structure - but that position works
    only for people who have enough insight to be able
    to envisage what hardware structures they're describing,
    without actually laying-out the gates and flops. For
    beginners, and traditional paper-and-pencil designers,
    it's tough.
    --
    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, Jan 18, 2007
    #16
  17. Jim Lewis Guest

    Jan,
    >> There are enough issues with design, verification,
    >> and HDL coding that new users must deal with and
    >> master. As a result, I don't think a new user
    >> needs to bother with variables in an RTL design.

    >
    >
    > Certainly a widely held opinion, but that doesn't make it
    > logical as I hope to show with the following two arguments.
    >
    > First, for essential skills such as verification, you need to
    > learn about variables. You'll need them immediately, for
    > example to write a for loop or a function. At the same time,
    > we know that variables are useful and work fine with RTL
    > design also. So why should we prevent users from using them
    > in RTL design, while they'll need them for verification
    > anyway? That seems arbitrary and artificial. Surely it
    > complicates matters more than it simplifies them.


    Note I state my guideline as a "recommendation" and not a rule.

    Recommendation:
    Avoid using variables for RTL design on your first couple of projects.

    This way those who already have FPGA design skills or are
    sharp would feel free to violate it.

    > Secondly, consider trying to explain variable versus signal
    > semantics to a junior software engineer. What will be the most
    > difficult? Obviously, variables are the easy stuff. In contrast,
    > signals are complex objects with pretty complicated semantics,
    > requiring a considerable amount of learning. Still, many
    > hardware designers have a tendency to label signals as
    > "basic" and variables as "advanced". It should really be the
    > other way around. Odd, isn'it?


    To some degree, I agree. Especially for verification.
    Here are my notes for RTL creation:

    RTL behavior in a clocked process:
    Signal assignment: Always implies* a register
    Variable assignment:
    Implies a register if variable read before written.
    Alternately implies a register if variable has a life time.
    Implies combinational logic when always written before read.

    *Registers are created for all implied registers unless there
    is a redundancy that can be merged with another register.


    RTL behavior in a combinational process:
    Signal assignment:
    Must get a value for every hardware execution of the
    process or it will create a latch.
    Recommendation: do not read a value that is written in the same
    process, otherwise, signal must be on sensitivity list and process
    must iterate.

    Variable assignment:
    Implies combinational logic when always written before read.
    If read before written then error
    Must get a value for every hardware execution of the
    process or it will create a latch.

    For design creation there are alot of details that must
    be managed. As you pare this down to RTL creation,
    you must master signals, but for most applications you
    don't need to use variables - hence you
    don't need to learn the additional hardware implications.

    Cheers,
    Jim
     
    Jim Lewis, Jan 18, 2007
    #17
  18. Jonathan Bromley wrote:

    > ... that position works
    > only for people who have enough insight to be able
    > to envisage what hardware structures they're describing,
    > without actually laying-out the gates and flops. For
    > beginners, and traditional paper-and-pencil designers,
    > it's tough.


    There are two tracks I use when an intern
    or engineer new to FPGA design asks for
    help getting started.

    1. For the circuit board designer with no
    software or simulation experience, the starting
    point is simple design examples and an RTL viewer.
    This shows the connection between
    source code view and the gates'n'flops. Simple
    designs can be validated on the bench with
    trial-and-error synthesis.
    Simulation of the validated code is a long final chapter.

    2. For the computer engineer, simulation is
    a more natural starting point. Here the connection
    to make is between source code and functional waveforms.
    I start with code template examples, testbenches
    and a simulator. Designs can be validated
    using trial-and-error simulation and debugged by tracing code.
    Synthesis of the validated code is the final chapter.

    -- Mike Treseler
     
    Mike Treseler, Jan 18, 2007
    #18
  19. Andy Guest

    When I first started flirting with variables in VHDL synthesis,
    understanding how they mapped to hardware took some time. OTOH, when I
    first started coding VHDL at all, understanding the non-sequential
    nature of signal assignment statements in sequential code took a while
    too. If I had a buck for every time a newbie asked me why their
    signal's value wasn't getting updated when it was clearly assigned
    before being read, I'd be a wealthy man! With variables, a read before
    a write in a clocked process creates a register, period. How hard is
    that? For a

    And don't get me started about stuff that Synopsys does not support in
    VHDL synthesis... ram/rom inferencing, direct entity instantiation
    (sorta, but broken in places), implementation of mod and / in
    numeric_std, and on, and on...! I should qualify the above with the
    fact that I haven't used Synopsys synthesis tools in a few years, but
    everyone else was supporting this stuff when I left them.

    If signal assignments to expressions of variables after the clocked
    clause are not addressed in the "synthesis standard" and yet the
    majority of synthesis tools support it, then they should be addressed,
    lest the standard become hopelessly irrelevant. The most recent update
    to the standard is a step in the right direction, namely away from
    templates and toward synthesis of behavior, but it still has a ways to
    go. I believe this is one place where the demands of the marketplace,
    and thus the feature sets of the tools are outstripping the ability of
    standardization efforts to keep up.

    Also, not the variables themselves, but _references_ to them imply
    storage or not (and thus register or not); the same variable name may
    represent a combinatorial value in one reference, and a register value
    in another. And the difference can even be dynamically controlled (e.g.
    a prior write may be conditional). The point is the synthesis tool will
    use a register or not (or a mux between the two) to implement the coded
    behavior.

    Andy


    Jim Lewis wrote:
    > Jan,
    > >> There are enough issues with design, verification,
    > >> and HDL coding that new users must deal with and
    > >> master. As a result, I don't think a new user
    > >> needs to bother with variables in an RTL design.

    > >
    > >
    > > Certainly a widely held opinion, but that doesn't make it
    > > logical as I hope to show with the following two arguments.
    > >
    > > First, for essential skills such as verification, you need to
    > > learn about variables. You'll need them immediately, for
    > > example to write a for loop or a function. At the same time,
    > > we know that variables are useful and work fine with RTL
    > > design also. So why should we prevent users from using them
    > > in RTL design, while they'll need them for verification
    > > anyway? That seems arbitrary and artificial. Surely it
    > > complicates matters more than it simplifies them.

    >
    > Note I state my guideline as a "recommendation" and not a rule.
    >
    > Recommendation:
    > Avoid using variables for RTL design on your first couple of projects.
    >
    > This way those who already have FPGA design skills or are
    > sharp would feel free to violate it.
    >
    > > Secondly, consider trying to explain variable versus signal
    > > semantics to a junior software engineer. What will be the most
    > > difficult? Obviously, variables are the easy stuff. In contrast,
    > > signals are complex objects with pretty complicated semantics,
    > > requiring a considerable amount of learning. Still, many
    > > hardware designers have a tendency to label signals as
    > > "basic" and variables as "advanced". It should really be the
    > > other way around. Odd, isn'it?

    >
    > To some degree, I agree. Especially for verification.
    > Here are my notes for RTL creation:
    >
    > RTL behavior in a clocked process:
    > Signal assignment: Always implies* a register
    > Variable assignment:
    > Implies a register if variable read before written.
    > Alternately implies a register if variable has a life time.
    > Implies combinational logic when always written before read.
    >
    > *Registers are created for all implied registers unless there
    > is a redundancy that can be merged with another register.
    >
    >
    > RTL behavior in a combinational process:
    > Signal assignment:
    > Must get a value for every hardware execution of the
    > process or it will create a latch.
    > Recommendation: do not read a value that is written in the same
    > process, otherwise, signal must be on sensitivity list and process
    > must iterate.
    >
    > Variable assignment:
    > Implies combinational logic when always written before read.
    > If read before written then error
    > Must get a value for every hardware execution of the
    > process or it will create a latch.
    >
    > For design creation there are alot of details that must
    > be managed. As you pare this down to RTL creation,
    > you must master signals, but for most applications you
    > don't need to use variables - hence you
    > don't need to learn the additional hardware implications.
    >
    > Cheers,
    > Jim
     
    Andy, Jan 19, 2007
    #19
  20. Jim Lewis Guest

    Andy,
    > If signal assignments to expressions of variables after the clocked
    > clause are not addressed in the "synthesis standard" and yet the
    > majority of synthesis tools support it, then they should be addressed,
    > lest the standard become hopelessly irrelevant. The most recent update
    > to the standard is a step in the right direction, namely away from
    > templates and toward synthesis of behavior, but it still has a ways to
    > go. I believe this is one place where the demands of the marketplace,
    > and thus the feature sets of the tools are outstripping the ability of
    > standardization efforts to keep up.


    Sure. You and Mike ready to take it up? These things
    take volunteers. The 2004 revision needs to be re-anlayzed
    with this in mind to see if it is missing or if it is there
    and I missed seeing it. There is also some need for adding
    more attributes and perhaps renaming fsm_complete (particularly
    if no-one has implemented it) to fsm_safe (as that is what it
    does).

    By the way, I am still waiting for vendors to support multiple
    clocked FIFOs and registers. I know that Xilinx at one time
    supported a coding style that uses VHDL-93 shared variables,
    however, as of VHDL-2000/2002, shared variables must be a
    protected type.


    > Also, not the variables themselves, but _references_ to them imply
    > storage or not (and thus register or not); the same variable name may
    > represent a combinatorial value in one reference, and a register value
    > in another.

    Obvious to the quick and the sharp. Subtle to new users
    who are overwhelmed by other pieces of the design and
    design flow.


    > And the difference can even be dynamically controlled (e.g.
    > a prior write may be conditional).

    Exciting :). Sometimes registered, sometimes combo logic.

    Cheers,
    Jim
     
    Jim Lewis, Jan 19, 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. C
    Replies:
    0
    Views:
    526
  2. Michael Pronath
    Replies:
    1
    Views:
    1,236
    Diez B. Roggisch
    Jan 3, 2005
  3. Emin
    Replies:
    4
    Views:
    434
    Paul McGuire
    Jan 12, 2007
  4. Skybuck Flying
    Replies:
    30
    Views:
    1,144
    Bill Reid
    Sep 19, 2011
  5. C
    Replies:
    3
    Views:
    246
    Manohar Kamath [MVP]
    Oct 17, 2003
Loading...

Share This Page