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