Subject: Re: [sv-ec] Asychronous mailbox proposal
From: Arturo Salz (Arturo.Salz@synopsys.com)
Date: Fri Dec 13 2002 - 14:40:35 PST
MessageStuart,
It is possible to wait on dynamically allocated objects. The rule is that the handle
is evaluated at the time at which the statement executes.
The LRM still contains a $wait_var system task to wait for dynamic as well as static
variables, but it is only there as part of the donation. I expect the @ operator to be
able to handle dynamic objects as well. Some committee members have already
suggested that.
Arturo
----- Original Message -----
From: Stuart Swan
To: Arturo Salz ; Kevin Cameron ; sv-ec@eda.org
Cc: david.smith@synopsys.COM ; Mehdi.Mohtashemi@synopsys.COM
Sent: Friday, December 13, 2002 2:08 PM
Subject: RE: [sv-ec] Asychronous mailbox proposal
Arturo-
I thought that it was only possible in SV to wait on objects that
were not dynamically allocated. (Is this true?)
In the example below, I assume that objects of class kmbox are dynamically
allocated, and thus bit has_message is dynamically allocated, and thus
you can't wait on it.. ?
Stuart
-----Original Message-----
From: Arturo Salz [mailto:Arturo.Salz@synopsys.com]
Sent: Friday, December 13, 2002 1:29 AM
To: Kevin Cameron; sv-ec@eda.org
Cc: david.smith@synopsys.com; Mehdi.Mohtashemi@synopsys.com
Subject: Re: [sv-ec] Asychronous mailbox proposal
Kevin,
Since mailbox is a class, you can inherit and add the functionality you need in a fairly straight forward manner, as shown below. Note that in this code, the @ uses the additional boolean bit that indicates if there is any message in the mailbox waiting to be read. This could be done in a very nice way if we had a way to specify read-only members, so that one could wait on a member boolean that can only be set internally by the class (but we don't have that).
----------------------------------------------------------------------------
class kmbox extends mailbox#(logic);
bit has_message = 0;
function new();
fork logic lval; forever begin
lm.peek(lval); has_message = 1; // wait for message but leave it in the queue
wait( has_message == 0 );
join none
endfunction
task get(var logic v);
super.get(v);
if( num() == 0 ) has_message = 0; // empty mailbox -> reset bit
endtask
endclass
// The code below is almost identical to Kevin's original
kmbox lm = new;
logic l_val1;
always @(posedge clock1) lm.put(l_val1) // write data on clock1
logic l_val2;
always @(posedge clock2 && lm.has_message) lm.get(l_val2); // sync data to clock2
----------------------------------------------------------------------------
Arturo
----- Original Message -----
From: "Kevin Cameron" <sv-xx@grfx.com>
To: <sv-ec@eda.org>
Cc: <david.smith@synopsys.COM>; <Mehdi.Mohtashemi@synopsys.COM>
Sent: Thursday, December 12, 2002 9:25 PM
Subject: RE: [sv-ec] Asychronous mailbox proposal
> From: "Mehdi Mohtashemi" <Mehdi.Mohtashemi@synopsys.com>
>
> Hi Kevin,
> The mailbox get method is blocking statement as you realize, however,
> the handle does not act as an event, therefore one can not wait on
> the change in the mailobx handle as it is indicated in your mail.
> The second statement [always @(lm && posedge clock2) lm.get(l_val2);]
> intends to qualify a blocking statement, i.e, the get method. This
> does not work.
It's not that big a deal, there is no syntactic problem with using
@(<mailbox>) - a bare mailbox name has no significance at the moment.
>From an implementation point-of-view you just create a dummy signal/event
that you trigger when the mailbox gets written to, and do a try_get before
suspending again.
>
> The clock-boundry-synchronization mechanism is a general synchronization
> issue within SystemVerilog, we can think of incorporating an extra bit
> variable to the mailbox type that allows updates once a put is executed.
> One has to be carefull with multiple readers of the mailbox as well.
> Obviously when there is only one to one reading/updating then the
> problem is more managable. One can also extend a mailbox to add
> the second level synchronization [i.e, this clock synchronizer, or asynchronous
> communication].
> A possible SV code would be:
> typedef mailbox #(logic) l_mbox;
> l_mbox lm = new; //global synchroizer defined
> logic l_val1;
> logic l_val2; ...
>
> // ... some processes in clock1 domain
> always @(posedge clock1) lm.put(l_val1); // write data on clock1
>
> // synchronizer be a re-entrant task as well if we wanted it
> // ... another process in clock2 domain...
> logic l_temp;
> lm.get(l_temp); //blocks here
> @(posedege clock2) l_val2= l_temp; // then synchronize to the edge of clock2,
> .................
> You can also define a method for this:
> // a generalized synchronizer between two known clocks can be:
> task sync_two (l_mbox l_in, output logic l_out)
> begin
> logic l_val_a;
> l_in.get(l_val_a); // this blocks, insures proper data in the mailbox is recieved
> @(posedege clock2) l_out= l_val_a; // then synchronize to the edge of clock2, now we
> endtask
>
> - Mehdi
The problem with just using the blocking get function is that it's difficult
to prioritize reads in different threads e.g.:
forever begin
l_in.get(l1);
@(clock1) ...
end
forever begin
l_in.get(l2);
@(clock2) ...
end
Vs:
always @ (l_in && posededge clock1) begin
l_in.get(l1);
...
end
always @ (l_in && posededge clock2) begin
l_in.get(l2);
...
end
In the top version you can't tell which clock edge will take an
item of data, in the bottom version it's the first one that occurs.
BTW, can the argument to get() be a reg?
Kev.
>
> -----Original Message-----
> From: owner-sv-ec@eda.org [mailto:owner-sv-ec@eda.org]On Behalf Of Kevin
> Cameron x3251
> Sent: Thursday, December 12, 2002 4:41 PM
> To: stuart@sutherland-hdl.com; david.smith@synopsys.COM
> Cc: sv-ec@eda.org
> Subject: RE: [sv-ec] Asychronous mailbox proposal
>
>
> > From: "David W. Smith" <david.smith@synopsys.com>
> >
> > Hi Kevin,
> > I would request that any additions like this go through me before going to
> > Stu. I believe there may be some problems with what you suggest and would
> > prefer to have the discussion first.
> >
> > Stu, please wait on adding this.
> >
> > Regards
> > David
> >
> > David W. Smith
> > Synopsys Scientist
>
> Since it's only a small extension to mailbox functionality, can we clear up
> any issues with it over the reflector?
>
> BTW, when was striking out dynamic processes approved?
>
> Kev.
>
>
> > -----Original Message-----
> > From: owner-sv-ec@eda.org [mailto:owner-sv-ec@eda.org] On Behalf Of Kevin Cameron
> > Sent: Thursday, December 12, 2002 12:30 PM
> > To: Stuart Sutherland
> > Cc: sv-ec
> > Subject: [sv-ec] Asychronous mailbox proposal
> >
> >
> > Stu,
> >
> > I was wondering if you could paste the section below into the LRM for review
> > with the mailbox stuff, it's the only functionality from the channels
> > proposal that isn't handled by mailboxes (the rest is handled by DirectC):
> >
> > 12.5.1 Asynchronous Mailbox Communication
> >
> > Data arriving at a mailbox generates an event. The event is true while data
> > remains in the mailbox. As with signal events these events can be waited for
> > with the @ operator. The following code could be used to replace a wire of
> > type logic with a FIFO to safely cross clock domains:
> >
> > typedef mailbox #(logic) l_mbox;
> >
> > l_mbox lm = new;
> >
> > logic l_val1;
> > always @(posedge clock1) lm.put(l_val1) // write data on clock1
> >
> > logic l_val2;
> > always @(lm && posedge clock2) lm.get(l_val2); // sync data to
> > clock2
> >
> > -------------------------------------------
> >
> >
> > Note: the alternative code without @(lm) would poll on every "posedge
> > clock2" and do a try_get - which is a lot more inefficient.
> >
> > Regards,
> > Kev.
> >
> > --
> > National Semiconductor, Tel: (408) 721 3251
> > 2900 Semiconductor Drive, Mail Stop D3-500, Santa Clara, CA 95052-8090
> >
> >
> >
> >
> >
>
This archive was generated by hypermail 2b28 : Fri Dec 13 2002 - 14:35:18 PST