+ All Categories
Home > Documents > TCL Language

TCL Language

Date post: 17-Nov-2014
Category:
Upload: binh-phan-tran
View: 159 times
Download: 0 times
Share this document with a friend
Description:
Ngôn ngữ Tcl (Tool control language). Đây là ngôn ngữ được sử dụng để viết các EDA tool ,ví dụ như Model Sim của hãng Mentor Graphics.Còn TK là toolkit cung cấp giao diện đồ họa người dùng cho Tcl.Tutorial này cung cấp một vài ví dụ về Tcl để có cái nhìn tổng quan về ngôn ngữ này.
22
TCL/TK Tcl/Tk for EDA Every user of EDA tools, and hardware description languages such as VHDL and Verilog, needs to know about Tcl! A good working knowledge of Tcl can help you gain greater productivity in using EDA tools for FPGA and ASIC design, but many Tcl courses and textbooks focus on using Tcl for general- purpose computing applications. At Doulos we understand the needs of EDA users, and our courses and example materials concentrate on those needs. Tutorial What is Tcl? Tcl is a programming language, but it's tailored to work best as a command language for controlling the behaviour of other tools. In fact, the name Tcl stands for "Tool Control Language" and Tcl was originally designed by programmers whose main interest was in developing tools for physical layout of integrated circuits. Whenever you use the command-line prompt in EDA tools such as Mentor's ModelSim, Cadence's NC simulator or Synopsys's FPGA Express synthesis tool, you are probably issuing commands to Tcl. Fully integrated with the EDA tool, Tcl deals with your commands, decides which internal functions of the tool to execute, and passes your command-line arguments to those functions. Why is Tcl helpful for tool control? Tcl provides a uniform, flexible framework for manipulating the commands that drive your EDA tool. Once you know Tcl's core flow control and data manipulation capabilities, you can use them
Transcript
Page 1: TCL  Language

TCL/TK

Tcl/Tk for EDA Every user of EDA tools, and hardware description languages such as VHDL and Verilog, needs to know about Tcl!

A good working knowledge of Tcl can help you gain greater productivity in using EDA tools for FPGA and ASIC design, but many Tcl courses and textbooks focus on using Tcl for general-purpose computing applications. At Doulos we understand the needs of EDA users, and our courses and example materials concentrate on those needs.

Tutorial

What is Tcl?

Tcl is a programming language, but it's tailored to work best as a command language for controlling the behaviour of other tools. In fact, the name Tcl stands for "Tool Control Language" and Tcl was originally designed by programmers whose main interest was in developing tools for physical layout of integrated circuits.

Whenever you use the command-line prompt in EDA tools such as Mentor's ModelSim, Cadence's NC simulator or Synopsys's FPGA Express synthesis tool, you are probably issuing commands to Tcl. Fully integrated with the EDA tool, Tcl deals with your commands, decides which internal functions of the tool to execute, and passes your command-line arguments to those functions.

Why is Tcl helpful for tool control?

Tcl provides a uniform, flexible framework for manipulating the commands that drive your EDA tool. Once you know Tcl's core flow control and data manipulation capabilities, you can use them to write scripts for any Tcl-equipped EDA tool. Although you'll need to learn the specific commands for each individual tool, the way those commands work together and the way you supply arguments to them is the same for any tool that uses Tcl.

Stand-alone Tcl

Although it's often integrated in other tools such as HDL simulators, Tcl is such a useful language in its own right that it is also available as a stand-alone program known as Tclsh, the Tcl shell. In a stand-alone Tcl environment, of course, you won't find commands like "run" and "force" that might be available in a simulator. But the sixty or so commands that form the core of Tcl are still available, and can be used to write all kinds of utility programs for file management,

Page 2: TCL  Language

text processing and similar tasks. File and text processing is very much easier to program in Tcl than in traditional programming languages such as C.

What is Tcl/Tk?

Tk is the graphical user interface toolkit for Tcl. It provides an astonishingly straightforward way to add GUI functionality to a Tcl program - windows, menus, dialog boxes, drawing, the whole works. If you haven't tried it yet, you're missing a lot of fun!

