Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Customization with CONSTANTS and/or GENERICs

Reply
Thread Tools

Customization with CONSTANTS and/or GENERICs

 
 
Sean Durkin
Guest
Posts: n/a
 
      04-10-2010
Hi *,

I've come across something I don't quite understand and thought I'd ask
the experts here. I've prepared a simple test case and put it here:
http://www.wiggy.de/testcase.html

Basically, what I'm doing is this:

I have two different entities with differing port lengths, and want to
instantiate one or the other depending on the value of a constant
defined in a package. So, in pseudo-code, what I have is this:

if (CONSTANT=value1) generate
instantiate_entity_1;
end generate;

if (CONSTANT=value2) generate
instantiate_entity_2;
end generate;

The entities connect to top-level ports, whose lengths are defined by
the same constant in the package.

Now, this works fine in ModelSim, but when I'm trying to synthesize in
Xilinx' XST, it throws an error about not-matching port lengths between
the top-level ports and the ports of the entity in the "wrong" generate
block. It seems that what's inside the generate blocks is ALWAYS
evaluated even if the if-condition is not met, or maybe it is evaluated
BEFORE the if-condition.

If I do the whole thing using a GENERIC, it works in both XST and
ModelSim, but in my eyes it shouldn't really make a difference.
Sometimes I prefer to do stuff like that with constants instead of
GENERICs so I don't have to drag a GENERIC through the entire hierarchy
and can just edit one central configuration package.

Now, is this a bug in XST or in ModelSim, or am I trying something
"illegal" here? What in general is the preferable way to do something
like this?

Looking at what XST does I would think that using a GENERIC, things are
thrown out or configured right at compile time, whereas when I use a
constant, stuff would not be thrown out until later in the optimization
stage.

Are there any differences in the end result in current tools? From a
pure language standpoint, there should be no difference, right?

cu,
Sean

--
Replace "MONTH" with the three-letter abbreviation of the current month
and the two-digit code for the current year (simple, eh?).
 
Reply With Quote
 
 
 
 
KJ
Guest
Posts: n/a
 
      04-10-2010
On Apr 10, 6:06*am, Sean Durkin <(E-Mail Removed)> wrote:
> Hi *,
>
> I've come across something I don't quite understand and thought I'd ask
> the experts here. I've prepared a simple test case and put it here:http://www.wiggy.de/testcase.html
>


Thanks...posting full working code demonstrating the problem makes
things easier for all who want to respond.

> Basically, what I'm doing is this:
>
> I have two different entities with differing port lengths, and want to
> instantiate one or the other depending on the value of a constant
> defined in a package. So, in pseudo-code, what I have is this:
>
> if (CONSTANT=value1) generate
> * instantiate_entity_1;
> end generate;
>
> if (CONSTANT=value2) generate
> * instantiate_entity_2;
> end generate;
>
> The entities connect to top-level ports, whose lengths are defined by
> the same constant in the package.
>


Looks good.

> Now, this works fine in ModelSim, but when I'm trying to synthesize in
> Xilinx' XST, it throws an error about not-matching port lengths between
> the top-level ports and the ports of the entity in the "wrong" generate
> block. It seems that what's inside the generate blocks is ALWAYS
> evaluated even if the if-condition is not met, or maybe it is evaluated
> BEFORE the if-condition.
>


XST has a bug.

> If I do the whole thing using a GENERIC, it works in both XST and
> ModelSim, but in my eyes it shouldn't really make a difference.


You are correct, it shouldn't.

> Sometimes I prefer to do stuff like that with constants instead of
> GENERICs so I don't have to drag a GENERIC through the entire hierarchy
> and can just edit one central configuration package.
>


Depending on the situation, constants in a package can be easier to
manage. It all depends on just how 'constant' those things are. I
find that repurposing some chunk of code or design can end up causing
yesterday's package constant to be today's generic parameter...but
this is all just a tangent...

> Now, is this a bug in XST or in ModelSim, or am I trying something
> "illegal" here?


Today, Modelsim and Quartus are what I consider to be the 'gold
standard' as far as correctly interpreting the language. That's not
to say that they don't have their bugs and can also be incorrect, but
at present they seem to be the closest to correct.

Your code synthesizes just fine with Quartus 9.0 (try it yourself with
the Web edition...those free downloads are useful even if you're not
intending to use those tools for design right now). Since you say it
compiles just fine in Modelsim than it is highly probable that the bug
is in XST. What you should do is:

