numeric_std package

Discussion in 'VHDL' started by Ramya Murali, Feb 17, 2012.

  1. Ramya Murali

    Ramya Murali Guest

    Hi all, I have recently started using the package IEEE.numeric_std to
    deal with unsigned numbers (as opposed to IEEE.std_logic_arith).
    I would like to check if an unsigned number is a zero by logical OR
    operation on each of its bits.

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;

    entity test is
    port (a_in : unsigned (3 downto 0);
    b_out : unsigned (0 downto 0));
    end entity test;

    architecture beh of test is
    b_out <= a_in(0) or a_in(1) or a_in(2) or a_in(3);
    end architecture beh;

    When I compile the above using Modelsim, I get an error "error
    resolving infix expression 'or' as type numeric_std.unsigned".

    However, c_out <= a_in or b_in where a_in, b_in and c_out are defined
    as unsigned ( 3 downto 0) compiles correctly.

    From what I understand, logical operations are defined for unsigned
    type in the package numeric_std. If so, what is incorrect in the first
    Ramya Murali, Feb 17, 2012
    1. Advertisements

  2. Ramya Murali

    KJ Guest

    In the first case each element that is being or-ed (i.e. a_in(0)...)
    is of type std_logic because type unsigned is defined as being an
    array of std_logic bits. This means the result of the or is also of
    type std_logic, but b_out is defined as being unsigned which as I
    stated is an array of std_logic. To fix it you can
    - Change the type of b_out to be std_logic. This more correctly
    reflects your usage (i.e. it is a flag that indicates when a = 0).
    - Change the assignment to be b_out (others => a_in(0) or a_in(1) or
    a_in(2) or a_in(3));. This assigns all of the bits of b_out (even
    though there is only 1) to be the result of the computation of the
    'or' operation
    - Change the assignment to be b_out(0) <= a_in(0) or a_in(1) or
    a_in(2) or a_in(3);

    Note also that you don't need to manually compare each bit of a_in to
    see if the a_in as a whole has a value of 0. The following will work
    just as well:

    b_out(0) <= '1' when (a_in = 0) else '0';
    b_out <= (others => '1' when (a_in = 0) else '0');

    As a further aside, I like to define a function called to_std_logic
    that receives a boolean as the input parameter and returns a
    std_logic. Then the above can be written more clearly as:

    b_out(0) <= to_std_logic(a_in = 0);
    b_out <= (others => to_std_logic(a_in = 0));

    Kevin Jennings
    KJ, Feb 17, 2012
    1. Advertisements

  3. Ramya Murali

    Rob Gaddi Guest

    a_in is declared as being of type unsigned because it is an ordered
    collection of bits that represents a number. b_out isn't though, it's
    just a single bit, or better, a single boolean value.

    entity test is
    port (a_in : unsigned (3 downto 0);
    b_out : boolean);
    end entity test;

    architecture beh of test is
    b_out <= (a_in = 0);
    end architecture beh;

    If you decide to fight with VHDL's typing system it will make your life
    hell. Work with it instead; use the type that means the thing you want.
    Rob Gaddi, Feb 17, 2012
  4. Ramya Murali

    KJ Guest

    Nah, mine is neater than that.
    I like to suggest using an already written function even before
    writing one of my own. In this case, making use of the following
    function from numeric_std
    function "=" (L: UNSIGNED; R: NATURAL) return BOOLEAN;
    ....because that way you don't have to apologize for possibly
    mistakes. But note that I did suggest writing a function, just not
    one of the type that you did.
    That's OK...VHDL 93 with the numeric_std functions has you covered as

    Kevin Jennings
    KJ, Feb 17, 2012
  5. Ramya Murali

    MBodnar Guest

    As other posters have mentioned, use the strong typing of VHDL to your
    advantage for both function and self-documentation.

    If you have an unsigned vector, that implies it's being used for math,
    so use a math-like comparison operation (e.g., std_log <= '1' if
    my_unsigned = 0 else '0' -- or any one of the above-mentioned

    If you have a std_logic_vector, like a collection of posted IRQs, and
    want to check for presence of an IRQ (e.g., "zero"), use something
    like "OR_REDUCE" (I think this is a standard function in 2008?). Then
    you don't have to ever change your "check for zero" statement should
    you want to expand width.

    MBodnar, Feb 17, 2012
  6. Ramya Murali

    JimLewis Guest

    In VHDL-2008 it is:
    b_out(0) <= OR a_in ;

    Or alternately:
    b_out(0) <= not (a_in ?= 0) ; -- don't forget the parens

    I note that the others who used "=" matched your description
    rather than your code. To match your code:
    b_out(0) <= '0' when (a_in = 0) else '1';

    SynthWorks VHDL Training
    JimLewis, Feb 29, 2012
  7. Kevin: I think the 2008 operator ?= does what you want. It returns a bit instead of a Boolean.

    b_out <= (0=> a_in ?= 0, others=>'0');

    kevin.neilson, Feb 21, 2013
  8. Ramya Murali

    valtih1978 Guest

    function or_reduce(u : unsigned) return std_logic is

    You must start adding items to zero because additive identity is 0 and
    OR stands for "boolean addition"! :)
    valtih1978, Feb 21, 2013
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.