TCL's eval command the key to dictionaries


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.