Array of constrained integers in port using generic

G

g_edit_here_thorpe

Hi,

I am trying to use an array of integers as an input to an entity. The number of
integers in the array is determined from a generic, but the integer values
should also be constrained by the generic.

For example:

entity ex0 is
generic(n : natural := 4);
port(
input1 : in integer range 0 to n-1;
input2 : in std_ulogic_vector(n-1 downto 0);
input3 : in array(n-1 downto 0) of integer range 0 to n-1;
output : std_ulogic
);
end entity ex0;


Inputs 1 & 2 will work, but 3 will produce a parse error (I know it is
incorrect, but it shows what I want to do). How can this be accomplished? Can
this be accomplished?

I understand that if I do not constrain the integers, they will be set to
32-bits each which will be a lot of extra wiring (it will also make
elaborating the design longer?) and wasted resources on bits that won't be
used. I cannot define types because the size of integer really does depend on
the generic (such as for input 1).
 
P

Paul Uiterlinden

entity ex0 is
generic(n : natural := 4);
port(
input1 : in integer range 0 to n-1;
input2 : in std_ulogic_vector(n-1 downto 0);
input3 : in array(n-1 downto 0) of integer range 0 to n-1;
output : std_ulogic
);
end entity ex0;


Inputs 1 & 2 will work, but 3 will produce a parse error (I know it is
incorrect, but it shows what I want to do). How can this be accomplished? Can
this be accomplished?

I understand that if I do not constrain the integers, they will be set to
32-bits each which will be a lot of extra wiring

As long as the signal connected to this port consists of an array of
constrained integers, I would not expect a lot of extra wiring. The
synthesizer (assuming that is what you meant with wiring) would take
into account the width of the signal connected. At least, that is what I
would expect.
(it will also make elaborating the design longer?) and wasted resources
on bits that won't be used.

I wouldn't worry about that too much. I do not know if integers with a
limited range really would occupy less bytes. I would expect only the
run time check to be affected by the range, not the size itself.
I cannot define types because the size of integer really does depend on
the generic (such as for input 1).

Yup, so a package cannot be used.

As said above, I would go for the array of unconstrained integers in the
port definition, and an array of constrained integers for the signal
declaration.

Paul.
 
G

gt_trysnip_horpe

Paul Uiterlinden said:
As long as the signal connected to this port consists of an array of
constrained integers, I would not expect a lot of extra wiring. The
synthesizer (assuming that is what you meant with wiring) would take
into account the width of the signal connected. At least, that is what I
would expect.

Thanks for responding.

It won't create extra wiring outside of the entity, but what about the
complexity inside? The extra wires will be synthesized and the entity will be
more complex than it would have to be (32 wires vs. 3 or 4 for each
integer, there are about 12 integers). I cannot use any other types even (for
example a std_ulogic_vector), because the both the size of the
array and the types in the array are constrained by the generic parameter.

I wouldn't worry about that too much. I do not know if integers with a
limited range really would occupy less bytes. I would expect only the
run time check to be affected by the range, not the size itself.

I think that unconstrained integers must at least be 32-bits long as required
by IEEE standards or the language itself. If I don't constrain the sizes, the
compiler will have to make them 32-bits long. This will make the compile take
much longer and the end result will have more wires than it needs. I am a
student, but it seems that in a real design this would be undesirable.

For a port, the compiler has to know the sizes at compile-time: even if the
entity higher up in the hierarchy does not use all 32-bits, I fear that this
entity will be created with a massive number of wires for its inputs.
Yup, so a package cannot be used.

Does VHDL support something like an anonymous type or types defined within the
context of the entity itself?
As said above, I would go for the array of unconstrained integers in the
port definition, and an array of constrained integers for the signal
declaration.

I may have to do that, or re-approach what the arbiter will need to make it's
decision.
 
G

gthorpe

looks like there is no other way than implementing a package.

Hi,

Thanks for the suggestion. I think that because I want to declare an array of
items that are constrained by the generic in the entity, I cannot declare the
type in a package (the generic is only defined within the scope of the entity).

Can you create types with generics in VHDL? That would help in my case...
 
R

Ralf Hildebrandt

I am trying to use an array of integers as an input to an entity. The number of
integers in the array is determined from a generic, but the integer values
should also be constrained by the generic.

For example:

entity ex0 is
generic(n : natural := 4);
port(
input1 : in integer range 0 to n-1;
input2 : in std_ulogic_vector(n-1 downto 0);
input3 : in array(n-1 downto 0) of integer range 0 to n-1;
output : std_ulogic
);
end entity ex0;


