Creating Virtual Peripheral Devices in a Digital Circuit Simulator Using Tcl/Tk Jeffery P. Hansen Institute for Complex Engineered Systems Carnegie Mellon University Pittsburgh, PA 15213 ABSTRACT TkGate is a digital circuit editor and simulator built as a hybrid C and Tcl/Tk application. It is used in circuit design courses at dozens of universities throughout the world and has interface support for nine European and Asian languages. In this paper we primarily focus on a feature of TkGate called VPDs (Virtual Peripheral Devices). VPDs are simulated representations of digitally controlled physical devices or systems. A VPD has a graphical interface, implemented in Tcl/Tk, representing the device and a Verilog stub module representing the digital interface to the device. Users interact with the simulated device through the GUI while a Verilog description of the controller is connected through the VPD stub module. 1) Introduction TkGate [1] is a digital circuit editor and simulator designed to be used in teaching digital circuit design at the university level. It provides a wide range of built-in features and is suitable for design up to and including medium sized microprocessors. TkGate was originally designed and built as a non-Tcl/Tk application and later ported to use Tcl/Tk. Tcl/Tk proved to be powerful and versatile enough to make this a surprisingly painless port. TkGate has since continued to build on using Tcl/Tk as an integral part of the application. One interesting feature and the focus of this paper is the ability for users to define Virtual Peripheral Devices (VPDs). VPDs are Tcl/Tk scripts that simulate a peripheral device or other physical system and include both user interaction and interaction with a controlling circuit description. A typical use for VPDs would be to create engaging and realistic laboratory assignments for University level engineering courses. 2) TkGate History and Architecture Work on the predecessor to the TkGate digital circuit editor and simulator, Gate, was started in 1986. It was designed for a window manager called ``wm'' which was developed as part of the Andrew project at Carnegie Mellon University. As X11 gained popularity, it was then ported to run under X11 as an Xlib application in about 1990 and in the late 1990s it was finally ported to run with Tcl/Tk. By treating the Xlib-based main editor window from the original Gate application as Tcl/Tk widget, and using Tcl/Tk to implement the interface look-and-feel adding menus and dialog boxes it was possible to create an initial running version of the new interface with only a few days of work. The first public release was TkGate 0.9 on May 1999. The current version is 1.8.6, and version 2.0 which contains support for VPDs has a planned release date in the Summer or Fall of 2005. TkGate is comprised of two primary executables: a graphical interface and a simulator. The graphical interface, is comprised of about 55,000 lines of C and 26,000 lines of Tcl/Tk. All direct user interaction is through the interface which includes circuit editing and control of the simulation. A Verilog simulator runs as a separate executable and includes extensions to support VPDs. Communication between the simulator and the interface is through a pipe. 3) Virtual Peripheral Devices To create a VPD, a user creates a Tcl/Tk script implementing the graphical interface and a Verilog stub module encapsulating the VPD into a circuit module. Typically users will use a Tcl namespace to create their VPD script. An API on both the Tcl side and the Verilog side is used to facilitate communication between the GUI and the Verilog stub module. Data from the Tcl/Tk script is transmitted to the Verilog stub through a "named channel", and data from the Verilog stub is transmitted to the Tcl/Tk script though a Verilog system task, $tkg$exec(), that constructs and executes a string as a Tcl/Tk command. For security purposes, it is possible to place limitations on the Tcl/Tk commands that can be executed though this interface. Two example VPDs are included with the standard TkGate distribution: a TTY device, and a drink vending machine. The VPD for the TTY device is an xterm-like window that interacts with a simulation of a small microprocessor. Key presses in the window are converted to output signals on the Verilog stub module, and input signals to the stub module, are converted to commands that generate an output character in Tcl/Tk TTY window. This is demonstrated through an interactive text program included as part of the microprocessor circuit description. In the drink vending machine VPD, a Tcl/Tk window showing an external and internal view of a vending machine appears when the simulation is started. As users press buttons or insert "coins" through the interface, these action are translated into signals in the circuit. The user circuit implementing the vending machine controller can then send signals to the vending machine VPD to dispense drinks and/or change. An excerpt from the Tcl/Tk portion of the VPD description is shown below: ----------------------------------------------------------------------------- namespace eval VendingMachine { ... proc post {name args} { # Drink selection button state variable variable osigPRESS ... # Create top-level window for drink machine set w [VPD::newtoplevel -title "Vending Machine $name" \ -shutdowncommand "VendingMachine::unpost $name"] ... # Register named channel with button state variable VPD::signal $name.PRESS VendingMachine::osigPRESS($name) ... } } ----------------------------------------------------------------------------- The vending machine interface is started by invoking the Tcl/Tk "VendingMachine::post" procedure. The "name" argument is a unique identifier for an instance of the vending machine peripheral. The "VPD::newtoplevel" command creates a top-level window for the device which is automatically closed when the simulation is terminated. The "VPD::signal" command causes the Tcl variable "VendingMachine::osigPRESS($name)" to be linked with the named channel "$name.PRESS". Any time this variable is assigned a value, the Verilog stub will be notified over that channel. An excerpt from the Verilog stub for the above VPD is shown below: ----------------------------------------------------------------------------- module cokemachine(..., PRESS, NOCHG, ...); output [5:0] PRESS; input NOCHG; // // Execute the drink machine post command to start up the Tcl/Tk interface. // initial $tkg$exec("VendingMachine::post %m"); ... // // Respond to changes in the Tcl/Tk osigPRESS variable. // always #10 PRESS = $tkg$recv("%m.PRESS"); // // Send // always @ (NOCHG) $tkg$exec("VendingMachine::setNoChange %m %b",NOCHG); endmodule ----------------------------------------------------------------------------- The "initial" block is executed at the start of simulation and causes the "VendingMachine::post" command to be executed. The $tkg$exec() system task supports a sprintf() like interface in which the string to be executed is constructed based on the given format string. A "%m" in the format string is replaced by the instance name of the module in the module hierarchy allowing multiple instances of the drink machine peripheral. The always block waits for data to be available on the "%m.PRESS" channel and assigns that value to the output signal in the vending machine stub module. References [1] TkGate Homepage, http://www.tkgate.org