|
||
This chapter discusses some concepts that are necessary to understand for more advanced protocol modeling.
The Edit Sheet provides a canvas for displaying a View object. Understanding the concept of a View object is important for knowing how to handle large architecture designs.
When a graphical item for a PE, Rule, Message, etc. is created on an Edit Sheet, there are really two acts of creation taking place. First an architectural object is created, and second a graphical display or view of that object is created on the current Edit Sheet:
1 - The architectural object is really a piece of code with a command name which exists in the global space. All PE and Message objects that are part of the same architecture are listed as components of the same Binder object. All other objects are listed as components of either a PE or Message object. All PE objects within a Binder are peers, they all live in the same execution space or environment.
2 - All of the object graphical displays found on an Edit Sheet are organized as part of a View object. There is a one-to-one correspondence between an Edit Sheet and a View object. It is possible to have multiple displays or views of the same architectural object on different Edit Sheets. In other words, it is possible to have a many-to-one mapping of graphical views to architectural object. This gives the designer complete flexibility in deciding what parts of the architecture to show on any given Edit Sheet.
Note: When a single object has multiple displays on different Edit Sheets, each display maintains separate and independent graphical data. The location, size, and color attributes are unique to each display.
As an example, Figure 6.1 shows a design for a protocol architecture that has a large number of Rules and Messages. By proper use of Views the protocol can be shown in a number of Edit Sheets that reduce the complexity seen at any one time.
The different Views available via the Edit Sheets are not considered to be part of the protocol architecture. They are simply a convenience for working with a large design in the graphical interface. It is good practice to make wise use of Views to organize a large project into smaller, more manageable pieces for easier comprehension and to simplify graphical editing.
Once an object has been created, showing an additional display or view of the object on another Edit Sheet is done by a process called deployment. Only PE and Rule objects can be directly deployed by the user.
Deployment of a Rule will automatically deploy the Rule's events and any attached Messages. If the other end of a Message terminates at a Rule which is not deployed, the Message will terminate at a coupler object as shown in Figure 6.2.
A display of a PE or Rule object can also be recalled or removed from an Edit Sheet. Any Messages affected by a Rule recall will automatically update their display to adapt to the new object diagram. (They may need to show coupler objects.)
To deploy a view of an existing PE object on the current sheet, enter PE Mode by
doing a left-click on the PE button
(
).
Then do Ctrl-left-click at a desired location on the sheet. A window will
pop up to allow selecting of a PE object by name. After this another window
will pop up to allow selection of which Rules should be deployed on this PE. Use left-click
to select a Rule in the list. A Ctrl-left-click will allow multiple rules to be individually selected,
and a Shift-left-click will select a contiguous set of rules.
To recall (remove) the display of a PE object, enter Select Mode by doing a
left-click on the Select button
(
).
Then use left-click to select the PE object to be recalled, then press the
keys Ctrl-<Delete>.
PE objects can also be deployed and recalled via the menu items Edit>Deploy PE and Edit>Recall PE. The deploy option will show a list of all current PE objects so that you can choose one for deployment. Deployment via the menu will cause all Rules on the PE to be deployed. The recall option will operate on all PE objects currently selected on the sheet.
To deploy a view of an existing Rule object on a PE, enter Rule Mode by doing a
left-click on the Rule button
(
).
Then do a Ctrl-left-click on the PE where the Rule is to be deployed. A window will
pop up to allow selection of the Rule to be deployed.
A Rule object can be recalled in a similar manner to a PE; select the Rule(s) and
then press the keys Ctrl-<Delete>.
Sometimes an architecture description is more efficiently described by using a piece of behavior in more than one place. For example, the 802.11 wireless LAN protocol defines a Station and it defines an Access Point. The Access Point includes all of the functionality of a Station, but adds the ability to connect other Stations to a distribution system.
Rather than having two PEs which duplicate the rules for a Station, a better way to model the architecture of the 802.11 protocol would be to model a Processing Entity that includes StationServices behavior, and then to use that same entity as part of the Station and Access Point model, as shown in Figuire 6.3 below:
A Pin object is attached to a Guard or Action event. If attached to a Guard event, the Pin allows any number of incoming Messages to terminate on itself. If attached to an Action event, the Pin allows any number of outgoing Messages to originate from itself.
By using Pin objects, it is possible to connect a PE and its rules to multiple locations in the model using multiple Messages. As seen in Figure 6.3, this is typically shown by displaying the multiple-use PE in different Edit Sheets.
Connecting multiple messages to a Pin object introduces ambiguity about which Message should be delivered to which PE in the architecture. This is resolved at simulation time by the user indicating which PE is to receive a Message.
The objects in ProtoCollum are based on the Itcl package, which is a popular object oriented extension for the Tcl scripting language used in many EDA tools. One can use the objects provided by ProtoCollum and the Tcl language to create a complete model of a message passing system.
The ProtoCollum GUI will perform many of the commands required to build a message passing system through its point-and-click interface: creating PE, Rule, Event and Message objects; setting object relationships; and even setting code to track Message passing during simulation is all done automatically by the GUI. A user will typically have a need to write Tcl code only when some state needs to be modeled in the protocol. Here is an example of Tcl code:
set ptag [::mps::Pe_ #auto binder_0] => pe_0
In the above code, a previously defined class command called ::mps::Pe_ is used to create a new object, with an automatically created name, with a parent object binder_0. The new object name is pe_0 and it is stored in the variable named ptag.
The value pe_0 is the object's name or tag. The tag is a command (hey, its Tcl - Tool Command Language, everything is a command!) in the global namespace which can be used to invoke the object's public methods or to examine/modify the public state of the object. All of the following lines of code operate on the object named pe_0:
pe_0 fade ;# cause faded graphical appearance pe_0 unfade ;# restore normal graphical appearance $ptag move to -x 256 -y 128 ;# move to desired coordinates
pe_0 cget -Parent ;# get tag of parent object $ptag cget -Parent ;# get tag of parent object $ptag configure -Label Network ;# change label to "Network"
Note: All objects live at the global level, so the complete name of an object would include the global namespace modifier of "::". So the complete name of the object above would be ::pe_0. In most circumstances it is not required to use the modifier since the global namespace is searched by default if the command (object) is not found in the current namespace.
As explained earlier during the discussion of the basic model, state is maintained inside of a Processing Entity. In practice this is done by creating Tcl variables; scalars, lists, and/or arrays. The scope of these variables (where they live) is discussed in the next section.
State variables can be created and initialized by placing the appropriate Tcl code inside the PreCode public variable of any PE object. A Right-click on any object brings up the object's properties window. A PE object will have a Tab labeled PreCode where the Tcl code can be placed.
Another place where Tcl code may need to be written is for a Event of Type=guard. A guard Event has a public variable GuardExpr where a Tcl expression can be placed. The expression is written in terms of State variables, Message history (has such-and-such a message arrived), and input Message parameter values. During simulation, the expression of each guard event is evaluated to true or false to determine if a Rule has triggered.
A guard Event also has a public variable called ActionCode. When a guard Event is used only to check a condition of State (no message is attached), Tcl code can be put here that can help simplify the expression in GuardExpr. For example, temporary variables can be created that are in terms of State variables, Message history, and/or Message parameters. These temp variables can then be used inside of GuardExpr.
Note: Inserting code for the GuardExpr and ActionCode of a guard Event with a message attached is automatically handled by the System Package.
Finally, an Event of Type=action, can have Tcl code put into its ActionCode public variable that can update the State of the PE and/or write values to the parameters of outgoing Messages.
The simulation or execution of a Test Sheet is invoked by the <scenario_tag> execute method. This method in turn loops though each PE Test object instantiated in the scenario and invokes a <petest_tag> execute.
The basic algorithm for simulation of a PE Test is to execute the events that have occurred in time order from top to bottom. Here is a more detailed description of the algorithm used:
During the setup for a re-execution (done with the <scenario_tag> inititalize method), all Message Test objects are set to Valid=0. However, an Init_Msg is always considered to be valid, as are all Message Tests which originate from a Whitehole since we know there are no preceding events to affect state. Thus it is the Init_Msg(s) in the test scenario which set the starting point(s) for execution. (See Originating Messages.)
It should also be noted that the Whitehole object has a Code variable where code can be written to initialize the parameters of a Msg coming out. The code found in Whitehole objects is executed first in <scenario_tag> execute before entering the loop for the PE Test objects.
All of the Event code found in ActionCode or GuardExpr, which is executed as each node is visited, is executed within the scope of the PE Test execute method.
Here is a simplified code represention of the PE Test execute method. Not all details are shown, but the basic flow and the creation of variables (see next section) can be seen.
array set State {}
foreach NodeTag $nodelist {
set MsgtestTag [$NodeTag cget -MsgtestTag]
set EventTag [$NodeTag cget -EvTag_guard]
array set Param [$MsgtestTag getParams]
if {$Attached} {
eval [$EventTag cget -ActionCode]
}
foreach RuleTag $rulelist {
array set PmIn {}
foreach EventTag $guardlist {
if {!$Attached} {
eval [$EventTag cget -ActionCode]
}
set Result [eval [$EventTag cget -GuardExpr]]
}
}
set RuleTag [$NodeTag cget -RuleTag]
foreach ActionTag $actionlist {
set EventTag [$ActionTag cget -EvTag]
array set PmOut {}
eval [$EventTag cget -ActionCode]
}
}
Several special arrays are maintained by the execution algorithm:
Inside of the <petest_tag> execute method,
the following variables are made available to the code being executed from
GuardExpr and ActionCode.
Some of the variables are available only during certain parts of the execute loop.
| NodeTag | The tag of the current Node being visited under the PE Test. |
| MsgtestTag | The tag of the Message Test coming into the Node. |
| EventTag | The tag of the Event currently being evaluated. |
| RuleTag | The tag of the Rule currently being evaluated. |
| Attached | A boolean which indicates if the guard Event has an attached Message, Segment, or Pin. |
| Result | The result of the last GuardExpr evaluation. |
| ResultMsg | A string describing the result of the last GuardExpr evaluation. |
| ActionTag | The tag of the Action object currently being evaluated. |
| this | The namespace-qualified name of the PE Test object |
| <public state> | The public state of the PE Test object is available. (See the Object Properties window.) |
Note: To avoid naming conflicts with internal variables, variable names in user code written for Guard and Action events, as well as instrumentation code written for Nodes, should not begin with an underscore ('_').
The Test sheet execution loop consists of running the execute method for each PE Test. The execute method, in turn, simply runs the code found in the chain of Nodes found under the PE Test. So gaining visiblity into the execute loop can be done by attaching instrumentation to the Nodes.
Node objects have a type attribute. A node of type=instrument can be used to hook other objects into the simulation. The Flag object is an example of this. When a Node of type=instrument is encountered during simulation, an object tag is retrieved from the Node variable ExecuteTag and the method <exec_tag> execute is invoked. In the case of the Flag object, the <flag_N> execute simply updates the flag object's displayed variables with the current values.
Another way to instrument the execution loop is to use the code hooks found in a Node of type=event. This system is used by the trc package which provides the PE Test code and data tracing capability. Each Node of type=event has a number of variables where code can be placed. During different parts of the execute loop, the code in each of these variables will be evaluated.
The following table shows the Node type=event code variables and indicates where the code is evaluated during the PE Test execute loop.
| PE Test execute code | Node Hooks | PE Test Hooks | ||||
|---|---|---|---|---|---|---|
| array set State {} | ||||||
| PreCode | ||||||
| foreach NodeTag $nodelist { | ||||||
| set MsgtestTag [$NodeTag cget -MsgtestTag] | ||||||
| Pre | ||||||
| set EventTag [$NodeTag cget -EvTag_guard] | ||||||
| if {$Attached} { | ||||||
| eval [$EventTag cget -ActionCode] | ||||||
| GuardCode1 | ||||||
| } | ||||||
| foreach RuleTag $rulelist { | ||||||
| array set PmIn {} | ||||||
| Rule | ||||||
| foreach EventTag $guardlist { | ||||||
| Guard | ||||||
| if {!$Attached} { | ||||||
| eval [$EventTag cget -ActionCode] | ||||||
| GuardCode1 | ||||||
| } | ||||||
| set Result [eval [$EventTag cget -GuardExpr]] | ||||||
| GuardExpr | ||||||
| } | ||||||
| } | ||||||
| set RuleTag [$NodeTag cget -RuleTag] | ||||||
| Mid | ||||||
| foreach ActionTag $actionlist { | set EventTag [$ActionTag cget -EvTag] | array set PmOut {} | ||||
| Action | eval [$EventTag cget -ActionCode] | |||||
| ActionCode | ||||||
| } | ||||||
| Post | ||||||
| } | ||||||
| PostCode | ||||||
1Only one of these will be evaluated due to $Attached variable.
When the code found in the hook variables of a Node type=event is retrieved for evaluation, code is also retrieved from an array named mps::Code(). The array code is placed before the variable code.
Any package can write code to the mps::Code() to have it executed during Test sheet simulation. When writing to this array, the following formats must be observed for forming the array indices:
The first form will cause every Node object (of type=event) to have the code executed in the indicated Node hook. The second form is for placing the code in a specific Node object.
The fields in the index form have the following meanings:
| <key> | text that creates a unique identifier for this code |
| <hook_name> | a Node hook name (lower case version of above Node hooks, ie. pre rule guard guardexpr guardcode mid action actioncode post) |
| <node_tag> | the object tag of the desired Node |
Here is an example showing how the trc package assigns code to various Node hooks:
set nodetop [$ptag cget -NodeTop]
for {set ntag $nodetop} {$ntag != "null"} {set ntag [$ntag getNext]} {
if {[$ntag isType instrum]} {
continue
}
set mps::Code(200,trc,pre,$ntag) $nodepre
set mps::Code(200,trc,guardcode,$ntag) $nodecode
set mps::Code(200,trc,guardexpr,$ntag) $nodeexpr
set mps::Code(200,trc,rule,$ntag) $noderule
set mps::Code(200,trc,mid,$ntag) $nodemid
set mps::Code(200,trc,actioncode,$ntag) $nodecode
set mps::Code(200,trc,post,$ntag) $nodepost
}
The package of code which defines the design objects and test scenario objects with their methods and state is called MPS (Message Passing System). However, the actual code inside the Guard, Mid, and Action events, which is executed during the running of a test scenario, is not included in the MPS package. These events are created empty by MPS (except for the default expression for a Guard event which is 1 (true)). The code for these events is supplied by specially organized code packages called System packages.
The graphical interface allows a Tcl package to be loaded into ProtoCollum and chosen as the System package. One or more of these special packages is shipped with ProtoCollum and one is loaded into the tool upon startup. The tool can be used with the default System package, or another package can be loaded and chosen. You can also create your own packages in order to supply code for a custom system.
Message context is a powerful concept that can be used to simulate the message passing system under parallel or simultaneous conditions. For sake of illustration, think of an arriving message which requests connection to a network. In a system with parallelism, each of these messages can be thought of as a new request. There could be many such requests active in the system. The entire transaction for each network connection should be treated as a unique flow of messages that should be tracked independently and not intermingled with other transactions.
Message context is a way for the System Package to provide the ability to independently track message flows. Each message flow is given a unique identity number which is inherited by each message in the flow. A user can choose this identity number when an Init_Msg is created on the Test Sheet. A popup window will prompt the user to choose the Context value of the Init_Msg. This popup will only appear when the Test Sheet (aka Scenario object) has a value greater than one in the field named ContextLimit.
To change the value of ContextLimit for a Scenario object, right click on the tab for a Test Sheet. A properties window will appear with an editable field called ContextLimit. Enter an integer value, which will indicate the maximum number of unique context flows that can be simulated in the Test Sheet.
The Cara System Package is currently structured to provide a context ability by default to all rules in the architecture. This is because the Tcl code automatically put into guard Event ActionCode and GuardExpr fields (cara::recv and [cara::rcvd] respectively) will create a default context variable named Cx. A Scenario with a default value of ContextLimit=1 will appear to not be using context because each rule will be tracked with the same context variable Cx, all with the same value of 1.
To specifically disable context, one could write the following code to indicate that no context variable should be used to track the message connected to the guard Event.
cara::recv -cxname ""
[cara::rcvd -cxname ""]
Note: If a "no context" behavior is the desired default, one could use the Edit>Class Properties... window, select the Event tab and then change the default ActionCode and GuardExpr fields to use the code shown above.
One other consideration in leveraging the context concept in designing an architecture, is that State too may need to be tracked by context. Thinking of the network connection example given earlier, perhaps a PE may need to store parameters for a message while awaiting an acknowledgement. These parameters should be stored with a context index so that the correct parameters can be retrieved, depending on the context flow be processed. This can be done by simply using the default context variable Cx in the PE:
set State($Cx,params) {p1 p2 p3}
There are three different concepts of time used in ProtoCollum.
A temporal partial ordering is established on a Test Sheet by virtue of the fact that the event of sending a message must occur before the event of receiving a message. Thus each Message Test shown on the Test Sheet establishes a temporal ordering between its send event and its receive event. This ordering is called a partial ordering because it only establishes temporal order for events that are found on the same message flow. In general it is not possible to pick any two arbitrary events on two different PEs and be able to establish a temporal order for the events. It can only be done if the events happen to exist on the same message flow.
The partial temporal ordering established by message flow is used by the simulation engine to indicate
a temporal violation when the user is attempting to connect messages on a Test Sheet. If the attempted
connection will violate the temporal order of the message flow, a forbidden symbol
will appear instead of a connection node being created.
Message Time is a representation of the order at which messages are received at a PE Test. Each time a message is received by a PE Test, a counter mtime is incremented. Thus the first message arriving at the PE Test arrives at mtime=1, the second message at mtime=2, etc. This time counter is maintained by the System Package.
The value returned by the procedure cara::rcvd is actually the mtime of the message. One can access the entire port history, or the history of messages received and sent by a PE Test, by using switches available on the Cara procedures. The mtime for messages can be retrieved and assigned to variables, as shown here:
set timeA [cara::rcvd -msglabel msgA]
set timeB [cara::rcvd -msglabel msgB]
set timeC [cara::sent -msglabel msgC -age 1]
Up to this point the procedure cara::rcvd has been used with no switches in a guard Event which has a message attached. In that situation, the procedure will refer to the attached message. But the cara::rcvd procedure can also be used in guard Events with no attached message by using the -msglabel <label> to make a message reference.
The switch -age <num> as used above, indicates that we want the mtime of a message labeled msgC, but not the most recent msgC (whose age=0), but the next older msgC. The Cara System Package allows one to retrieve the current mtime as well:
set timeNow [cara::mtime now]
We can then write an expression for a GuardExpr field that can be an arbitrarily complex time expression:
($timeB == $timeNow) && ($timeA < $timeB) && ($timeC > $timeA)
"msgB must have just arrived, msgA arrived before msgB, and a previous msgC must
have arrived after msgA"
Using expressions of port history when writing architecture rules can often be a concise replacement for using large amounts of state to perform the same function.
Elapsed Time represents the passing of real time or wall-clock time in the system. It is made available in order to relate events to the passing of real time. For example, an architecture may require that after a TimerStart message is received, that 5 msec pass before sending a TimerDone message. Elapsed time is managed by the user by manipulating a time counter called etime.
One way to manipulate the etime counter is by use of the Clock object
. When placed on a PE Test, the user
can set the TimeIncr field to an integer value which represents the amount of
time units to increment the etime counter. Setting TimeIncr
to 5 can be used to represent the passing of 5 msec in the Scenario.
The etime counter can also be modified by using a procedure supplied by the System Package:
cara::etime set 23.0
cara::etime incr 1
cara::etime incr 5
A user can use this capability in a number of different ways. Perhaps an action Event will contain the code cara::etime incr 5 to represent the passage of 5 time units to do the work of the action Event.
Another innovative use can be done while using a ProtoCollum Test Sheet in Checker mode when tied to a lower-level model (such as an HDL model). The simulation times from the clock accurate HDL model can be passed to the Test Sheet and attached to the appropriate events to do an assignment to etime. The architecture can then have rules which check expressions of etime. For instance, that a Reply message is received within 10 msec of sending a Request.
The etime value for a message is retrieved by using a switch to the procedure cara::rcvd, as shown here:
set timeA [cara::rcvd -msglabel msgA -timetype wall]
set timeB [cara::rcvd -msglabel msgB -timetype wall]
set timeC [cara::sent -msglabel msgC -age 1 -timetype wall]
As shown previously, one can then write an arbitrary time expression to relate the time values.
|
Copyright © 2003-2005 by Bellum Software
last updated on 29 May 2005 |