How to drive record fields from procedure AND testbench?

J

Joe Vanderwall

Hi folks,

I am having a problem that is beyound my present VHDL capabilities.

I am trying to model a bus in a testbench using the following
(incomplete) record:

type rec is record
rd, wr, waitreq : std_logic;
writedata : std_logic_vector(31 downto 0);
end record;

(I left a bunch out for brevity).

- rd, wr, and writedata are driven by the master of the bus.
- waitreq is driven by the slave, indicating when it can't immediately
satisfy a master request.

I then have some useful functions having prototypes:

procedure InitBus( signal busRec: inout rec );
procedure WriteValue( signal busRec: inout rec;
address: integer;
value: integer );

And in my code I hook things up:

architecture ...
signal busRec : rec;
...
begin
DUT_inst : DUT port map ( wr=>wr, rd=>rd,
waitreq=>waitreq, readdata=>readdata,
... );

wr <= rec.wr;
rd <= rec.rd;
writedata <= rec.writedata;
rec.waitreq <= waitreq;

InitBus( rec );

end;

This setup causes an error, presumably because some records are driven
from the procedure, and others from the DUT.

How do the "professionals" create and use a record that has some
fields driving one way, and others driving the other?

I've successfully used this arrangement before, but I managed to have
all the fields of the record driven from the procedures. In this case
I now have a waitreq, which is an integral part of the bus model,
driven by the DUT . Is it possible to bring this signal into the
procedures using a single record? Or do things have to get messy?

A further question is when I have a birectional data bus (driven by
the master during writes, driven by the DUT during reads). Example:

begin
DUT_inst: DUT port map ( data => bidir_data ... );
rec.bidir_data <= bidir_data;
end;

Can I even manage bidirection data buses with the record approach?

Can someone suggest further reading on how to do this stuff? An
admittedly cursory Google search brought up all kinds of stuff on
records, but nothing that I could relate to my problem. Obviously,
though, this sort of thing must be done all the time in testbenches,
but I somehow haven't come across. I certainly don't want to manually
write out bus transaction without procedures.

Joe
 
J

Jim Lewis

Joe,
Initialize the record element to 'Z'.

Step 1 declare the following constant after the place in
the package where you declare "rec":