- Open a bug report with Xilinx against XST, mentioning that "it
compiles just fine with both Modelsim and Quartus. If this bug is not
corrected in a timely manner, I may have to consider switching to
devices that are supported by tools that do not have this bug".
Whether or not you're paid up on support or a freeloader, you're
providing useful feedback on a product deficiency that the product
owner is likely motivated to correct.
- Develop a work around, whether that means using generics where you'd
like to use a constant so that you can continue to use XST or consider
using other tools and devices as mentioned in the first bullet. In
general, the code work around is usually the path taken, but one
should always consider all the options.

> What in general is the preferable way to do something
> like this?
>


I assume "like this" is referring to using package constants versus
generics.

If so, then it depends mostly on just how 'constant' those things in
the package really are as I mentioned earlier. But it's also not that
big of a deal if something needs to change from a package constant to
a design parameter generic. The process is
- Comment out the constant definition in the package
- Edit all the places you find the constant being used and
parameterize it wherever is the appropriate place in the design for it
to be a parameter. Compile all.
- Fix up the places that you missed above and recompile...repeat until
you've got it right.

> Looking at what XST does I would think that using a GENERIC, things are
> thrown out or configured right at compile time, whereas when I use a
> constant, stuff would not be thrown out until later in the optimization
> stage.
>


You're thinking too hard about a design you probably no nothing about
(i.e XST). Just how exactly XST, Quartus, Synplify, etc. translate a
set of text files containing VHDL code into a bitstream is anybody's
guess. Once you've exhausted your review of your design (which in
many cases IS the source of the error, not the tool) and the only
thing left to suspect is the tool, then usually the best course of
action is to try a different tool.

You've already taken the step of reducing it down to a simple test
case, so submit it to Xilinx and when the bug gets fixed you've done
your part to improve XST not only for yourself but for all. Unless
this is something that Xilinx is already aware of, their fix won't
likely be available for you on your current project so step #2 is
always to come up with how you're going to work around the problem.
Even if Xilinx chooses not to fix the problem (or not in a timely
manner), they are just hurting themselves by ignoring valid customer
feedback.

Don't hold your breath waiting for a fix unless this is absolutely
critical and you're too far down the road to change tools and
devices...in those situations, you'll need to engage the local FAE to
try to have the issue escalated. In your situation though, since
there does seem to be a work around it likely wouldn't be considered
'critical'.

Also, don't interpret any of this as trying to disparage Xilinx. Bugs
happen with all tools, your post was simply questioning brand X tools.

Good luck.

Kevin Jennings
 
Reply With Quote
 
 
 
 
Sean Durkin
Guest
Posts: n/a
 
      04-10-2010
Hi KJ,

thank you for responding.

KJ wrote:
> XST has a bug.


OK, that's what I thought. I just wasn't sure if maybe I was missing
something. I'll file a bug report with Xilinx.

By now I've tried it with Precision Synthesis, works there as well. I'll
try Synplify and ActiveHDL when I get back to the office next week, just
to have some more ammo.

> Depending on the situation, constants in a package can be easier to
> manage. It all depends on just how 'constant' those things are. I
> find that repurposing some chunk of code or design can end up causing
> yesterday's package constant to be today's generic parameter...but
> this is all just a tangent...


OK, so there's no "golden" standard to do this.

Currently, I use a mixture of both, which makes me a little unhappy. As
you said, it always depends...

When I design a more or less isolated functional module that someone
else might put into their design, I prefer GENERICs, since I don't want
to have to burden them with adding another package to their design,
dragging around yet another file... Plus for testbenches I prefer
GENERICs, since I can just override them when starting the simulation
and can then easily e.g. select which test to run via command-line
parameters to my simulation script. And GENERICs are more handy if it's
just a couple of parameters...

But when it's some bigger design made up of a lot of files and levels of
hierarchy, and potentially a dozen or more GENERICs clogging up my
entity declarations, I prefer constants. That way I don't have to drag a
GENERIC through a dozen files until I finally reach the only file it
really pertains to.
Plus, I hate having a dozen ports like "din: in
std_logic_vector(BITWIDTH-1 downto 0) in every entity, I'd rather
declare a subtype or a record in a central types package or something.

In this specific test case, as a quick workaround, I might just do both:
Add a GENERIC to the entity that is initialized with the constant value
from the package, and use the GENERIC in the module. That way, the
changes neccessary are minimal and don't affect any other parts and
files of the design. This works in XST as well.

>> Looking at what XST does I would think that using a GENERIC, things are
>> thrown out or configured right at compile time, whereas when I use a
>> constant, stuff would not be thrown out until later in the optimization
>> stage.
>>

