Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > "Generics" in VHDL Package

Reply
Thread Tools

"Generics" in VHDL Package

 
 
Charles Steinkuehler
Guest
Posts: n/a
 
      05-16-2006
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I'm trying to do something with type definitions in a package, and it
seems like I need something like generics, but they don't seem to be
supported in packages.

The setting:

In my package, I define an enumerated global configuration type which is
used to specifiy which 'flavor' the design compiles to (ie: controls
number of active DMA channels, buffer sizes, etc). The top-level design
file passes the configuration type down the physical design tree as a
generic parameter, and functions in the package are used to control
generate statements, interface widths, etc. All this works fine.

The problem:

I'm trying to define some array subtypes in the package that depend on
which 'flavor' of chip is being built (a buffer-pointer address type,
which is a subtype of unsigned with it's length dependent on the
particular configuration being built).

ie:

package my_Pkg is
type conf_T is (BabyBear, MamaBear, PapaBear);

type SettingType_T is (DMA_PBUF_SIZE, DMA_PBUF_BITS);

function get_param (config : conf_T;
setting : SettingType_T) return natural;

subtype Buf_Addr_T is unsigned(12 downto 0);
type DMA_Buf_IF_T is record
req : std_logic;
ack : std_logic;
done : std_logic;
ptr : Buf_Addr_T;
end record DMA_Buf_IF_T;

end package my_Pkg;

....except I need to be able to configure the length of the Buf_Addr_T
subtype "dynamically" (at compile time) based on the selected conf_T type.

I could simply use my existing configuration functions to control the
declaration of unsigned (instead of Buf_Addr_T) types where needed, but
that would leave me without the DMA_Buf_IF_T type (which doesn't like to
compile with ptr as an unconstrained array).

The question:

Is there any way to declare a record type that contains an array who's
length depends on the environment (ie: a generic or similar)? I tried
breaking the above code into two packages, one with the get_param
function and one with the Buf_Addr_T and DMA_Buf_IF_T type declarations,
but there's no way (that I've found) to pass my compile-time conf_T
value to the package (or to do something similar).

- --
Charles Steinkuehler
http://www.velocityreviews.com/forums/(E-Mail Removed)

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (MingW32)

iD8DBQFEahhQenk4xp+mH40RAufCAJ9hd2hZbaaJWdn2pm+txl 0N/D4v3wCdH2sh
yy9Rz0mbSBTyUqNSabX69No=
=KQo0
-----END PGP SIGNATURE-----
 
Reply With Quote
 
 
 
 
Mike Treseler
Guest
Posts: n/a
 
      05-16-2006
Charles Steinkuehler wrote:

> The question:
> Is there any way to declare a record type that contains an array who's
> length depends on the environment (ie: a generic or similar)?


No, but keep in mind that it's the process that
uses the package. The package doesn't know and
can't care which of its types is in use.

> I tried
> breaking the above code into two packages, one with the get_param
> function and one with the Buf_Addr_T and DMA_Buf_IF_T type declarations,
> but there's no way (that I've found) to pass my compile-time conf_T
> value to the package (or to do something similar).


The process passes nothing to the package.
The process *uses* the declarations it contains.
The process can declare its own variables or
constants using any of the types in the package.
I can't work with types directly.
I use the types as a template for local constants or registers
in the process. For example:

Suppose that I have a generic_c = 0, 1 or 2
for BabyBear, MamaBear, PapaBear

With your package, I could do things like:

type bear_vec_t is array (conf_t) of unsigned(7 downto 0);
constant bear_choices_c : bear_vec_t := (x"ff", x"f7", x"42");
subtype generic_t is natural range conf_t'pos(BabyBear)
to conf_t'pos(PapaBear);

constant which_bear_c : conf_t := conf_t'val(generic_c);
constant this_bear_vec_c : unsigned := bear_choices_c(which_bear_c);

-- Mike Treseler
 
Reply With Quote
 
 
 
 
Charles Steinkuehler
Guest
Posts: n/a
 
      05-16-2006
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Mike Treseler wrote:
> Charles Steinkuehler wrote:
>
>> The question:
>> Is there any way to declare a record type that contains an array who's
>> length depends on the environment (ie: a generic or similar)?

>
> No, but keep in mind that it's the process that
> uses the package. The package doesn't know and
> can't care which of its types is in use.
>
>> I tried
>> breaking the above code into two packages, one with the get_param
>> function and one with the Buf_Addr_T and DMA_Buf_IF_T type declarations,
>> but there's no way (that I've found) to pass my compile-time conf_T
>> value to the package (or to do something similar).

