| SID Simulator Component Developer's Guide | ||
|---|---|---|
| <<< Previous | Next >>> | |
A bridge-tcl component is a shell that hooks all SID API calls to an embedded Tcl interpreter so that they can be handled as Tcl procedure calls. In addition, SID API calls are exposed to that interpreter, so the Tcl procedures can call back out to the C++ system. With these two capabilities, a user-provided Tcl package may become a first class SID component.
Objects such as bus, component, and pin pointers may be passed through Tcl scripts safely, because the bridging calls represent these as unique strings, and convert them back to C++ pointers automatically. Any pointers seen through incoming call arguments, or outgoing call return values, are transparently converted into unique long-lived opaque strings. This way, C++ pointers can safely pass through the Tcl bridge in both directions.
Unlike C++ components, Tcl scripts that run in a bridge-tcl do not have access to the sidutil:: group of utility classes. This means that only low level operations are directly provided, and sidutil:: abstractions would need to be rewritten (if needed) in tcl.
Almost all incoming SID API calls are passed through verbatim to the embedded Tcl interpreter. (Exceptions are parametrized and noted below.) Plain types are mapped according to the table below: C++ object to Tcl for arguments, and Tcl to C++ for return values. If Tcl procedures by the appropriate names are not loaded into the interpreter by the time they are invoked from another SID component, a TCL ERROR message is printed to cerr, and a function-specific error indication is returned.
Calls belonging to sid::pin and sid::bus are similarly mapped to Tcl procedure calls. The C++ pin/bus object on which they are called is passed to the procedures as an extra argument. (C++ pin/bus objects may be constructed for a Tcl component through special callback functions, listed below.)
Functions with multiple outputs, like the sid::bus::read reference arguments, map to Tcl procedures returning a list with the mapped C++ return type as first element, and the output reference argument as second element.
| C++ Type | Tcl Type |
|---|---|
| string | string |
| vector<string> | list of strings |
| component,bus,pin pointer | opaque strings |
| {little,big,host}_int_{1,2,4,8} | numeric integer - care with 64-bit ints |
| component::status | string: ok, bad_value, not_found |
| bus::status | string: ok, misaligned, unmapped, unpermitted |
| vector<component*> | list of opaque strings |
| vector<pin*> | list of opaque strings |
| 0 (null pointer) | "" |
In sid::component:
| Incoming C++ call | Outgoing Tcl call |
|---|---|
| attribute_names() | attribute_names |
| attribute_names(category) | attribute_names_in_category $category |
| attribute_value(name) | attribute_value $name |
| set_attribute_value(name,value) | set_attribute_value $name $value |
| pin_names | pin_names |
| find_pin(name) | find_pin $name |
| connect_pin(name, pin) | connect_pin $name $pin |
| disconnect_pin(name, pin) | disconnect_pin $name $pin |
| connected_pins(name) | connected_pins $name |
| bus_names | bus_names |
| find_bus(name) | find_bus $name |
| accessor_names | accessor_names |
| connect_accessor(name,bus) | connect_accessor $name $bus |
| disconnect_accessor(name,bus) | disconnect_accessor $name $bus |
| connected_bus(name) | connected_bus $name |
| relationships() | relationships |
| set_related_components(rel,comps) | set_related_components $rel $comp1 $comp2 $comp3 ... |
| related_components(rel) | related_components $rel |
In sid::pin:
In sid::bus, for host_int_4 address and {big,little}_int_Y data types:
| Incoming C++ call | Outgoing Tcl call |
|---|---|
| read(address,data) | read_h4_{l,b}Y $address ** return [list $status $data] ** |
| write(address,data) | write_h4_{l,b}Y $address $data |
Incoming C++ calls that access these parameters are not passed through to the embedded Tcl interpreter. Rather, they are processed in the bridge code attribute.
Loads the given Tcl script into the interpreter using the source procedure pin
Passes control to the tcl/Tk event loop, in non-blocking mode
| <<< Previous | Home | Next >>> |
| CDK Tutorial | Outgoing SID API Calls |