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
    begin
    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
    case?
     
    Ramya Murali, Feb 17, 2012
    #1
    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
    #2
    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
    begin
    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
    #3
  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
    well.

    Kevin Jennings
     
    KJ, Feb 17, 2012
    #4
  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
    schemes).

    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.

    MB
     
    MBodnar, Feb 17, 2012
    #5
  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';

    Best,
    Jim
    SynthWorks VHDL Training
     
    JimLewis, Feb 29, 2012
    #6
  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
     
    kevin.neilson, Feb 21, 2013
    #7
  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
    #8
    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.