avoid the warnig

M

Max

I wrote this code:

------------8<---------------------
entity main is
Generic (w : integer := 12);
Port ( addr : in std_logic_vector(3 downto 0);
ce : in std_logic;
y : out std_logic_vector(w-1 downto 0));
end main;

architecture Behavioral of main is

begin

process (addr, ce)
begin
y <= (others => '0');
if (addr < w and ce = '1') then
y(to_integer(unsigned(addr))) <= '1';
end if;
end process;
end Behavioral;

------------8<---------------------

when I try to synthetize I obtain:
WARNING:Xst:790 - main.vhd line XX: Index value(s) does not match
array range, simulation mismatch.

This is correct, but there is no way to overflow y array index.
So how can I avoid this warnig?

thanks
 
D

Dan RADUT

(e-mail address removed) (Max) wrote in message
Please see my suggestion below:
I wrote this code:

------------8<---------------------
entity main is
Generic (w : integer := 12);
Port ( addr : in std_logic_vector(3 downto 0);
ce : in std_logic;
y : out std_logic_vector(w-1 downto 0));
end main;

architecture Behavioral of main is

begin

process (addr, ce)
-- declare a variable here
-- variable v_index: std_logic_vector(15 downto 0) := (others => '0');
begin
y <= (others => '0');
if (addr < w and ce = '1') then
y(to_integer(unsigned(addr))) <= '1';
-- replace the above statement with:
-- v_index(to_integer(unsigned(addr))):= '1';
-- add this statement here:
-- y <= v_index(w-1 downto 0);
end process;
end Behavioral;

------------8<---------------------

when I try to synthetize I obtain:
WARNING:Xst:790 - main.vhd line XX: Index value(s) does not match
array range, simulation mismatch.

This is correct, but there is no way to overflow y array index.
So how can I avoid this warnig?

HTH,
Dan R
 
T

Tim Hubberstey

Max said:
I wrote this code:

------------8<---------------------
entity main is
Generic (w : integer := 12);
Port ( addr : in std_logic_vector(3 downto 0);
ce : in std_logic;
y : out std_logic_vector(w-1 downto 0));
end main;

architecture Behavioral of main is

begin

process (addr, ce)
begin
y <= (others => '0');
if (addr < w and ce = '1') then
y(to_integer(unsigned(addr))) <= '1';
end if;
end process;
end Behavioral;

------------8<---------------------

when I try to synthetize I obtain:
WARNING:Xst:790 - main.vhd line XX: Index value(s) does not match
array range, simulation mismatch.

This is correct, but there is no way to overflow y array index.
So how can I avoid this warnig?

You could try coding it using a case statement:

process (addr, ce)
begin
y <= (others => '0');
case to_integer(unsigned(addr)) is
when 0 to 11 =>
if (addr < w and ce = '1') then
y(to_integer(unsigned(addr))) <= '1'; end if;

when others => null;
end case;

However, this will probably give you "time = 0" warnings from the
simulator ('U' in arithmetic op) so it may not be an improvement.

You could also just ignore this as a superfluous warning. The
"simulation mismatch" is that the simulator will give you an out of
range error and halt while the logic must actually return something.
This is not something that deserves a warning, in my opinion.

One of my big gripes with the Xilinx toolset is the number of
superfluous warnings they generate. Trying to get rid of all of them is
impossible. For instance, they issue a warning if you use 'open' to port
map an unused output port telling you that the port is unconnected! Duh!
 
M

Max

Tim Hubberstey said:
You could try coding it using a case statement:

process (addr, ce)
begin
y <= (others => '0');
case to_integer(unsigned(addr)) is
when 0 to 11 =>
if (addr < w and ce = '1') then
y(to_integer(unsigned(addr))) <= '1'; end if;

when others => null;
end case;

I tried this one:
process (addr, ce)
begin
y <= (others => '0');
if(ce = '1') then
case to_integer(unsigned(addr)) is
when 0 to w-1 =>
y(to_integer(unsigned(addr))) <= '1';
when others => null;
end case;
end if;
end process;

but I obtain this error:
ERROR:HDLParsers:817 - main.vhd Line XX. Choice .to. is not a locally
static expression.

I cannot uderstand.


thnaks
 
M

Max

Please see my suggestion below:
-- declare a variable here
-- variable v_index: std_logic_vector(15 downto 0) := (others => '0');
-- replace the above statement with:
-- v_index(to_integer(unsigned(addr))):= '1';
-- add this statement here:
-- y <= v_index(w-1 downto 0);

Ok, the following seems to work:

process (addr, ce)
variable v_index: std_logic_vector(15 downto 0) := (others => '0');
begin
v_index := (others => '0');
if (ce = '1') then
v_index(to_integer(unsigned(addr))) := '1';
end if;
y <= v_index(w-1 downto 0);
end process;

Now I need to substitute "15" in
variable v_index: std_logic_vector(15 downto 0) := (others => '0');

with something with 'w'...
something like "the 2-power that contains w"

otherwise if I change w I need to edit and change 15 in something else.

The device occupation is exactly the same, but I wonder if the presence
of variable could influence this parameter.
In the report there is no track of obtimization.

thanks
 
T

Tim Hubberstey

Max said:
I tried this one:
process (addr, ce)
begin
y <= (others => '0');
if(ce = '1') then
case to_integer(unsigned(addr)) is
when 0 to w-1 =>
y(to_integer(unsigned(addr))) <= '1';
when others => null;
end case;
end if;
end process;

but I obtain this error:
ERROR:HDLParsers:817 - main.vhd Line XX. Choice .to. is not a locally
static expression.

Unfortunately, using a generic in the 'when' clause causes it to not be
locally static. This is yet another of those cases where VHDL is too
restrictive about what is locally static.

You could try this:

signal tmp : std_logic_vector(15 downto 0);
begin
process (addr, ce)
begin
tmp <= (others => '0');
if (unsigned(addr) < w and ce = '1') then
tmp(to_integer(unsigned(addr))) <= '1';
end if;
end process;
y <= tmp(w-1 downto 0);

though this will probably produce warnings about tmp(15 downto 12) being
unused.

However, after looking at your first example again, I don't agree with
XST that there will be a sim/synth mismatch. The statement that could
produce a mismatch:

-----vvvvvvvv added missing "unsigned" conversion
if ( unsigned(addr) < w and ce = '1') then
y(to_integer(unsigned(addr))) <= '1'; -- possibly out of range

should never be executed if addr is out of range so I think XST is full
of something rather smelly. It is possible that the warning resulted
from the unsigned conversion you were missing. As I said before, the
code will work with what you originally had so I'd simply ignore the
warning and get on with it.
 
J

Jim Lewis

Max,
variable v_index: std_logic_vector(15 downto 0) := (others => '0');
v_index'left = addr'length**2 - 1

So hence,
variable v_index: std_logic_vector(addr'length**2 - 1 downto 0) := (others => '0');

Note, this only makes sense if you fully make addr parameterizable:
entity main is
Generic (w : integer := 12;
x : integer := 4 );
Port ( addr : in std_logic_vector(x-1 downto 0);
ce : in std_logic;
y : out std_logic_vector(w-1 downto 0));
end main;

And now v_index can also be based on the generic:
variable v_index: std_logic_vector(x**2 - 1 downto 0) := (others => '0');


Now it is up to you to pick better names as
w and x are both critic and are very similar
in what they specify w (actual length),
x (max length per addr).

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

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,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top