From: "Arturo Salz" <salz@synopsys.com>
To: <sv-ec@eda.org>
References: <5.1.0.14.0.20030124102321.029e0000@orange.he.net>
Subject: Re: [sv-ec] Comments on Chapter 9
Date: Mon, 27 Jan 2003 11:02:45 -0800
MIME-Version: 1.0
Content-Type: multipart/alternative;
	boundary="----=_NextPart_000_18B9_01C2C5F3.9F1910A0"
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.50.4807.1700
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4807.1700

This is a multi-part message in MIME format.

------=_NextPart_000_18B9_01C2C5F3.9F1910A0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

I  believe that Kevin and Stefen have brought up very good points.  If =
we
need to provide fine granularity control for SystemVerilog processes =
then
these mechanisms need to be intuitive, general, and robust.
After reviewing Kevin's proposal I came up with the following proposal.

Process Control

Use the process keyword to denote a new built-in class.  This way, users =
can
declare objects of type process and safely pass them around through =
tasks or
incorporate them into other objects.

Objects of type process include several built-in methods:
    task terminate - Terminates the process
    function int status - Returns process status (0 dead, 1 ready, -1 =
created, 2 waiting...).
        (A cleaner way might be an enum but that would add top-level =
identifiers)
    task suspend - Suspend execution of the process (process is still =
ready)
    task wait - Wait until process terminates

The key to the process class is that (a) it's an object and therefore =
subject to
the same type-checking rules as other objects, (b) it can be garbage =
collected
like any other object, and (c) it's a built-in class, and only the =
fork..join construct
creates these types of objects.  The statement "process e =3D new()" =
could be
disallowed altogether, or it could be used to retrieve a handle to the =
calling process.

Also required is an atomic mechanism for assigning all process'es =
created by a
fork..join.  Atomic means a mechanism whereby all processes are =
initialized before
the calling process or any of the sub-processes has had a chance to =
execute and
perhaps terminate.  One way to provide for this would be to modify the =
grammar of
the fork construct to accomplish this:

  process pids[*];

  pids =3D fork
    p1();
    p2();
    p3();
  join any

  // user implementation of fork ... join=20
  // and terminate all remaining processes.
  // Like a priority fork .. join

  for( int i =3D 0; i < pids.size; i++ ) begin
      if( pids[i].status !=3D 0 )
          pids[i].terminate();
  end
The example shows using a dynamic array to receive the process objects, =
but one
could also use a fixed-size array (i.e., pids[1:3]).  The basic concept =
is that the pids
array is initialized by fork before any of the sub-processes begin =
executing.  This way
the parent process, or any of the sub-processes has access to all the =
process objects
and avoids a situation where a process executes and terminates before =
one has had a
chance to monitor the process externally.

Also, by making this an explicit part of the fork..join, the compiler =
can decide if all the
process objects are needed and optimize accordingly.

    Arturo



------=_NextPart_000_18B9_01C2C5F3.9F1910A0
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 5.50.4807.2300" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY>
<DIV><FONT face=3DArial size=3D2>
<DIV><FONT size=3D2>I&nbsp; believe that Kevin and Stefen have brought=20
up&nbsp;very good points.&nbsp; If we</FONT></DIV>
<DIV>need to provide fine granularity control for SystemVerilog =
processes=20
then</DIV>
<DIV>these mechanisms need to be intuitive, general, and robust.<FONT=20
size=3D2></FONT></DIV>
<DIV><FONT size=3D2>After reviewing Kevin's proposal I came up with the =
following=20
proposal.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2><STRONG>Process Control</STRONG></FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Use the <STRONG>process</STRONG> keyword to denote a =
new=20
built-in class.&nbsp; This way, </FONT><FONT size=3D2>users =
can</FONT></DIV>
<DIV><FONT size=3D2>declare objects of type process and safely pass them =

</FONT><FONT size=3D2>around through tasks or</FONT></DIV>
<DIV><FONT size=3D2>incorporate them into other objects.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Objects of type process include several built-in=20
methods:</FONT></DIV>
<DIV><FONT size=3D2>&nbsp;&nbsp;&nbsp; <STRONG>task terminate</STRONG> - =

