How to make this code generic?

Discussion in 'VHDL' started by Thoma, Nov 20, 2009.

  1. Thoma

    Thoma Guest

    Hi all,

    I am new with possibility of the VHDL "generic" keyword.
    I tried to make the below code generic.

    Do you think this is possible?
    If yes, this would allow me to make a number of my descriptions
    customizable.

    Does anyone have a solution? An example?

    Thank you in advance.

    Thoma

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;

    entity barrelshifter is
    Port ( entrance : in STD_LOGIC_VECTOR (3 downto 0);
    selection : in STD_LOGIC_VECTOR (3 downto 0);
    sortie : out STD_LOGIC_VECTOR (3 downto 0));
    end barrelshifter;

    architecture Behavioral of barrelshifter is

    signal internal : std_logic_vector(6 downto 0);

    begin
    internal <= entrance(2 downto 0) & entrance;
    sortie <= internal(3 downto 0) when (selection(0) = '1') else
    internal(4 downto 1) when (selection(1) = '1') else
    internal(5 downto 2) when (selection(2) = '1') else
    internal(6 downto 3);
    end Behavioral;
    Thoma, Nov 20, 2009
    #1
    1. Advertising

  2. Thoma

    KJ Guest

    On Nov 20, 4:15 pm, Thoma <> wrote:
    > Hi all,
    >
    > I am new with possibility of the VHDL "generic" keyword.
    > I tried to make the below code generic.
    >
    > Do you think this is possible?
    > If yes, this would allow me to make a number of my descriptions
    > customizable.
    >
    > Does anyone have a solution? An example?
    >
    > Thank you in advance.
    >
    > Thoma
    >
    > library IEEE;
    > use IEEE.STD_LOGIC_1164.ALL;
    >
    > entity barrelshifter is
    >     Port ( entrance : in  STD_LOGIC_VECTOR (3 downto 0);
    >            selection : in  STD_LOGIC_VECTOR (3 downto 0);
    >            sortie : out  STD_LOGIC_VECTOR (3 downto 0));
    > end barrelshifter;
    >
    > architecture Behavioral of barrelshifter is
    >
    > signal internal : std_logic_vector(6 downto 0);
    >
    > begin
    >   internal <= entrance(2 downto 0) & entrance;
    >   sortie <= internal(3 downto 0) when (selection(0) = '1') else
    >             internal(4 downto 1) when (selection(1) = '1') else
    >                                 internal(5 downto 2) when (selection(2) = '1') else
    >             internal(6 downto 3);
    > end Behavioral;


    I'm not exactly sure how you want to parameterize this. I'm guessing
    that that the width of all of the I/O would be one parameter.
    Assuming...

    entity barrelshifter is
    generic(Width: in positive)
    Port ( entrance : in STD_LOGIC_VECTOR (Width - 1 downto 0);
    selection : in STD_LOGIC_VECTOR (Width - 1 downto 0);
    sortie : out STD_LOGIC_VECTOR (Width - 1 downto 0));
    end barrelshifter;

    Then parameterize the width of 'internal'

    signal internal : std_logic_vector(Width - 2 downto 0);

    Then go through your signal assignments and replace '3' with 'Width -
    1'; '4' with 'Width', etc.

    Kevin Jennings
    KJ, Nov 20, 2009
    #2
    1. Advertising

  3. Thoma

    Andy Guest

    In general, parameterizable code cannot contain long if-then-elsif
    trees or case statements, because they are fixed by their very nature.

    You need to re-write the tree in the form of a loop that indexes over
    the parameterizable signal(s), and calculates the other indices off of
    the loop index. The loop may contain if-statements, but they can't
    have anything to do with indexes into paramerizable signals.

    You can also use unconstrained ports (no range specified in the port,
    each port on each instance takes its width from the signal mapped to
    it). Then you can use pre-defined attributes like 'length or 'range to
    create loops or matching width internal signals. You may have to
    include concurrent assertion statements to make sure that different
    ports are sized appropriately if they have to match.

    Andy
    Andy, Nov 20, 2009
    #3
  4. Thoma

    Thoma Guest

    Hi Kevin,

    entity barrelshifter is
    Generic ( width : in positive );
    Port ( entrance : in STD_LOGIC_VECTOR (width - 1 downto 0);
    selection : in STD_LOGIC_VECTOR (width - 1 downto 0);
    sortie : out STD_LOGIC_VECTOR (width - 1 downto 0));
    end barrelshifter;

    architecture Behavioral of barrelshifter is

    signal internal : std_logic_vector(2 * (width - 1) downto 0);

    begin
    internal <= entrance(width - 2 downto 0) & entrance;

    -- My problem lies here:

    -- If width = 4
    sortie <= internal(3 downto 0) when (selection(0) = '1') else
    internal(4 downto 1) when (selection(1) = '1') else
    internal(5 downto 2) when (selection(2) = '1') else
    internal(6 downto 3);

    -- But if width = 6
    sortie <= internal(5 downto 0) when (selection(0) = '1') else
    internal(6 downto 1) when (selection(1) = '1') else
    internal(7 downto 2) when (selection(2) = '1') else
    internal(8 downto 3) when (selection(3) = '1') else
    internal(9 downto 4) when (selection(4) = '1') else
    internal(10 downto 5);

    end Behavioral;

    I do not know how to make the 'sortie' expression generic.
    Have you some tips?

    Thoma

    On 20 nov, 22:33, KJ <> wrote:
    > On Nov 20, 4:15 pm, Thoma <> wrote:
    >
    > I'm not exactly sure how you want to parameterize this.  I'm guessing
    > that that the width of all of the I/O would be one parameter.
    > Assuming...
    >
    > entity barrelshifter is
    >     generic(Width: in positive)
    >     Port ( entrance : in  STD_LOGIC_VECTOR (Width - 1 downto 0);
    >            selection : in  STD_LOGIC_VECTOR (Width - 1 downto 0);
    >            sortie : out  STD_LOGIC_VECTOR (Width - 1 downto 0));
    > end barrelshifter;
    >
    > Then parameterize the width of 'internal'
    >
    > signal internal : std_logic_vector(Width - 2 downto 0);
    >
    > Then go through your signal assignments and replace '3' with 'Width -
    > 1'; '4' with 'Width', etc.
    >
    > Kevin Jennings
    Thoma, Nov 21, 2009
    #4
  5. Hi Thoma,

    you can also use so called "unconstrained types". The beauty being that
    the vector widths are decided by the hierarchical layer in which the
    unit is instantiated. The vector width can in fact be propagated through
    multiple levels.
    You generally cannot do this on the top level by the way, at least not
    if you want to synthesise it. Synthesis tools must map the vectors to
    physical pins somehow.


    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;

    entity barrelshifter is
    Port ( entrance : in STD_LOGIC_VECTOR;
    selection : in STD_LOGIC_VECTOR;
    sortie : out STD_LOGIC_VECTOR );
    end barrelshifter;

    architecture Behavioral of barrelshifter is

    -- Not sure that meets your intention, but something similar anyway
    signal internal : std_logic_vector((2 * entrance'length) - 2 downto 0);

    begin
    -- check for correct usage. Many simulators will fail during
    -- elaboration anyway if they detect a width assignment problem
    assert entrance'length > 3 report "Input vector too small"
    severity failure;

    process(entrance)
    variable v_entrance : std_logic_vector(entrance'length - 1 downto
    0);
    begin
    -- Covers the case that entrance is not 'n' downto 0
    v_entrance := entrance;
    internal <= v_entrance(v_entrance'left - 2 downto 0) & v_entrance;
    end process;

    sortie <= internal(sortie'length - 1 downto 0)
    when (selection(0) = '1') else
    internal(sortie'length downto 1)
    when (selection(1) = '1') else
    internal(sortie'length + 1 downto 2)
    when (selection(2) = '1') else
    internal(sortie'length + 2 downto 3);
    end Behavioral;


    Thoma schrieb:
    > Hi all,
    >
    > I am new with possibility of the VHDL "generic" keyword.
    > I tried to make the below code generic.
    >
    > Do you think this is possible?
    > If yes, this would allow me to make a number of my descriptions
    > customizable.
    >
    > Does anyone have a solution? An example?
    >
    > Thank you in advance.
    >
    > Thoma
    >
    Charles Gardiner, Nov 21, 2009
    #5
  6. Thoma

    Thoma Guest

    Hi all,

    Thank you all three.

    The generic version seems to work.

    Thoma

    On 21 nov, 10:34, Brian Drummond <> wrote:
    > On Sat, 21 Nov 2009 00:11:34 -0800 (PST), Thoma <> wrote:
    > >Hi Kevin,

    >
    > >entity barrelshifter is

    > ...
    > >begin
    > >  internal <= entrance(width - 2 downto 0) & entrance;

    >
    > >-- My problem lies here:

    >
    > >-- If width = 4
    > >  sortie <= internal(3 downto 0) when (selection(0) = '1') else
    > >            internal(4 downto 1) when (selection(1) = '1') else
    > >            internal(5 downto 2) when (selection(2) = '1') else
    > >            internal(6 downto 3);
    > >I do not know how to make the 'sortie' expression generic.
    > >Have you some tips?

    >
    > I don't think you can do this with the conditional "when...else" clause.
    >
    > However, recognise that this is merely a convenient shorthand for a process:
    >
    > process(internal,selection)
    > begin
    >    if selection(0) = '1' then
    >        sortie <= internal(3 downto 0);
    >    elsif ....
    >    end if;
    > end process;
    >
    > and parameterise that.
    >
    > -- avoid mistakes...
    > Assert width = selection'length report "Width error" severity failure;
    > -- or eliminate "width" and use the size of the selector instead!
    >
    > process(internal,selection)
    > begin
    >    for i in selection'range loop
    >         if selection(i) = '1' then
    >             sortie <= internal(width - 1 + i downto i);
    >         end if;
    >    end loop;
    > end process;
    >
    > -- Brian
    Thoma, Nov 21, 2009
    #6
  7. Thoma

    KJ Guest

    On Nov 21, 7:43 am, Charles Gardiner <> wrote:
    > Hi Thoma,
    >
    > you can also use so called "unconstrained types". The beauty being that
    > the vector widths are decided by the hierarchical layer in which the
    > unit is instantiated. The vector width can in fact be propagated through
    > multiple levels.


    The catch to using unconstrained type is that you also need to then
    add additional code to test and verify that it works with 'unexpected'
    vector ranges when instantiated. The downside to using unconstrained
    vectors in the OP's case are:

    - Additional code is typically needed to 'normalize' the vectors,
    converting any vectors that are (0 to n) into (n downto 0) for example
    if that's how the rest of the code is expecting them. Typically that
    code would be more typing than the additional amount of typing in the
    entity to explicitly define the vector size and direction.
    - Additional code is typically required to make sure that vectors that
    have size relationships do in fact have them. In the OP, 'entrance',
    'selection' and 'sortie' all need to be of the same size so the
    architecture would typically have to have this check as an assertion.
    Again, this is more typing then by defining the vector size and
    direction in the entity.
    - If you don't add the additional code to handle the above bullets,
    then you've created a potential problem for some user down the
    road...long after you (or whoever wrote it) has forgotten the detailed
    dependencies and will now need to (re)discover them.
    - Any usage errors don't get caught until you start the simulation as
    opposed to being caught as soon as you compile the file...wasted time
    and potentially more rework to other code because the problem gets
    caught later.
    - Usage of the entity by someone else (or the same person later down
    the road) is less clear because relationships that are expected (i.e.
    the above mentioned vector directions and vector size relationships)
    are buried in the architecture either explicitly in assertions (if
    that extra code was added) or implicitly because the sim crashes. I'd
    much rather have those relationships explicitly defined on the entity
    and not have to wade through somebody's code trying to discover what
    they are.

    The above mentioned downsides are neatly avoided by defining a generic
    and then defining the vector sizes all in the entity. The only
    downside to that approach is to the user of the entity in that they
    must now specify the value for the generic. This can easily be
    handled cleanly by specifying that value by use of the 'length
    attribute. In the OP's case, proper use of the entity would be of the
    following form and would work regardless of changes in size of the
    vectors.

    The_Shifter : entity work.barrelshifter
    generic map(Width => entrance'length)
    Port map(entrance => entrance,
    selection => selection,
    sortie => sortie);

    Unless you can prove your design works with all abuses of vector
    directions and sizes you should probably limit it to the forms that
    you have tested and verified and make it easy on the user by defining
    the tested relationships right on the entity via generics and
    explicitly defined vector sizes and directions. If you want to go the
    extra mile and insure that it works with all forms, go for it...but
    also first yourself if that extra work is within the scope of what the
    boss is paying for right now or if this is something that is only
    important to you...and why? When starting from scratch, most entities
    will not benefit and simply incur costs now (extra time) and later
    (rediscovering implicit assumptions).

    In my opinion, this particular case is probably not a good use of
    unconstrained types because it creates additional work with no
    benefit...ask yourself, what's the upside here?

    Kevin Jennings
    KJ, Nov 21, 2009
    #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. Pablo Gutierrez
    Replies:
    0
    Views:
    330
    Pablo Gutierrez
    Oct 27, 2003
  2. =?Utf-8?B?U2FuZHk=?=

    Please check code - need to make generic

    =?Utf-8?B?U2FuZHk=?=, Apr 23, 2005, in forum: ASP .Net
    Replies:
    4
    Views:
    394
    =?Utf-8?B?U2FuZHk=?=
    Apr 24, 2005
  3. Murat Tasan
    Replies:
    1
    Views:
    8,021
    Chaitanya
    Feb 3, 2009
  4. Replies:
    2
    Views:
    418
  5. minlearn
    Replies:
    2
    Views:
    443
    red floyd
    Mar 13, 2009
Loading...

Share This Page