Inputs 1 & 2 will work, but 3 will produce a parse error (I know it is
incorrect, but it shows what I want to do). How can this be accomplished? Can
this be accomplished?

What about breaking the 2D-array down to a 1D-vector ((n-1)*n downto 0)?
This would also be better, if the code is going to be synthesized.


Ralf
 
G

gthorpe

Ralf Hildebrandt said:
(e-mail address removed) wrote:
What about breaking the 2D-array down to a 1D-vector ((n-1)*n downto 0)?
This would also be better, if the code is going to be synthesized.

That would work for std_(u)logic_vector, or bit_vector, but I don't see how I
can do it for integer types: the constraint just says how many values it can
hold, not how many bits it contains.
 
P

Paul Uiterlinden

It won't create extra wiring outside of the entity, but what about the
complexity inside? The extra wires will be synthesized and the entity will be
more complex than it would have to be (32 wires vs. 3 or 4 for each
integer, there are about 12 integers).

They will be optimized away, I would expect. Just give it a try and see
what you get. If it is not to your liking, then it is time to see what
else must be done.
I think that unconstrained integers must at least be 32-bits long as required
by IEEE standards or the language itself. If I don't constrain the sizes, the
compiler will have to make them 32-bits long. This will make the compile take
much longer

Why do you say that? Have you actually seen this happening?
and the end result will have more wires than it needs. I am a
student, but it seems that in a real design this would be undesirable.

For a port, the compiler has to know the sizes at compile-time: even if the
entity higher up in the hierarchy does not use all 32-bits, I fear that this
entity will be created with a massive number of wires for its inputs.

Just give it a try and observe the result.
Does VHDL support something like an anonymous type or types defined within the
context of the entity itself?

There is a declaritive region in the entity declaration (see
http://www.iis.ee.ethz.ch/~zimmi/download/vhdl93_syntax.html, under
entity_declaration), but I have never used that. You could put type
declarations there, but I have no idea whether that is supported by
synthesizers. Normally you would put declarations of types that are used
in the port of an entity in a package and make that package visible by a
use clause in front of the entity declaration. This is the preferred way
anyway, because you not only need the types in the entity declaration,
you also need them in the component instantiation.

Paul.
 
A

Alan Fitch

That would work for std_(u)logic_vector, or bit_vector, but I don't see how I
can do it for integer types: the constraint just says how many values it can
hold, not how many bits it contains.

Another approach you can try is to create a package containing a
constant, e.g.

constant N : POSITIVE := 10;
subtype myIntT is INTEGER range 0 to N-1;
subtype mySULT is std_ulogic_vector(N-1 downto 0);

and then use N and the subtypes on your entity, e.g.

entity ex0 is
port (
input1 : in myIntT;
input2 : in mySLUT;
input3 : in array (N-1 downto 0) of myIntT;
)

However I guess you don't want to do this as you'd have to
edit the constant for each different entity (i.e. you can't
set the constant per entity like you can for a generic).

Can you avoid your parse error by using two generics which have to
have the same value? You could then do

entity ex0 is
generic(n : natural := 4; m : natural := 4);
port(
input1 : in integer range 0 to n-1;
input2 : in std_ulogic_vector(n-1 downto 0);
input3 : in array(n-1 downto 0) of integer range 0 to m-1;
output : std_ulogic
);

and add an assert that n=m (you never know, it might work!).

Can you avoid the parse error by using 'REVERSE_RANGE, e.g.

port(
input1 : in integer range 0 to n-1;
input2 : in std_ulogic_vector(n-1 downto 0);
input3 : in array(n-1 downto 0) of integer input2'REVERSE_RANGE;
output : std_ulogic
);

What exactly is the parse error that you are getting?

kind regards
Alan

--
Alan Fitch
Consultant

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

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24
1AW, UK
Tel: +44 (0)1425 471223 mail:
(e-mail address removed)
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.
 
R

Ralf Hildebrandt

That would work for std_(u)logic_vector, or bit_vector, but I don't see how I
can do it for integer types

Then convert it to std_(u)logic_vector for the entity and if you really
need integers convert it back in the architecture.


Note: Often synthesis tools are configured, to change every I/O signal
to std_logic_vector xor std_ulogic_vector. So if you are going to
synthesize your design you have to convert all I/O signals anyway - if
your sythesis tool is configured as I said.


I for my own prefer std_ulogic_vector for all signals and do conversion
only if I really need them. This makes it easier to see unnessecary
hardware overhead.

Ralf
 

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,733
Messages
2,569,440
Members
44,832
Latest member
GlennSmall

Latest Threads

Top