> You're thinking too hard about a design you probably no nothing about
> (i.e XST). Just how exactly XST, Quartus, Synplify, etc. translate a
> set of text files containing VHDL code into a bitstream is anybody's
> guess. Once you've exhausted your review of your design (which in
> many cases IS the source of the error, not the tool) and the only
> thing left to suspect is the tool, then usually the best course of
> action is to try a different tool.

You're right, I know nothing about the inner workings of synthesis
tools. That's why I thought I'd ask here, maybe somone knows.

It would be interesting to know if maybe there actually are differences
in the way synthesis tools handle GENERICs and constants like in my
case; and if so, why. If it were really like I guessed in my original
post, I'd suspect that there would be differences in the runtime of the
synthesis process, and possibly even differences in the end result.

But, well, just a thought experiment. This is not an issue that can't
easily be worked around or has any major implications.

cu,
Sean

--
Replace "MONTH" with the three-letter abbreviation of the current month
and the two-digit code for the current year (simple, eh?).
 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      04-10-2010
Sean Durkin wrote:

> When I design a more or less isolated functional module that someone
> else might put into their design, I prefer GENERICs, since I don't want
> to have to burden them with adding another package to their design,
> dragging around yet another file...


Sometimes I put a package at the top of the file containing
the design entity. That way the testbench, or anything using the design
file gets access to the package as well.

-- Mike Treseler

 
Reply With Quote
 
Andy
Guest
Posts: n/a
 
      04-12-2010
On Apr 10, 3:27*pm, Sean Durkin <(E-Mail Removed)> wrote:
> Hi KJ,
>
> thank you for responding.
>
> KJ wrote:
> > XST has a bug.

>
> OK, that's what I thought. I just wasn't sure if maybe I was missing
> something. I'll file a bug report with Xilinx.
>
> By now I've tried it with Precision Synthesis, works there as well. I'll
> try Synplify and ActiveHDL when I get back to the office next week, just
> to have some more ammo.
>
> > Depending on the situation, constants in a package can be easier to
> > manage. *It all depends on just how 'constant' those things are. *I
> > find that repurposing some chunk of code or design can end up causing
> > yesterday's package constant to be today's generic parameter...but
> > this is all just a tangent...

>
> OK, so there's no "golden" standard to do this.
>
> Currently, I use a mixture of both, which makes me a little unhappy. As
> you said, it always depends...
>
> When I design a more or less isolated functional module that someone
> else might put into their design, I prefer GENERICs, since I don't want
> to have to burden them with adding another package to their design,
> dragging around yet another file... Plus for testbenches I prefer
> GENERICs, since I can just override them when starting the simulation
> and can then easily e.g. select which test to run via command-line
> parameters to my simulation script. And GENERICs are more handy if it's
> just a couple of parameters...
>
> But when it's some bigger design made up of a lot of files and levels of
> hierarchy, and potentially a dozen or more GENERICs clogging up my
> entity declarations, I prefer constants. That way I don't have to drag a
> GENERIC through a dozen files until I finally reach the only file it
> really pertains to.
> Plus, I hate having a dozen ports like "din: in
> std_logic_vector(BITWIDTH-1 downto 0) in every entity, I'd rather
> declare a subtype or a record in a central types package or something.
>
> In this specific test case, as a quick workaround, I might just do both:
> Add a GENERIC to the entity that is initialized with the constant value
> from the package, and use the GENERIC in the module. That way, the
> changes neccessary are minimal and don't affect any other parts and
> files of the design. This works in XST as well.
>
> >> Looking at what XST does I would think that using a GENERIC, things are
> >> thrown out or configured right at compile time, whereas when I use a
> >> constant, stuff would not be thrown out until later in the optimization
> >> stage.

>
> > You're thinking too hard about a design you probably no nothing about
> > (i.e XST). *Just how exactly XST, Quartus, Synplify, etc. translate a
> > set of text files containing VHDL code into a bitstream is anybody's
> > guess. *Once you've exhausted your review of your design (which in
> > many cases IS the source of the error, not the tool) and the only
> > thing left to suspect is the tool, then usually the best course of
> > action is to try a different tool.

>
> You're right, I know nothing about the inner workings of synthesis
> tools. That's why I thought I'd ask here, maybe somone knows.
>
> It would be interesting to know if maybe there actually are differences
> in the way synthesis tools handle GENERICs and constants like in my
> case; and if so, why. If it were really like I guessed in my original
> post, I'd suspect that there would be differences in the runtime of the
> synthesis process, and possibly even differences in the end result.
>
> But, well, just a thought experiment. This is not an issue that can't
> easily be worked around or has any major implications.
>
> cu,
> Sean
>
> --
> Replace "MONTH" with the three-letter abbreviation of the current month
> and the two-digit code for the current year (simple, eh?).


