Out of Range - simulation vs. synthesis

USE ieee.numeric_std.ALL;

IF cCLUSTER-1 >= to_integer( unsigned( Addr(3 DOWNTO 2) ) ) THEN
ls_addr_cluster(to_integer( unsigned( Addr(3 DOWNTO 2) ) )) <= Addr(1 DOWNTO 0);
END IF;

Kind regards,

Pieter Hulshoff
 
Hi Andy,

some additional question. How can I describe it as a loop when
using the following addressing:

Addr: IN std_logic_vector(3 DOWNTO 0);
....
constant cCLUSTER : integer := 4;
type cluster_type is array(cCLUSTER-1 downto 0) of std_logic_vector(1
downto 0);
signal ls_addr_cluster : cluster_type;


process(Clk)
begin
if rising_edge(Clk) then


if TxValid='1' then


case Addr(3 DOWNTO 2) is
when "00" => if cCLUSTER >= 1 then
ls_addr_cluster(0) <= Addr(1
DOWNTO 0);
end if;
when "01" => if cCLUSTER >=2 then
ls_addr_cluster(1) <=
Addr(1 DOWNTO 0);
end if;
when "10" => if cCLUSTER >=3 then
ls_addr_cluster(2) <= Addr(1
DOWNTO 0);
end if;
when "11" => if cCLUSTER >=4 then
ls_addr_cluster(3) <= Addr(1
DOWNTO 0);
end if;
end case;


end if;
end if;
end process;


Rgds
Andre
 
Hi Andy,

thank you for your clear explanation.

Rgds
Andre
 
On Mar 5, 3:22 am, "ALu...@web.de" <ALu...@web.de> wrote:
Hi all,

I have the following piece of VHDL code which
is not accepted in simulation but in synthesis:

constant cCLUSTER : integer := 4;
type cluster_type is array(cCLUSTER-1 downto 0) of std_logic_vector(1
downto 0);
signal ls_addr_cluster : cluster_type;

process(Clk)
begin
if rising_edge(Clk) then

if TxValid='1' then

case Addr is
when "00" => if cCLUSTER >= 1 then
ls_addr_cluster(0) <= Addr;
end if;
when "01" => if cCLUSTER >=2 then
ls_addr_cluster(1) <= Addr;
end if;
when "10" => if cCLUSTER >=3 then
ls_addr_cluster(2) <= Addr;
end if;
when "11" => if cCLUSTER >=4 then
ls_addr_cluster(3) <= Addr;
end if;
end case;

end if;
end if;
end process;

When using cCLUSTER=3 the simulation is aborted with the error
message: "Index value 3 is out of range 2 downto 0".
The if-condition seems not to keep Modelsim from checking
the assignment "ls_addr_cluster(3) <= Addr;" although
cCLUSTER is a constant definition. Synthesis does not complain ...
How can I solve that problem ?

Thank you for your opinion.

Rgds
Andre
It looks like your trying to store Addr in ls_addr_cluster, but
limiting the size of ls_addr_cluster to below what might appear in
Addr? This is a common issue in address decoding.

Instead of a case statement, use a for-loop indexed on the range of
the array:

for i in ls_addr_cluster'range loop
if i = unsigned(Addr) then
ls_addr_cluster(i) <= Addr;
exit; -- optional, speeds up sim
end if;
end loop;

Whenever the size of an array is variable, it is almost never a good
idea to use a case statement to access elements of it.

Loop statements are unrolled for synthesis, so this becomes a sequence
of if statements (the exit statements turns it into one big if-elsif-
elsif... statement)

The exit statement in this example will have no effect on synthesis
(the if conditions are mutually exclusive anyway), but it terminates
the loop in simulation once a match is found.

Andy
 
A

ALuPin@web.de

Guest
Hi all,

I have the following piece of VHDL code which
is not accepted in simulation but in synthesis:

constant cCLUSTER : integer := 4;
type cluster_type is array(cCLUSTER-1 downto 0) of std_logic_vector(1
downto 0);
signal ls_addr_cluster : cluster_type;

process(Clk)
begin
if rising_edge(Clk) then

if TxValid='1' then

