OSDN Git Service

* public snapshot of sid simulator
[pf3gnuchains/pf3gnuchains3x.git] / sid / component / tcl / bridge-tcl.txt
1 * Name
2   bridge-tcl bridge-tk bridge-blt
3
4 * Synopsis
5
6   This family of components implements a bridge between the C++ SID
7   API and Tcl, in an embedded Tcl/Tk/Tk+blt 8.0 interpreter.
8
9   * Pins: !event !event-control (+BRIDGED)
10   * Attributes: load! eval! (+BRIDGED)
11   * Buses: (BRIDGED)
12   * Accessors: (BRIDGED)
13   * Relationships: (BRIDGED)
14
15   * Library: libtclapi.la
16   * Symbol name: tcl_component_library
17
18 * Functionality
19
20   - Modelling 
21
22   * As this family of components is just a bridge, the nature of
23     modelling performed is up to the script on the other side of the
24     bridge.  This component merely funnels SID API calls between the
25     outer C++ system and each bridge component's isolated embedded tcl
26     interpreter.
27
28   - Behaviors
29
30   * Configuration
31
32     You must configure the embedded Tcl interpreter with the
33     Tcl scripting code that will receive bridged C++ SID API calls.
34     This can be done in two ways.  First, if the "load!" attribute is
35     written to, the value is interpreted as a file name, and loaded
36     into the Tcl interpreter as if with the Tcl "source" command.
37     This file may contain procedure definitions and any Tcl code to be
38     evaluated right away.  Second, if the "eval!" attribute is written
39     to, the value is interpreted as a Tcl expression as if the
40     Tcl_Eval() function had been used.
41
42     A "bridge-tk" type component is automatically initialized with the
43     usual bindings to the Tk windowing toolkit.  A "bridge-blt" type
44     component, where available, includes the same Tk bindings, in  
45     addition to the usual bindings to the BLT Tcl extension library.
46
47   * Event handling
48
49     The embedded Tcl interpreter requires regular-event polling in
50     order to operate, especially if the tk or tk+blt extensions are in
51     use.  Whenever the "!event" input pin is driven, the
52     Tcl_DoOneEvent() function is called repeatedly for all pending Tcl
53     events.  
54
55     In response, the "!event-control" output pin is driven with a
56     number between 1 and 1000.  The number represents the component's
57     suggestion about the time interval to the next "!event" signal,
58     and is meant to be compatible with the "sid-sched-*" components'
59     "NNN-control" inputs.  This way, the Tcl bridge component attempts
60     to adaptively regulate its own event polling rate, balancing good
61     response time in busy periods and low overhead during idle
62     periods.
63
64   * Bridging
65
66     With only the exceptions noted above, all incoming C++ SID API
67     calls are bridged by making appropriate calls to an embedded Tcl
68     interpreter.  One Tcl procedure call is made per C++ call.  Types
69     and function names are mapped as specified in the Incoming sid API 
70     calls section.
71
72     The invoked Tcl procedure may perform any necessary processing and
73     return a value.  It may make further SID API calls outward to
74     other components through the symmetrical Tcl-to-C++ bridging 
75     described in the Outgoing sid API calls section.
76
77     Tcl interpreter errors are caught during the bridging process.  In
78     case the interpreter fails to run the appropriate Tcl procedure to
79     completion, a "TCL ERROR" message is printed to stderr, and some
80     error-suggesting return value is made up for completing the C++
81     call.  This situation is analogous to a C++ component throwing an
82     exception during its execution of an incoming SID API call, though
83     in the pure C++ case, uncaught exceptions cause the SID process to
84     terminate.
85
86   - SID conventions
87
88     This component bridges an API.  Any conventions supported by the
89     loaded script on the Tcl side will be supported on the C++ side
90     of the bridge.  The bridge does not implement any SID conventions
91     on its own.
92
93 * Environment
94
95   - Related components
96
97   * As suggested in the "Event handling" behavior section above, this
98     component performs best if the "!event" and "!event-control" pins
99     are connected to a scheduler.  If the bridge component is to carry
100     out any work, it is necessary to load Tcl script fragments into
101     it.  Here is a script fragment that does both.
102
103         new bridge-tcl tracer
104         new sid-sched-host sched
105         set tracer load! "/path/my-component.tcl"
106         connect-pin sched 0-event -> tracer !event
107         connect-pin sched 0-control <- tracer !event-control
108
109   * A more sophisticated way to use a bridge component is to
110     associate SID triggerpoint hits with scripted actions.  For example,
111     the following fragment activates a triggerpoint on a register of a
112     peripheral, and prints a message whenever it hits.  Note how the Tcl
113     script is fed in piece by piece using the "eval!" attribute.
114
115         new bridge-tcl watcher
116         new some-type victim
117         # Configure bare minimum tcl code to make an input pin and
118         # respond to it being driven.  Note how find_pin does not
119         # check the pin name, so any name will be accepted in the
120         # later connect-pin line.
121         set watcher eval! "set p [sid::pin::new]"
122         set watcher eval! "proc find_pin {name} {global p ; return $p}"
123         set watcher eval! "proc driven_h4 {pin value} {puts \"triggerpoint hit v=$value!\"}"
124         # triggerpoint: watch victim component's register "r0" for value 0xAA
125         connect-pin victim watch:r0:value:0xAA -> watcher anyname
126
127   - Host system
128
129   * The bridge-tcl and bridge-tk components are available on all
130     platforms.  The bridge-blt component is available only if the BLT
131     Tcl extension library was compiled into this component.
132
133   * Each instance of a "bridge-tk" or "bridge-blt" component creates a
134     separate new top-level tk window.
135
136
137 * SID interface reference
138
139   - low level:
140
141     Note that this list includes only those low level interfaces that
142     are actually provided by the bridge component.  In order to act
143     transparent, these are excluded from the pin_names and
144     attribute_names inquiry functions.  All visible low level
145     interfaces actually come from the Tcl scripting code loaded into
146     the bridge.
147
148     * pins
149       - !event | input | any | event handling
150       - !event-control | output | 1-1000 | event handling
151
152     * attributes
153       - load! | | file name | n/a | configuration
154       - eval! | | string | n/a | configuration
155
156
157
158 Theory of operation for tcl-bridge component
159 --------------------------------------------
160
161 A tcl-bridge component is a shell that hooks all sid API calls to an
162 embedded tcl interpreter so that they can be handled as tcl procedure 
163 calls.  In addition, sid API calls are exposed to that interpreter, so 
164 the tcl procedures can call back out to the C++ system.  With these two
165 capabilities, a user-provided tcl package may *become* a first class
166 sid component.
167
168 Objects such as bus, component, and pin pointers may be passed through
169 tcl scripts safely, because the bridging calls represent these as
170 unique strings, and convert them back to C++ pointers automatically.  Any
171 pointers seen through incoming call arguments, or outgoing call return
172 values, are transparently converted into unique long-lived opaque
173 strings.  This way, C++ pointers can safely pass through the tcl
174 bridge in both directions.
175
176 Unlike C++ components, tcl scripts that run in a tcl-bridge do not
177 have access to the sidutil:: group of utility classes.  This means
178 that only low level operations are directly provided, and sidutil::
179 abstractions would need to be rewritten (if needed) in tcl.
180
181
182 Incoming sid API calls
183 ----------------------
184
185 Almost all incoming sid API calls are passed through verbatim to the
186 embedded tcl interpreter.  (Exceptions are parameterized and noted
187 below.)  Plain types are mapped according to the table below: C++
188 object to tcl for arguments, and tcl to C++ for return values.  If tcl
189 procedures by the appropriate names are not loaded into the
190 interpreter by the time they are invoked from another sid component,
191 a "TCL ERROR" message is printed to cerr, and a function-specific
192 error indication is returned.
193
194 Calls belonging to sid::pin and sid::bus are similarly mapped to
195 tcl procedure calls.  The C++ pin/bus object on which they are called
196 is passed to the procedures as an extra argument.  (C++ pin/bus
197 objects may be constructed for a tcl component through special
198 callback functions, listed below.)
199
200 Functions with multiple outputs, like the sid::bus::read reference
201 arguments, map to tcl procedures returning a list with the mapped C++
202 return type as first element, and the output reference argument as
203 second element.
204
205
206 C++ type                        tcl type
207
208 string                          string
209 vector<string>                  list of strings
210 component,bus,pin pointer       opaque string
211 {little,big,host}_int_{1,2,4,8} numeric integer - care with 64-bit ints!
212 component::status               string: "ok", "bad_value", "not_found"
213 bus::status                     string: "ok", "misaligned", "unmapped",
214                                         "unpermitted", "delayed"
215 vector<component*>              list of opaque strings
216 vector<pin*>                    list of opaque strings
217 0 (null pointer)                ""
218
219
220 incoming C++ call               outgoing tcl call
221
222 -- in sid::component
223
224 attribute_names()               attribute_names
225 attribute_names(category)       attribute_names_in_category $category
226 attribute_value(name)           attribute_value $name
227 set_attribute_value(name,value) set_attribute_value $name $value
228 pin_names                       pin_names
229 find_pin(name)                  find_pin $name
230 connect_pin(name, pin)          connect_pin $name $pin
231 disconnect_pin(name, pin)       disconnect_pin $name $pin
232 connected_pins(name)            connected_pins $name
233 bus_names                       bus_names
234 find_bus(name)                  find_bus $name
235 accessor_names                  accessor_names
236 connect_accessor(name,bus)      connect_accessor $name $bus
237 disconnect_accessor(name,bus)   disconnect_accessor $name $bus
238 connected_bus(name)             connected_bus $name
239 relationship_names()            relationship_names
240 relate(rel,comp)                relate $rel $comp
241 unrelate(rel,comp)              unrelate $rel $comp
242 related_components(rel)         related_components $rel
243
244 -- in sid::pin
245
246 driven(value)                           driven_h4 $pin $value
247
248 -- in sid::bus, for host_int_4 address and {big,little}_int_Y data types
249
250 read(address,data)                      read_h4_{l,b}Y $address   ** return [list $status $data] **
251 write(address,data)                     write_h4_{l,b}Y $address $data
252
253
254 Outgoing sid API calls
255 ----------------------
256
257 Once a tcl program is loaded into the interpreter, it is able to make 
258 outgoing sid API calls, not merely respond to incoming ones.  All sid 
259 API functions are exposed to tcl as procedure hooks, in a very
260 symmetric way to the incoming calls.  Simply, each function in the
261 incoming set has a shadow: "sid::component::FUNCTION",
262 "sid::pin::FUNCTION" or "sid::bus::FUNCTION", as appropriate.  Each
263 outgoing procedure takes a receiver handle (the same opaque string
264 passed in an incoming call) as its first argument.
265
266 There is no checking that would prevent an outgoing sid API call from
267 becoming recursive and referring to the originating component, either
268 directly or indirectly.  As for all other components, infinite
269 recursion prevention is the responsibility of the component author.
270
271
272 incoming                        outgoing
273
274 attribute_value $name           sid::component::attribute_value $component $name
275 driven_h4 $pin $value           sid::pin::driven_h4 $pin $value
276 ... etc ...
277
278
279 There are some special outgoing functions that function as
280 constructors for local object handles.
281
282 sid::component::this    returns an opaque string handle to this component 
283 sid::pin::new           returns an opaque string handle to a new private C++ pin,
284                            usable as a return value to `find_pin'
285 sid::bus::new           returns an opaque string handle to a new private C++ bus,
286                            usable as a return value to `find_bus'