Using TCL to implement an HDL design in a Xilinx FPGA

Scripting Xilinx® ISE™ using Tcl

A Tutorial based on a simple implementation

Introduction

Xilinx ISE is one of the many EDA tools that can be controlled using Tcl. Why would you want to do that? Well, on our courses we often see delegates make an edit to their source code, then re-implement it only to find that the synthesis/layout doesn't do the same as it did before.

This is a constant danger if repeatability depends on remembering to click on the correct boxes and menus in the user interface. If you create a command file you can run that same file many times, thus guaranteeing that you are issuing the same commands to the tool each time.

There are two ways of running the script:

1. Within the GUI there is a Tcl command window, in which you can source (i.e. call/run) a script.

2. You can issue the command "xtclsh scriptname" in your DOS command window or *nix shell and avoid the overhead of a graphical interface completely.

With all this in mind, we are now going to explore some of the ways in which we can drive ISE from a Tcl script. We will synthesise a small design using XST and implement it in a Spartan3e device (chosen to match the boards used on our course VHDL for FPGA Design).

Input files

The first thing we need to do is to tell the tool which source files will be used. We want to do this in a maintainable way, and to this end all filenames are given at the top of the script.

We set some Tcl variables to contain the filenames we require:

Page 3: TCL  Language

# where all output will be createdset compile_directory spartan3e# the top-level of our HDL source:set top_name spartan3e_top# input source files:set hdl_files [ list \ ../constants_spartan.vhd \ ../components.vhd \ ...Other files... \]# constraints with pin placements.set constraints_file ../spartan3e_fsm.ucf

A # denotes a comment; the comment is terminated by a newline and is ignored by the parser. Care is required, as other Tcl behaviour means a hash character will not always be interpreted as the beginning of a comment. Until you know this behaviour it's best to follow these rules about comments:

Each comment appears on a separate line where # is the first character on that line In a comment, don't include mismatched round or square brackets and don't use curly

brackets at all

The set command is used to apply a value to a variable:

set variable_name value

In the setting of the variable "hdl_files" we used the list command to create a Tcl list from the text strings that follow it. As a simpler alternative, we could have used braces to enclose a set of strings: set hdl_files { ../constants_spartan.vhd ../components.vhd ...Other files...}

This approach has some drawbacks, especially when the list items have spaces or special characters. It's generally best to construct the list using the list command. This also allows you to use lappend and lindex commands to manipulate the list.

Setting a Compilation Directory

We now need somewhere to process our files. We can use the file command and its sub-command mkdir to create a directory:

if {![file isdirectory $compile_directory]} { file mkdir $compile_directory}

This code asks if the directory exists; if not, it is created. You may also find file exists useful. Using $ in front of a variable name give you the content of that variable.

Project Creation and Settings

Page 4: TCL  Language

So, now we have a directory and we can do something there. Assuming no project exists in this directory we can go ahead and make one. Xilinx provide the project command, which includes sub-commands for the project settings and other related tasks. Let's try some:

project new $proj.iseproject set family Spartan3Eproject set device xc3s500eproject set package fg320project set speed -4

This is one of the strengths of Tcl; it is easy to add new commands by writing your own procedures. Doing that is outside the scope of this discussion but is covered fully in Essential Tcl/Tk.

Now we need to add some files to the project. Again, Xilinx provide a Tcl command for this: the xfile command is used to add or remove files and to get information on any source files in the current ISE project. We need to add some files, but we don't really want to type filenames again (maintainability, remember?) and we already have a list of source files. The solution is to loop through the list adding each file to the project:

foreach filename $hdl_files { xfile add $filename puts "Adding file $filename to the project."}

The puts command is a simple way to write to STDOUT (which is usually the console/shell). Note: don't forget to add the constraints file; NGDBuild does not automatically detect .ucf files when run from Tcl. Use xfile add in the same way.

Running Processes

Before we run any processes, we can set process options using project set as above; see the provided script for examples and the Xilinx Development System Reference Guide for exhaustive detail.

