Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Can a signal be resolved as 'most recent event wins'?

Reply
Thread Tools

Can a signal be resolved as 'most recent event wins'?

 
 
Iwo Mergler
Guest
Posts: n/a
 
      09-17-2007
Hi,

This is an exercise in simplifying port maps in
testbench code.

I'm trying to use a record as a bus with signals
going in opposite directions. Is this possible
in VHDL?

Something like this:

type mytype is
record
cmd : with_the_flow type;
busy : against_the_flow type;
end record;

The idea is to have this record be an in-signal
for entity A and an out-signal for entity B.
Which makes signal.busy an out signal for entity
A and an in-signal for entity B.

I'm fairly sure that no such thing exists in VHDL.

To solve the problem, I tried to describe the
record as a resolved bus. The idea is to declare the
bus as inout signals for both entities and fix the
multiple driver problem by resolving the individual
record elements.

Entities A & B know which end of the bus they represent,
so only A ever drives signal.busy and only B ever drives
signal.cmd.

I think the problem boils down to having to resolve such
that the most recent assignment wins. Typical resolution
functions will look at the signal values, I would like
to look at the signal attributes.

Unfortunately, I don't seem to be able to get at the
attributes of the component signals of the record, only
the attributes of the record itself:

package test is
type cmd_t is (idle,read,write);
type operation_t is
record
cmd : cmd_t;
busy : boolean;
end record;
type op_vector is array (integer range <>) of operation_t;
function op_resolve(ov : in op_vector) return operation_t;
subtype op_t is op_resolve operation_t;
end test;

package body test is
function op_resolve(ov : in op_vector) return operation_t is
variable f2p_i : integer := 0;
variable p2f_i : integer := 0;
variable result : operation_t;
begin
-- Current assignment wins
for i in ov'range loop -- OK
if ov(i).cmd'event then -- This breaks
f2p_i := i;
end if;
if ov(i).busy'event then
p2f_i := i;
end if;
end loop;
result.cmd := ov(f2p_i).cmd;
result.busy := ov(p2f_i).busy;
return result;
end function op_resolve;
end package body;

The compiler says

Model Technology ModelSim ALTERA vcom 6.1g Compiler 2006.08 Aug 12 2006
-- Loading package standard
-- Compiling package test
-- Compiling package body test
-- Loading package test
** Error: Z:/resolving.vhd(27): Attribute "event" requires a static signal
prefix.
** Error: Z:/resolving.vhd(30): Attribute "event" requires a static signal
prefix.
** Error: Z:/resolving.vhd(39): VHDL Compiler exiting

Is there a way to get at the record member attributes?

Kind regards,

Iwo

 
Reply With Quote
 
 
 
 
Mike Treseler
Guest
Posts: n/a
 
      09-17-2007
Iwo Mergler wrote:

> This is an exercise in simplifying port maps in
> testbench code.
> I'm trying to use a record as a bus with signals
> going in opposite directions. Is this possible
> in VHDL?


This is problematic. See:
http://groups.google.com/groups/sear...ucture+norberg
(and many others)

Consider using remote procedures as an alternative
http://home.comcast.net/~mike_tresel...c_overload.vhd

Good luck.

-- Mike Treseler
 
Reply With Quote
 
 
 
 
Jim Lewis
Guest
Posts: n/a
 
      09-17-2007
Iwo,
I do this by individually resolving the elements of
the record. The easy way to do this is to assign
the driving value of a port to an identity value when
it is not being driven. The obvious example is to drive
a 'Z' for a std_logic element of the record.

For other types, you can write a resolution function by
deciding that 0 makes a good identity element.
The package ResolutionPkg.vhd shows two different ways
to do this (I generally use resolved):
http://www.synthworks.com/papers/ResolutionPkg.vhd

Cheers,
Jim



