Goto page Previous 1, 2
Sudoer
Guest
Sat Jul 24, 2010 8:29 pm
So I've started using records as ports with client/server records for
input and output. I also have a combined version of each record, and
wherever I use the records I have a procedure that combined the client/
server records into a single record - in this way I have a single
interface with both in and out ports, but as opposed to inout, I don't
risk getting confused - I get an error when I assign to the wrong
direction.
The issue is, it's a bit cumbersome. For each interface I have 6
records (client, server, combined, client unconstrained array, server
unconstrained array, combined unconstrained array, so that I can have
a variable number of items connected to the interface), and 4
procedures (make client in and server out, make server in and client
out, and those two again, but for the unconstrained arrays).
Some quick musings/questions... I don't suppose I can overload the
procedures based on in/out, that way I'd only need two functions (one
for individual "bundles" as I call the records, and one for
"collections", which is what I call the unconstrained arrays of
bundles) and never risk using the wrong one on the wrong side of the
interface.
Next, is there any way for me to combine two records into a new
records - sort of a multiple inheritance? Right now I just list all
the variables in the server and client side records a second time into
the combined record, but if I ever change one of the server of client
records, I'll need to remember to change the combined record and the
procedures I use to change them... I could just list the server and
client records in the combined record, but then that defeats the
purpose of combining them into a single interface...
Any VHDL veterans know a cleaner solution to merging the client and
server records?
Thanks!
Sudoer
Guest
Sat Jul 24, 2010 8:32 pm
On Jul 24, 1:29 pm, Sudoer <TheProperN...@psychophile.com> wrote:
Quote:
So I've started using records as ports with client/server records for
input and output. I also have a combined version of each record, and
wherever I use the records I have a procedure that combined the client/
server records into a single record - in this way I have a single
interface with both in and out ports, but as opposed to inout, I don't
risk getting confused - I get an error when I assign to the wrong
direction.
The issue is, it's a bit cumbersome. For each interface I have 6
records (client, server, combined, client unconstrained array, server
unconstrained array, combined unconstrained array, so that I can have
a variable number of items connected to the interface), and 4
procedures (make client in and server out, make server in and client
out, and those two again, but for the unconstrained arrays).
Some quick musings/questions... I don't suppose I can overload the
procedures based on in/out, that way I'd only need two functions (one
for individual "bundles" as I call the records, and one for
"collections", which is what I call the unconstrained arrays of
bundles) and never risk using the wrong one on the wrong side of the
interface.
Next, is there any way for me to combine two records into a new
records - sort of a multiple inheritance? Right now I just list all
the variables in the server and client side records a second time into
the combined record, but if I ever change one of the server of client
records, I'll need to remember to change the combined record and the
procedures I use to change them... I could just list the server and
client records in the combined record, but then that defeats the
purpose of combining them into a single interface...
Any VHDL veterans know a cleaner solution to merging the client and
server records?
Thanks!
Oh, and now whenever I try to simulate in iSim I get a compiler
assertion error saying I should open a Xilinx webcase. Of course
they'll just ask me to send them my source, which I can't, and it
wouldn't resolve my issue this century. That said, it synthesizes
nicely... (Although simulation is rather of crucial for me...)
Brian Drummond
Guest
Sat Jul 24, 2010 9:30 pm
On Sat, 24 Jul 2010 10:29:18 -0700 (PDT), Sudoer <TheProperNoun_at_psychophile.com>
wrote:
Quote:
The issue is, it's a bit cumbersome.
Working first, elegant later :-)
I find it much easier to clean up (heh, refactor they call it now) something
that's basically working.
Quote:
Some quick musings/questions... I don't suppose I can overload the
procedures based on in/out, that way I'd only need two functions (one
for individual "bundles" as I call the records, and one for
"collections", which is what I call the unconstrained arrays of
bundles) and never risk using the wrong one on the wrong side of the
interface.
Without checking the LRM, I would expect overloading based on argument mode to
work.
Quote:
Next, is there any way for me to combine two records into a new
records - sort of a multiple inheritance?
Records can contain records, if that's what you mean.
Quote:
Any VHDL veterans know a cleaner solution to merging the client and
server records?
- Brian
Brian Drummond
Guest
Sat Jul 24, 2010 9:38 pm
On Sat, 24 Jul 2010 12:06:17 -0700 (PDT), Sudoer <TheProperNoun_at_psychophile.com>
wrote:
Quote:
On Jul 24, 2:44 pm, Brian Drummond <brian_drumm...@btconnect.com
wrote:
On Sat, 24 Jul 2010 10:32:53 -0700 (PDT), Sudoer <TheProperN...@psychophile.com
wrote:
In ISE10, ISIM would crash (Segment Violation) returning an access type
(specifically Line, = access-to-string) from a function. Pass the access type as
an OUT parameter from a procedure, and it worked fine...
- Brian
It turns out the crashing had nothing to do with the records as ports
or merging them in a single record on each end -
Figures.
Quote:
Kind of hard to tell when
all you get is an assert out of Xilinx's compiler with nothing but an
error indicating which line in their code it occurred on (less useful
since we don't have their code...)
Even if you trace that sort of error to a real mistake in your code, it's still
worth reporting as a Webcase, with the simplest possible illustrating case.
It ought to fail compilation with a meaningful message rather than crash
randomly.
I believe there are some good guys behind ISIM who want to make a good product
of it ... you just have to reach them through the lolcats providing first level
support.
At one time I had 8 open Webcases, and 5 of them were real ISIM bugs.
Some of them have even been fixed...
Quote:
There's no way for me to use a function as
the target of an alias, is there? (Man would that be a nice feature...)
Heh, in Ada you can "rename" (=alias) functions as well as anything else.
But I would expect overloading to work for your purpose.
- Brian
Sudoer
Guest
Sat Jul 24, 2010 10:06 pm
On Jul 24, 2:44 pm, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
Quote:
On Sat, 24 Jul 2010 10:32:53 -0700 (PDT), Sudoer <TheProperN...@psychophile.com
wrote:
Any VHDL veterans know a cleaner solution to merging the client and
server records?
Thanks!
Oh, and now whenever I try to simulate in iSim I get a compiler
assertion error saying I should open a Xilinx webcase. Of course
they'll just ask me to send them my source, which I can't, and it
wouldn't resolve my issue this century. That said, it synthesizes
nicely... (Although simulation is rather of crucial for me...)
ISIM is finally starting to look like a real simulator, but still has quite a
few errors.
I suggest a divide-and-conquer to find the specific construct that kills it -
there may well be a usable workround. I can't make specific suggestions of
course; but one anecdote:
In ISE10, ISIM would crash (Segment Violation) returning an access type
(specifically Line, = access-to-string) from a function. Pass the access type as
an OUT parameter from a procedure, and it worked fine...
- Brian
It turns out the crashing had nothing to do with the records as ports
or merging them in a single record on each end - it had to do with a
TO_SLV I wrote for some special datatypes. Kind of hard to tell when
all you get is an assert out of Xilinx's compiler with nothing but an
error indicating which line in their code it occurred on (less useful
since we don't have their code...) Now I'm getting a silly error that
leads me to believe somewhere I'm reading AND writing to an in or out
port somewhere, but only on some of of the records as ports. More
interesting is that it synthesized without so much as a squeak.
Since Simulation will likely be possible, that still begs the question
of whether or not there's a neater way for me to handle the merged/
combination record as port. There's no way for me to use a function as
the target of an alias, is there? (Man would that be a nice feature...)
Sudoer
Guest
Mon Jul 26, 2010 7:31 pm
On Jul 24, 4:38 pm, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
Quote:
On Sat, 24 Jul 2010 12:06:17 -0700 (PDT), Sudoer <TheProperN...@psychophile.com
wrote:
On Jul 24, 2:44 pm, Brian Drummond <brian_drumm...@btconnect.com
wrote:
On Sat, 24 Jul 2010 10:32:53 -0700 (PDT), Sudoer <TheProperN...@psychophile.com
wrote:
In ISE10, ISIM would crash (Segment Violation) returning an access type
(specifically Line, = access-to-string) from a function. Pass the access type as
an OUT parameter from a procedure, and it worked fine...
- Brian
It turns out the crashing had nothing to do with the records as ports
or merging them in a single record on each end -
Figures.
Kind of hard to tell when
all you get is an assert out of Xilinx's compiler with nothing but an
error indicating which line in their code it occurred on (less useful
since we don't have their code...)
Even if you trace that sort of error to a real mistake in your code, it's still
worth reporting as a Webcase, with the simplest possible illustrating case.
It ought to fail compilation with a meaningful message rather than crash
randomly.
I believe there are some good guys behind ISIM who want to make a good product
of it ... you just have to reach them through the lolcats providing first level
support.
At one time I had 8 open Webcases, and 5 of them were real ISIM bugs.
Some of them have even been fixed...
There's no way for me to use a function as
the target of an alias, is there? (Man would that be a nice feature...)
Heh, in Ada you can "rename" (=alias) functions as well as anything else.
But I would expect overloading to work for your purpose.
- Brian
So, it turns out my procedure to merge all the client and server side
of the records as ports was the issue. Because I took one record as
in, one record as out, and has the merged record be inout, well ...
here's an example...
type client_record is record
A : std_logic;
end record;
type server_record is record
B : std_logic;
end record;
type both_record is record
A : std_logic;
B : std_logic;
end record;
procedure merger(
signal client : in client_record;
signal server : out server_record;
signal both : inout both_record) IS
BEGIN
both.A <= client.A;
server.B <= both.B;
END merger
All looks well. Then when I try the following:
....
signal client : client_record;
signal server : server_record;
signal both : both_record;
begin
merger( client, server, both ); -- Line produces an error
...
both.B <= '1'; -- Line produces an error
....
The issue here is that both merger and the line below it are assigning
to the "both" record, so Xilinx's XST asks me for a resolution
function even though they never assign to the same members.
My question is: is this a VHDL thing, or is this a Xilinx thing?
Brian Drummond
Guest
Mon Jul 26, 2010 10:08 pm
On Mon, 26 Jul 2010 09:31:46 -0700 (PDT), Sudoer <TheProperNoun_at_psychophile.com>
wrote:
Quote:
So, it turns out my procedure to merge all the client and server side
of the records as ports was the issue. Because I took one record as
in, one record as out, and has the merged record be inout, well ...
here's an example...
type client_record is record
A : std_logic;
end record;
type server_record is record
B : std_logic;
end record;
type both_record is record
A : std_logic;
B : std_logic;
end record;
procedure merger(
signal client : in client_record;
signal server : out server_record;
signal both : inout both_record) IS
BEGIN
both.A <= client.A;
server.B <= both.B;
END merger
All looks well. Then when I try the following:
...
signal client : client_record;
signal server : server_record;
signal both : both_record;
begin
merger( client, server, both ); -- Line produces an error
...
both.B <= '1'; -- Line produces an error
...
The issue here is that both merger and the line below it are assigning
to the "both" record, so Xilinx's XST asks me for a resolution
function even though they never assign to the same members.
My question is: is this a VHDL thing, or is this a Xilinx thing?
This is a record thing, and the reason why I suggested that all members of a
record have the same direction (and others have lobbied for records with bidir
members in future VHDL versions.)
Here, "both" is not really of mode "inout" - one member is pure "in" and the
other is pure "out".
You can bodge it with inout, but it would need a resolution function (which
would pass the problem to std_logic resolution, and the "in" member would have
to be driven with 'Z', or it would resolve to 'X')
But I really wouldn't want to do it that way. Using a separate record in each
direction is less tidy, but it works.
- Brian
Andy
Guest
Tue Jul 27, 2010 8:02 pm
I have not lobbied in any of your list of the "right places". A review
of my posting record here would indicate that I have advocated for
this for a long time (perhaps in hopes of someone else championing the
issue

.
Andy
Andy
Guest
Tue Jul 27, 2010 8:07 pm
On Jul 23, 2:31 am, Thomas Stanka <usenet_nospam_va...@stanka-web.de>
wrote:
Quote:
On 22 Jul., 15:58, Brian Drummond <brian_drumm...@btconnect.com
wrote:
Is there any way for me to "bring" ports from entities lower in the
hierarchy up to the top without threading them all the way through?
There are "shared variables" but they won't help you if the intent is synthesis.
They can be used as test points in testbenches so that you don't need to bring
internal test points all the way up the hierarchy, but synthesis support for
these is likely to be somewhere between poor and non-existent.
You can use global signals in your design and will end up with a good
synthesis result (at least with Synplify)
In therory this would allow you to build all entities without ports
and save a lot of signal routing through hierarchies.
Nevertheless I would recommend not to use global signals in rtl
because you will likely break on several points when maintaining the
code.
bye Thomas
I have not tried it lately, but Synplify used to accept a global
signal declaration, but each invocation was a separate, local signal
and they were not global. I don't remember the details about what
constituted a separate invocation, but I know that two architectures
of two entities both had the signal, but not connected between them.
This was a long time ago, and they may well have fixed it by now.
Andy
Andreas Ehliar
Guest
Wed Jul 28, 2010 11:21 am
On 2010-07-22, Andy <jonesandy_at_comcast.net> wrote:
Quote:
others (receivers or ignorers) always drive 'Z's. No muxes, the
synthesis tool just figures it out.
The only downside is you can't use enums, integers, booleans, etc.
Another downside is that you may cause a mismatch between synthesis
and simulation if you are not careful.
Consider the following part of a process:
if ctrl = '1' then
led1_o <= data;
end if;
if ctrl = '0' then
led2_o <= data;
end if;
Lets just say that this code is unlikely to behave in the same way in
both synthesis and simulation if ctrl is set to 'Z'.
regards
/Andreas
Andy
Guest
Wed Jul 28, 2010 6:49 pm
In most cases where you would use an inout port instead of an in port
or an out port, if ctrl = 'Z', then there was no driver connected, and
neither of these if statements will get implemented, just like neither
of these will be executed in simulation. But no errors would be
generated in simulation (warnings are generated in synthesis). If the
inout is used for a truly bidirectional signal (that would be
implemented with two unidirectional signals), you would still have to
safely handle the condition when nobody was driving (or nobody's mux
input was enabled).
I use home-grown functions is1() and is0() that test for meta-values,
and convert weak values. Is1(ctrl) asserts an error if ctrl is 'Z' (or
'-', 'X', 'U', or 'W'), but returns true if ctrl is 'H' or '1'. I can
default a tri-state signal to 'H' or 'L' instead of 'Z' (or just
create a continuous driver to 'H' or 'L'), but that might hide cases
where a driver was mistakenly omitted.
I use is1() or is0() everywhere I need a boolean condition, not just
when I think there might be a meta-value. I use Rising_edge(clk)
because it correctly handles transitions to and from weak values (not
to mention it is more self-documenting).
Andy
Goto page Previous 1, 2