Now we can run something. Just as with the ISE graphical interface, running any given process will run any required prior processes. In our example, I can issue this command:

process run "Generate Programming File"

and the design will be synthesised and implemented first before the bitfile is created. Again, just as in the graphical interface, source and intermediate file dependencies are checked and processes are run only if required. For example, to force a rerun:

process run "Implement Design" -force rerun_all

Programming the Device

Page 5: TCL  Language

Here we have to change our approach as Impact does not have a Tcl interface. However, this does allow us to explore another way of controlling applications. Impact has the ability to run a script file that consists of a series of commands. These are not Tcl commands, but we can use Tcl to construct this file. We can then run Impact from with the Tcl script. Let's see how.

First we need to open a file that will become the Impact script. We do this with the open command:

if {[catch {set f_id [open $impact_script_filename w]} msg]} { puts "Can't create $impact_script_filename" puts $msg exit}

What's going on here? The open command returns a handle to the file which we put in the variable "f_id". If open fails it would stop the script; this is probably the best thing to do here, but in general you may want to trap errors and continue with other things. That's what catch can do; it will return a non-zero error code if the command it runs (in this case the open) fails, and it places any error message from that command in the variable that here we have called "msg". Hence, if the open fails $msg will contain the reason why.

How do we write text to the file? With the puts command. Earlier we used it to write text to the console, but here we see an addition:

puts $f_id "addDevice -position 1 -file $bit_filename"

Well, it's not really an addition: the default destination of a puts command is the standard output, so if we leave off the second argument then STOUT is where the output goes. The line above uses a second argument, so the text is written to the file given by $f_id instead. After we have written the required command to the Impact script we should close the file.

Now we have to start Impact. There are several ways of calling external programs from Tcl; the easiest is to use the exec command, which runs the external program, waits for it to finish and returns all its output. This is acceptable for quick programs but not for anything more complicated, as you cannot direct any input to the program or control it while it is running. More flexibility is provided by using open, but this time as a pipe from the program:

set impact_p [open "|impact -batch $impact_script_filename" r]

This line starts Impact with the script, and returns its output to the variable "impact_p". The benefit of using the pipe is that we can now watch the STDOUT of the tool from within our Tcl script:

while {![eof $impact_p]} { gets $impact_p line ; puts $line }

This code writes each line of Impact's output to the Tcl script's own standard output. The command eof returns true when the external program finishes. This approach will not work if the external program requires some interaction because that program will not tell you when it

Page 6: TCL  Language

requires some input. In our case, however, this is fine, because we want the Impact script to run until completion. We explore ways of interacting with programs in Essential Tcl/Tk.

Assuming all this runs successfully you should have a working device. Congratulations!

Examples

ModelSim Compile Script

This is a general script for compiling, recompiling and simulating VHDL/Verilog code using ModelSim. It is intended for rapid code writing and testing where small code modifications can be checked very quickly using few keystrokes. Once ModelSim is running in GUI mode and the script has been sourced then recompiling out-of-date files and rerunning a simulation requires two keystrokes: r for recompile and press the Enter key. The key features are:

Support for one or more libraries Simple mechanism for recompiling out-of-date and dependent files

Easily specify waveforms for viewing

Easily specify waveform radices

Simple project time report

Specify SDF file for timing simulations

Here's the script. There's a zip file to download it with some example VHDL/Verilog at the end.

puts { ModelSimSE general compile script version 1.1 Copyright (c) Doulos June 2004, SD}

# Simply change the project settings in this section# for each new project. There should be no need to# modify the rest of the script.