> Hi,
>
> This is an exercise in simplifying port maps in
> testbench code.
>
> I'm trying to use a record as a bus with signals
> going in opposite directions. Is this possible
> in VHDL?
>
> Something like this:
>
> type mytype is
> record
> cmd : with_the_flow type;
> busy : against_the_flow type;
> end record;
>
> The idea is to have this record be an in-signal
> for entity A and an out-signal for entity B.
> Which makes signal.busy an out signal for entity
> A and an in-signal for entity B.
>
> I'm fairly sure that no such thing exists in VHDL.
>
> To solve the problem, I tried to describe the
> record as a resolved bus. The idea is to declare the
> bus as inout signals for both entities and fix the
> multiple driver problem by resolving the individual
> record elements.
>
> Entities A & B know which end of the bus they represent,
> so only A ever drives signal.busy and only B ever drives
> signal.cmd.
>
> I think the problem boils down to having to resolve such
> that the most recent assignment wins. Typical resolution
> functions will look at the signal values, I would like
> to look at the signal attributes.
>
> Unfortunately, I don't seem to be able to get at the
> attributes of the component signals of the record, only
> the attributes of the record itself:
>
> package test is
> type cmd_t is (idle,read,write);
> type operation_t is
> record
> cmd : cmd_t;
> busy : boolean;
> end record;
> type op_vector is array (integer range <>) of operation_t;
> function op_resolve(ov : in op_vector) return operation_t;
> subtype op_t is op_resolve operation_t;
> end test;
>
> package body test is
> function op_resolve(ov : in op_vector) return operation_t is
> variable f2p_i : integer := 0;
> variable p2f_i : integer := 0;
> variable result : operation_t;
> begin
> -- Current assignment wins
> for i in ov'range loop -- OK
> if ov(i).cmd'event then -- This breaks
> f2p_i := i;
> end if;
> if ov(i).busy'event then
> p2f_i := i;
> end if;
> end loop;
> result.cmd := ov(f2p_i).cmd;
> result.busy := ov(p2f_i).busy;
> return result;
> end function op_resolve;
> end package body;
>
> The compiler says
>
> Model Technology ModelSim ALTERA vcom 6.1g Compiler 2006.08 Aug 12 2006
> -- Loading package standard
> -- Compiling package test
> -- Compiling package body test
> -- Loading package test
> ** Error: Z:/resolving.vhd(27): Attribute "event" requires a static signal
> prefix.
> ** Error: Z:/resolving.vhd(30): Attribute "event" requires a static signal
> prefix.
> ** Error: Z:/resolving.vhd(39): VHDL Compiler exiting
>
> Is there a way to get at the record member attributes?
>
> Kind regards,
>
> Iwo
>

 
Reply With Quote
 
Paul Uiterlinden
Guest
Posts: n/a
 
      09-17-2007
Iwo Mergler wrote:

> Hi,
>
> This is an exercise in simplifying port maps in
> testbench code.
>
> I'm trying to use a record as a bus with signals
> going in opposite directions. Is this possible
> in VHDL?


Yes, by the use of a proper resolution function and handshake mechanism this
is possible.

See http://groups.google.com/group/comp....5574c4e8034cd8

It shows quite some similarities with your approach.

--
Paul Uiterlinden
www.aimvalley.nl
e-mail addres: remove the not.
 
Reply With Quote
 
Iwo Mergler
Guest
Posts: n/a
 
      09-18-2007
Iwo Mergler wrote:
> Hi,
>
> This is an exercise in simplifying port maps in
> testbench code.

<snip>

Mike, Jim, Paul,

thank you very much for the pointers. All three responses
together solve my problem.

Jim's suggestion, as implemented in Paul's example shows
resolution by signal value. I now know that an undriven
signal assumes a default value, the leftmost element in
an enumeration. This solves my problem - I can resolve
the signals this way.

Mike, what you describe as remote procedures is exactly
what I'm trying to do. I was under the illusion that
the idea was so clever that there was no need to research
other people's solutions. I feel suitably chastised.

This is a bus simulator for use in a testbench. It is
implemented as a package with a whole bunch of bus
activity procedures and an entity which is the actual
bus driver. They communicate over an inout signal which
is my record. The procedures contain handshake waits with
the bus driver which effectively 'block' the procedure
calls for the duration of the bus sequence.

The resulting testbench looks roughly like this:

....
use work.mypackage.all;
....
architecture tb of testbench is
....
component thebusexerciser is
port (
-- global
clk : in std_logic;
reset : in std_logic;
op : inout bus_op_t;

-- bus interface
...
);
end component;

signal op : bus_op_t;

....
begin
master : thebusexerciser
port map (
...
op => op;
...
);
...
simulation : process
variable data : bus_data_t;
begin
wait(5); -- waits 5 clock cycles after reset.
bus_write(op,0x"00000000",0x"DEADBEEF");
while bus_read(op,0x"00000008") = 0x"00000000" loop
null; -- polling
end loop;
data := bus_read(op,0x"00000004");
if data /= 0x"12345678" then
scream_in_terror;
end if;
...
end process;

