RE: Named events

From: <john.aynsley@doulos.com>
Date: Tue Nov 16 2010 - 12:03:42 PST

Bishnupriya,

Well, I agree that I have not come up with anything better than your proposal so far 8=)

I've not really thought about the use case for named events. Practically, if the use case is accepting names from a user interface, then yes, I can see that it simplifies matters to have one unified namespace (or, equivalently, two separate namespaces with a "magic" connection between them to avoid overlaps). sc_find_object("foo") only returns sc_objects and sc_find_event("foo") only returns events.

So, what we've got then is named sc_objects and named sc_events that both share the same namespace, and moreover, those names have common prefixes - in each case the prefix is the hierarchical name of the parent. The legacy sc_find_object("foo") only finds objects.

sc_name_exists("foo") is clearly not a big deal, but I would be in favor.

We could derive sc_object and sc_event from a common base class and push the name up into that. Is it worth it? It might be prettier!

John A

-----Bishnupriya Bhattacharya <bpriya@cadence.com> wrote: -----
To: "john.aynsley@doulos.com" <john.aynsley@doulos.com>
From: Bishnupriya Bhattacharya <bpriya@cadence.com>
Date: 11/16/2010 06:39PM
Cc: "systemc-p1666-technical@eda.org" <systemc-p1666-technical@eda.org>
Subject: RE: Named events

    
John,
 
I would argue, the proposal only *seems* weird and IMO other alternatives (e.g. light weight sc_objects) are also weird. You cannot come up with a nice spanking clean solution here because that is only possible when you have a clean sheet instead of retrofitting.
 
Consider your example. If we leave aside the theory for a bit, what does it *practically* buy the user to be able to name both a signal and an event "foo" in the same module? I can only see it buys more confusion. Stepping outside the OSCI simulator, consider a GUI or a command prompt in a commercial SystemC simulator. You type at the prompt "value top.foo" - wait a minute - did you mean the signal or the event?
 
Now lets come back to the theory. In your example, things work quite well if the user takes into account that *both* objects and events are now named in SystemC, and accordingly adjusts the way he does hierarchy traversal, object lookup etc. Note that legacy code would generally not need to change, since in legacy code no events are explicitly named. In new code that user writes, he would have to take event naming into account
 
void T()
{
        sc_event ev("foo");

        // Is there a local object or event named "foo"?
        my_object* obj = sc_find_object("top.m.T.foo");
        sc_assert( obj == 0 ); 
        sc_event* ev = sc_find_event("top.m.T.foo");
        sc_assert(ev == 0); // this assertion fails
}

Similarly, in hierarchy traversal code, child events have to be obtained using get_child_events() in addition to obtaining child objects using get_child_objects().
 
Maybe, the lookup can be made easier by introducing a new function
 
  bool sc_name_exists(const char* nm);
 
which shall return true if either an object or an event exists with that name.
 
In summary, I really do not see what is the benefit to the user in letting an object and an event have the same name. On the contrary, I see a clear benefit in all named entities having an unique name. 
 
Thoughts?
 
Thanks,
-Bishnupriya 
      From: john.aynsley@doulos.com [mailto:john.aynsley@doulos.com]
Sent: Tuesday, November 16, 2010 4:22 PM
To: Bishnupriya Bhattacharya
Cc: systemc-p1666-technical@eda.org
Subject: RE: Named events

   
Bishnupriya,

I still think the proposal is weird regarding the namespaces. Consider:

struct my_object: sc_object;

void T()
{
        sc_event ev("foo");

        // Is there a local object named "foo"?
        my_object* obj = sc_find_object("top.m.T.foo");
        sc_assert( obj == 0 );

        // No, so let's make one
        obj = new my_object("foo");

        // What is the new object called?
        cout << obj->name() << endl;     //   top.m.T.foo_0
        // Surprise!!

        // Why did it not use the name I chose? Perhaps the name "foo" is already in use
        obj = sc_find_object("top.m.T.foo");
        cout << obj << endl;                      // 0

        // No, it isn't!!!!
}

The sc_object namespace now has a bunch of holes punched in it corresponding to sc_events of the same name, yet the API says those names are not part of the namespace! I find that confusing.

Regarding lightweight sc_objects, I am not wedded to these, but I suppose they would have

        name() = ""
        basename() = ""
        kind() = "sc_object"
        get_parent_object() = 0
        get_child_objects() = empty_vector
        add_attribute() => error
        get_attribute() = 0
        num_attributes() = 0

Lightweight objects would not appear in the sc_object namespace, but unlike your proposal, they would not punch holes in that namespace.

I guess lightweight objects are a bit weird too, because they are sc_objects and yet their name() is an empty string. Any code that grabs the name of an sc_object would now have to deal with the fact that the string could be empty, which is not pretty with respect to backward compatibility.