>
> The process passes nothing to the package.
> The process *uses* the declarations it contains.
> The process can declare its own variables or
> constants using any of the types in the package.
> I can't work with types directly.
> I use the types as a template for local constants or registers
> in the process. For example:
>
> Suppose that I have a generic_c = 0, 1 or 2
> for BabyBear, MamaBear, PapaBear
>
> With your package, I could do things like:
>
> type bear_vec_t is array (conf_t) of unsigned(7 downto 0);
> constant bear_choices_c : bear_vec_t := (x"ff", x"f7", x"42");
> subtype generic_t is natural range conf_t'pos(BabyBear)
> to conf_t'pos(PapaBear);
>
> constant which_bear_c : conf_t := conf_t'val(generic_c);
> constant this_bear_vec_c : unsigned := bear_choices_c(which_bear_c);


A very interesting approach I hadn't thought of...thanks!

I assume the extra complexity (array indexing) would be generally
ignored by the synthesis tool since it all winds up being globally
static (ie: known at compile-time), right?

Also, why go through the trouble of numerically indexing the array,
wouldn't directly assigning a conf_t type to which_bear_c (or in my
case, passing it as a conf_t typed generic) work as well? What benefit
is there to converting to and from the integer generic_c type?

/me - wanders off to try this in modelsim and Quartus...

- --
Charles Steinkuehler
(E-Mail Removed)

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (MingW32)

iD8DBQFEak7wenk4xp+mH40RAl8VAJ92M1mVF4b78zwNChTQig Kne97jDQCggJPS
cCLzZg8Mv1TqBKvAQovEIQs=
=OxOx
-----END PGP SIGNATURE-----
 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      05-16-2006
Charles Steinkuehler wrote:

> A very interesting approach I hadn't thought of...thanks!


You are welcome.
It was an interesting question.

> I assume the extra complexity (array indexing) would be generally
> ignored by the synthesis tool since it all winds up being globally
> static (ie: known at compile-time), right?


Ignored in the sense of using up gates and flops.
Not ignored in the sense of type checking
and making things line up right automatically.

> Also, why go through the trouble of numerically indexing the array,
> wouldn't directly assigning a conf_t type to which_bear_c (or in my
> case, passing it as a conf_t typed generic) work as well? What benefit
> is there to converting to and from the integer generic_c type?


The intended benefit was a clear example.
No benefit at all for your design since
your entity is using a package anyway.

>
> /me - wanders off to try this in modelsim and Quartus...


Tell how Quartus does with enumerated generics.

-- Mike Treseler
 
Reply With Quote
 
Charles Steinkuehler
Guest
Posts: n/a
 
      05-16-2006
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Mike Treseler wrote:

> Tell how Quartus does with enumerated generics.