A couple of suggestions:

If you have enough generics to cause a headache (especially plumbing
them through multiple levels of hierarchy) then create a record in a
package that contains fields for all of your generics. That way, when
you need to add a top level generic for a lower level entity that
needs it, you just add it to the record, define it at the top, and
extract it at the entity that needs it. Of course the record has to be
defined in a package that must be referenced by every entity that uses
or passes it.

Use unconstrained ports.

Andy
 
Reply With Quote
 
Sean Durkin
Guest
Posts: n/a
 
      04-12-2010
Hi,

in case anyone's interested:
I opened a web case with Xilinx. They admit that it's a bug, but they
won't fix it... They wrote a new HDL parser for the Virtex-6 and
Spartan-6 architectures which doesn't have this bug anymore. For older
architectures, the old parser will still be used.

Since all the development time will now go into the new architectures,
the parser will not be fixed for the "obsolete" architectures like the
Virtex-5 I am using at the moment.

Yeah, well...

cu,
Sean

> Hi *,
>
> I've come across something I don't quite understand and thought I'd ask
> the experts here. I've prepared a simple test case and put it here:
> http://www.wiggy.de/testcase.html
>
> Basically, what I'm doing is this:
>
> I have two different entities with differing port lengths, and want to
> instantiate one or the other depending on the value of a constant
> defined in a package. So, in pseudo-code, what I have is this:
>
> if (CONSTANT=value1) generate
> instantiate_entity_1;
> end generate;
>
> if (CONSTANT=value2) generate
> instantiate_entity_2;
> end generate;
>
> The entities connect to top-level ports, whose lengths are defined by
> the same constant in the package.
>
> Now, this works fine in ModelSim, but when I'm trying to synthesize in
> Xilinx' XST, it throws an error about not-matching port lengths between
> the top-level ports and the ports of the entity in the "wrong" generate
> block. It seems that what's inside the generate blocks is ALWAYS
> evaluated even if the if-condition is not met, or maybe it is evaluated
> BEFORE the if-condition.


--
Replace "MONTH" with the three-letter abbreviation of the current month
and the two-digit code for the current year (simple, eh?).
 
Reply With Quote
 
Sean Durkin
Guest
Posts: n/a
 
      04-12-2010
Andy wrote:

> A couple of suggestions:
>
> If you have enough generics to cause a headache (especially plumbing
> them through multiple levels of hierarchy) then create a record in a
> package that contains fields for all of your generics. That way, when
> you need to add a top level generic for a lower level entity that
> needs it, you just add it to the record, define it at the top, and
> extract it at the entity that needs it. Of course the record has to be
> defined in a package that must be referenced by every entity that uses
> or passes it.

That's the kind of case where I usually use a constant in a package.
Doesn't really make much of a difference if I change a top-level generic
or a constant in a central configuration package, plus I don't have to
drag any generics around at all, be it one record containing all I need
or a dozen single generics. But you're right, that would be a "unified"
way of doing this... all generics, with minimal entity declaration
clutter... hmm...

> Use unconstrained ports.

You're right, that would be the most "elegant" solution for the test
case I posted, and I use that technique on occasion.

But in the actual design I'm working on at the moment, the two
selectable entities are two different CoreGen-cores, so it didn't quite
work there.

cu,
Sean

--
Replace "MONTH" with the three-letter abbreviation of the current month
and the two-digit code for the current year (simple, eh?).
 
Reply With Quote
 
KJ
Guest
Posts: n/a
 
      04-13-2010
On Apr 12, 5:13*pm, Sean Durkin <(E-Mail Removed)> wrote:

> > Use unconstrained ports.

>
> You're right, that would be the most "elegant" solution for the test
> case I posted, and I use that technique on occasion.
>


Actually, unconstrained ports on entities are generally not
appropriate because one or both of the following apply:
- The size of two or more vectors on the entity are related in some
fashion, they are not independent.
- The direction of the vectors matter because internal to the entity
implicit assumptions were made about vector directions (i.e. 'to' or
'downto').

In your test case, point #1 applies because 'din' and 'dout' must be
the same length. Sluffing off making this requirement explicit (by
defining the lengths via a generic as you did in your test case) and
instead hiding the requirement (by using unconstrained vectors) isn't
in any way 'elegant'. Yes, it is more typing...that extra typing is
also known as 'live, executable documentation'. Some user down the
road that inherits your code will appreciate it.