How about we keep the sc_object and sc_event namespaces separate so that the same name can exist in both, but mandate that the implementation shall generate a warning whenever this occurs?

Just my two cents 8=)

John A

                     From: Bishnupriya Bhattacharya <bpriya@cadence.com> To: "john.aynsley@doulos.com" <john.aynsley@doulos.com>, "systemc-p1666-technical@eda.org" <systemc-p1666-technical@eda.org> Date: 15/11/2010 19:43 Subject: RE: Named events
      

John,
ÿ
Your summary is nice and accurate.
ÿ
Comments/answers below.

      From: john.aynsley@doulos.com [mailto:john.aynsley@doulos.com]
Sent: Monday, November 15, 2010 5:59 PM
To: Bishnupriya Bhattacharya; systemc-p1666-technical@eda.org
Subject: Re: Named events

Bishnupriya,

To summarize the proposal, I think you are saying:

* Events are not sc_objects

* Static events are named
* Dynamic events can be named or unnamed
* Kernel events are unnamed

* Named events share the same namespace (not a C++ namespace) as the object hierarchy. An event name shall not clash with an object name
* The prefix to each event's name is the hierarchical name of the event's parent in the object hierarchy

* There are methods get_child_events, get_top_level_events, and sc_find_event that mirror the methods of the object hierarchy

Comments/questions:

Presumably get_child_objects() does not return any events? ÿ
ÿ
>>> [bpriya: no]

Why not make the namespace of sc_objects and the namespace of sc_events separate? I do not much like having these two different kinds of animal pushed into the same namespace. It seems odd to pollute the namespace of sc_objects with things that are not sc_objects, and then have those things invisible from the point-of-view of the object hierarchy (get_child_objects).

>>> [bpriya: I see your point, but do not agree. The reason for keeping the same namespace for events and objects is simple - intuitiveness and lack of confusion. Inside a module, if a user has both an event named foo and a signal named foo, it is inherently confusing, and moreover, what does it buy the user? The fact that get_child_objects() does not return a sc_event is also simple - because an event is not an object, so there is no sc_object* pointer that can be returned for a sc_event.]
ÿ
Alternatively, why not derive sc_event from sc_object (making events part of the object hierarchy proper) and add a lightweight variant to the sc_object, where a lightweight sc_object is unnamed and is excluded from the object hierarchy. Then we only need one unified namespace for events and sc_objects. By default, sc_event would be the only example of a lightweight sc_object, but applications could derive new lightweight sc_objects from sc_object. (If performance is an issue, I guess sc_object could become a template where the default is a heavyweight object.)

>>> [bpriya: I would need specifics of the lightweight sc_object variant to fully analyse the proposal. One data point - Cadence has done actual experiments deriving sc_event from sc_object (as it now stands), and encountered performance degradation. Hence, the alternate proposal.]
ÿ
Thanks,
-Bishnupriya
ÿ
Just an idea.

John A

                     From: john.aynsley@doulos.com To: systemc-p1666-technical@eda.org Cc: bpriya@cadence.com Date: 15/11/2010 11:56 Subject: Named events Sent by: owner-systemc-p1666-technical@eda.org

      

All,

The race is now on to get all the enhancements finished by the end of November.

The final enhancement on our priority list is named events. I include Cadence's proposal below.

Comments please

John A

-----

John, All,

In response to ST's enhancement request presented in this forum, below is a proposal from Cadence for naming sc_events. In this proposal sc_event does not derive from sc_object for performance concerns. One concern is sc_events are meant to be lightweight objects, and deriving from sc_object can make it too heavyweight.

Three categories of events are considered in the proposal:

- 'static' events created up to and including phase start_of_simulation ÿ ÿ
- 'dynamic' events created after phase start_of_simulation
- kernel events that are directly or indirectly specified in the LRM (e.g. posedge_event of sc_signal<bool>)

The proposal aims to provide a simple, consistent set of rules aligned with sc_object naming semantics, and also keeping in mind performance considerations.

The detailed proposal is given below.

Thanks,
-Bishnupriya

class sc_event {
public:
....
sc_event(); <-------------- existing
sc_event(const char* nm); <------------ new
const char* name() const; <------------ new
...
};

1) constructors and hierarchical name of sc_event
ÿ==============================================

a) static events - created up to and including phase start_of_simulation
ÿ---------------------------------------------------------------------

Before simulation starts running, both constructors shall register the sc_event as part of the event hierarchy and shall construct a hierarchical name for the event using the string name passed as an argument. Calling the constructor sc_event(const char*) with an empty string shall have the same behavior as the default constructor, that is, the string name shall be set to "event".

A hierarchical name shall be composed of a set of string names separated by the period character '.', starting with the string name of a top-level sc_object instance and including the string name of each module instance or process instance descending down through the object hierarchy until the current sc_event is reached. The hierarchical name shall end with the string name of the sc_event itself.