case Addr is
when "00" => if cCLUSTER >= 1 then
ls_addr_cluster(0) <= Addr;
end if;
when "01" => if cCLUSTER >=2 then
ls_addr_cluster(1) <= Addr;
end if;
when "10" => if cCLUSTER >=3 then
ls_addr_cluster(2) <= Addr;
end if;
when "11" => if cCLUSTER >=4 then
ls_addr_cluster(3) <= Addr;
end if;
end case;

end if;
end if;
end process;


When using cCLUSTER=3 the simulation is aborted with the error
message: "Index value 3 is out of range 2 downto 0".
The if-condition seems not to keep Modelsim from checking
the assignment "ls_addr_cluster(3) <= Addr;" although
cCLUSTER is a constant definition. Synthesis does not complain ...
How can I solve that problem ?

Thank you for your opinion.

Rgds
Andre
 
On Mar 6, 5:31 am, "ALu...@web.de" <ALu...@web.de> wrote:
Hi Andy,

some additional question. How can I describe it as a loop when
using the following addressing:

Addr: IN std_logic_vector(3 DOWNTO 0);
...
constant cCLUSTER : integer := 4;
type cluster_type is array(cCLUSTER-1 downto 0) of std_logic_vector(1
downto 0);
signal ls_addr_cluster : cluster_type;

process(Clk)
begin
if rising_edge(Clk) then

if TxValid='1' then

case Addr(3 DOWNTO 2) is
when "00" => if cCLUSTER >= 1 then
ls_addr_cluster(0) <= Addr(1
DOWNTO 0);
end if;
when "01" => if cCLUSTER >=2 then
ls_addr_cluster(1) <=
Addr(1 DOWNTO 0);
end if;
when "10" => if cCLUSTER >=3 then
ls_addr_cluster(2) <= Addr(1
DOWNTO 0);
end if;
when "11" => if cCLUSTER >=4 then
ls_addr_cluster(3) <= Addr(1
DOWNTO 0);
end if;
end case;

end if;
end if;
end process;

Rgds
Andre
You declared "cCLUSTER" to be a constant with a value of 4. Then in
your case statements you have
when "01" => if cCLUSTER >= 2 then...

But AFAIK that's the same as when "01" => if 4 >= 2 then...

So I'm confused. What are you trying to do???
-Dave Pollum
 
Hi Pieter,
thank you for your proposal.

@ Dave
Generic Multiplexer of two-dimensional arrays

Rgds
Andre
 
On Mar 6, 5:31 am, "ALu...@web.de" <ALu...@web.de> wrote:
Hi Andy,

some additional question. How can I describe it as a loop when
using the following addressing:

Addr: IN std_logic_vector(3 DOWNTO 0);
...
constant cCLUSTER : integer := 4;
type cluster_type is array(cCLUSTER-1 downto 0) of std_logic_vector(1
downto 0);
signal ls_addr_cluster : cluster_type;

process(Clk)
begin
if rising_edge(Clk) then

if TxValid='1' then

case Addr(3 DOWNTO 2) is
when "00" => if cCLUSTER >= 1 then
ls_addr_cluster(0) <= Addr(1
DOWNTO 0);
end if;
when "01" => if cCLUSTER >=2 then
ls_addr_cluster(1) <=
Addr(1 DOWNTO 0);
end if;
when "10" => if cCLUSTER >=3 then
ls_addr_cluster(2) <= Addr(1
DOWNTO 0);
end if;
when "11" => if cCLUSTER >=4 then
ls_addr_cluster(3) <= Addr(1
DOWNTO 0);
end if;
end case;

end if;
end if;
end process;

Rgds
Andre
If you are asking what difference it makes if the addressed space is
indicated by Addr(4 downto 0), it doesn't. Have the loop iterate on
the elements of the array, and check to see if the value of the array
(loop) index equals the value of Addr (independent of length of Addr).
If it does, assign the element of the array, indexed with the loop
index, not Addr.

If you are asking how to control the width of Addr based on cCLUSTER,
then you need to pass cCluster in as a generic on the entity, and
specify the Addr port range in terms of that generic.

If, on the other hand, you are wanting to declare cCluster based on
the width of the Addr port, then you can use the Addr'length attribute
and exponentiation to determine the value of cCluster.

Andy
 
Hi Andy,

thank you for your proposed different approaches.

Rgds
Andre
 

Welcome to EDABoard.com

Sponsor

Back
Top