Earlz
Earlz

Reputation: 63825

How to do a bitwise AND on integers in VHDL?

I'm learning VHDL and I'm having a problem with some code I'm trying to write to satisfy a bound-check exception.

Here is my basic summarized code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_unsigned.all; 
...
port(
Address: in std_logic_vector(15 downto 0);
...
constant SIZE : integer := 4096;
variable addr: integer range 0 to SIZE-1 := 0;
...
process ... 
addr := conv_integer(Address) and (SIZE-1); --error here

The error message I get is

src/memory.vhd:37:35: no function declarations for operator "and"

Basically, my goal is to make a 16-bit address bus, reference memory with only 4096 bytes. Why do I get this odd error? Am I missing a library include or something?

Upvotes: 3

Views: 9404

Answers (4)

tentner
tentner

Reputation: 1

In your specific case you could also use "mod SIZE" instead of "and (SIZE-1)".

Upvotes: 0

Jay M
Jay M

Reputation: 4287

And does not make sense for an integer. Integer is a number within a range, but it has no standard way of implementing itself, i.e. it has no predefined representation in binary.

you can use something like the syntax, below;

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;





entity testand is
    generic (nBITS:integer:=32);
    port (
        i:in integer;
        a:in std_logic_vector(nBITS-1 downto 0);
        o:out std_logic_vector(nBITS-1 downto 0));
end entity;



architecture beh of testand is

signal v:std_logic_vector(a'length-1 downto 0);

begin

    v<=std_logic_vector(conv_unsigned(i,o'length));

    o<=v and a;


end architecture;

Upvotes: 2

Martin Thompson
Martin Thompson

Reputation: 16792

First: Don't use std_logic_arith and numeric_std. And you don't need std_logic_arith

You can't do bitwise ANDs on integers, so you need to do something like:

addr := Address and to_unsigned(SIZE-1, Address'length);

But you'll probably want to guarantee SIZE is a power-of-2

what I tend to do is create a constant in bits and work up from there:

constant mem_bits : integer := 16;
constant SIZE     : integer := 2**16;

then

addr := Address(mem_bits-1 downto 0);

Upvotes: 3

sonicwave
sonicwave

Reputation: 6092

I don't think and is defined for integers, although there might be a standard library that includes that functionality.

Why not keep your address as a std_logic_vector though? When it comes to addresses, you often want to be able to do easy decoding by looking directly at certain bits, so I think it makes rather good sense.

Just make addr a std_logic_vector(11 downto 0), and assign the lowest 12 bits of address to it - that will ignore the upper 4 bytes, and give you 4096 bytes of space (for an 8-bit databus).

Upvotes: 2

Related Questions