Type conversion problem: closely related arrays

R

Rick Jackson

Guest
Can anyone tell me why this type conversion:

C(25 downto 0) := A & std_logic_vector(B(22 downto -1));

isn't working (test prog below)? ModelSim reports

**Error: test.vhd(17): value -1 is out of range 0 to 2147483647".

ModelSim appears to be checking that the indexes of std_logic_vector
and B have the same type, rather than being closely related. Does the
fact that 'std_logic_vector' doesn't have a range mean that the two
arrays aren't closely related?

This code did, I think, compile correctly on an older ModelSim which I
no longer have access to (~1999); I'm trying to get it to run with a
more current version. I've cut out various bits, but hopefully nothing
relevant.

Thanks!

Rick
------
Library IEEE;
Use IEEE.Std_logic_1164.all;

entity E is
end entity E;

architecture A of E is
subtype WordType is std_logic_vector(31 downto 0);
type logic_vector is array(integer range <>) of std_logic;
begin

process is
variable A : std_logic_vector(1 downto 0);
variable B : logic_vector(23 downto -4);
variable C : WordType;
begin
C(25 downto 0) := A & std_logic_vector(B(22 downto -1)); -- error
wait;
end process;
end architecture A;
 
Rick,

type std_logic_vector is array (natural range <>) of std_logic;

natural is a subtype of type integer with a range of 0 to integer'high

In other words, you cannot use a negative index for a std_logic_vector

Charles
 
On 21 Nov 2005 07:06:48 -0800, charles.elias@wpafb.af.mil wrote:

Rick,

type std_logic_vector is array (natural range <>) of std_logic;

natural is a subtype of type integer with a range of 0 to integer'high

In other words, you cannot use a negative index for a std_logic_vector

Charles
Ummm... but the -1 isn't an index into a std_logic_vector; it's an
index into a type B.

-1 is legal for type B, and type B has an index of type integer, which
is closely related to std_logic_vector's index type of natural, so it
seems to me that a conversion is possible.

I guess the issue is that the object being converted has a size of
24 bits, and 'std_logic_vector' does not specify a size, which appears
to violate the 'closely related' type requirements (see the fix
below). On the other hand, how did the original code get through both
ModelSim and DC? Has the current ModelSim tightened up on the spec, or
is there another explanation?

Note that

C(25 downto 0) := A & std_logic_vector(23 downto 0)(B(22 downto -1));

compiles Ok. however, I need to compile the old code unmodified if
possible.

Cheers

Rick
 
On Mon, 21 Nov 2005 16:13:55 +0000,
Rick Jackson <nospam@nospam.com> wrote:


Ummm... but the -1 isn't an index into a std_logic_vector; it's an
index into a type B.
Yes, but the point you're missing is this: Your array type
conversion will, by default, preserve the subscript range of
the original array. So your type-converted std_logic_vector
has the same subscript range as your original slice of B. Oops.

-1 is legal for type B, and type B has an index of type integer, which
is closely related to std_logic_vector's index type of natural, so it
seems to me that a conversion is possible.
For sure. But your conversion must re-jig the subscript range.

I guess the issue is that the object being converted has a size of
24 bits, and 'std_logic_vector' does not specify a size, which appears
to violate the 'closely related' type requirements (see the fix
below).
Nope; see my comments above.

On the other hand, how did the original code get through both
ModelSim and DC?
I have no idea; it would quite possibly get through a *compilation*
step, as ranges don't need to be checked at that point; but it should
never get through elaboration or runtime.

Has the current ModelSim tightened up on the spec, or
is there another explanation?
Maybe it's being a bit more aggressive than it used to be about
compile-time checking of ranges in situations where it can work
out the range as a compile time constant???

Note that

C(25 downto 0) := A & std_logic_vector(23 downto 0)(B(22 downto -1));

compiles Ok.
Does it? That sounds really weird to me. If you define a subtype

subtype SLV24 is std_logic_vector(23 downto 0);

and then use it to do the cast:

C(25 downto 0) := A & SLV24(B(22 downto -1));

then I could believe it; but your example looks like bad syntax to me.
I could be wrong - don't have time to check the LRM in detail, sorry.

however, I need to compile the old code unmodified if
possible.
Depressingly, it is a bad idea to try to compile erroneous code
even if it is "legacy" that by some mishap has "worked" in the past.

It strikes me that by far the easiest fix is for you to create a
custom type conversion:

function to_slv(B: B_type) return std_logic_vector is
variable BN: B_type(B'length-1 downto 0);
begin
BN := B; -- normalise the subscript range
return std_logic_vector(BN);
end;

Then it should be rather easy to do a search-and-replace to
fix all your typecasts to call the conversion function instead.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Jonathan Bromley wrote:

Maybe it's being a bit more aggressive than it used to be about
compile-time checking of ranges in situations where it can work
out the range as a compile time constant???
This is true.
I had to fix up some ranges in a testbench
package sometime around v6.0.

however, I need to compile the old code unmodified if
possible.

Depressingly, it is a bad idea to try to compile erroneous code
even if it is "legacy" that by some mishap has "worked" in the past.
Yes. I would rather start from scratch
than include code that either I or modelsim
didn't understand.

-- Mike Treseler
 
On Mon, 21 Nov 2005 16:55:02 +0000, Jonathan Bromley
<jonathan.bromley@doulos.com> wrote:

however, I need to compile the old code unmodified if
possible.

Depressingly, it is a bad idea to try to compile erroneous code
even if it is "legacy" that by some mishap has "worked" in the past.
Ah, indeed. Unfortunately, I have a (working) 110 mm^2 ASIC which
includes this code, and I need to rebuild it (without the benefit of
1999 versions of ModelSim and DC) before I start modifying it. It's
probably impossible, but I need to give it a go.

Thanks for the other input - I'll dig up the LRM and look it up.

Cheers

Rick
 
Rick Jackson wrote:

Ah, indeed. Unfortunately, I have a (working) 110 mm^2 ASIC which
includes this code, and I need to rebuild it (without the benefit of
1999 versions of ModelSim and DC) before I start modifying it. It's
probably impossible, but I need to give it a go.
I didn't mean to imply that the job was impossible
or even difficult. Just follow Jonathan's recipe
to eliminate the pesky anonymous types, and you'll
be back in business.

-- Mike Treseler
 

Welcome to EDABoard.com

Sponsor

Back
Top