Terminates the process</FONT></DIV>
<DIV><FONT size=3D2>&nbsp;&nbsp;&nbsp; <STRONG>function int status -=20
</STRONG>Returns process status (0 dead, 1 ready, -1 created, 2=20
waiting...).</FONT></DIV>
<DIV><FONT size=3D2>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (A cleaner way =
might be=20
an enum but that would add top-level identifiers)</FONT></DIV>
<DIV><FONT size=3D2>&nbsp;&nbsp;&nbsp; <STRONG>task suspend</STRONG> - =
Suspend=20
execution of the process (process is still ready)</FONT></DIV>
<DIV><FONT size=3D2>&nbsp;&nbsp;&nbsp; <STRONG>task wait</STRONG> - Wait =
until=20
process terminates</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>The key to the process class is that (a) it's an =
object and=20
therefore subject to</FONT></DIV>
<DIV><FONT size=3D2>the same </FONT><FONT size=3D2>type-checking rules =
as other=20
objects, (b) it can be garbage collected</FONT></DIV>
<DIV><FONT size=3D2>like any other object, and (c) it's a built-in =
class, and only=20
the fork..join </FONT><FONT size=3D2>construct</FONT></DIV>
<DIV><FONT size=3D2>creates these types of objects.&nbsp; The statement =
"process e=20
=3D new()" could be</FONT></DIV>
<DIV><FONT size=3D2>disallowed altogether, or it could be used to =
retrieve a=20
handle to the calling process.</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>Also required is an atomic mechanism for assigning =
all=20
</FONT><FONT size=3D2><STRONG>process'</STRONG>es created by =
a</FONT></DIV>
<DIV><FONT size=3D2>fork..join.&nbsp; Atomic means a mechanism whereby=20
</FONT><FONT size=3D2>all processes are initialized before</FONT></DIV>
<DIV><FONT size=3D2>the calling process or any of the sub-processes has =
had a=20
</FONT><FONT size=3D2>chance to execute and</FONT></DIV>
<DIV><FONT size=3D2>perhaps terminate.&nbsp; One way to provide for this =
would be=20
to modify the grammar of</FONT></DIV>
<DIV>the fork construct <FONT size=3D2>to accomplish this:</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<BLOCKQUOTE dir=3Dltr style=3D"MARGIN-RIGHT: 0px">
  <DIV><FONT face=3D"Courier New"><FONT size=3D2><STRONG>process=20
  </STRONG>pids[*];</FONT></FONT></DIV>
  <DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3D"Courier New" size=3D2>pids =3D fork</FONT></DIV>
  <DIV><FONT face=3D"Courier New" size=3D2>&nbsp; p1();</FONT></DIV>
  <DIV><FONT face=3D"Courier New" =
size=3D2>&nbsp;&nbsp;p2();</FONT></DIV>
  <DIV><FONT face=3D"Courier New" =
size=3D2>&nbsp;&nbsp;p3();</FONT></DIV>
  <DIV><FONT face=3D"Courier New" size=3D2>join any</FONT></DIV>
  <DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
  <DIV><FONT face=3D"Courier New" size=3D2>
  <DIV><FONT size=3D2>// user implementation of fork ... join =
</FONT></DIV>
  <DIV>// and terminate all remaining processes.</DIV>
  <DIV>// Like a priority fork .. join</DIV>
  <DIV><FONT face=3DArial></FONT>&nbsp;</DIV>for( int i =3D 0; i &lt; =
pids.size; i++=20
  ) begin</FONT></DIV>
  <DIV><FONT face=3D"Courier New" size=3D2>&nbsp;&nbsp;&nbsp; if( =
pids[i].status !=3D=20
  0 )</FONT></DIV>
  <DIV><FONT face=3D"Courier New" size=3D2>&nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;=20
  pids[i].terminate();</FONT></DIV>
  <DIV><FONT size=3D2>end</FONT></DIV></BLOCKQUOTE>
<DIV><FONT size=3D2><FONT size=3D2>The example shows using a dynamic =
array to=20
receive the process objects, but one</FONT></DIV>
<DIV>
<DIV><FONT size=3D2>could also use a fixed-size array (i.e., =
pids[1:3]).&nbsp;=20
</FONT>The basic concept is that the pids</DIV>
<DIV>array is initialized by fork before any of the sub-processes begin=20
executing.&nbsp; This way</DIV>
<DIV>the parent process, or any of the sub-processes has access to all =
the=20
process objects</DIV>
<DIV>and avoids a situation where a process executes and terminates =
before one=20
has had a</DIV>
<DIV>chance to monitor the process externally.</DIV>
<DIV>&nbsp;</DIV>
<DIV>Also, by making this an explicit part of the fork..join, the =
compiler can=20
decide if all the</DIV>
<DIV>process objects are needed and optimize accordingly.</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;&nbsp;&nbsp; Arturo</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV></FONT></DIV></FONT></DIV></BODY></HTML>

------=_NextPart_000_18B9_01C2C5F3.9F1910A0--