I haven't tested your constant array idea with Quartus yet, but Quartus
does just fine with enumerated generics (at least in 5.0 and 5.1, which
is what I've been using).

I have different top-level design files (and corresponding project files
for Quartus and ModelSim) that pass a conf_T to the underlying logic as
a generic, ie:

in BabyBear.vhd:

use work.my_Pkg.vhd
...

constant config : conf_T := BabyBear;
...

component BackEnd_C is
generic (
config : conf_T);
port (
...

be : BackEnd_C
generic map (
config => config)
port map (
...

The code in the other top-level files is pretty much identical (with
appropriate values assigned to config, of course!), and mainly differs
in external I/O (different configurations have different numbers and
types of external interfaces).

I have a config generic on most of the lower-level design units, and
just pass the top-level provided config down the heirarchy. The
lower-level design units use the config parameter and functions provided
in my_Pkg to control various design parameters (ie: number of active DMA
channels, number of input/output video streams, etc). I have had no
problems with Quartus compiling this, and don't expect any wierdness
caused by the addition of a constant array with an enumerated index (but
won't know for sure until I try it, of course...saddly, it's looking
like that won't happen until tomorrow).

- --
Charles Steinkuehler
(E-Mail Removed)

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (MingW32)

iD8DBQFEals+enk4xp+mH40RAorWAJ9CScLPdFW2vq1ZCF4GbH rCbDl9VACeMyh5
+/qSkVZjcDfJTT499mlKHBg=
=q3iX
-----END PGP SIGNATURE-----
 
Reply With Quote
 
KJ
Guest
Posts: n/a
 
      05-17-2006
Mike,

Maybe I'm missing something here but I thought the basic problem was that
the number of bits in the 'Buf_Addr_T' subtype needed to vary as a function
of a top level generic and I don't see how your post addresses that
problem....except for the very first statement where you say "No, but ...."

Presumably the 'DMA_Buf_IF_T' record type is used to communicate between
various entities and is therefore defined in the package. Since the 'ptr'
element of that type is defined to be 'Buf_Addr_T is unsigned(12 downto 0);'
but the actual range '12 downto 0' that is needed is design dependent so I
*thought* what was needed was for the

BabyBear to somehow have a range like '10 downto 0'
MamaBear to somehow have a range like '11 downto 0'
PapaBear to somehow have a range like '12 downto 0'

Also presuming that the reason for wanting to vary the range is because than
the 'BabyBear' design would fit into a 22V10, the 'MamaBear' design would
fit into a Stratix and the 'PapaBear' design would fit into a Virtex-5. (I
realize that this is probably not really the case but also that there
probably is some actual advantage to 'BabyBear' being smaller than
'PapaBear' otherwise why post the question?) So the real motivation here is
to have a single common code base that can be easily 'configured' in some
sense to use in different design applications.

If the 'ptr' element happened to work it's way out to the top level of the
design than it's likely that you can simply leave 'ptr' defined as needed
for the largest application and the fitter would be able to optomize out the
unneeded bits (i.e. ptr elements 10 and 9 for BabyBear, bit 11 for
MamaBear).

If 'ptr' doesn't make it's way out to the top then I think the fitter would
likely have a hard time spotting the optomization and 'BabyBear' would
likely end up being implemented the same way as 'PapaBear' and would require
use of the Virtex-5 instead of the 22V10 so it would be a rather pricey way
to keep the 'common code base'.

I *think* about the only way to handle this would be to have separate
'BabyBear.vhd', 'MamaBear.vhd' and 'PapaBear.vhd' source files. In each of
those file would be the same package containing the needed subtype/record
definitions where you modify it as required for the 'BabyBear', 'MamaBear'
and 'PapaBear' designs and then include only one of these source files in
the targetted build.

subtype Buf_Addr_T is unsigned(12 downto 0); <- Use '10 downto 0' for
'BabyBear', etc.
type DMA_Buf_IF_T is record
req : std_logic;
ack : std_logic;
done : std_logic;
ptr : Buf_Addr_T;
end record DMA_Buf_IF_T;

Either that, or like I said, I totally missed something

KJ


 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      05-17-2006
KJ wrote:

> Maybe I'm missing something here but I thought the basic problem was that
> the number of bits in the 'Buf_Addr_T' subtype needed to vary as a function
> of a top level generic and I don't see how your post addresses that
> problem....except for the very first statement where you say "No, but ...."


I said no because the only direct solution to the problem
of generic width types in a package is
to move the declarations to the process
or architecture where the
generic dimensions are in scope.

If the separate package is a requirement,
then the only solution I can imagine
is indirect. Some generic has to index
some sort of prepackaged constant array.

....
> If the 'ptr' element happened to work it's way out to the top level of the
> design than it's likely that you can simply leave 'ptr' defined as needed
> for the largest application and the fitter would be able to optomize out the
> unneeded bits (i.e. ptr elements 10 and 9 for BabyBear, bit 11 for
> MamaBear).


I think that could work also.
I'm sure Charles will sort it out.
Thanks for the new ideas.

-- Mike Treseler
 
Reply With Quote
 
Charles Steinkuehler
Guest
Posts: n/a
 
      05-17-2006
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

KJ wrote:
> Mike,
>
> Maybe I'm missing something here but I thought the basic problem was that
> the number of bits in the 'Buf_Addr_T' subtype needed to vary as a function
> of a top level generic and I don't see how your post addresses that
> problem....except for the very first statement where you say "No, but ...."
>
> Presumably the 'DMA_Buf_IF_T' record type is used to communicate between
> various entities and is therefore defined in the package. Since the 'ptr'
> element of that type is defined to be 'Buf_Addr_T is unsigned(12 downto 0);'
> but the actual range '12 downto 0' that is needed is design dependent so I
> *thought* what was needed was for the
>
> BabyBear to somehow have a range like '10 downto 0'
> MamaBear to somehow have a range like '11 downto 0'
> PapaBear to somehow have a range like '12 downto 0'
>
> Also presuming that the reason for wanting to vary the range is because than
> the 'BabyBear' design would fit into a 22V10, the 'MamaBear' design would
> fit into a Stratix and the 'PapaBear' design would fit into a Virtex-5. (I
> realize that this is probably not really the case but also that there
> probably is some actual advantage to 'BabyBear' being smaller than
> 'PapaBear' otherwise why post the question?) So the real motivation here is
> to have a single common code base that can be easily 'configured' in some
> sense to use in different design applications.
>
> If the 'ptr' element happened to work it's way out to the top level of the
> design than it's likely that you can simply leave 'ptr' defined as needed
> for the largest application and the fitter would be able to optomize out the
> unneeded bits (i.e. ptr elements 10 and 9 for BabyBear, bit 11 for
> MamaBear).
>
> If 'ptr' doesn't make it's way out to the top then I think the fitter would
> likely have a hard time spotting the optomization and 'BabyBear' would
> likely end up being implemented the same way as 'PapaBear' and would require
> use of the Virtex-5 instead of the 22V10 so it would be a rather pricey way
> to keep the 'common code base'.
>
> I *think* about the only way to handle this would be to have separate
> 'BabyBear.vhd', 'MamaBear.vhd' and 'PapaBear.vhd' source files. In each of
> those file would be the same package containing the needed subtype/record
> definitions where you modify it as required for the 'BabyBear', 'MamaBear'
> and 'PapaBear' designs and then include only one of these source files in
> the targetted build.
>
> subtype Buf_Addr_T is unsigned(12 downto 0); <- Use '10 downto 0' for
> 'BabyBear', etc.
> type DMA_Buf_IF_T is record
> req : std_logic;
> ack : std_logic;
> done : std_logic;
> ptr : Buf_Addr_T;
> end record DMA_Buf_IF_T;
>
> Either that, or like I said, I totally missed something


No, you're absolutely correct. The technique of using constant arrays
indexed by an enumerated configuration specifier is simply a more
elegant way of doing what I've got already (with functions where I pass
a config specifier, a desired constant name, and get a value back). I
was temporarily blinded by the elegance (or at least code-reduction)
this solution has over my function based solution.

I still don't have a way to change the values in the package (when used
in type declarations) based on the desired configuration, because the
package has no way of knowing what configuration I want to use.

I really need something like configuration generics, which look like
they're being added to VHDL 200x (at least based on my review of the
proposed floating point library), but I'm not holding my breath until I
can use this feature with Quartus and Modelsim.

As you mention, I think the only way around this problem is to have
separate package files with the required types defined hard-coded (or at
least with the configuration specifier hard-coded...then the type sizes
can be crafted from globally static constant/function expansions).

What I'll probably do is split my package so the stuff that controls the
configuration is in one package, and things like records and type
definintions that rely on a particular configuration are in a separate
package. I'll then have to select individual source files for the
second package, depending on which configuration I'm compiling for.

At least if I design the second package correctly, the only difference
between the configuration-specific files should be one line: The line
that specifies the desired configuration (as a constant). Then once
VHDL 200x actually becomes real enough, I can loose the multiple files
and use a package generic...in the mean-time, however, it's about
getting product out the door!

- --
Charles Steinkuehler
(E-Mail Removed)

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (MingW32)

iD8DBQFEazwyenk4xp+mH40RAi1rAJ40t8xSYsQoQpSIFJHUqB fMWetfKwCg7x2f
M7fj+d2uYgxdxYr0fVnKlDA=
=Ytx8
-----END PGP SIGNATURE-----
 
Reply With Quote
 
KJ
Guest
Posts: n/a
 
      05-17-2006
Darn, I was actually hoping that I had just completely missed something
too. What Mike posted is good stuff but I thought maybe I was having a
senior moment or something and had totally misunderstood something.

> As you mention, I think the only way around this problem is to have
> separate package files with the required types defined hard-coded (or at
> least with the configuration specifier hard-coded...then the type sizes
> can be crafted from globally static constant/function expansions).


I'm not getting how you'd be able to have a configuration specifier
help in changing the number of bits in 'ptr' though (assuming that's
what you meant by "then the type sizes can be crafted from globally
static constant/function expansions"

> What I'll probably do is split my package so the stuff that controls the
> configuration is in one package, and things like records and type
> definintions that rely on a particular configuration are in a separate
> package. I'll then have to select individual source files for the
> second package, depending on which configuration I'm compiling for.


Dang...if only VHDL had the C style #include...sigh

KJ

 
Reply With Quote
 
KJ
Guest
Posts: n/a
 
      05-17-2006
> I said no because the only direct solution to the problem
> of generic width types in a package is
> to move the declarations to the process
> or architecture where the
> generic dimensions are in scope.


Twas actually hoping that I had completely misunderstood and that if I
studied it more all would've been clear...alas, the new trick that was
leaned was not the new trick that I was hoping for.

KJ

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
VHDL-2002 vs VHDL-93 vs VHDL-87? afd VHDL 1 03-23-2007 09:33 AM
Package that imports with name of dependent package David Pratt Python 4 05-13-2006 05:12 PM
single package import v/s the entire package Parvinder Java 6 02-27-2005 02:02 PM
package module import name clash with global package George P Python 3 09-11-2004 01:19 PM
Importing a package and looping through modules in the package Dave Python 2 02-10-2004 08:14 PM



Advertisments