Unconstrained array and range direction

  • Thread starter Nicolas Matringe
  • Start date
N

Nicolas Matringe

Guest
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
 
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

Nicolas Matringe wrote:
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
 
Nicolas Matringe wrote:
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
 
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).
 
KJ a écrit :
Nicolas Matringe wrote:
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);
Really ?
Then I apologize for my question, I was absolutely certain that it would
not compile (I am using ModelSim too)


Nicolas
 
Nicolas Matringe wrote:
KJ a écrit :
Nicolas Matringe wrote:
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);

Really ?
Yes....I double checked before posting it....I've been known to make
simple mistakes too.

KJ
 
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
 
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


James Unterburger wrote:
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).
 
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
 
"Nicolas Matringe" <nicolas.matringe@fre.fre> wrote in message
news:45240ed7$0$9989$426a74cc@news.free.fr...
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 <>);

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
 
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
 
On Tue, 03 Oct 2006 20:03:30 +0200, Nicolas Matringe
<nicolas.matringe@fre.fre> wrote:

[...]
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
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.
 
Nicolas Matringe wrote:
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
Nope, that won't work for the same reason the original unconstrained
range specificaiton did not constrain the direction.

Andy
 

Welcome to EDABoard.com

Sponsor

Back
Top