Variable/Configurable Entity Port List

K

Kevin Neilson

I would like to know if it is possible to change the name and number of
ports of the top-level entity in VHDL. Let me introduce this by saying
that I'm normally a Verilog user, I think the answer is probably "no",
and I've searched the archives of this group and Google without finding
a definitive answer. I know that unfortunately this can't be done in
Verilog without the use of `ifdefs, which are awkward.

Let me be more specific: say I want to make a core with an input clk,
an output q, and optional inputs ce and clr. I want the user to be able
to select (via some sort of generics) whether there will be ce or clr
(or both or neither) inputs at the top level; therefore there will be
four possible top-level port lists. Furthermore, I want the top level
ports in the resulting netlist to have the correct names (i.e., "ce" and
"clr"). (I know I could make a single variable-length input named, for
example, "generic_in" and then remap the bits of that to internal
signals called "ce" and "clr", but that's not desirable.)

I am fairly certain I can't employ "generates" within the entity port
list. So is there any way to do this short of using a homemade
preprocessor (e.g., Perl script) to write out the VHDL with the i/o
ports I want?
-Kevin
 
M

Mike Treseler

Kevin said:
say I want to make a core with an input clk,
an output q, and optional inputs ce and clr.

For the purposes of a simple testbench,
I would leave ce and clr as inputs
on the base entity and use port mapped direct instances
to rename the versions with grounded inputs.
Synthesis will clean up the unused resources.

-- Mike Treseler
 
K

KJ

Let me be more specific:  say I want to make a core with an input clk,
an output q, and optional inputs ce and clr.  I want the user to be able
to select (via some sort of generics) whether there will be ce or clr
(or both or neither) inputs at the top level; therefore there will be
four possible top-level port lists.  Furthermore, I want the top level
ports in the resulting netlist to have the correct names (i.e., "ce" and
"clr").  (I know I could make a single variable-length input named, for
example, "generic_in" and then remap the bits of that to internal
signals called "ce" and "clr", but that's not desirable.)

You can add default values to ce and clr in the entity like this...
ce: in std_ulogic := '1';
clr: in std_ulogic := '0';

Then the user can simply choose to connect them to appropriate signals
or leave them disconnected in which case the default values that were
supplied on the entity interface will be used.

This is a cleaner approach then it would be to have generics to
specify whether or not certain signals on the interface are used or
not.

Kevin Jennings
 
M

Mark McDougall

Kevin said:
I would like to know if it is possible to change the name and number of
ports of the top-level entity in VHDL.

Whilst Mike & Kevin gave great responses, they didn't actually answer your
question. The answer is "no".

To weigh in on this myself, I'd personally steer clear of using generics
to specify which inputs are supported/implemented and simply use the
defaults as Kevin suggested. Mike's suggestion is perhaps "nicer" but it's
also more work and I'm lazy... ;)

Regards,
 
K

Kevin Neilson

Mark said:
Whilst Mike & Kevin gave great responses, they didn't actually answer
your question. The answer is "no".

To weigh in on this myself, I'd personally steer clear of using generics
to specify which inputs are supported/implemented and simply use the
defaults as Kevin suggested. Mike's suggestion is perhaps "nicer" but
it's also more work and I'm lazy... ;)

Regards,
Thanks; the "no" does indeed answer my question. I have to make a core
with a variable port list so now I know that I must do it by using a
script to generate HDL.
-Kevin
 
T

Thomas Stanka

Whilst Mike & Kevin gave great responses, they didn't actually answer your
question. The answer is "no".

I would relative the "no" to "not good at all".
You could use a record for the signals on the entity and defer the
real pinout in a package. You could then instantiate different
packages or even use configurations to differ between the different
contents of the record. You need different architectures for the
toplevel to handel the different records.

entity top
(my_in : input_record;
my_out : output_record);
end top;

The problem is, that records in toplevel Entity may lead to unpleasant
synthesis results. I've seen a design with complex record on top
beeing flattend to an array size 180 in synthesis. It is no fun, to
map this array in a testbench.
Second is, that your architecture needs to be written in a way that
fits to the different used records.

bye Thomas
 
M

Mark McDougall

Thomas said:
You could use a record
for the signals on the entity and defer the real pinout in a package.
You could then instantiate different packages or even use
configurations to differ between the different contents of the record.

I have an on-going (personal) project which consists of a generic
framework wrapping a relatively large number of (similar) designs on a
number of different hardware platforms that is constantly evolving.

One problem I have had since day one is that occasionally I need to change
the interface on key modules to punch out more signals to the top level,
for example. Each time this happens, it's a major operation to update
every project for every target!

Recently I've started sorting the ports into functional groups and
defining a pair of records for each group (one for each direction). The
idea being that when I add a new signal to the group, in *most* cases I
don't need to change any of the code that instantiates entities with the
functional group in their port lists.

The jury is still out atm since I've only got 2 functional groups defined
so far as records, and I haven't yet needed to add a signal to the
already-created records... but in theory it'll help?!?

Regards,
 
M

Mike Treseler

Thomas said:
The problem is, that records in toplevel Entity may lead to unpleasant
synthesis results. I've seen a design with complex record on top
beeing flattend to an array size 180 in synthesis. It is no fun, to
map this array in a testbench.

Yes, a device-level top entity must be
mapped to a simple pin array if it
is to be used in a real device.
To complete a gate-level simulation,
this mapping must be unambiguous, so
I have to stick with types that all the
device fitters can all handle.
This is one reason that I keep my data
structures on the inside.

Second is, that your architecture needs to be written in a way that
fits to the different used records.

What looks like a top level entity to *me*
may also be viewed as a structural instance to
someone else. Someone else, may not like vhdl,
much less my clever data structures.
This is another reason I keep port types simple.

-- Mike Treseler
 
K

KJ

Thanks; the "no" does indeed answer my question.  I have to make a core
with a variable port list so now I know that I must do it by using a
script to generate HDL.
-Kevin-

Just curious...what is the reason that you "have to make a core with a
variable port list" rather than provide default values on input ports
that are optional?

Kevin Jennings
 
K

Kevin Neilson

Thomas said:
I would relative the "no" to "not good at all".
You could use a record for the signals on the entity and defer the
real pinout in a package. You could then instantiate different
packages or even use configurations to differ between the different
contents of the record. You need different architectures for the
toplevel to handel the different records.

entity top
(my_in : input_record;
my_out : output_record);
end top;

The problem is, that records in toplevel Entity may lead to unpleasant
synthesis results. I've seen a design with complex record on top
beeing flattend to an array size 180 in synthesis. It is no fun, to
map this array in a testbench.
Second is, that your architecture needs to be written in a way that
fits to the different used records.

bye Thomas
The problem with this is that when I synthesize something like this the
top level has only fat ports named "my_in" and "my_out". I have to
deliver a netlist, and the customer expects a netlist with real signal
names. This scheme might work well for internal work, connecting
between my own entities.
-Kevin
 
K

Kevin Neilson

KJ said:
Just curious...what is the reason that you "have to make a core with a
variable port list" rather than provide default values on input ports
that are optional?

Kevin Jennings
I have to develop a highly configurable core with many different modes.
The customer doesn't want to have a netlist with a whole pile of I/Os
that aren't relevant to his particular mode, much like you wouldn't want
a vacuum cleaner with two power cords on it when you only plan to use it
with 120VAC. It's just not friendly to deliver a netlist with, for
example, an ethernet port on it when the lines aren't connected to
anything. Or say, for example, you have a memory controller with up to
16 ports but the user has specified he wants only 3. You could still
have 16 sets of buses and make the user tie off 13 but that's lame. Or
you could concatenate all the buses together: maybe the first 8 bits
would be port 0, the next 16 bits port 1, and the next 24 bits port 3.
But that's also pretty lame. -Kevin
 
T

Thomas Stanka

On 4 Apr., 01:19, Kevin Neilson <[email protected]>
wrote:
[..]
I would relative the "no" to "not good at all". [..]
The problem is, that records in toplevel Entity may lead to unpleasant
synthesis results.
[..]
The problem with this is that when I synthesize something like this the
top level has only fat ports named "my_in" and "my_out". I have to
deliver a netlist, and the customer expects a netlist with real signal
names. This scheme might work well for internal work, connecting
between my own entities.

This is why I consider this way as "not good at all" :). But in fact
this is a problem of the bad synthesis tool you are using.
A good synthesis tool wouldn't flat the name to an array called my_in
instead of using my_in_clk, my_in_reset,....
Unfortunately the big ones in synthesis are not selling good tools
w.r.t. vhdl language support.

bye Thomas
 
T

Tricky

I have to develop a highly configurable core with many different modes.
The customer doesn't want to have a netlist with a whole pile of I/Os
that aren't relevant to his particular mode, much like you wouldn't want
a vacuum cleaner with two power cords on it when you only plan to use it
with 120VAC. It's just not friendly to deliver a netlist with, for
example, an ethernet port on it when the lines aren't connected to
anything. Or say, for example, you have a memory controller with up to
16 ports but the user has specified he wants only 3. You could still
have 16 sets of buses and make the user tie off 13 but that's lame. Or
you could concatenate all the buses together: maybe the first 8 bits
would be port 0, the next 16 bits port 1, and the next 24 bits port 3.
But that's also pretty lame. -Kevin

The only "useful" way I can see of implementing this would be to have
a wrapper around your "ugly" top level that had a separate package
with all the set up constants in it (instead , and a function to
generate the width of "my_in" and "my_out", and then connects all the
bits from these busses intelligently to the right parts of the top
level.

Personally, I would rather be presented with an entity declaration
with clearly labelled signals that I could chose to ignore rather than
a single "my_In/out" that I then had to work out where everything was
supposed to connect.

Also, if this is on an FPGA then everything, whether it's used or not,
is going going to be connected to the same pins on the FPGA
regardless, so from an implementation point of view your PIN
assignments are far easier to maintain (because they're static).
 
K

KJ

I have to develop a highly configurable core with many different modes.
  The customer doesn't want to have a netlist with a whole pile of I/Os
that aren't relevant to his particular mode,

If the customer only wants a specific mode, then one might question
why you're developing the 'highly configurable core' that they don't
intend to use in anything but a specific configuration (presumably
you're doing so though so that the 'highly configurable' version can
be reused with other customers for their specfic modes).

In any case, if you want to develop the highly configurable core but
also don't want to expose the customer to all of that wonderfullness,
then you simply add a customer specific wrapper around the
configurable core, connecting up only the signals relevant to the
customer's mode, leaving the others unconnected (assuming the
configurable core uses default values for any 'optional' inputs).

That way the customer doesn't even see the extra signals that come
along with the configurable core entity since they interface to the
wrapper and you don't have to bother with defaulting the unneeded
things in the wrapper where it connects to the configurable core since
the proper default values to use are on the entity.
It's just not friendly to deliver a netlist with, for
example, an ethernet port on it when the lines aren't connected to
anything.  Or say, for example, you have a memory controller with up to
16 ports but the user has specified he wants only 3.  You could still
have 16 sets of buses and make the user tie off 13 but that's lame.  

That's why specifying default values on the entity inputs for optional
inputs is nice, the user wouldn't have to do anything with the unused
ethernet port or the 13 unneeded buses, they simply wouldn't connect
them up. These unconnected signals don't become 'floating' or part of
the netlist in any way, the synthesis tool optomizes them
appropriately based on the logic values that are specified as default
values on the entity. Zero extra logic/signals/etc.
Or
you could concatenate all the buses together:  maybe the first 8 bits
would be port 0, the next 16 bits port 1, and the next 24 bits port 3.
But that's also pretty lame.

Agreed, I wouldn't do it that way either.

Kevin Jennings
 
K

Kevin Neilson

KJ said:
If the customer only wants a specific mode, then one might question
why you're developing the 'highly configurable core' that they don't
intend to use in anything but a specific configuration (presumably
you're doing so though so that the 'highly configurable' version can
be reused with other customers for their specfic modes).

In any case, if you want to develop the highly configurable core but
also don't want to expose the customer to all of that wonderfullness,
then you simply add a customer specific wrapper around the
configurable core, connecting up only the signals relevant to the
customer's mode, leaving the others unconnected (assuming the
configurable core uses default values for any 'optional' inputs).

That way the customer doesn't even see the extra signals that come
along with the configurable core entity since they interface to the
wrapper and you don't have to bother with defaulting the unneeded
things in the wrapper where it connects to the configurable core since
the proper default values to use are on the entity.
But I still can't insert the correct wrapper based on a generic (I don't
think). Anyway, there are too many possible top-level port
combinations, so I'd still have to use a script to generate the wrapper.
> That's why specifying default values on the entity inputs for optional
inputs is nice, the user wouldn't have to do anything with the unused
ethernet port or the 13 unneeded buses, they simply wouldn't connect
them up. These unconnected signals don't become 'floating' or part of
the netlist in any way, the synthesis tool optomizes them
appropriately based on the logic values that are specified as default
values on the entity. Zero extra logic/signals/etc.
This might work if one is delivering HDL, but not if one is delivering a
netlist (as I am). Since the synthesizer doesn't know if a top-level
input is to be connected or left open, default values are ignored at the
top level. The customer that gets a netlist still has to connect up the
"unused" inputs. -Kevin
 
K

Kevin Neilson

Tricky said:
The only "useful" way I can see of implementing this would be to have
a wrapper around your "ugly" top level that had a separate package
with all the set up constants in it (instead , and a function to
generate the width of "my_in" and "my_out", and then connects all the
bits from these busses intelligently to the right parts of the top
level.

Personally, I would rather be presented with an entity declaration
with clearly labelled signals that I could chose to ignore rather than
a single "my_In/out" that I then had to work out where everything was
supposed to connect.

Also, if this is on an FPGA then everything, whether it's used or not,
is going going to be connected to the same pins on the FPGA
regardless, so from an implementation point of view your PIN
assignments are far easier to maintain (because they're static).
The core is to be used on an FPGA but it's a piece of "internal" IP;
none of the I/O on the core connects to pins. -Kevin
 
M

Mike Treseler

Kevin said:
This might work if one is delivering HDL, but not if one is delivering a
netlist (as I am). Since the synthesizer doesn't know if a top-level
input is to be connected or left open, default values are ignored at the
top level. The customer that gets a netlist still has to connect up the
"unused" inputs.

I'll take the source code option please ;)
How much will that cost me?

-- Mike Treseler
 
K

Kevin Neilson

KJ said:
This might work if one is delivering HDL, but not if one is delivering a
netlist (as I am). Since the synthesizer doesn't know if a top-level
input is to be connected or left open, default values are ignored at the
top level. The customer that gets a netlist still has to connect up the
"unused" inputs. -Kevin

I take that back--when instantiating a netlist in HDL (either type) you
are allowed (at least by Xilinx's NGDBUILD) to leave i/o unconnected.
So like you describe, you can put all the possible i/o on the top level
but give the customer an instantiation template that only contains the
i/o he'll need for his configuration.

I was a bit confused because I thought that leaving a signal
"unconnected" meant that it still had to be declared in the VHDL
component instantiation and tied to "OPEN". I didn't understand you
could just actually leave it completely unmentioned. In Verilog all of
the i/o have to be mentioned in then instantiation, even if outputs are
left unconnected. Unused inputs have to be tied low (to a
properly-sized constant) in the instantiation and can't be assigned
default values in the module itself. This is kind of a nice feature of
VHDL, and surprising, since Verilog is normally the more permissive of
the two.
-Kevin
 
K

Kevin Neilson

Mike said:
I'll take the source code option please ;)
How much will that cost me?

-- Mike Treseler

I'd take the source code too. But marketing doesn't like things that
are easily portable to competing architectures. I say "easily" because
many netlists are resynthesizable with a little effort. -Kevin
 

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,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top