ERROR: Selector is an unconstrained array

M

Mad I.D.

Guest
ERROR MESSAGE :
"Selector (Signal 'addr' of type std_logic_vector) is an unconstrained
array."

Architecture body, declarative part (before begin) can use entity
generics but statement part can't ?

I'm I right? Little explanation on this please.



entity rom1 is
generic (
ADDR_WIDTH : integer :=4;
DATA_WIDTH : integer :=8
);
port (
addr : in std_logic_vector (ADDR_WIDTH-1 downto 0);
dout : out std_logic_vector (DATA_WIDTH-1 downto 0)
);
end rom1;

architecture beh of rom1 is
begin
with addr select
dout <= "11001101" when "0000",
"01011100" when "0001",
"01010101" when "0010",
"00000000" when "0011",
...............
...............
 
On Sun, 8 Mar 2009 13:18:51 -0700 (PDT), "Mad I.D." wrote:

"Selector (Signal 'addr' of type std_logic_vector) is an unconstrained
array."

Architecture body, declarative part (before begin) can use entity
generics but statement part can't ?

I'm I right? Little explanation on this please.



entity rom1 is
generic (
ADDR_WIDTH : integer :=4;
DATA_WIDTH : integer :=8
);
port (
addr : in std_logic_vector (ADDR_WIDTH-1 downto 0);
dout : out std_logic_vector (DATA_WIDTH-1 downto 0)
);
end rom1;

architecture beh of rom1 is
begin
with addr select
dout <= "11001101" when "0000",
with...select is equivalent to a case statement inside
a process. Case statements require their selector to
have a constrained subtype. This is sometimes irritating,
but it allows the compiler to do various things with
the case statement that it couldn't easily do otherwise.
Strictly, the selector's type must be "locally static".

In truth you don't need the generic in the code you
showed us. Your with...select evidently assumes that
the selector is 4 bits wide, and won't work if it is not.

There are other approaches that neatly solve this
problem. For example, you could convert the incoming
address to an integer, and use integers as the choices
in your case or with...select statement. Also, the
code you present is basically a lookup table so you
could code that explicitly as a table of constants;
this is more likely to map to memory in an FPGA:

use ieee.numeric_std.all;
........
subtype addr_i_type is integer range 0 to 2**ADDR_WIDTH - 1;
subtype data_type is std_logic_vector(DATA_WIDTH-1 downto 0);
type rom_table_type is array (addr_i_type) of data_type;
constant rom1_table: rom_table_type :=
( 0 => "11001101"
, 1 => "01011100"
, ...
, others => (others => '0')
);
.....
---- do lookup in the table
dout <= rom1_table(to_integer(unsigned(addr)));

--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Mad I.D. wrote:
ERROR MESSAGE :
"Selector (Signal 'addr' of type std_logic_vector) is an unconstrained
array."

Architecture body, declarative part (before begin) can use entity
generics but statement part can't ?

I would code a constant array as Jonathan did.
http://mysite.verizon.net/miketreseler/sync_rom.vhd
Generic dimensions are ok for arrays, but not for case selections.
The only way to make an asynchronous one-liner,
is to use fixed widths as shown below.

-- Mike Treseler
__________________
library ieee;
use ieee.std_logic_1164.all;
entity rom1 is
port (
dout : out std_logic_vector(7 downto 0);
addr : in std_logic_vector(3 downto 0));
end entity case_vs_if;

architecture sim of rom1 is
begin
with addr select
dout <=
"11001101" when "0000",
"01011100" when "0001",
"01010101" when "0010",
"00000000" when "0011",
"00000000" when others;
end architecture sim;
 
On Sun, 08 Mar 2009 15:19:13 -0700, Mike Treseler <mtreseler@gmail.com> wrote:

Mad I.D. wrote:
ERROR MESSAGE :
"Selector (Signal 'addr' of type std_logic_vector) is an unconstrained
array."

Architecture body, declarative part (before begin) can use entity
generics but statement part can't ?


I would code a constant array as Jonathan did.
http://mysite.verizon.net/miketreseler/sync_rom.vhd
Generic dimensions are ok for arrays, but not for case selections.
The only way to make an asynchronous one-liner,
is to use fixed widths as shown below.

-- Mike Treseler
__________________
library ieee;
use ieee.std_logic_1164.all;
entity rom1 is
port (
dout : out std_logic_vector(7 downto 0);
addr : in std_logic_vector(3 downto 0));
end entity case_vs_if;

architecture sim of rom1 is
begin
with addr select
dout <=
"11001101" when "0000",
....
"00000000" when others;
end architecture sim;

With generic ports you can do it but you have to cover two bases:

The first is as Mike says: the case expression must have a fixed width:

with addr(3 downto 0) select
-- this expression width must match the literals

The second is to cover the cases where the generic doesn't satisfy this
condition

e.g.
assert ADDR_WIDTH > 3 report "Address bus too small" severity FAILURE;

will verify that the address bus is large enough and map the ROM multiple times
if it is larger than necessary. That may or may not be the behaviour you want.

- Brian
 

Welcome to EDABoard.com

Sponsor

Back
Top