constant INIT_REC : rec := ('Z', 'Z', 'Z', (others => 'Z') ;


Step 2 initialize the signal declaration (in the testbench):
signal busRec : rec := INIT_REC ;


This is not in books, however, it is in our testbench classes:
http://www.synthworks.com/vhdl_testbench_verification.htm

In the class we also use a similar technique for our transaction
based models. Some details are in the testbench paper at:
http://www.synthworks.com/papers

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
M

Mike Treseler

Joe Vanderwall wrote :
I am trying to model a bus in a testbench using the following
(incomplete) record:

type rec is record
rd, wr, waitreq : std_logic;
writedata : std_logic_vector(31 downto 0);
end record;

How do the "professionals" create and use a record that has some
fields driving one way, and others driving the other?

No easy answers.
The record direction problem is discussed in this thread:
http://groups.google.com/groups?q=gaggle.DSPaddr

The signal scope problem is discussed in this thread:
http://groups.google.com/groups?q=vhdl+recap+clumsy

-- Mike Treseler
 
P

Peter Sommerfeld

Hi Mike,

Thanks for the reply. I must be on the right track, because it looks
like I have been doing what you suggested in
http://groups.google.com/groups?q=gaggle.DSPaddr. However, the InitBus
call causes compile errors in my design. If I comment out the InitBus
call, it compiles fine. (Note that I'm not tackling the inout
(tristate) problem at the moment, just the problem of record fields
that are either driven from procedures or from the DUT.)

In the thread you cited, no procedure calls are shown, so I'm
wondering if this is not possible? Why exactly does my procedure call
cause problems with resolution?

I'm wondering if the VHDL standard dictates to not look inside the
procedure to check if there really would be a resolution problem. My
evidence for this is that even if my procedure contains nothing at
all, it still will not compile. When the procedure is empty, in my
mind it should be the the same as not having the procedure present at
all (a case which compiles fine). Strange. Is the prototype for the
InitBus procedure correct for a record that is driven in and out of
the procedure?

Another way for the compile to succeed is to remove the driving of
rec.waitreq, so the problems are hinging on the fact that different
fields being driven from different sources.

prototype:

procedure InitBus( signal busRec: inout rec );

architecture:

-- connections
wr <= rec.wr;
rd <= rec.rd;
writedata <= rec.writedata;
rec.waitreq <= waitreq;

-- this line will cause compile to fail:
InitBus( rec );

Joe
 
M

Mike Treseler

Peter said:
Thanks for the reply. I must be on the right track, because it looks
like I have been doing what you suggested in
http://groups.google.com/groups?q=gaggle.DSPaddr. However, the InitBus
call causes compile errors in my design.

You have stumbled onto the procedure scope problem.
Re-read that thread and see the lines I added
to my example architecture below.

-- Mike Treseler


------------------------------------------------------------
architecture synth of signal_structure is
-- note, I changed your type to data in and out signals

type DSPIF_type is
record
DSPaddr : std_logic_vector(23 downto 0);
DSPdata_in : std_logic_vector(31 downto 0);
DSPdata_out : std_logic_vector(31 downto 0);
nDHOLD : std_logic;
nDHOLDA : std_logic;
nDPAGE : std_logic_vector(3 downto 0);
nDSTRB : std_logic;
nDBE : std_logic_vector(3 downto 0);
nDOE : std_logic;
nDWE : std_logic;
nDRDY : std_logic;
end record;

signal gaggle : DSPIF_type;
signal output_enabled : boolean;
-------------------------------------------------------------------------------
-- Added proc example in scope
procedure InitBus( signal gaggle: inout DSPIF_type )
is begin end InitBus;
-------------------------------------------------------------------------------
begin
-- wire up signal structure to pins
gaggle.DSPaddr <= DSPaddr;
gaggle.DSPdata_in <= DSPdata;
-- . . . (rest of INs go here)
-- then OUTs:
nDHOLD <= gaggle.nDRDY;
nDRDY <= gaggle.nDRDY;
DSPdata <= gaggle.DSPdata_out when output_enabled
else (DSPdata'range => 'Z');

-- processes using the gaggle signals go here

end architecture synth;


-- Mike Treseler
 
P

Peter Sommerfeld

Hi Mike,

Yes I found my problem, and it was unfortunately in a part of my
record that I didn't post. In my record, I had a field that was of the
physical type time which I was using inside my procedures for certain
delays. ie:

type rec is record
...
clock_period : time;
...
end record;

So while I was assuming a signal-driving issue to be the problem, it
was this field (which is still bizarre, because I set this field only
once and never write it again, therefore, I would have thought, it
could not be a problem). Anyways, I replaced this field with a clock
signal which makes more sense now anyways and everything works great,
and thanks to yours and Jim's replies, I understand what's going on
much better too. I had better post the whole thing the next time I
have a problem like this.

-- Pete
 
J

Jim Lewis

Peter,
You can convert time to std_logic_vector by converting
it to integer first:

i_int <= NOW / 1 ns ; -- now an integer value with ns units

time_slv <= std_logic_vector(to_unsigned(i_int, time_slv'length)) ;

Cheers,
Jim
Hi Mike,

Yes I found my problem, and it was unfortunately in a part of my
record that I didn't post. In my record, I had a field that was of the
physical type time which I was using inside my procedures for certain
delays. ie:

type rec is record
...
clock_period : time;
...
end record;

So while I was assuming a signal-driving issue to be the problem, it
was this field (which is still bizarre, because I set this field only
once and never write it again, therefore, I would have thought, it
could not be a problem). Anyways, I replaced this field with a clock
signal which makes more sense now anyways and everything works great,
and thanks to yours and Jim's replies, I understand what's going on
much better too. I had better post the whole thing the next time I
have a problem like this.

-- Pete


--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
J

Jim Lewis

Peter,
As a PS to my other post, to date I have found
that if I want to work with a single record,
I have been limited to std_logic family.

I have tried tinkering with integers and resolution
functions, but have had problems with resolving a value
to drive when the record field is not to be driven.
It seems that the resolution function is called at the
block level and there currently no way I could find to
work around this.

This is a topic we are kicking around in the VHDL-200X
effort. I had wished for it to be part of the fast track
effort and I made a proposal, but it is not clear even to
me that the proposal is the best long term solution, so I
don't want to push it. My preference is to see what comes
up when we give more time and consideration to the problem.

For more on the vhdl-200x effort, see:
http://www.eda.org/vhdl-200x

IEEE standards are open to public participation.

Best Regards,
Jim

Hi Mike,

Yes I found my problem, and it was unfortunately in a part of my
record that I didn't post. In my record, I had a field that was of the
physical type time which I was using inside my procedures for certain
delays. ie:

type rec is record
...
clock_period : time;
...
end record;

So while I was assuming a signal-driving issue to be the problem, it
was this field (which is still bizarre, because I set this field only
once and never write it again, therefore, I would have thought, it
could not be a problem). Anyways, I replaced this field with a clock
signal which makes more sense now anyways and everything works great,
and thanks to yours and Jim's replies, I understand what's going on
much better too. I had better post the whole thing the next time I
have a problem like this.

-- Pete


--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
P

Peter Sommerfeld

Hi Jim,

Yes I would love to participate in the VHDL-200X effort. It's nice to
see it's open to the non-members. Is there a target release date for
VHDL-200X?

This problem of the fields of a record appearing to be resolved as a
group, and not individually, is particularly vexing to me. Hopefully I
won't have to deal with it in the next VHDL version.

-- Pete
 
J

Jim Lewis

Peter,
Yes I would love to participate in the VHDL-200X effort. It's nice to
see it's open to the non-members. Is there a target release date for
VHDL-200X?
VHDL-200X is a multi-phased effort.

The first phase is fast-track. These are critical update
items. It is due to have ready for ballot some time this
year. Details on this are at:
http://www.eda.org/vhdl-200x/vhdl-200x-ft

There are things that will go out with FT that are not on
the FT proposal list. These are items from the other
groups that are working them as separate issues.
This problem of the fields of a record appearing to be resolved as a
group, and not individually, is particularly vexing to me. Hopefully I
won't have to deal with it in the next VHDL version.

It has been vexing me too. I don't think we will have the
solution for fast track, however, it is one of my high
priorities so I will be pushing for it making the revision
that follows fast track.

Cheers,
Jim



--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
T

Tom Hawkins

Hi Jim,

Yes I would love to participate in the VHDL-200X effort. It's nice to
see it's open to the non-members. Is there a target release date for
VHDL-200X?

This problem of the fields of a record appearing to be resolved as a
group, and not individually, is particularly vexing to me. Hopefully I
won't have to deal with it in the next VHDL version.

-- Pete

Pete, I'm sure you're aware that Confluence does not have this
limitation:

component some_comp *gaggle with local_source external_reference is
gaggle.from_here <- local_source
gaggle.from_somewhere_else -> external_reference
end

And in the second thread that Mike referenced, the author mentioned
partial function applications. As a functional programming language,
Confluence has a few forms of partial functions:

system = {my_component _ _ _}

This allows you to instantiate a component with the ports unconnected,
then pass around the resulting system to be wired up later.

-Tom
 
P

Peter Sommerfeld

Hi Tom,

Yes I was, I think, a very early adopter of Confluence. I find the
language very impressive. Your FFT core on OpenCores is what got me
interested in it.

The biggest problem has been convincing my company to consider the
tool, which I have so far been unsuccessful with. As is typical, a
company adopts certain standards and practices, and the intertia is
difficult to overcome. Hopefully someday ...

Not that I'm unhappy with VHDL, in fact as long as I can work with the
latest FPGAs with whatever language I think I'll be very happy, but
from my tests I can write IP faster in Confluence than VHDL, and the
learning curve is shorter.

-- Pete
 

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

Latest Threads

Top