Cadence® system design and verification solutions, integrated under our System Development Suite, provide the simulation, acceleration, emulation, and management capabilities.
System Development Suite Related Products A-Z
Cadence® digital design and signoff solutions provide a fast path to design closure and better predictability, helping you meet your power, performance, and area (PPA) targets.
Full-Flow Digital Solution Related Products A-Z
Cadence® custom, analog, and RF design solutions can help you save time by automating many routine tasks, from block-level and mixed-signal simulation to routing and library characterization.
Overview Related Products A-Z
Driving efficiency and accuracy in advanced packaging, system planning, and multi-fabric interoperability, Cadence® package implementation products deliver the automation and accuracy.
Cadence® PCB design solutions enable shorter, more predictable design cycles with greater integration of component design and system-level simulation for a constraint-driven flow.
An open IP platform for you to customize your app-driven SoC design.
Comprehensive solutions and methodologies.
Helping you meet your broader business goals.
A global customer support infrastructure with around-the-clock help.
24/7 Support - Cadence Online Support
Locate the latest software updates, service request, technical documentation, solutions and more in your personalized environment.
Cadence offers various software services for download. This page describes our offerings, including the Allegro FREE Physical Viewer.
Get the most out of your investment in Cadence technologies through a wide range of training offerings.
This course combines our Allegro PCB Editor Basic Techniques, followed by Allegro PCB Editor Intermediate Techniques.
Virtuoso Analog Design Environment Verifier 16.7
Learn learn to perform requirements-driven analog verification using the Virtuoso ADE Verifier tool.
Exchange ideas, news, technical information, and best practices.
The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information.
It's not all about the technlogy. Here we exchange ideas on the Cadence Academic Network and other subjects of general interest.
Cadence is a leading provider of system design tools, software, IP, and services.
Get email delivery of the Cadence blog featured here
The way SKILL++ deals with functions is a bit different than the
way traditional SKILL deals with them. In this posting I'd
like to show how to implement a design hierarchy traversal engine in
SKILL++ and use it as an introduction to SKILL++.
What is SKILL++?
SKILL++ is a subset of the SKILL language, not a separate language as
one might suppose. The term SKILL++ refers to a small but powerful
set of extensions that were made to the core SKILL language in the
mid 1990s and are now available for use in many Cadence tools. In
fact, any Cadence tool that is extensible by loading and executing
SKILL programs is a candidate for using SKILL++, including: Virtuoso,
VirtuosoXL, pipo, Assura, Dracula, PVS, Allegro-PCB, cdnsip and
probably a few more that I'm forgetting.
Basically the language features are:
By contrast, traditional SKILL offers
variables and separate names spaces (sometimes called Lisp-2) for
functions and variables. Dynamic and lexical variables are both
useful for different purposes.
What are dynamic and lexical variables?
These two kinds of variables differ semantically but not
syntactically. All variables appearing in SKILL++ code are considered
lexical while all variables appearing in traditional SKILL code are
If you are wondering what the semantic difference is:
Perceptions of SKILL++
In this article, we'll ignore the SKILL++ object system and
concentrate on the first two of these capabilities -- sometimes referred
to jointly as the SKILL++
Dialect. Unfortunately, the other dialect which lives alongside
Scheme has no official marketing name. For lack of a better name,
we'll call it traditional SKILL. Hereafter, I'll just use the
term SKILL++ rather than the SKILL++ Scheme Dialect.
If you haven't started using SKILL++ yet, the basics are simpler than
you might think. If you are completely new to SKILL, you'll find
SKILL++ easy and intuitive. If you're a long time SKILL programmer,
you'll do things in SKILL++ pretty much the way you would have wanted
to 25 years ago when you started learning SKILL. That is, you've already
learned the hard way; now you can take a look at the easy way.
How to create SKILL++ code
There are several ways to indicate to the SKILL interpreter that you
want to use SKILL++ rather than traditional SKILL. One way is to end
your file names with the .ils extension for SKILL++
and .il for traditional SKILL; file.ils is
SKILL++; file.il is traditional SKILL.
Please assume all the functions in the remainder of this article are
The first example function, walkCvHier, is an ultra-simple
design hierarchy traversal engine. It won't work for all purposes you
might need but is good for the purpose of the examples below.
1.1: (defun walkCvHier (cv consume)1.2: (foreach inst cv~>instances1.3: (walkCvHier inst~>master consume))1.4: (consume cv))
This function is a type of
function, because it takes a function as one of its arguments. It
is also possible with SKILL++ for functions to compute and create
other functions at run time according to their given arguments -- more
about this in a future article. Although it is sometimes possible to
use traditional SKILL to create higher-order functions with limited
capability, my advice is that you always use SKILL++ if you need this
How does it work? The function, walkCvHier, steps through
the explicit cellView hierarchy such as a layout, assuming you always
want to descend into the instance master. At each step of the
hierarchy, a given function is applied. You can pass in any function
as long as that function can take a cellView as its only argument.
The function, walkCvHier, will happily call that function
for you at each cellView found of the hierarchy, every time that
Saving the hierarchy?
Here's an example of how to use walkCvHier. The
function saveCvHier asks walkCvHier to
call dbSave on each cellView in the hierarchy.
2.1: (defun saveCvHier (cv)2.2: (walkCvHier cv dbSave))
The function walkCvHier has a local
variable consume, declared on line 1.1, which it uses on
line 1.4 in the function call position (consume cv).
Because this is SKILL++, consume does not refer to the
global function of that name, but since there is a local variable of
that name, that variable is used instead. The value of that variable
better be a function, else an error will occur at run-time. On line
2.2, the saveCvHier function calls dbSave as
this second argument. There are several important things to note here:
3.1: (defun _reportCv (cv)3.2: (println (list cv~>libName3.3: cv~>cellName3.4: cv~>viewName)))3.5:3.6: (defun reportCvHier (cv)3.7: (walkCvHier cv _reportCv))
The intent here is that _reportCv be private and
only be used in this one place. However, because it is defined
with defun (the same would be true if it were defined
with procedure) it is actually available globally. Its
private status cannot be enforced. In the past, privacy has been
implemented in traditional SKILL using naming conventions and
documentation. SKILL++ provides better fixes this problem by
providing ways systematic ways for
...to be continued...
In the next posting we'll look at local functions, closures (functions
with state), and a few slightly more advanced examples using
the walkCvHier function.
Hi Andrew, thanks for the comments. Dynamic variables are interesting creatures. They certainly provide the SKILL language with an expert feature that few languages can match, especially co-called modern ones. They'll become even more powerful in combination with some cool upcoming features of 615 and 616.
Probably some readers have not grasped the difference between dynamic and lexical scoping (Jim's explanation was a little terse) - in fact most people may have assumed that the scoping was actually lexical in traditional SKILL.
Lexical scoping is probably the more natural - the extent of the binding of a variable is the block of code (or text, hence the term "lexical") that it is defined in. So you can clearly see where a name is valid, and which variable is which. As I think Jim will show in future postings, you can use this lexical scoping for some pretty neat features in SKILL++.
Dynamic scoping can be thought of as a each variable being a stack - as you declare each variable in a let() (or similar) or define it as a formal parameter of a function, it pushes the new value onto the top of the stack, and then pops it off when that let() or function has returned. What this means is that the binding of a variable may not actually be global - it will see whatever is on the top of the stack at that point in the program's execution. Now this can be extremely useful, and allow you to do some powerful things, but it's probably more of an expert feature and for most users the effects of dynamic scoping only show up when you accidentally forget to declare a local variable.
So I would suggest that lexical scoping is more intuitive and easier to grasp and take advantage of for most novice users, and that dynamic scoping (or at least taking advantage of dynamic scoping) is more of an expert feature.
The lesson is - don't be scared by the "++" in the name SKILL++! You can completely ignore the object system if that scares you (although it shouldn't), yet still take advantage of the neat features that come as a result of lexical scoping without it hurting your brain!
Yes that's right. You can also use the inSkill and inScheme macros/primitives to surround code you want evaluated with particular scoping. E.g.,
(defvar XYZ 42))
(defvar XYZ -13))
For those who want to try it out interactively with a REPL, type
(toplevel 'ils) in the CIW and go from there.