

Writing TCL apps
If there is one thing that I always enjoy doing it is writing apps in TCL/TK. Since John Ousterhout wrote it to support the MAGIC VLSI layout system I've always felt a particular connection to it as an electrical engineer. Today though it has seriously out grown its original roots and spread to a wide spectrum of application domains. But I use it for scripting in Modelsim mainly and the occasional home grown app.
Yesterday I was figuring out how to pass a list of keys into the 'dict' command. Dict allows your scripts to setup easy, fast, ASCII databases for use in your applications. It is based on a key-value pair system that looks (and acts) very much like a regular TCL list. On the inside however, there is a powerful internal representation of the character strings that makes access very quick.
What is it used for? Think about how you would store a list of signals associated with various levels of your hierarchical VHDL/Verilog code that you want to have displayed in a simulator wave window. The dict data structure is ideal for that use. Here is a hand coded dictionary (with indenting for clarity):
top {ctrlr {counter {up down clr} fsm {state1 state2} mux {sel d1 d2 d3 d4 out} } dsp { ... } }
The dictionary is hierarchical because each value in the key-value pair can itself be a nested dictionary!
To access that hierarchy you need to get access to those lower level nested dictionaries. The syntax for the set sub command permits that:
dict set dictionaryvar key [key ...] value
The ability to specify multiple keys (as a variable number of arguments) allows the coder to descend down multiple levels in the dictionary hierarchy without calling the dict command multiple times.
To add another set of signals for a new block mem using the example dictionary above you would code:
% dict set SIGNALS top ctrlr mem [list addr rnw datain dataout]
Unfortunately, my requirement was to pass a (variable sized) list of keys to the dict set command. How do you flatten them out? You can't just do something like this: (Warning blatant self promotion coming...)
% set keylist [list "ASPEN LOGIC" SKILLS] % dict set SKILLS $keylist "VHDL Verilog FPGA Design Xilinx {{ASPEN LOGIC} SKILLS} {VHDL Verilog FPGA Design Xilinx}
That only passes one key to the command. Note that in the result there is only a single key-value pair and the key is {{ASPEN LOGIC} SKILLS}. Also, 'FPGA Design' isn't one keyword. How to fix all that?
The eval command comes to the rescue. Let's try this:
% set keylist [list "ASPEN LOGIC" SKILLS] % set value [list "VHDL" "Verilog" "FPGA Design" "Xilinx"] % eval dict set SKILLS $keylist {$value} {ASPEN LOGIC} {SKILLS {VHDL Verilog {FPGA Design} Xilinx}}
Now we can see the desired hierarchical result. {ASPEN LOGIC} is the top key, "SKILLS" is the next lower level and it has {VHDL Verilog {FPGA Design} Xilinx} as the associated value. And, the list command has correctly wrapped the skill FPGA Design as a two word list {FPGA Design}.
You might have noticed the {$value} on the eval command. Why does the dict argument need to be in braces? This is slightly complicated but worth understanding. The eval command does a concat operation to flatten EVERYTHING on its command line. Without the braces the $value gets substituted and the contents then get flattened by concat. That would have the undesirable effect of making some of the words in $value become keys on the dict command line. By using braces around $value, which is the value part of the key-value pair, it remains as only a single argument.
You can do it all inline as well:
% eval dict set SKILLS [list "ASPEN LOGIC" CONTACT] janitor@aspenlogic.com {ASPEN LOGIC} {SKILLS {VHDL Verilog {FPGA Design} Xilinx} CONTACT janitor@aspenlogic.com }
I hope you find a good use for the dict command in your synthesis, simulation and embedded development tools.
Copyright © 2009 ASPEN LOGIC, INC. All Rights Reserved.