etc.

The idea is to use a simple sequential process to coordinate
the busmaster with other parts of the testbench.

Kind regards,

Iwo

 
Reply With Quote
 
Paul Uiterlinden
Guest
Posts: n/a
 
      09-18-2007
Iwo Mergler wrote:

> The resulting testbench looks roughly like this:
>
> ...
> use work.mypackage.all;
> ...
> architecture tb of testbench is
> ...
> component thebusexerciser is
> port (
> -- global
> clk : in std_logic;
> reset : in std_logic;
> op : inout bus_op_t;
>
> -- bus interface
> ...
> );
> end component;
>
> signal op : bus_op_t;
>
> ...
> begin
> master : thebusexerciser
> port map (
> ...
> op => op;
> ...
> );
> ...
> simulation : process
> variable data : bus_data_t;
> begin
> wait(5); -- waits 5 clock cycles after reset.
> bus_write(op,0x"00000000",0x"DEADBEEF");
> while bus_read(op,0x"00000008") = 0x"00000000" loop
> null; -- polling
> end loop;
> data := bus_read(op,0x"00000004");
> if data /= 0x"12345678" then
> scream_in_terror;
> end if;
> ...
> end process;
>
> etc.
>
> The idea is to use a simple sequential process to coordinate
> the busmaster with other parts of the testbench.


Yup, that's the way I use it.

A problem that is see with your example is in this piece:

while bus_read(op,0x"00000008") = 0x"00000000" loop
null; -- polling
end loop;

Subprogram bus_read clearly is a function and it must have a wait statement
inside (or calls another procedure with a wait statement). That is a
combination that is not possible in VHDL. So bus_read should be a
procedure.

The result value should either be returned via an out or inout mode
parameter of bus_read, or it could be retrieved from signal op with a
second function, like get_data.

I use the latter solution, because the first solution tends to clutter the
bus_read procedure with a lot of parameters. And if you want to make them
optional, you end up with a whole lot of overloaded procedures.

So my solution would be:

