Unconstrained array and range direction

  • Thread starter Nicolas Matringe
  • Start date
N

Nicolas Matringe

Hello all
I had a discussion with a colleague and we were wondering how to
constrain the range direction but not the bounds.
I know strings are defined as :
type string is array (positive range <>) of character;
How come strings must always have a rising range ? Where/how is it defined ?

Nicolas
 
A

Andy

You have stumbled onto an implementation (tool) that is not per the
standard. The standard allows any direction, as long as the endpoints
are both compatible with that direction, and are both positive.

You could declare an arbitrarily large subtype of the master type (say,
1 to integer'high), and then define subtypes of that type, or maybe
even signals/variables of that type with a smaller range constraint. I
don't know about the legality of that last part. I know you can do it
with constrained integer subtypes, but with constrained array subtypes,
I don't know.

The only caveat is that it would no longer be an error to declare a
signal/variable of that subtype that was not further constrained (it
would be really large, but correct).

Andy
 
K

KJ

Nicolas said:
How come strings must always have a rising range ?
They don't. The following line of code compiles correctly in Modelsim:

signal X: STRING(10 downto 4);
Where/how is it defined ?
It's not in the standard so therefore in it's in the tool you're using.
If the above line of code does not compile correctly using your tool
then there is a bug in your tool and it is not compliant to the
standard and you should submit a bug report to the vendor.

KJ
 
J

James Unterburger

I think the question is really about why values of the STRING
type seem always to have a TO direction.

constant c1 : string := "abcd"; -- index is 1 to 4
constant c2 : string := ('a','b','c','d'); -- ditto
constant c3 : string := (4 => 'd',2 => 'b',1 => 'a',3 => 'c'); -- ditto
constant c4 : string := (3 downto 2 => 'X', 1 => 'A', 4 => 'Z'); -- ditto

Note that c1, c2, and c3 all have the exact same value "abcd" with the
exact same index range 1 TO 4.
Constant c4's value "AXXZ" also has an index range of 1 TO 4.

The direction TO comes from the index subtype, POSITIVE in this case.
POSITIVE has a direction of TO. As others have pointed out, you
can give a direction TO or DOWNTO only in a subtype of STRING.

Constants c1 and c2 get the index value 1 from POSITIVE'LEFT.
Constants c3 and c4 get the index values 1 and 4 from the aggregate choices,
but again the direction comes from the index subtype POSITIVE.

The bottom line is that you can't force the direction of an unconstrained
array in a string literal (when allowed), nor in an aggregate.
Same for unconstrained array type formals associated with either of
these things (when allowed).
 
N

Nicolas Matringe

KJ a écrit :
They don't. The following line of code compiles correctly in Modelsim:

signal X: STRING(10 downto 4);

Really ?
Then I apologize for my question, I was absolutely certain that it would
not compile (I am using ModelSim too)


Nicolas
 
N

Nicolas Matringe

James Unterburger a écrit :
I think the question is really about why values of the STRING
type seem always to have a TO direction.

constant c1 : string := "abcd"; -- index is 1 to 4
constant c2 : string := ('a','b','c','d'); -- ditto
constant c3 : string := (4 => 'd',2 => 'b',1 => 'a',3 => 'c'); -- ditto
constant c4 : string := (3 downto 2 => 'X', 1 => 'A', 4 => 'Z'); -- ditto


This comes from the default direction being TO. It's the same for any
array. Define a constant like this :
constant C_FOO : std_logic_vector := x"132";
and it will have an ascending range (0 to 11 in this case).

The discussion with my colleague was exactly about that : how to have a
std_logic_vector constant that would default to a descending range.

Nicolas
 
A

Andy

Scalar subtypes can also be defined with opposite range direction from
the parent type/subtype.

i.e. subtype mine is natural range 3 downto 0; -- initializes to 3

Andy
 
N

Nicolas Matringe

Andy a écrit :
Scalar subtypes can also be defined with opposite range direction from
the parent type/subtype.

i.e. subtype mine is natural range 3 downto 0; -- initializes to 3

Very interesting.
So maybe defining two subtypes would do the trick:

subtype my_natural is natural range natural'high downto 0;
subtype slv is std_logic_vector(my_natural range <>);

so that slv would have an ascending range by default.
Have to try it...

Nicolas
 
K

KJ

Nicolas Matringe said:
Andy a écrit :

Very interesting.
So maybe defining two subtypes would do the trick:

subtype my_natural is natural range natural'high downto 0;
subtype slv is std_logic_vector(my_natural range <>);
Almost....what you need is...

subtype my_natural is natural range natural'high downto 0;
type slv is array(my_natural range <>) of std_logic;

KJ
 
N

Nicolas Matringe

KJ a écrit :
Almost....what you need is...

subtype my_natural is natural range natural'high downto 0;
type slv is array(my_natural range <>) of std_logic;

Ah right. But then I can't define a constant and blindly assign it to a
signal or variable, I'll have to cast it.
Never mind, anyway :)
Nicolas
 
J

Jonathan Bromley

On Tue, 03 Oct 2006 20:03:30 +0200, Nicolas Matringe

[...]
This comes from the default direction being TO. It's the same for any
array. Define a constant like this :
constant C_FOO : std_logic_vector := x"132";
and it will have an ascending range (0 to 11 in this case).

The discussion with my colleague was exactly about that : how to have a
std_logic_vector constant that would default to a descending range.

It is tedious that VHDL doesn't have modified versions of the
unconstrained array type declaration, something like this:

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

which would enforce the subscript direction. On the other hand,
it's easy to re-arrange the subscript direction inside your own
code, particularly in a function or procedure:

function F(V: std_logic_vector) return ... is
subtype T_descending is std_logic_vector(V'high downto V'low);
constant V_descending: T_descending := V;
begin
...
--
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
(e-mail address removed)
http://www.MYCOMPANY.com

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

Andy

Nicolas said:
Andy a écrit :

Very interesting.
So maybe defining two subtypes would do the trick:

subtype my_natural is natural range natural'high downto 0;
subtype slv is std_logic_vector(my_natural range <>);

so that slv would have an ascending range by default.
Have to try it...

Nicolas

Nope, that won't work for the same reason the original unconstrained
range specificaiton did not constrain the direction.

Andy
 

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

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,052
Latest member
LucyCarper

Latest Threads

Top