Subject: Re: [sv-ec] disabling of single threads
From: Kevin Cameron (sv-xx@grfx.com)
Date: Tue Mar 25 2003 - 00:21:24 PST
> From: Simon Davidmann <simon@his-home.demon.co.uk>
>
> Arturo,
>
> begin :-)
>
> I note your new idea below and have a question: where does this fit with
> the spirit of Verilog?:
>
> --- insert --
> pids = fork
> p1();
> p2();
> p3();
> join any
> --- end insert --
>
> I cannot recall this language procedural style in any existing Verilog
> construct.
Got to agree with that. What was wrong with using a method off the fork
label to get the pids or perform other functions ? - at least it would be
consistent with other new syntax. E.g.:
fork : f1
p1();
p2();
p3();
join any
...
disable f1.processes(); // kill dangling processes
> Value returning statements were thrown out with Verilog (we had them in
> HILO, but Phil left them out of Verilog saying you always need a function
> call) - next we will have the return of the dreaded valcase... eg
> a = valcase (i)
> j: 3;
> k: 2;
> endcase
> i.e. if i == j then a = 3, etc
>
> if you want to add this processid stuff, then you need to change the fork
> to be more like it, ie something like this:
> pids = fork (any)
> p1 ();
> p2 ();
> p3 ();
> join
>
> and then there are also several other things we should change to make them
> into this new syntax style - but in fact it is not a nice style:
>
> for example could I have
> val = begin
> if (a) return (1); else return (0);
> end
> i.e. a begin block as well that returns a value? - would make sense right?
>
> and then we could have
> if (begin if (a) return (1); else return (0); end) $display
> ("returns 0); else $display ("returns 0");
>
> and then because the begin end only is one statement we could do without
> it, etc, like this:
> if (if (a) return (1); else return (0);) $display... - and it can get
> quite messy
>
> of course we could just say that process assignment from a fork join block
> is an exception - and we dig a bigger hole - as then whole language just
> becomes a collection of strange constructs that are only allowed in certain
> conditions in certain places... and we end up with a bad language
>
> I recommend not adding new styles away from the spirit of Verilog - unless
> you overhaul many things properly - adding new styles for each new type of
> operation just makes the language more and more complex and more and more
> difficult as a user can never remember exactly how the syntax and semantics
> of each construct or grouping of constructs works.
>
> end :-)
BTW, gcc allows you to nest statements in expressions e.g.:
int c = ({int a = x, b = z ; a+b;})
- the last statement of sequence is the result - it's a logical extension of
the syntax for expressions which lets you do this:
if ((c = 0, b0()) ||
(c = 1, b1()) ||
(c = 2, b2())) {
switch (c) {
case 0: ... ; // b0 true
case 1: ... ; // b1 true
case 2: ... ; // b2 true
}
- it's actually very useful.
BCPL (a precursor of C) had a similar mechanism for using begin/end blocks
in expressions.
Kev.
> Simon
>
> At 03:15 AM 3/25/2003, Arturo Salz wrote:
> >Michael,
> >
> >My proposal for thread control is attached. Unfortunately, it didn't get in
> >this version.
> >Your comments are welcome.
> >
> > Arturo
> >
> >----- Original Message -----
> >From: "Michael Burns" <Michael.Burns@motorola.com>
> >To: <sv-ec@eda.org>
> >Cc: <rob.slater@motorola.com>
> >Sent: Monday, March 24, 2003 3:24 PM
> >Subject: [sv-ec] disabling of single threads
> >
> >
> >
> >Hi folks,
> >
> >I have a question about disabling/terminating threads. There does not
> >appear to be a syntax for terminating a specific thread; you can only
> >terminate all child threads of the current thread, or terminate all
> >threads from a named block. Does anyone know of a handy way to start
> >a bunch of threads, then terminate specific ones under various
> >conditions? There are folks here in Motorola who are very intereseted
> >in having this ability - does anyone else have opinions on the
> >desireability or lack thereof for this feature? If there's a "thread"
> >on the reflector about this, feel free to just point me there.
> >
> >Thanks,
> >Mike
> >
> >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
> >
> >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 = 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 = fork
> > p1();
> > p2();
> > p3();
> >join any
> >
> >// user implementation of fork ... join
> >// and terminate all remaining processes.
> >// Like a priority fork .. join
> >
> >for( int i = 0; i < pids.size; i++ ) begin
> > if( pids[i].status != 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
> >
> >
This archive was generated by hypermail 2b28 : Tue Mar 25 2003 - 00:22:31 PST