bus_read(op, 0x"00000008");
poll: while get_data(op) = 0x"00000000" loop
bus_read((op, 0x"00000008");
end loop poll;

bus_read(op, 0x"00000004");
if get_data(op) /= 0x"12345678" then
scream_in_terror;
end if;

The duplicated read in the poll part can be avoided with an exit statement

poll: loop
bus_read((op, 0x"00000008");
exit poll when get_data(op) /= 0x"00000000";
end loop poll;

Or if you don't like exit statements, with an extra boolean variable:

variable poll_end: boolean;
...
while not poll_end loop
bus_read((op, 0x"00000008");
poll_end := get_data(op) /= 0x"00000000";
end loop;

Or with a loop-until construct, which VHDL unfortunately does not have...

--
Paul Uiterlinden
www.aimvalley.nl
e-mail addres: remove the not.
 
Reply With Quote
 
Jim Lewis
Guest
Posts: n/a
 
      09-18-2007
Iwo,
> Mike, what you describe as remote procedures is exactly
> what I'm trying to do. I was under the illusion that
> the idea was so clever that there was no need to research
> other people's solutions. I feel suitably chastised.


Been teaching this in our VHDL Testbench classes since the
late 90's. At that time mainly focused on std_logic.

A paper on applying this technique to both subblocks and
chips (and hence not writing duplicating tests at both
levels) is posted here:
http://www.synthworks.com/papers/

under the title:
"Accelerating Verification Through Pre-Use of
System-Level Testbench Components"

I did not start using integer, time, and real resolution
functions until last fall. Ironically Paul U had posted
something about them earlier and I had missed it and instead
I had to learn it in a less direct way. So me too, I wish
I had been collaborating more and sooner.

My current plan is to make more of our packages publicly
available in some form - time permitting.

Cheers,
Jim Lewis
SynthWorks VHDL Training
 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      09-18-2007
Iwo Mergler wrote:

> Mike, what you describe as remote procedures is exactly
> what I'm trying to do. I was under the illusion that
> the idea was so clever that there was no need to research
> other people's solutions. I feel suitably chastised.


The idea is from Jonathan Bromley.
I just coded the simplest possible example.
But I'm happy that it made sense to you.

> This is a bus simulator for use in a testbench. It is
> implemented as a package with a whole bunch of bus
> activity procedures and an entity which is the actual
> bus driver. They communicate over an inout signal which
> is my record. The procedures contain handshake waits with
> the bus driver which effectively 'block' the procedure
> calls for the duration of the bus sequence.


Do your procedures use signals
or process variables to retain
state information?

> The resulting testbench looks roughly like this:


Thanks for the outline. Looks interesting.
Maybe you can make us a small example when
you get it all worked out.

All the verification gurus like the client-server
architecture arbitrating multiple processes,
so it sounds like you are on a solid track.

I prefer to use a single test process
where the only signals are the wires to the UUT.
But I'm an over-the-top procedural guy.

Good luck on your project.

-- Mike Treseler

 
Reply With Quote
 
Iwo Mergler
Guest
Posts: n/a
 
      09-20-2007
Paul Uiterlinden wrote:

> Iwo Mergler wrote:
>
>> The resulting testbench looks roughly like this:
>>
>> ...
>> use work.mypackage.all;
>> ...
>> architecture tb of testbench is
>> ...
>> component thebusexerciser is
>> port (
>> -- global
>> clk : in std_logic;
>> reset : in std_logic;
>> op : inout bus_op_t;
>>
>> -- bus interface
>> ...
>> );
>> end component;
>>
>> signal op : bus_op_t;
>>
>> ...
>> begin
>> master : thebusexerciser
>> port map (
>> ...
>> op => op;
>> ...
>> );
>> ...
>> simulation : process
>> variable data : bus_data_t;
>> begin
>> wait(5); -- waits 5 clock cycles after reset.
>> bus_write(op,0x"00000000",0x"DEADBEEF");
>> while bus_read(op,0x"00000008") = 0x"00000000" loop
>> null; -- polling
>> end loop;
>> data := bus_read(op,0x"00000004");
>> if data /= 0x"12345678" then
>> scream_in_terror;
>> end if;
>> ...
>> end process;
>>
>> etc.
>>
>> The idea is to use a simple sequential process to coordinate
>> the busmaster with other parts of the testbench.

>
> Yup, that's the way I use it.
>
> A problem that is see with your example is in this piece:
>
> while bus_read(op,0x"00000008") = 0x"00000000" loop
> null; -- polling
> end loop;
>
> Subprogram bus_read clearly is a function and it must have a wait
> statement inside (or calls another procedure with a wait statement). That
> is a combination that is not possible in VHDL. So bus_read should be a
> procedure.
>
> The result value should either be returned via an out or inout mode
> parameter of bus_read, or it could be retrieved from signal op with a
> second function, like get_data.
>
> I use the latter solution, because the first solution tends to clutter the
> bus_read procedure with a lot of parameters. And if you want to make them
> optional, you end up with a whole lot of overloaded procedures.
>
> So my solution would be:
>
> bus_read(op, 0x"00000008");
> poll: while get_data(op) = 0x"00000000" loop
> bus_read((op, 0x"00000008");
> end loop poll;
>
> bus_read(op, 0x"00000004");
> if get_data(op) /= 0x"12345678" then
> scream_in_terror;
> end if;
>


Thanks for solving my next problem.
I added a results array to my state record and implemented your suggestion.

Kind regards,

Iwo

 
Reply With Quote
 
Iwo Mergler
Guest
Posts: n/a
 
      09-20-2007
Mike Treseler wrote:
> Iwo Mergler wrote:
>> This is a bus simulator for use in a testbench. It is
>> implemented as a package with a whole bunch of bus
>> activity procedures and an entity which is the actual
>> bus driver. They communicate over an inout signal which
>> is my record. The procedures contain handshake waits with
>> the bus driver which effectively 'block' the procedure
>> calls for the duration of the bus sequence.

>
> Do your procedures use signals
> or process variables to retain
> state information?


Signals. I admit I didn't think of using process variables.
Is there an advantage in doing so?

Kind regards,

Iwo

 
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
resolved signal rehansherwani VHDL 1 06-21-2008 07:45 PM
want info on resolved signal.... Vineeth V VHDL 4 02-27-2007 04:48 PM
Aside from delta cycles and/or resolution functions, how can the effective value of a signal differ from a driving signal of its? Colin Paul Gloster VHDL 0 01-11-2007 01:31 PM
resolved/unresolved signal?! jozo VHDL 1 05-16-2004 02:47 PM
RE: linkbutton event not working (Resolved but still have a question) =?Utf-8?B?YW5kcmV3IFdpZWQ=?= ASP .Net 1 04-27-2004 04:01 AM



Advertisments