Hierarchical names are case-sensitive.

It shall be an error if a string name includes the period character (.) or any white-space characters. It is strongly recommended that an application limit the character set of a string name to the following:
a) The lower-case letters a-z
b) The upper-case letters A-Z
c) The decimal digits 0-9
d) The underscore character _

An implementation may generate a warning if a string name contains characters outside this set but is not obliged to do so.

There shall be a single global namespace for hierarchical names of objects and events. Each sc_object and sc_event shall have a unique nonempty hierarchical name. An implementation shall not add any names to this namespace other than the hierarchical names of sc_objects and sc_events explicitly constructed by an application.

The sc_event constructor shall build a hierarchical name from the string name (either passed in as an argument or the default name "event") and test whether that hierarchical name is unique in the global namespace consisting of objects and events. If it is unique, that hierarchical name shall become the hierarchical name of the event. If not, the constructor shall call function
sc_gen_unique_name, passing the string name as a seed. It shall use the value returned as a replacement for the string name and shall repeat this process until a unique hierarchical name is generated. If function sc_gen_unique_name is called more than once in the course of constructing any given sc_object, the choice of seed passed to sc_gen_unique_name on the second and subsequent calls shall be implementation-defined but shall in any case be either the string name passed as the seed on the first such call or shall be one of the string names returned from sc_gen_unique_name in the course of constructing the given sc_event. In other words, the final string name shall have the original string name as a prefix.

If the constructor needs to substitute a new string name in place of the original string name as the result of a name clash, the constructor shall generate a single warning.

b) Dynamic events - created after phase start_of_simulation
ÿ---------------------------------------------------------

After simulation starts running, there can be a run-time performance impact associated with hierarchically naming an event, e.g.,in the case of a dynamically spawned process with a local event where the process comes and goes repeatedly. To address this performance concern, the behavior of sc_event's default ctor after simulation start is kept unspecified, i.e. implemenntation-defined. An implementation may choose to treat such events exactly the same as static events, or it can choose to not name them at all, or somewhere in between.

The behavior of the second constructor for dynamic events shall be the same as that for static events, i.e. if the user explicitly names a dynamic event, it shall be a part of the event hierarchy, and it shall have a proper hierarchical name following the same rules as in 1a). Calling the constructor sc_event(const char*) with an empty string shall have the same behavior as the default constructor, i.e the behavior is left implementation-dependent.

c) Kernel events
ÿ---------------

There are events created by the SystemC kernel for various purposes. These events can be classified into two categories

i) Events that are directly or indirectly specified in the LRM, e.g. LRM specifies "const sc_event& sc_signal<bool>::posedge_event()". Lets call these explicit kernel events.

ii) Events that kernel creates for internal implementation. Lets call these implementation kernel events

For implementation kernel events, the implementation is obliged to exclude those events from the event hierarchy and from the namespace of hierarchical names. This would necessitate an extension to the semantics of class sc_event, and the implementation would be obliged to make such an extension transparent to the application.

For explicit kernel events also, the implementation is obliged to exclude such events from the event hierarchy, and from the namespace of hierarchical names, thus not polluting the global namespace. This implies if get_child_events() is invoked on the parent scope of an explicit kernel event, the returned vector shall not contain a reference to the explicit kernel event. Furthermore, the user is always free to name his own application event as he chooses to, without having to worry about his event clashing with an explicit kernel event. ÿ

2) obtaining the name of a sc_event
ÿ================================

const char* sc_event::name() const;

Member function name shall return the hierarchical name of the sc_event instance in the event
hierarchy.

3) add member method to retrieve a list of sc_events from parent scope
ÿ===================================================================

add member method to sc_module, and sc_process_handle, as below:

const std::vector<sc_event*>& get_child_events() const;

Member function get_child_events shall return a std::vector containing a pointer to every instance of class sc_event that lies within the module/process in the design hierarchy.

NOTE 1-The phrase within a module does not include instances nested within modules instances but only includes the immediate children of the given module.

4) add global functions to retrieve top-level events and to find event by name
ÿ=============================================================================

namespace sc_core {
const std::vector<sc_event*>& get_top_level_events() const;
sc_event* sc_find_event(const char* name);
};

Function sc_get_top_level_events shall return a std::vector containing pointers to all of the toplevel sc_events.

Function sc_find_event shall return a pointer to the sc_event that has a hierarchical name that
exactly matches the value of the string argument or shall return the null pointer if there is no
sc_event having a matching name.

-- 
This message has been    scanned for viruses and 
dangerous content by MailScanner, and is 
believed    to be clean. 
-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Tue Nov 16 12:05:08 2010

This archive was generated by hypermail 2.1.8 : Tue Nov 16 2010 - 12:05:11 PST