Kevin Jennings
 
Reply With Quote
 
Andy
Guest
Posts: n/a
 
      04-13-2010
On Apr 12, 9:51*pm, KJ <(E-Mail Removed)> wrote:
> On Apr 12, 5:13*pm, Sean Durkin <(E-Mail Removed)> wrote:
>
> > > Use unconstrained ports.

>
> > You're right, that would be the most "elegant" solution for the test
> > case I posted, and I use that technique on occasion.

>
> Actually, unconstrained ports on entities are generally not
> appropriate because one or both of the following apply:
> - The size of two or more vectors on the entity are related in some
> fashion, they are not independent.
> - The direction of the vectors matter because internal to the entity
> implicit assumptions were made about vector directions (i.e. 'to' or
> 'downto').
>
> In your test case, point #1 applies because 'din' and 'dout' must be
> the same length. *Sluffing off making this requirement explicit (by
> defining the lengths via a generic as you did in your test case) and
> instead hiding the requirement (by using unconstrained vectors) isn't
> in any way 'elegant'. *Yes, it is more typing...that extra typing is
> also known as 'live, executable documentation'. *Some user down the
> road that inherits your code will appreciate it.
>
> Kevin Jennings


Assertion statements that can verify relationships between port sizes
can be put in the entity itself, so they are just as self-documenting
as defining the port widths explicitly from generics in the port map.
And those assertion statements can handle more complex relationships
too.

They may or may not be less typing... but I tend to agree that less
typing is not always a good thing. I think of some of the verbosity of
VHDL is really just compiler-enforced comments.

Andy
 
Reply With Quote
 
Andy
Guest
Posts: n/a
 
      04-13-2010
On Apr 12, 4:13*pm, Sean Durkin <(E-Mail Removed)> wrote:
> Andy wrote:
> > A couple of suggestions:

>
> > If you have enough generics to cause a headache (especially plumbing
> > them through multiple levels of hierarchy) then create a record in a
> > package that contains fields for all of your generics. That way, when
> > you need to add a top level generic for a lower level entity that
> > needs it, you just add it to the record, define it at the top, and
> > extract it at the entity that needs it. Of course the record has to be
> > defined in a package that must be referenced by every entity that uses
> > or passes it.

>
> That's the kind of case where I usually use a constant in a package.
> Doesn't really make much of a difference if I change a top-level generic
> or a constant in a central configuration package, plus I don't have to
> drag any generics around at all, be it one record containing all I need
> or a dozen single generics. But you're right, that would be a "unified"
> way of doing this... all generics, with minimal entity declaration
> clutter... hmm...
>
> > Use unconstrained ports.

>
> You're right, that would be the most "elegant" solution for the test
> case I posted, and I use that technique on occasion.
>
> But in the actual design I'm working on at the moment, the two
> selectable entities are two different CoreGen-cores, so it didn't quite
> work there.
>
> cu,
> Sean
>
> --
> Replace "MONTH" with the three-letter abbreviation of the current month
> and the two-digit code for the current year (simple, eh?).


The advantage of plumbing generics all the way to the top is that
their value can be set via command line arguments in the tool, and
thus no re-compilation is required, which would be required if they
were constants in a package. I define the "default" values for the
record elements in the same package that defines the record itself, so
you can use it both ways if you want.

Depending on the tool's ability to allow a record type generic value
to be specified via the command line, you may have to break out the
record's elements into individual generics at the top level. The tools
that do allow you to define a record type generic value on the command
line are going to require you to define the entire record, whereas
individual generic values can be defined on the command line for only
those generics for which you do not want to use the default value.

I have not looked at generics on packages yet, but I'll bet there's an
easier way to handle "system-wide" generics using them (once the tools
establish support for the feature), especially if the package can
define several different constants that are related to a single
package generic.

Andy
 
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
generics depending on generics Soul VHDL 0 02-02-2009 09:14 AM
Generics and constants Rob Misc VHDL 13 10-04-2007 07:19 PM
Generics vs Constants - what criteria do you use to choose between these? Andrew FPGA VHDL 19 10-11-2006 02:20 AM
question on generics, constants in vhdl geoffrey wall VHDL 1 10-01-2005 08:48 PM
Can't convert a generics list of objects into a generics list ofinterfaces Juergen Berchtel Java 1 05-20-2005 02:07 PM



Advertisments