set library_file_list { design_library {counter.vhd} test_library {countertb.vhd countercf.vhd}}set top_level test_library.Cfg_CounterTBset wave_patterns { /*}set wave_radices { hexadecimal {data q}}

Page 7: TCL  Language

# After sourcing the script from ModelSim for the# first time use these commands to recompile.

proc r {} {uplevel #0 source compile.tcl}proc rr {} {global last_compile_time set last_compile_time 0 r }proc q {} {quit -force }

#Does this installation support Tk?set tk_ok 1if [catch {package require Tk}] {set tk_ok 0}

# Prefer a fixed point font for the transcriptset PrefMain(font) {Courier 10 roman normal}

# Compile out of date filesset time_now [clock seconds]if [catch {set last_compile_time}] { set last_compile_time 0}foreach {library file_list} $library_file_list { vlib $library vmap work $library foreach file $file_list { if { $last_compile_time < [file mtime $file] } { if [regexp {.vhdl?$} $file] { vcom -93 $file } else { vlog $file } set last_compile_time 0 } }}set last_compile_time $time_now

# Load the simulationeval vsim $top_level

# If waves are requiredif [llength $wave_patterns] { noview wave foreach pattern $wave_patterns { add wave $pattern } configure wave -signalnamewidth 1 foreach {radix signals} $wave_radices { foreach signal $signals { catch {property wave -radix $radix $signal} } } if $tk_ok {wm geometry .wave [winfo screenwidth .]x330+0-20}}

# Run the simulation

Page 8: TCL  Language

run -all

# If waves are requiredif [llength $wave_patterns] { if $tk_ok {.wave.tree zoomfull}}

puts { Script commands are:

r = Recompile changed and dependent files rr = Recompile everything q = Quit without confirmation}

# How long since project began?if {[file isfile start_time.txt] == 0} { set f [open start_time.txt w] puts $f "Start time was [clock seconds]" close $f} else { set f [open start_time.txt r] set line [gets $f] close $f regexp {\d+} $line start_time set total_time [expr ([clock seconds]-$start_time)/60] puts "Project time is $total_time minutes"}

Download a copy of this script along with some example VHDL/Verilog code (up down counter with test bench), compile_script.zip. Then modify the script settings and use it for your own ModelSim projects.

Notes

The Tcl variable library_file_list stores the library name(s) and files that should be compiled into each library. It is a two dimensional Tcl formatted list. The first element is the name of a library, the second element is a list of files that should be compiled into that library. If there is more than one library then a third and fourth element should be written for the second library name and its list of files. And so on.

The order of libraries and files is significant, they should appear in order of dependency. The script will compile every file the first time. Subsequent recompiles will run through the list of files looking for a file that has been modified since the last compile time. The modified file and every file after it in the list will be recompiled.

The Tcl variable top_level keeps the library and name of the top level for elaboration. In fact the contents of this variable is used as the arguments to ModelSim's vsim command, so any valid options may be specified for example:

set top_level {-t ps -sdftyp /uut=counter.sdf test_library.cfg_gate}

Page 9: TCL  Language

The Tcl variable wave_patterns can contain a list of signals or patterns that should be loaded into the wave window. For most block level testbenches just /* is enough. If no waves are required or the script is being used for command line simulations then this list can be left empty (nothing but white space).

The Tcl variable wave_radices is a two dimensional Tcl formatted list like library_file_list. The first element is a radix to use: hexadecimal, unsigned, binary etc. The second element is a list of wave signals for applying this radix to. There can be zero, one or more pairs of elements in this list.

To recompile out-of-date and dependent files type r and Enter. To force complete recompilation type rr and Enter. To quit without ModelSim confirming that you want to quit type q and Enter.

To start ModelSim and source this script from the command line, type this:

vsim -do compile.tcl

Or, if ModelSim is already running with the correct working directory, type this in the ModelSim main window:

source compile.tcl

Tcl/Tk Buttons

Here is a short example showing how to use Tcl/Tk to create toplevel windows containing frequently used buttons. Mostly there are just three things we need to know about buttons:

What does the label say? What Tcl command should be executed when clicked?

Where does the button appear in its window?

Here, button creation is wrapped up in procedure add_button. It takes two arguments, what the label should say and what Tcl commands should be executed when the button is clicked. Buttons are arranged in a single column.

# A Tcl/Tk gadget to construct a window of buttons# SD 20 Nov 2002

########################################### ######## Leave these lines unchanged ######## ###########################################destroy .buttonstoplevel .buttonswm title .buttons "Buttons"set count 0

Page 10: TCL  Language

proc add_button {title command} { global count button .buttons.$count -text $title -command $command pack .buttons.$count -side top -pady 1 -padx 1 -fill x incr count}

########################################### ######## Change these lines to ######## add your own buttons ######## ###########################################add_button "Resize Main" { wm geometry . 464x650+0+0 }add_button "Hello" { puts "Hello there" }add_button "Goodbye" { puts "Cheerio" }add_button "Exit" { exit }

The four add_button commands in this example produce a window like this one. You can replace them with any commands appropriate for your EDA tools. Any Tcl commands may be used for the second arguments.

Multiple Frames of Buttons

You may want a dozen buttons or more organised in columns. Here's one way to do it:

# A Tcl/Tk gadget to construct a window of buttons# SD 8 Aug 2003

########################################### ######## Leave these lines unchanged ######## ###########################################destroy .buttonstoplevel .buttonswm title .buttons "Doulos Buttons"set count 0proc add_frame title { global frame count set frame .buttons.frame$count frame $frame -border 2 -relief groove label $frame.label -text $title pack $frame -side left -padx 2 -pady 2 -anchor n -fill both pack $frame.label -side top -padx 2 -pady 2 incr count}

Page 11: TCL  Language

proc add_button {title command} { global frame count button $frame.$count -text $title -command $command pack $frame.$count -side top -pady 1 -padx 1 -fill x incr count}

########################################### ######## Change these lines to add ######## your own frames and buttons ######## ###########################################add_frame "Control"add_button "Window Size" {wm geometry . 464x692+0+0}add_button "Create Library" {vlib mylib; vmap work mylib}add_button "Compile" { vcom counter.vhd vcom countertb.vhd vcom countercf.vhd }add_button "Load Simulation" {vsim mylib.cfg_countertb}add_button "Wave Window" {source wave.do}add_button "Quit" {quit -force}

add_frame "Simulate"add_button "Run 10" {run 10}add_button "Run 100" {run 100}add_button "Run 1000" {run 1000}add_button "Run all" {run -all}add_button "Restart" {restart -force}

add_frame "Zoom"add_button "Full" {.wave.tree zoomfull}add_button "2x" {WaveZoom .wave out 2.0}add_button "4x" {WaveZoom .wave out 4.0}add_button "1/2x" {WaveZoom .wave in 2.0}add_button "1/4x" {WaveZoom .wave in 2.0}

There is now an add_frame procedure. Each group of add_button commands must be preceded by a call to add_frame. Frames are packed left to right and buttons are still packed in columns.

Once again you can change the add_frame and add_button commands for your own buttons. This example is taken from a ModelSim SE project so the commands are EDA tool specific.

How To Use

Page 12: TCL  Language

These examples are useful for EDA tools that support Tcl and the Tk package. Copy and paste one of the above examples into a file, maybe called buttons.tcl. Edit your copy changing add_button commands to suit your project. From inside the Tcl command window of the EDA tool type:

   source buttons.tcl

Commands issued by button clicks are directly interpreted by the EDA tool.

Does Your EDA Tool Support Tk?

Try typing this into the Tcl command window:

   package require Tk

If the tool responds with a version number like 8.4 then it does. If the tool responds like this can't find package Tk then it doesn't and it might be quite tricky or impossible to support Tk directly. Check the manual. If your EDA tool doesn't support Tk then you can still add Tk functionality to it indirectly.

Add External Support for Tk?

Standard Tcl supports pipelines and events. Pipelines let Tcl-only tools interact with other Tcl applications that can support buttons and other powerful Tk widgets. Tcl is free and you can compile your own Tcl interpreter supporting Tk from source code or just download and install a free binary distribution.

This example was written to work with ModelSim PE which doesn't support Tk. The first procedure, include_these_buttons, contains the only ModelSim specific parts. You can change the add_frame and add_button commands to suit your own EDA tool and project.

#! /usr/bin/wish

proc include_these_buttons {} {

add_frame "Control" add_button "Create Library" {vlib mylib; vmap work mylib} add_button "Compile" { vcom counter.vhd vcom countertb.vhd vcom countercf.vhd } add_button "Load Simulation" {vsim mylib.cfg_countertb} add_button "Wave Window" {source wave.do} add_button "Quit" {quit -force}

add_frame "Simulate" add_button "Run 10" {run 10} add_button "Run 100" {run 100} add_button "Run 1000" {run 1000} add_button "Run all" {run -all}

Page 13: TCL  Language

add_button "Restart" {restart -force}

}

proc add_frame title { global buttons set buttons(frame) .frame$buttons(widget_count) frame $buttons(frame) -border 2 -relief groove label $buttons(frame).label -text $title -font $buttons(font) pack $buttons(frame) -side left -padx 2 -pady 2 -anchor n -fill both -expand 1 pack $buttons(frame).label -side top -padx 2 -pady 2 incr buttons(widget_count)}

proc add_button {title command} { global buttons button $buttons(frame).b$buttons(widget_count) -text $title -font $buttons(font) \ -command "puts \"$command\"" pack $buttons(frame).b$buttons(widget_count) -side top -pady 2 -padx 2 -fill x incr buttons(widget_count)}

proc respond_to_buttons {} { global buttons if [eof $buttons(pipe_id)] { catch {close $buttons(pipe_id)} } elseif { [gets $buttons(pipe_id) line] >= 0 } { puts $line eval $line }}

if [string compare $argv buttons_gui] { global buttons if [catch {set buttons(pipe_id) [open "|wish buttons.tcl buttons_gui" r+]}] { puts "Couldn't start wish for the buttons GUI\n" } else { fconfigure $buttons(pipe_id) -blocking 0 -buffering line fileevent $buttons(pipe_id) readable respond_to_buttons }} else { wm title . Buttons set buttons(font) [font create -family {Arial Helvetica "Courier New"} -size 12] set buttons(frame) {} set buttons(widget_count) 1 include_these_buttons}

Page 14: TCL  Language

To make this example work the standalone Tcl/Tk interpreter must be installed. It's command name is usually wish. The line containing this fragment starts the wish interpreter through a pipeline:

   [open "|wish buttons.tcl buttons_gui" r+]

If your system uses another name such as wish84 then you should modify this line.

This script is run twice. First from the EDA tool by typing source buttons.tcl. The script then opens a command pipeline calling the Tcl/Tk interpreter and supplying its own name as the script to execute but this time with buttons_gui command line argument. This tells the Tcl script it's being run as the standalone application to display the buttons specified in the include_these_buttons procedure.

Communication takes place through the pipeline. When a button is clicked it sends the Tcl commands as plain text down the command pipeline to the EDA tool. For example:

   puts {vlib mylib; vmap work mylib}

A file event is set up in the EDA tool to respond to new information from the pipeline:

   fileevent $buttons(pipe_id) readable respond_to_buttons

This executes the procedure respond_to_buttons everytime the buttons application sends commands. It reads from the pipeline and uses the eval command to pass them on to the EDA tool's Tcl interpreter.

This example assumes the EDA tool uses an event loop. If it doesn't you can easily modify the script to start one with the vwait command. However, the event loop may have to be terminated to pass control back to the EDA tool's command window.

Find the Driver in Synopsys DC TM

Tcl in Synopsys Design Compiler

The Design CompilerTM synthesis tool from Synopsys, Inc. has two different console-mode user interfaces: the traditional dc_shell command language, and a Tcl shell which can be obtained by using the command dc_shell -t to launch the tool.

Tcl scripting in DC

Design Compiler (DC) uses an internal database to store your design throughout the synthesis process. As you execute various DC commands to optimise and modify the synthesised design, the database is updated. Finally, when you are satisfied with the synthesised results, you can write the database out in some format such as EDIF, or as a Verilog or VHDL netlist.

Page 15: TCL  Language

When you use Tcl in DC you need to understand how DC exposes its database. Tcl can handle only string data, and of course the DC database is in a proprietary binary format, so your Tcl scripts must access the database through the commands and functions provided as part of DC. In particular it's very important to understand how DC allows you to group database objects into collections which can then be supplied as the arguments to various commands.

Doulos offers Tcl training including an optional module on Tcl in Synopsys DC, to give synthesis users a get-you-started overview of how to approach DC scripting.

Exploring the DC database using Tcl

One of the worked examples from our DC-Tcl module is a script that explores the DC design database, to any required depth of hierarchy, in order to locate the gate or module that drives a specified net. This could be useful, for example, as part of a script that adjusts the size of driver devices to suit the capacitive loading of the nets they drive.

This example script illustrates how to traverse the design hierarchy, and how to investigate the relationship between different objects (for example, discovering what net is connected to some pin of a module).

# find_driver.tcl## Tcl script to run within Synopsys Design Compiler(TM)# in Tcl-shell mode.## Tcl procedure to find the driver on a specified object.# The argument "thing" should be an object name. # The procedure will descend arbitrarily deep into the# design hierarchy to find the ultimate driving cell of # the specified object.## The procedure works correctly when "thing" is the name of a net,# port, or pin.## Jonathan Bromley, 13 June 2002######################################################################## DISCLAIMER:## This software is provided "as-is" by Doulos Ltd as a service to# members of the electronics design community, and comes WITHOUT# WARRANTY OF ANY KIND. Doulos has made all reasonable efforts# to ensure that this software performs as described, but accepts# no liability for any consequences of its use either in its # present form or in any modified form that you may create.## You are welcome to use this software, or any modification of# it, in your own application. If you modify it, you must# add comments clearly indicating that it is not the original# version as provided by Doulos Ltd.#

Page 16: TCL  Language

# You are very welcome to contribute improvements or corrections# to this software, and your authorship of any such changes that# we incorporate will be acknowledged in the source code. Send# your contributions by email to [email protected] mentioning# "Tcl for DC" in the subject line.######################################################################

proc find_driver {thing} {

# Get the driving pins of thing within the instance. # First we need to know the name of thing's net(s).

# First, assume it's a net and find the related object. # Use "redirect" to avoid unwanted console output from the # get_net command. redirect /dev/null {set net [get_net $thing]}

# Did we fail to locate the net that way? if {![sizeof_collection $net]} { # Try to locate its net... this works if it's a port. redirect /dev/null {set net [get_net -of_object $thing]} }

# Did we fail to locate the net that way? if {![sizeof_collection $net]} { # try to find what it's connected to! set its_nets [find net [all_connected $thing]] # But we want only those nets at the top of the current hierarchy. set net {} foreach_in_collection n $its_nets { if {![string match */* [get_object_name $n]]} { # No need to redirect this, since it's inside a loop and hence # doesn't return its result. set net [add_to_collection $net $n -unique] } } }

# Now we know its net name, we can scan for pins on that net. set pin [get_pin -of_object $net -filter @pin_direction!=in] # Bail out if there's not exactly one pin driving the net! set nDrivers [sizeof_collection $pin] if {$nDrivers == 0} { error "There appears to be no driver on this port or net!" } elseif {$nDrivers != 1} { foreach_in_collection n $pin { puts "[get_object_name $n]\n" } error "Bailing out, I can only cope with one driver per net!" } # Extract the pin's name. It will have the form "instance/port". set driver [get_object_name $pin] # Parse the pin name "instance/port" to get both

Page 17: TCL  Language

foreach {inst port} [split $driver {/}] {} # Find if we've reached a leaf of the hierarchy. if {[get_attribute $inst is_hierarchical]} { # It's hierarchical so we must descend into it.

# Stack the current context redirect /dev/null {set home [get_object [current_design]]} # Find the design name of the instance and descend into it redirect /dev/null {current_design [get_attrib $inst ref_name]} # Dig down to find the driver within this instance set driver [find_driver $port] # puts "reached driver $driver" # Make up the hierarchical name set driver [join [list $inst $driver] {/}] # Unstack context redirect /dev/null {current_design $home} } return $driver }


Recommended