numeric_std package

R

Ramya Murali

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?
 
K

KJ

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?

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
 
R

Rob Gaddi

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?

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.
 
K

KJ

Probably the neatest solution is

  b_out(0) <= a_in(0) or a_in(1) or a_in(2) or a_in(3);

then the target is also std_logic.

Nah, mine is neater than that.
I'm sure someone else will suggest writing a function! In fact that
someone is me...

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;
....
Not compiled, so apologies for any mistakes.
....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.
P.S. reduction operators are built in to VHDL 2008, but I haven't got
the standard to hand to see what data types they work on.
That's OK...VHDL 93 with the numeric_std functions has you covered as
well.

Kevin Jennings
 
M

MBodnar

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

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
 
J

JimLewis

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
 
K

kevin.neilson

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

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
 
V

valtih1978

function or_reduce(u : unsigned) return std_logic is
variable result : std_logic := '1';
begin
for i in u'range loop
result := result or u(i);


You must start adding items to zero because additive identity is 0 and
OR stands for "boolean addition"! :)
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top