INTEGER CONSTANT Question

Discussion in 'VHDL' started by Analog_Guy, Aug 28, 2006.

  1. Analog_Guy

    Analog_Guy Guest

    Here's a two part question:

    Q#1:
    If a CONSTANT is defined of type INTEGER (i.e. CONSTANT counter_bits
    : INTEGER := 1;), does a range need to be specified? For synthesis, it
    is generally good practice to constrain INTEGERs. However, I can see
    that this makes sense for VARIABLES and SIGNALS, but does it also apply
    to CONSTANTS?

    Q#2:
    Is it acceptable coding style to define a STD_LOGIC_VECTOR counter load
    as an INTEGER CONSTANT (where conversion functions need to be called
    when the counter is loaded), or can this lead to any synthesis issues?

    CONSTANT counter_bits : INTEGER := 6;
    CONSTANT counter_load : INTEGER := 59;
    SIGNAL counter : STD_LOGIC_VECTOR(counter_bits - 1 DOWNTO 0);

    strobe: PROCESS (reset_n, CLOCK)
    BEGIN
    IF (reset_n = '0') THEN
    counter <= CONV_STD_LOGIC_VECTOR(counter_load, counter_bits);
    ELSIF (CLOCK = '1' AND CLOCK'EVENT) THEN
    IF (counter /= 0) THEN
    counter <= counter - '1';
    ELSE
    counter <= CONV_STD_LOGIC_VECTOR(counter_load, counter_bits);
    END IF;
    END IF;
    END PROCESS strobe;
    Analog_Guy, Aug 28, 2006
    #1
    1. Advertising

  2. On 28 Aug 2006 14:02:17 -0700, "Analog_Guy"
    <> wrote:

    >Here's a two part question:
    >
    >Q#1:
    >If a CONSTANT is defined of type INTEGER (i.e. CONSTANT counter_bits
    >: INTEGER := 1;), does a range need to be specified? For synthesis, it
    >is generally good practice to constrain INTEGERs. However, I can see
    >that this makes sense for VARIABLES and SIGNALS, but does it also apply
    >to CONSTANTS?


    It depends on what you do with the constant. If the constant
    appears in a data path, you may (note *may*) end up with a 32-bit
    data path that you didn't want. Typical examples here might be the
    use of constants as the coefficients in a digital filter.
    Providing a suitable range on the integer constant will tell the
    synthesis tool how many bits to use for it. The best way to
    do this is to define a subtype:

    subtype UNSIGNED_10_BIT is integer range 0 to 1023;

    and then you can use that new subtype for your constants:

    constant Coeff_1 : UNSIGNED_10_BIT := 55;


    By contrast, if the constant is used only to determine some
    parameter of the design or part of it - for example, it's used
    to set the size of a vector, or a subscript - then it doesn't appear
    in the physical data path, but is used only to determine what
    signals are used in any given situation. In that case, plain integers
    are just fine.


    >Q#2:
    >Is it acceptable coding style to define a STD_LOGIC_VECTOR counter load
    >as an INTEGER CONSTANT (where conversion functions need to be called
    >when the counter is loaded), or can this lead to any synthesis issues?

    [snip example]

    I can't see any problem with this, except for the obvious one that the
    code is ugly; all the usual vector<->integer conversions simply map on
    to a bunch of wires in synthesis. I'd be tempted, though, to make
    the datapath constant a vector:

    >CONSTANT counter_bits : INTEGER := 6;
    >CONSTANT counter_load : INTEGER := 59;


    CONSTANT counter_load_vec: std_logic_vector :=
    conv_std_logic_vector(counter_load, counter_bits);

    and now you can use "counter_load_vec" directly in your code,
    without needing to place multiple calls to the conversion function.

    By the way, please consider using the numeric_std package instead
    of the clunky and poorly-standardised STD_LOGIC_UNSIGNED
    and its various obsolescent friends. Plenty of discussion on that
    in the recent past on this group.
    --
    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, Aug 29, 2006
    #2
    1. Advertising

  3. Analog_Guy

    Analog_Guy Guest

    Thank you very much for your responses.


    Jonathan Bromley wrote:
    > It depends on what you do with the constant. If the constant
    > appears in a data path, you may (note *may*) end up with a 32-bit
    > data path that you didn't want. Typical examples here might be the
    > use of constants as the coefficients in a digital filter.
    > Providing a suitable range on the integer constant will tell the
    > synthesis tool how many bits to use for it. The best way to
    > do this is to define a subtype:
    >
    > subtype UNSIGNED_10_BIT is integer range 0 to 1023;
    >
    > and then you can use that new subtype for your constants:
    >
    > constant Coeff_1 : UNSIGNED_10_BIT := 55;
    >
    >

    In this case, I would still have to set the range based on the number
    of bits of my counter. Is there any difference in using the following?
    CONSTANT counter_load : INTEGER RANGE 58 TO 60 := 59;


    >I'd be tempted, though, to make the datapath constant a vector:
    >
    > CONSTANT counter_load_vec: std_logic_vector :=
    > conv_std_logic_vector(counter_load, counter_bits);
    >
    > and now you can use "counter_load_vec" directly in your code,
    > without needing to place multiple calls to the conversion function.
    >

    That's actually a lot cleaner ... thanks!
    Analog_Guy, Aug 29, 2006
    #3
  4. On 29 Aug 2006 08:45:25 -0700, "Analog_Guy"
    <> wrote:

    > CONSTANT counter_load : INTEGER RANGE 58 TO 60 := 59;


    I think you'll find most tools would give you a 6-bit (0 to 63)
    constant here, even though the integer range needs only
    two bits to describe it completely.
    --
    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, Aug 30, 2006
    #4
  5. Analog_Guy

    Andy Guest

    Most synthesis tools create storage for the largest number in the range
    (for non-negative ranges). For signed integer subtypes, they assume
    the number of bits necessary to store 2x the largest of the absolute
    values of the ranges.

    However, I believe Jonathan is mistaken when it comes to constant
    subtypes' effect on bit widths in synthesis.

    Sub-range bit widths are enforced only upon storage, not during
    operations. Since a constant never "stores" anything in the hardware
    context (it is never written to), its range is irrelevant, only its
    value is important.

    For example, the following code works very well for natural subtypes:

    process (clk)
    variable count : natural range 0 to 12;
    begin
    if rising_edge(clk) then
    if count - 1 < 0 then
    count := 12;
    rollover <= true;
    else
    count := count - 1;
    rollover <= false;
    end if;
    end if;
    end process;

    Even though count cannot contain a negative number, the subtraction
    operation returns a 32 bit signed number, and it can be tested for less
    than zero.

    Note that the synthesis tool automatically optimizes out bits that are
    not stored or otherwise used. It only stores 4 bits, but uses a 5th
    (combinatorially, not registered) for the borrow out, used to control
    the reload mux on the counter. Actually, Synplify only creates a mux
    for the bits that would not roll over to that value anyway, i.e. those
    bits that are not one in the load value.

    The above example will not work for vector based arithmetic! The
    subtraction operator for unsigned and natural returns an unsigned type,
    which by definition is never less than zero. The synthesizer dutifully
    recognnizes that, and optimizes out the load completely, which is
    probably not what you wanted, but exactly what you said!

    That is not to say that ranges on constants aren't sometimes
    beneficial. They remind me of the possible range of values that can be
    used for that constant, especially if the constant is declared in a
    package, away from where it is used.

    Andy


    Jonathan Bromley wrote:
    > On 29 Aug 2006 08:45:25 -0700, "Analog_Guy"
    > <> wrote:
    >
    > > CONSTANT counter_load : INTEGER RANGE 58 TO 60 := 59;

    >
    > I think you'll find most tools would give you a 6-bit (0 to 63)
    > constant here, even though the integer range needs only
    > two bits to describe it completely.
    > --
    > 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.
    Andy, Aug 30, 2006
    #5
  6. On 30 Aug 2006 11:27:33 -0700, "Andy"
    <> wrote:

    >However, I believe Jonathan is mistaken when it comes to constant
    >subtypes' effect on bit widths in synthesis.
    >
    >Sub-range bit widths are enforced only upon storage, not during
    >operations. Since a constant never "stores" anything in the hardware
    >context (it is never written to), its range is irrelevant, only its
    >value is important.


    On reflection, I'm pretty much convinced that you're right.
    Thanks for the correction.

    As you say, it's the value of the constant that determines how
    it's implemented if it happens to appear in the datapath.

    Nevertheless I would tend to use integer range subtypes in
    situations where they are meaningful. It protects me against
    certain kinds of stupidity. For example, if I wanted to use
    Xilinx embedded multipliers to multiply by an arbitrary
    constant, it would be a good idea to declare that
    constant to have a subtype of "-(2**17) to 2**17-1"
    so that the compiler would complain if I tried to use
    a constant that was bigger than signed 18-bit - as you
    mentioned at the end of your post.

    Thanks again, and apologies if I misled anyone
    --
    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, Sep 1, 2006
    #6
    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. Christopher M. Lusardi
    Replies:
    1
    Views:
    4,086
  2. Martin Magnusson
    Replies:
    2
    Views:
    503
    John Harrison
    Oct 8, 2004
  3. Tor Erik Soenvisen
    Replies:
    14
    Views:
    559
    Tim Roberts
    Nov 23, 2006
  4. Replies:
    4
    Views:
    338
    Keith Thompson
    Dec 14, 2006
  5. Replies:
    13
    Views:
    12,923
    Kai-Uwe Bux
    Jan 22, 2007
Loading...

Share This Page