Uploaded by Павел Бобков

SkillAdv IC 6 1 8 ICADVM 20 1.secured.lect

advertisement
This document is for the sole use of Firuz Shomahmadov of Nxp
Advanced SKILL® Language
Programming
Course Version IC 6.1.8/ ICADVM 20.1
Lecture Manual
Revision 2.0
This document is for the sole use of Firuz Shomahmadov of Nxp
© 1990-2023 Cadence Design Systems, Inc. All rights reserved.
Printed in the United States of America.
Cadence Design Systems, Inc. (Cadence), 2655 Seely Ave., San Jose, CA 95134, USA.
Trademarks: Trademarks and service marks of Cadence Design Systems, Inc. (Cadence) contained in this document are
attributed to Cadence with the appropriate symbol. For queries regarding Cadence trademarks, contact the corporate legal
department at the address shown above or call 1-800-862-4522.
All other trademarks are the property of their respective holders.
Restricted Print Permission: This publication is protected by copyright and any unauthorized use of this publication may
violate copyright, trademark, and other laws. Except as specified in this permission statement, this publication may not be
copied, reproduced, modified, published, uploaded, posted, transmitted, or distributed in any way, without prior written
permission from Cadence. This statement grants you permission to print one (1) hard copy of this publication subject to the
following conditions:
The publication may be used solely for personal, informational, and noncommercial purposes;
The publication may not be modified in any way;
Any copy of the publication or portion thereof must include all original copyright, trademark, and other proprietary notices
and this permission statement; and
Cadence reserves the right to revoke this authorization at any time, and any such use shall be discontinued immediately upon
written notice from Cadence.
Disclaimer: Information in this publication is subject to change without notice and does not represent a commitment on the
part of Cadence. The information contained herein is the proprietary and confidential information of Cadence or its licensors,
and is supplied subject to, and may be used only by Cadence customers in accordance with, a written agreement between
Cadence and the customer.
Except as may be explicitly set forth in such agreement, Cadence does not make, and expressly disclaims, any representations
or warranties as to the completeness, accuracy or usefulness of the information contained in this document. Cadence does not
warrant that use of such information will not infringe any third party rights, nor does Cadence assume any liability for
damages or costs of any kind that may result from use of such information.
Restricted Rights: Use, duplication, or disclosure by the Government is subject to restrictions as set forth in FAR52.227-14
and DFAR252.227-7013 et seq. or its successor.
ii
January 13, 2023
This document is for the sole use of Firuz Shomahmadov of Nxp
Table of Contents
Advanced SKILL Language Programming
Module 1
About This Course ............................................................................................. 3
Module 2
Introduction to Advanced SKILL ..................................................................... 11
Module 3
Classes and Objects ......................................................................................... 22
Lab 3-1 Creating SKILL++ Classes
Lab 3-2 Creating Instances of a Class
Module 4
Class Inheritance .............................................................................................. 40
Lab 4-1 Construct Classes: Single Inheritance
Module 5
Symbols and Quotes ........................................................................................ 54
Lab 5-1 Using Quotes and Back Quotes in SKILL Commands
Lab 5-2 lineread
Module 6
Function Parameters ........................................................................................ 62
Lab 6-1 Implementing Your Own Variable Argument Function
Module 7
Assert
Lab 7-1
Module 8
Scoping ............................................................................................................ 83
Lab 8-1 Examining the Scope of a Variable in SKILL and SKILL++
Module 9
destructuringBind .......................................................................................... 108
Lab 9-1 Destructuring the Lists Using the destructuringBind Expression
Module 10
Methods (Primary)........................................................................................... 117
Lab 10-1 Examining the Primary Methods on a Given Class
Module 11
Access SKILL Data Structures with setf ....................................................... 131
Lab 11-1 Using the setf Function to Access List Data
Module 12
Methods (Intermediate) ................................................................................... 139
Lab 12-1 Using the @before and @after Methods in SKILL++ Code
Lab 12-2 Using Lazy Slots
Module 13
Introduction to Macros ................................................................................... 157
Lab 13-1 Implementing SKILL Code with Macros
Lab 13-2 Implementing Macros and Defclass
Cadence Design Systems, Inc.
............................................................................................................ 79
Examining the assert Function Hands-On to Design a Software Test
iii
This document is for the sole use of Firuz Shomahmadov of Nxp
Module 14
Local Functions ...............................................................................................172
Lab 14-1 Implementing Local Functions in the SKILL Programs
Module 15
Packages .........................................................................................................181
Lab 15-1 Implementing a Simple Counter Data Type in the SKILL Language
Lab 15-2 Implementing a SKILL++ Counter Data Type
Lab 15-3 Re-Implementing the Counter Data Type (Optional)
Module 16
Indirect Function Calls....................................................................................187
Lab 16-1 Creating Extended Built-In Functions: Rod and Hi
Lab 16-2 Implementing the mapappend Function
Lab 16-3 Implementing Flatten and Deep-Copy
Module 17
Initializing Objects ......................................................................................... 204
Lab 17-1 Exploring Instance Initialization Examples
Module 18
Multiple Inheritance........................................................................................ 212
Lab 18-1 Implementing Multiple Class Inheritance in SKILL++ Code
Module 19
Methods (Advanced) ...................................................................................... 225
Lab 19-1 Implementing the Methods by Adding Additional Arguments for Extended
Capabilities
Lab 19-2 Implementing Equivalence Specializers
Lab 19-3 Implementing objType Specializers
Module 20
Control Flow (Optional) ................................................................................. 239
Module 21
Next Steps ....................................................................................................... 250
iv
Cadence Design Systems, Inc.
This document is for the sole use of Firuz Shomahmadov of Nxp
Advanced SKILL® Language Programming
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
3 Days
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
1
This document is for the sole use of Firuz Shomahmadov of Nxp
About This Course
Module
1
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated Time:
● Lecture
15 minutes
● Lab
NA
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
3
This document is for the sole use of Firuz Shomahmadov of Nxp
Course Prerequisites
Before taking this course, you need to have already
● Developed basic SKILL® programs or completed a SKILL Language Programming course
● Used the Virtuoso® Design Environment or completed a Virtuoso Design Environment, Analog Design, or
Analog Layout course
4
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
4
This document is for the sole use of Firuz Shomahmadov of Nxp
Course Objectives
In this course, you
● Apply advanced capabilities of SKILL and SKILL++
● Write code that is simpler and create fewer bugs
● Create simple and complex macros
● Develop SKILL++ programs using lexical scoping
● Develop SKILL++ programs using the SKILL++ Object System
5
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
5
This document is for the sole use of Firuz Shomahmadov of Nxp
Course Agenda
● Introduction to Advanced SKILL
● Classes and Objects
▪ Creating SKILL++ Classes
▪ Creating Instances of a Class
● Class Inheritance
▪ Construct Classes: Single Inheritance
● Symbols and Quotes
▪ Using Quotes and Back Quotes in SKILL Commands
▪ lineread
● Function Parameters
▪ Implementing Your Own Variable Argument Function
● Assert
▪ Examining the assert Function Hands-On to Design a
Software Test
6
● Scoping
▪ Examining the Scope of a Variable in SKILL and
SKILL++
● destructuringBind
▪ Destructuring the Lists Using the destructuringBind
Expression
● Methods (Primary)
▪ Examining the Primary Methods on a Given Class
● Access SKILL Data Structures with setf
▪ Using the setf Function to Access List Data
● Methods (Intermediate)
▪ Using the @before and @after Methods in SKILL++
Code
▪ Using Lazy Slots
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
6
This document is for the sole use of Firuz Shomahmadov of Nxp
Course Agenda (continued)
● Introduction to Macros
▪ Implementing SKILL Code with Macros
▪ Implementing Macros and Defclass
● Local Functions
▪ Implementing Local Functions in the SKILL Programs
● Packages
● Initializing Objects
▪ Exploring Instance Initialization Examples
● Multiple Inheritance
▪ Implementing Multiple Class Inheritance in SKILL++
Code
● Methods (Advanced)
▪ Implementing a Simple Counter Data Type in the
SKILL Language
▪ Implementing the Methods by Adding Additional
Arguments for Extended Capabilities
▪ Implementing a SKILL++ Counter Data Type
▪ Implementing Equivalence Specializers
▪ Re-Implementing the Counter Data Type (Optional)
▪ Implementing objType Specializers
● Indirect Function Calls
● Control Flow (Optional)
▪ Creating Extended Built-In Functions: Rod and Hi
▪ Implementing the mapappend Function
▪ Implementing Flatten and Deep-Copy
7
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
7
This document is for the sole use of Firuz Shomahmadov of Nxp
Software and Licenses
For the software and licenses used in the labs for this course, go to:
https://www.cadence.com/en_US/home/training/all-courses/84401.html
If there is additional information regarding the specific software, it is detailed in the lab document
and/or the README file of the database provided with this course.
8
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
8
This document is for the sole use of Firuz Shomahmadov of Nxp
Become Cadence Certified by Earning a Digital Badge
Digital badges indicate mastery in a certain technology or skill and give managers and potential employers a
way to validate your expertise.
● Cadence Training Services offers digital badges for our popular training courses.
● Your digital badge can be added to your email signature or social media platforms like LinkedIn or Facebook.
Benefits of Cadence Certified Digital Badges
● Validate expertise
▪ Expand career opportunities
● Professional credibility
▪ Stand apart from your peers
● For more information,
go to www.cadence.com/training
or email es_digitalbadge@cadence.com.
How do I register to take the exam?
● Log in to our Learning Management System to locate the
exam in your transcript.
How long will it take to complete the exam?
● Most exams take 45 to 90 minutes to complete. You may
retake the exam multiple times to pass the exam.
How do I access and use the digital badge?
● After you pass the exam, you get a digital badge and
instructions on how to place it on social media sites.
How is the digital badge validated?
● Credly validates the digital badge as issued to you by
Cadence and includes the details of the criteria you
completed to earn the badge.
9
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
9
This document is for the sole use of Firuz Shomahmadov of Nxp
Icons Used in This Class
Best Practice
Problem & Solution
10
Language/
Command Syntax
Quick Reference
Concept/
Glossary
GUI and Command
Frequently Asked
Questions/
Quiz
How To
Error Message
Throughout this class, we
use icons to draw your
attention to certain kinds of
information. Here are the
icons we use, and what they
mean.
Lab List
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
10
This document is for the sole use of Firuz Shomahmadov of Nxp
Introduction to Advanced SKILL®
Module
2
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
30 minutes
● Lab
NA
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
11
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Compare the working of SKILL and SKILL++
● Create and load SKILL++ files
● Identify to control the visibility of variables and functions in the SKILL and SKILL++ dialects
12
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
12
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is Advanced SKILL?
Advanced features of the SKILL Language can be applied to solve complex problems and
create code that is easier to reuse and maintain.
Some of the advanced features of the SKILL language are:
● SKILL++
▪ Lexical scoping
▪ Object-oriented system
o Classes and methods
● Symbols and Quoting
▪ Treating the language as data
● Macros
▪ Code that writes code
13
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
13
This document is for the sole use of Firuz Shomahmadov of Nxp
Things to Know About SKILL++
● SKILL++ is an extension of SKILL
● SKILL and SKILL++ are two dialects of the same language
● Functions from both environments can be mixed in the same procedure
● Supports lexical scoping
● Private functions and data (encapsulation)
● Object system
Both SKILL and SKILL++ have the same syntax but sometimes different semantics.
14
© Cadence Design Systems, Inc. All rights reserved.
SKILL++ was developed as an extension of the SKILL language that supplies critical support for the
advanced features required to solve complex problems and create code that is easier to reuse and
maintain. The improvements include lexically scoped variables and the creation of private functions, as
well as a significantly enhanced object system.
© Cadence Design Systems, Inc. All rights reserved.
14
This document is for the sole use of Firuz Shomahmadov of Nxp
Defining Function in SKILL and SKILL++
procedure(functionName(argument list)
….body….)
defun(functionName (argument list) ….body….)
defun and procedure are different syntaxes to do the same work.
● Both define the function.
▪ Either can be used, SKILL or SKILL++.
o They can be used interchangeably.
The other way to define a function:
(procedure (functionName argument list) …body…)
(defun functionName (argument list) …body….)
15
© Cadence Design Systems, Inc. All rights reserved.
Functions are defined in files using commands like procedure or defun. These are the same command
using a different syntax and can be used interchangeably in either SKILL or SKILL++.
There are other function creation methods, such as lambda, for creating an unnamed function;
defglobalfun, for creating global functions in closures; and flet, for creating functions local to another
function. We will explore some of these in this class.
© Cadence Design Systems, Inc. All rights reserved.
15
This document is for the sole use of Firuz Shomahmadov of Nxp
Defining Global Variables in SKILL and SKILL++
defvar(varName expression)
(defvar varName expression)
Variables are defined the same in both SKILL and SKILL++.
● It creates a new global variable and assigns the value of the expressions.
● Or modifies the value of the global variable.
However, because SKILL++ provides lexical scoping, you can also use defvar within a let statement to define a
variable for a local environment. For example:
let((a b c)
defvar(d 23)
defglobalfun(myFunc (e) prog1(d d=e))
)
A call to myFunc(45) returns the last value of d and updates d to the arg (45 in this case). So, in this context, a
global variable d doesn't exist.
16
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
16
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is an Interactive Interface for SKILL and SKILL++?
Virtuoso®, when invoked, supports an interactive Read Eval Print Loop (REPL) in which we
type an expression. The system parses, compiles, and evaluates according to either SKILL
or SKILL++ syntaxes and displays the result.
To determine which REPL you are in, type theEnvironment()in the CIW input pane:
● The SKILL interface return nil.
● The SKILL++ interface returns non-nil environment ID.
To start a new interactive interface:
● In the CIW input pane, type toplevel( `ils ) → it starts a new SKILL++ REPL interface.
● In the CIW input pane, type toplevel( `il ) → it starts a new SKILL REPL interface.
● If you type resume() →it exits the current REPL.
However, initially, when the Virtuoso environment
is invoked, the interface will be using SKILL REPL.
17
© Cadence Design Systems, Inc. All rights reserved.
A common technique for debugging functions and methods is to copy and paste from an editor into the
CIW. This may be a problem because the function may be redefined in the wrong environment. The
command top-level changes the environment between SKILL and SKILL++.
Note: If you paste code in the CIW while another function is executing, the environment will be
determined by the executing function.
© Cadence Design Systems, Inc. All rights reserved.
17
This document is for the sole use of Firuz Shomahmadov of Nxp
How to Write SKILL and SKILL++ Code
Functions defined in a file with a .ils extension will be defined in the SKILL++ dialect.
Functions in any file with a different extension are loaded in SKILL.
SKILL
1. Loading the source file
▪ load( "mySKILLFile.il" )
2. Executing a function
▪ mySKILLfunction( “An argument string” 8)
SKILL++
1. Loading the source file
▪ load( "myAdvSKILLFile.ils" )
2. Executing a function
▪ myAdvSKILLfunction( “Another string” 12 )
18
Note: The files with .ilse extension are
encrypted SKILL++ files.
© Cadence Design Systems, Inc. All rights reserved.
The suffix of the source file containing the function definition determines the dialect. Once the source
file is loaded, the function can be called/invoked with the same syntax, independent of the dialect at the
call site: the procedure name followed by the values for the arguments, the required arguments, and the
optional or keyed arguments.
Functions defined in a file with a .ils extension will be defined in the SKILL++ dialect. Functions in any
file with a different extension are loaded in SKILL.
If you want to encrypt your .ils file, use the below command:
encrypt("mycode.ils" "mycode.ilse")
© Cadence Design Systems, Inc. All rights reserved.
18
This document is for the sole use of Firuz Shomahmadov of Nxp
How to Reference Variables Between SKILL and SKILL++
Normally, each SKILL++ global variable is bound to the function slot of the symbol with the
same name. In this way, SKILL and SKILL++ can share functions transparently.
1. For a one-time reference of a variable
▪ inScheme( varName )
o Sets a SKILL++ global variable, regardless if it appears in the SKILL file.
▪ inSKILL( varName )
o Sets a SKILL global variable, regardless if it appears in the SKILL++ file.
2. To create a permanent binding of the variable
▪ importSkillVar( varName )
o Creates a permanent binding between a SKILL and SKILL++ (Scheme) global variable.
o Updates the variable in one environment and allows for immediate access to the value of the variable in the other environment.
19
© Cadence Design Systems, Inc. All rights reserved.
The Scheme is the original standard that SKILL++ is based upon. SKILL originated from a small LISP,
Franz LISP, which pre-dates both Common LISP and Scheme. In the early 1990s, there was an
organization called the CAD Framework Initiative (CFI), which had the goal of establishing a Scheme
as the customization language for CAD tools.
The "ils" mode of SKILL was designed to provide Scheme-like features within SKILL without losing
compatibility. There was initially a more aggressive Scheme implementation too, but SKILL++ was
implemented to adopt some of the concepts without the strict language compatibility with the Scheme.
You can define functions in a different environment than the one defined by the source file suffix using
the functions inSkill and inScheme.
In a SKILL++ source file (.ils), the block defined in the inSkill statement will be executed in the SKILL
environment. Global variables and function definitions will be defined in the SKILL environment with
the environment’s dynamic scoping.
In a SKILL source file (.il), the block defined within the inScheme statement will be executed in the
SKILL++ environment. These commands allow you to mix SKILL and SKILL++ function definitions in
the same source file.
© Cadence Design Systems, Inc. All rights reserved.
19
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is Function and Variable Visibility?
Since SKILL and SKILL++ functions share the namespace, two functions cannot have the
same name, even if one is SKILL and the other is SKILL++.
Functions
● A SKILL function may call a SKILL++ function by name.
● A SKILL++ function may call a SKILL function by name.
▪ Consequently, a SKILL function cannot have the same name as a SKILL++ function.
Variables
● A SKILL function cannot see SKILL++ global variables.
● A SKILL++ function cannot see SKILL global variables.
● A SKILL++ function sees SKILL and SKILL++ functions as global variables.
▪ Consequently, a SKILL variable may have the same name as a SKILL++ variable.
▪ A SKILL function cannot have the same name as a different SKILL++ global variable.
20
© Cadence Design Systems, Inc. All rights reserved.
Since SKILL and SKILL++ functions share the namespace, two functions cannot have the same name,
even if one is SKILL and the other is SKILL++. If there are multiple definitions of the same function,
the last one overrides any previously defined one, which is the one accessible by the user.
© Cadence Design Systems, Inc. All rights reserved.
20
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Summary
In this module, you
● Compared the working of SKILL and SKILL++
● Created and loaded SKILL++ files
● Identified how to control the visibility of variables and functions in the SKILL and SKILL++ dialects
21
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
21
This document is for the sole use of Firuz Shomahmadov of Nxp
Classes and Objects
Module
3
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
30 minutes
● Lab
30 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
22
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Create a basic class and a SKILL++ instance of that class
● Analyze slots
▪ Define a slot
▪ Set and get the data in the slots
▪ Combine slots in hierarchical classes
● Query the information about an object instance
23
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
23
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are Classes and Instances in Object-Oriented Programming?
A class is a template definition of the
methods and variables in a particular
kind of object.
Slots
An object is an instance of a class.
States
params
params
constants
rules
Methods
Behaviors
Classes are blueprints that contain:
Instances are objects:
● Slots: Data defining the class.
● States: Current settings of the data in the instance.
● Methods: Actions taking place on the data.
● Behaviors: How the methods perform on the
instance.
24
© Cadence Design Systems, Inc. All rights reserved.
A principle feature of the Object-Oriented programming paradigm (OO) is the class. The simplest
explanation of a class, found in the Java® tutorial at java.sun.com, is that a class is the blueprint of a
container. The container has data that defines the class and procedures that act on that data. SKILL++,
like lisp, calls the data slots and the methods of the procedure.
An object is an instance of a class. Multiple instances can be made of the same class, each creating a
new object. Each instance of the same class has its own set of slots and methods. Unlike procedures,
there can be multiple methods with the same name, each operating on a different class of objects. The
first argument of a method is the object on which the method should operate. This determines which
method is used.
Images inspired by java.sun.com Java Tutorial.
© Cadence Design Systems, Inc. All rights reserved.
24
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are Classes and Instances in Object-Oriented Programming?
(continued)
Class
● Multiple instances can be made of the same class:
Slots
▪ Each creates a new object with its own set of slots and
methods.
● There can be multiple methods with the same
name, each operating on a different class of
objects.
Methods
● The methods are defined separately from the
class, unlike languages like C++ and Python.
● The arguments of a method are the objects on
which the method should operate. These
determine which method is used.
States
params
Behaviors
States
params
constants
constants
rules
rules
Behaviors
Instances
25
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
25
This document is for the sole use of Firuz Shomahmadov of Nxp
Class Declaration in SKILL++ with defclass
(Space required)
(defclass className ({list of superClasses})
({list of slot descriptors}))
● Classes must be declared before an instance of the
class (the object) is created.
● Slot descriptors indicate data the instances will
contain.
● Slot descriptors are also inherited from the
superclasses.
26
(defclass library ()
((name)
(owner)))
© Cadence Design Systems, Inc. All rights reserved.
Classes are declared using the defclass command. The class has a name. The class can have a superclass
or a list of superclasses from which it inherits slots and access to methods. If the class has no declared
superclasses, it is a subclass of the SKILL++ standard object. The slots of the class are also declared.
These add to the slots of any superclasses. An instance of the class will have the slots of the current
class and the slots of any superclasses.
© Cadence Design Systems, Inc. All rights reserved.
26
This document is for the sole use of Firuz Shomahmadov of Nxp
Creating an Instance of a Class
instanceName = makeInstance('className)
● Instances of a class are created with
makeInstance.
(defclass library () ((name)(owner)))
● Each instance has an identity independent of the
other instances.
instA = makeInstance('library )
Has slots: name, owner
● Slot values are instance-specific.
instB = makeInstance('library )
Has slots: name, owner
These slots are independent of instA.
27
© Cadence Design Systems, Inc. All rights reserved.
A class must be defined before any objects can be made of it. The object is also called an instance of the
class. The function makeInstance is used to create an instance of the class. Each instance is independent
of other instances of the same class. They have the same structure, but the slots are associated with the
instance and can have different values.
Note: The name of the class is passed into makeInstance as a quoted symbol.
© Cadence Design Systems, Inc. All rights reserved.
27
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Specifying Class Slots and Their Default Value
Class Definition
Class name
superClasses
(defclass library ()
(
(name)
(owner)
(path)
)
)
Slot descriptors
Slot Name
Value
Class
name
\*slotUnbound\*
library
owner
\*slotUnbound\*
library
path
\*slotUnbound\*
library
Object Instantiation
instA = makeInstance('library )
instA → An object of class library
28
© Cadence Design Systems, Inc. All rights reserved.
The class definition specifies the slots and places to store information on an instance of the class. The
makeInstance function creates an instance of the class that contains the slots and their values. By
default, the slot values are unbound, returning the value \* slotUnbound \*. These slots are associated
with this instance and are independent of any other instance of the class.
© Cadence Design Systems, Inc. All rights reserved.
28
This document is for the sole use of Firuz Shomahmadov of Nxp
Functions to Find the Information of the Class and Its Objects
To find the class of an instance:
● classOf( instA )
▪ Returns the class of the instance.
● className( classOf( instA ) )
▪ Returns the print name of the class of the instance.
● classp( object 'class )
▪ Returns t if the object is an instance of the class or a subclass.
To find a class ID:
● class = findClass( 'library )
▪ Returns the class.
● In SKILL++, a class is a first-class object, unlike Java®, C++, and so on.
29
© Cadence Design Systems, Inc. All rights reserved.
The class of an instance can be found using the command classOf. This returns the class of the instance.
This can be turned into a print name using className.
A straightforward test for the object of a class uses classp to determine if the object is an instance of the
class or one of its subclasses.
findClass returns the pointer to the class defined by the symbol name.
© Cadence Design Systems, Inc. All rights reserved.
29
This document is for the sole use of Firuz Shomahmadov of Nxp
Setting and Retrieving the Slot Value
putprop( instName "newname" 'slotName ) → writes value to the slot.
get( instName 'slotName) → reads values from the slot.
The slots are accessed on an instance of the
class.
● The putprop function writes the value to the slot.
putprop( instA "newValue" 'path )
● The get function reads the value from the slot.
value = get( instA 'path )
To print the contents of an object (can be useful while
debugging the code):
instA->? → Lists the slots of the instance.
instA->?? → Lists the slots and values of the instance.
● The dashed arrow (->) is an accessor for the slot –
both read and write.
instA->path = list( "lnx18a" "/usr1/libs" )
instA->path → ( "lnx18a" "/usr1/libs" )
30
© Cadence Design Systems, Inc. All rights reserved.
Direct access to the slots is provided by the get/getq, putprop/putpropq, and the dash-arrow (->).
Accessing the slots directly is discouraged in object-oriented programming. Accessor methods are
usually used so that the underlying data structure can be modified without requiring changes to
programs that use the slots.
Note that the whole value of the slot is accessed. If a new value is assigned to the slot, the value in the
slot is completely replaced. If the slot contains a table, the complete table is retrieved or replaced using
these accessors. Complex data structures require the class developer to create a method for accessing the
substructure of the slot value.
© Cadence Design Systems, Inc. All rights reserved.
30
This document is for the sole use of Firuz Shomahmadov of Nxp
Use @initform to Assign a Default Value to a Slot
The slot can be assigned a default value when the instance is created by specifying the
initial value in the slot declaration using the @initform keyword.
● Initialize simple values in the slots with @initform.
● The initform can be a fixed value or an expression.
▪ The expression is evaluated when the instance is
created.
▪ The return value of the expression is assigned to the
slot.
(defclass library ()
( ( name )
( owner @initform getShellEnvVar("user"))
( path @initform getWorkingDir() )
))
instA = makeInstance( 'library )
In the example:
● The owner slot is assigned the value of the shell
environment variable “USER”.
Slot Name
Value
Class
name
\*slotUnbound\*
library
● The slot path is assigned to the current working
directory where Virtuoso® was launched.
owner
“john”
library
path
“/libs”
library
Note: When the default value of one slot depends on the value given
for another slot, @initform cannot be used.
31
© Cadence Design Systems, Inc. All rights reserved.
The slot can be assigned a default value when the instance is created by specifying the initial value in
the slot declaration using the @initform keyword. The expression that follows the keyword can be a
value or an expression that evaluates into a value. The expression is evaluated when the instance is
created, and the value is stored in the slot on the class.
The expressions were evaluated when the instance was created; changing the USER variable or the
working directory will not affect that instance, but the new values will be stored in the slots of new
instances.
Note: The name slot is unbound as it has no @initform.
© Cadence Design Systems, Inc. All rights reserved.
31
This document is for the sole use of Firuz Shomahmadov of Nxp
Use @initarg to Initialize a Slot Value
The slot values can be assigned when the instance is created through the @initarg keyword.
● @initarg acts like a keyed argument.
● @initarg and @initform can be used together.
▪ @initform supplies the default value.
▪ @initarg overrides the value.
In the example:
● The initial values of the Owner and Path slots are
overridden using the @initarg keyword.
● The argument is used as a keyed argument to the
makeInstance function, and that value is assigned
to the slot.
32
(defclass library ()
( ( name @initarg libName )
( owner @initform getShellEnvVar("user")
@initarg owner )
( path @initform getWorkingDir()
@initarg path )))
instA = makeInstance( 'library
?libName "skillClassLib"
?path "/libs/training" )
Slot Name
Value
Class
name
"skillClassLib"
library
path
“/libs/training”
library
© Cadence Design Systems, Inc. All rights reserved.
The slot values can be assigned when the instance is created through the @initarg keyword. The
argument is used like a keyed argument for a procedure when the instance is created. The argument is
preceded by a question mark, and the value is the next expression following the key. The value is
assigned to the slot.
Note: The argument does not have to have the same name as the slot.
When the instance is created, the initial values of the slots can be overridden using @initarg in the slot
generation. The argument is used as a keyed argument to the makeInstance function. The value is
assigned to the slot. If the slot is not initialized using @initarg, it retains the value of its @initform. If
that was not specified, the value of the slot is \*slotUnbound\*.
© Cadence Design Systems, Inc. All rights reserved.
32
This document is for the sole use of Firuz Shomahmadov of Nxp
Things to Remember: @initarg
● The initarg does not have to be the same as the slot name. makeInstance won't complain!
(defclass C () ((slot1 @initarg s1)))
(makeInstance 'C ?slot1 42)
; ?slot1 42 has NO EFFECT
● Two slots might have the same initarg.
(defclass square_matrix (matrix)
((rows @initarg rank)
(cols @initarg rank)))
● With inheritance, slots can acquire multiple initargs.
● A common error is typing @initarg when you mean @initform.
● The syntax is:
▪ @initarg X
▪ Not @initarg 'X and not @initarg ?X
33
© Cadence Design Systems, Inc. All rights reserved.
In the example above (makeInstance 'C ?slot1 42), ?slot1 42 has no effect because class C does not have
a slot with @initarg slot1. This is a source of error because makeInstance will not issue an error or a
warning. The programmer might think the slot has been initialized to 42, but it most assuredly has not
been.
For the class square_matrix, a call to (makeInstance 'square_matrix ?rank (get_rank)) will call the
function, get_rank, exactly once and with initialize two slots, rows, and cols, with its return value.
The class square_matrix inherits from the matrix. We have not seen the inheritance yet but will shortly.
If the matrix class has a slot descriptor (row @initarg row), then square_matrix has two initargs for the
row slot. A call to makeInstance can use ?rows or ?rank. This is a source of error because it would,
unfortunately, be possible to create a square_matrix with ?rows 3 ?cols 4, which would not be square.
You would need to check for this somewhere else, such as the initializeInstance @after method, which
we will see later also.
© Cadence Design Systems, Inc. All rights reserved.
33
This document is for the sole use of Firuz Shomahmadov of Nxp
Setting and Getting Slot Values: Direct Access
setSlotValue(instName 'slotName
"value" ) → sets the slot value
slotValue( instName 'slotName )
→ gets the slot value
● Set the slot value using setSlotValue.
● Get the slot value using slotValue.
● -> (the dashed arrow) is the accessor for the slots
on a class instance.
● Accessing the slots directly can make your classes
harder to maintain.
● Other functions set and retrieve the value directly.
● Changing slot names requires you to find all places
where the slots are accessed and fix them.
setSlotValue( instA 'name "testLib2" )
value1 = slotValue( instA 'name )
setSlotValue( instA 'owner "Your Name Here" )
=> "testLib2"
value2 = slotValue( instA 'owner)
=> "Your Name Here"
34
© Cadence Design Systems, Inc. All rights reserved.
Besides the dashed arrow, the functions setSlotValue and slotValue are used to access the slots once an
instance has been created. These provide direct access to the slot values. The argument is the slot name
itself, not the @initarg.
The slot values are overwritten when using setSlotValue directly. This does not support any merging of
the values into a data structure like a defstruct or a table.
The use of the dashed arrow or the functions setSlotValue and slotValue require the programmer to
know the name of the slot to be accessed. If the class changes and the slot is renamed, then the programs
that use that access will have to be updated.
© Cadence Design Systems, Inc. All rights reserved.
34
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are Slot Reader and Writer Methods?
The @reader and @writer slot options are used for reading and writing slots when the
classes are defined.
● Automatic read/write methods are created
when a class is declared.
● Slots are usually accessed through methods.
● Underlying data structure is abstracted through
methods.
● Generic methods are available for slots.
▪ @reader reads the data from a slot.
(defclass library ()
(( name @initarg libName
@reader getLibName @writer setLibName)
( owner @initform getShellEnvVar( "user" )
@initarg owner
@reader getOwner @writer setOwner)
( path @initform getWorkingDir() @initarg path
@reader getPath @writer setPath)))
▪ @writer writes the data to the slot.
35
© Cadence Design Systems, Inc. All rights reserved.
Accessing slots directly or using slotValue and setSlotValue is discouraged in object-oriented
programming if the underlying data structure, such as the slot name, changes, and any program that
directly accesses the slot has to be updated to the new structure.
Reader and writer methods are used to access the slot data, abstracting away the dependency on the
name of the slot. The methods are declared using @reader and @writer keywords, followed by the name
of the method.
Methods are like procedures, but they are called with the first argument, being the instance of a class to
work on. The method to execute that matches the name and the class of the object is found, and that
method is executed. We will explore the methods some more in a future module.
© Cadence Design Systems, Inc. All rights reserved.
35
This document is for the sole use of Firuz Shomahmadov of Nxp
What Happens When a Class Is Redefined?
When a class is redefined and the instance is updated, a property list is created that
captures the slot names and values of all the discarded slots with values in the original
instance.
● During program development, you will redefine your class several times before you get it right.
● If there are instances of the class in virtual memory, SKILL++ will examine them and potentially update them.
▪ Obsolete instance slots may get removed.
▪ New instance slots may get added.
▪ New Uninitialized slots may get initialized.
▪ Old Uninitialized slots remain uninitialized, even if an @initform was added.
● You can customize this behavior using the generic function updateInstanceForRedefinedClass.
You will look more at the generic functions and redefining classes in the coming modules.
36
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
36
This document is for the sole use of Firuz Shomahmadov of Nxp
defclass Summary
● Classes are blueprints/templates for creating structured containers.
● An object is created by instantiating the class.
● Slots are the place where data is stored. Slots:
▪ Have names.
▪ May have a default value (@initform).
▪ May have an initialization argument (@initarg).
▪ May have reader and writer methods (@reader and @writer).
● Each object has a copy of the slots defined for the class.
▪ Slot values can be different for each instance.
● Class redefinition is allowed and is robust.
37
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
37
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Summary
In this module, you
● Created a basic class and a SKILL++ instance of that class
● Analyzed @initform, @initargs keywords
● Identified different slot value accessing methods
38
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
38
This document is for the sole use of Firuz Shomahmadov of Nxp
Labs
Lab 3-1 Creating SKILL++ Classes
Lab 3-2 Creating Instances of a Class
39
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
39
This document is for the sole use of Firuz Shomahmadov of Nxp
Class Inheritance
Module
4
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
15 minutes
● Lab
30 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
40
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Create classes
● Create a class hierarchy with subclasses and superclasses
● Examine how slots in classes inherit from other classes
41
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
41
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is Class Inheritance?
Superclass will provide a separate copy of properties to each object of a subclass such that
data shared by different objects do not have to be recreated.
Characteristics:
Class
● Inheritance allows for the reuse of classes.
library
Least specific
● Shared slots do not have to be repeated.
The diagram shown illustrates:
● userLib is a subclass of a library.
userLib
● library is a superclass of userLib.
● designLib is a subclass of userLib.
● userLib is a superclass of designLib.
● library is a superclass of designLib.
42
designLib
Most specific
© Cadence Design Systems, Inc. All rights reserved.
The superclasses are further used to specify the class of the object. This can be done by adding new slots
or modifying the initial data in slots inherited from the superclass. The userLib class inherits the slots
from the library class, and the designLib class inherits the slots of the userLib class, including the
classes of the library class.
A subclass is said to be more specific than its superclasses, and a superclass is less specific than its
subclasses.
© Cadence Design Systems, Inc. All rights reserved.
42
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Class Inheritance
● refLib class is a subclass of the library class.
● userLib class is a subclass of the library class.
library
● They share the same template for instance creation.
▪ Name
▪ Owner
▪ Path
refLib
userLib
designLib
43
© Cadence Design Systems, Inc. All rights reserved.
The advantage of using classes is that template data that is shared by different objects do not have to be
recreated. In the example, the refLib and the userLib share the common superclass of the library, each
inheriting the slots from that class. If changes were made to the superclass, it would be reflected in both
the refLib and userLib classes.
© Cadence Design Systems, Inc. All rights reserved.
43
This document is for the sole use of Firuz Shomahmadov of Nxp
Creating a Class Hierarchy
library
(defclass library ()
(( name @initarg libName … )
( owner @initform getShellEnvVar( "user" ) … )
( path @initform getWorkingDir() @initarg path … )
)
)
userLib
(defclass userLib ( library ) ;superClass
(( users @initform makeTable( "users" nil)
@initarg users @reader getUsers @writer setUsers)
)
)
Class
designLib
44
(defclass designLib ( userLib )
(( users @initform pcoGetProjUsers()
@initarg designers )
( project @initform pcoGetProjectId()
@initarg project )
)
User functions
)
called when
creating the object.
© Cadence Design Systems, Inc. All rights reserved.
Classes are created using defclass. To create a subclass, specify the name of the superclass when
declaring the class. Specify the additional slots for the class and change the initialization of values by
creating the instance of the class using the make Instance command. This creates an instance of the class
with all the slots from that class and the superclasses. Set the value of the slots using the @initarg from
the slot declaration.
When a designLib object is created, the slots users and project are initialized by executing the user
functions pcoGetProjUsers and pcoGetProjectId and assigning the return value to the slots.
© Cadence Design Systems, Inc. All rights reserved.
44
This document is for the sole use of Firuz Shomahmadov of Nxp
Finding Class Inheritance Information
● Is a class1 a subclass of class2?
subclassp( classOf( inst1 )
classOf( inst2 ) )
=> t/nil
● Find the class hierarchy of an instance.
superclassesOf( classOf( instA ) )
subclassesOf( classOf( instA ) )
45
© Cadence Design Systems, Inc. All rights reserved.
SKILL++ keeps track of the class inheritance as classes are built. The commands superclassesOf and
subclassesOf return the hierarchy as a list of classes with single inheritance. This list is easy to predict.
These tools become more useful when analyzing multiple inheritance.
© Cadence Design Systems, Inc. All rights reserved.
45
This document is for the sole use of Firuz Shomahmadov of Nxp
makeInstance: Instantiation of a Class Inheritance
For instantiating a class, we can use the makeInstance function.
● makeInstance function creates an object of the class.
▪ Inherits from library and userLib classes.
● That object can inherit all the slots of the classes in the design hierarchy.
● No need to create any intermediate instances.
curProject = makeInstance(
'designLib
?libName "A2_43b"
?designers pcoGetProjUsers( "MEMS" ))
46
© Cadence Design Systems, Inc. All rights reserved.
Using makeInstance, a new instance of the designLib class is created. This new object inherits all the
slots of the designLib, userLib, and library classes. The userLib and library classes did not have objects
allocated for the classes. These are abstract classes that usually are not used in creating objects directly,
although they can be used that way.
The user’s slot was assigned its value through the @initarg ?designers. This argument was added with
the designLib class and can be used in addition to the original @initarg ?users.
© Cadence Design Systems, Inc. All rights reserved.
46
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is Slot Inheritance?
Classes inherit the slots of their superclasses. If the subclass declares a new slot, that slot is
added to the class at that level of the class hierarchy.
If the subclass declares a new slot:
● The slot is included in the subclass.
● The superclass does not know about the new slot.
If the subclass declares a slot that exists in a superclass:
● @initform – the value is inherited from the most specific class.
▪ Overrides value from the superclass.
● @initarg – the argument is added to the initargs in the superclasses.
▪ Merged with initargs from subclasses.
47
© Cadence Design Systems, Inc. All rights reserved.
The superclasses of the class do not have access to the data in that slot.
If the subclass declares a slot that already exists from a superclass, the initial value is set by the most
specific class that declares the slot with an @initform. The initialization argument set by @initarg is
added to the existing initargs inherited from the superclasses.
© Cadence Design Systems, Inc. All rights reserved.
47
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Class Slot Inheritance for library Class
(defclass library ()
(( name @initarg libName … )
( owner @initform getShellEnvVar( "user" ) … )
( path @initform getWorkingDir() @initarg path … )))
48
Slot Name
Value
@initarg
Created By
name
\*slotUnbound\*
libName
library
owner
"tedp"
owner
library
path
“/libs"
path
library
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
48
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Class Slot Inheritance for userLib Class
Class name
superClass
(defclass userLib ( library )
(( users @initform makeTable( "users" nil)
@initarg users @reader getUsers @writer setUsers)
))
49
Slot Name
Value
@initarg
Created By
name
\*slotUnbound\*
libName
library
owner
"tedp"
owner
library
path
“/libs"
path
library
users
table
users
userLib
Additional Slots
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
49
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Class Slot Inheritance for designLib Class
Class name
superClass
(defclass designLib ( userLib )
( ( users @initform pcoGetProjUsers()
@initarg designers )
( project @initform pcoGetProjectId()
@initarg project )
))
New @initarg
Additional Slot
Slot Name
Value
@initarg
Created By
name
'slotUnbound
libName
library
owner
"tedp"
owner
library
path
“/libs"
path
library
Table of project
users
users
users
designers
userLib and
designLib
“projectld"
project
designLib
project
50
New Initial Value
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
50
This document is for the sole use of Firuz Shomahmadov of Nxp
Summary of Class and Inheritance
Classes are templates for data containers:
● Slots hold data for the class.
● They identify the data that represents the class.
Classes inherit from superclasses:
● Slot information is inherited.
● New slots and new values are assigned by the class.
● Each subclass is more specialized than the superclasses.
● Multiple classes can inherit from the same superclasses.
Objects are instances of classes:
● Each object is unique.
● Slot values are not shared.
51
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
51
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Summary
In this module, you
● Created classes that inherit from other classes
● Examined how initialization is affected by superclasses
52
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
52
This document is for the sole use of Firuz Shomahmadov of Nxp
Lab
Lab 4-1 Construct Classes: Single Inheritance
53
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
53
This document is for the sole use of Firuz Shomahmadov of Nxp
Symbols and Quotes
Module
5
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
15 minutes
● Lab
30 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
54
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Examine the role of symbols in SKILL®
● Examine how to use the quote and back quote in SKILL
55
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
55
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are Symbols?
In an expression, value is referenced by using the symbol name without modifiers such as a
quote, back quote, or surrounded by double quotes.
A single quote or back quote refers to the symbol itself. Surrounding the string with double
quotes makes it a string.
Symbols commonly implement names in SKILL.
Quoted names are symbols.
● Without double quotes: abc
● In evaluated positions, refer to an explicit symbol
using a quote.
● Double quotes make it a string: "abc"
Symbols are often used as variables to store
values.
abc = 4 + 5
'abc → the symbol abc
● Refer to the value using the symbol name alone.
abc → 63
abc * 7
56
© Cadence Design Systems, Inc. All rights reserved.
SKILL++ makes more use of symbols than SKILL. In SKILL (and SKILL++), a symbol is a name,
starting with an alphabetic character or an underscore (_) without double quotes. Most often, symbols
are used as variables to hold values.
In an expression, value is referenced by using the symbol name without modifiers such as a quote, back
quote, or surrounded by double quotes. A single quote or back quote refers to the symbol itself.
Surrounding the string with double quotes makes it a string.
© Cadence Design Systems, Inc. All rights reserved.
56
This document is for the sole use of Firuz Shomahmadov of Nxp
Uses of Symbols
Name of a Function
● procedure( myFunction
▪ Creates a symbol, myFunction, that holds the reference to the
procedure body
Name of a Variable
● A variable can hold a value
▪ myVar = 7
● It can hold a function (lambda expression)
▪ comparePoint = lambda( ( x y) list(min(minX x) min(minY y)))
Name of a Key
● Disembodied property list
▪ '( nil one 1 two "two" three 9/3)
● Table
▪ layerTable['poly ]
Name of a Class
● defclass( myClass
▪ Creates a symbol, 'myClass, that holds the class description
57
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
57
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are Quote and Back Quote?
Quote and Back quote both operate similarly. All the elements in a quoted list are literal. If a
symbol or expression in the list is preceded by a comma, the symbol or expression is
evaluated, and the value replaces the expression in the list.
'(quote):
`(back quote):
Everything that follows a quote is taken literally.
Like the quote until it encounters a comma. The
expression following the comma is evaluated.
myList =
myList = `( a "b" ,(3 + 5) ,@list(1 2 3
4) )
'( a "b" (3 + 5) )
car( myList )
→ a ; the symbol a
caddr( myList ) → the list ( 3 + 5 )
car( myList )
caddr( myList ) → 8
myList
58
→ a ; the symbol a
→ ( a "b" 8 1 2 3 4 )
© Cadence Design Systems, Inc. All rights reserved.
Two very important operators are the quote and the back quote. They both operate similarly – all the
elements in a quoted list are literal. If the element is a symbol, it remains a symbol. An expression in the
list is returned as a list.
The back quote operates similarly to the quote but with added capabilities. If a symbol or expression in
the list is preceded by a comma, the symbol or expression is evaluated, and the value replaces the
expression in the list. If the value or expression is preceded by a comma followed by the at sign (@), the
expression is evaluated, and the list returned is flattened into the containing list.
© Cadence Design Systems, Inc. All rights reserved.
58
This document is for the sole use of Firuz Shomahmadov of Nxp
Quote and Back Quote: Comparison of Runtime Allocation
'(quote): Does no runtime allocation.
`(back quote): Does runtime allocation.
(defun listQ ()
'(1 2 3))
(defun listBQ ()
`(1 2 3))
(listQ)
→ (1 2 3)
(eq (listQ) (listQ)) → t
(listBQ)
→ (1 2 3)
(eq (listBQ) (listBQ)) → nil
59
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
59
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Summary
In this module, you
● Identified the role of Symbols in SKILL and SKILL++
● Compared the usage of quote and back quote in SKILL and SKILL++
60
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
60
This document is for the sole use of Firuz Shomahmadov of Nxp
Labs
Lab 5-1 Using Quotes and Back Quotes in SKILL Commands
Lab 5-2 lineread
61
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
61
This document is for the sole use of Firuz Shomahmadov of Nxp
Function Parameters
Module
6
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
30 minutes
● Lab
30 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
62
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Work with the arglist function
● Develop simple type templates
● Examine the following arguments:
▪ @key
▪ @optional
▪ @rest
63
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
63
This document is for the sole use of Firuz Shomahmadov of Nxp
Required Arguments for defun and procedure
defun( name ( argument_list ) body… ) => s_funcName
procedure( name( argument_list ) body… ) => s_funcName
● defun and procedure are equivalent functions.
● All the arguments must be given at the call site, and the order matters.
procedure( offset( pt dx dy)
list( xCoord( pt ) + dx
yCoord( pt ) + dy ))
64
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
64
This document is for the sole use of Firuz Shomahmadov of Nxp
The arglist Function Returns the Parameter List
arglist( g_function ) => l_argumentList
arglist is a built-in function that returns the parameter list of user-defined functions or built-in functions.
Examples
●
arglist( 'cons ) => (g_general l_list)
●
procedure( offset( pt dx dy )
list( xCoord( pt ) + dx
yCoord( pt ) + dy ))
arglist( 'offset ) => (pt dx dy)
65
; built-in
; user-defined
© Cadence Design Systems, Inc. All rights reserved.
Actually, (arglist ‘cons) returns a different value containing a type template. Type templates are seen
later in this section. Sometimes, type templates for built-in SKILL® functions are wrong or misleading.
© Cadence Design Systems, Inc. All rights reserved.
65
This document is for the sole use of Firuz Shomahmadov of Nxp
The Optional Type Template Defines the Parameter Data Types
procedure( name( argument_list [ t_typeTemplate ] ) body… ) => s_funcName
If the last item in the parameter list is a string, it is taken to be
a type template. When the function is invoked, the supplied
values must match the specified types. For example:
The last template character repeats implicitly. For example:
procedure( offset1( pt dx dy "lnn" )
list( xCoord( pt ) + dx
yCoord( pt ) + dy )))
In this case, the “n” template type is repeated for the dy and dz
variables.
● Match the individual characters of the type template
"lnn" with the respective function parameters(pt dx
dy).
● Variable dx has type template "n" – declares dx as a number
▪
Variable pt has type template "l" – declares pt as a list
▪
Variable dx has type template "n" – declares dx as a number
▪
Variable dy has type template "n" – declares dy as a number
procedure( offset2( pt dx dy dz "ln" ) ...)
● Variable pt has type template "l" – declares pt as a list
● Variable dy has type template "n" – declares dy as a number
● Variable dz has type template "n" – declares dz as a number
● offset1( '(0 0) '(1 2) '(3 4) )
→ *Error* offset: argument #2 should be a
number (type template = "lnn") - (1 2)
66
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
66
This document is for the sole use of Firuz Shomahmadov of Nxp
Type Template Characters
Some available type template characters include:
67
Type Template
Characters
Specify Column Header
Type Template
Characters
Specify Column Header
"l"
list
"R"
rodObject
"n"
number
"S"
symbol or string
"p"
port
"U"
binary or funobj
"s"
symbol
"a"
array
"t"
string
"d"
dbobject
"u"
symbol, funobj, or cons
"f"
flonum
"w"
wtype
"g"
t – general – unrestricted
"x"
fixnum
© Cadence Design Systems, Inc. All rights reserved.
There are many available type template characters. The SKILL programmer is not allowed to define
new ones. The most common ones are listed here. Use "g" to specify generic (meaning unrestricted
type).
© Cadence Design Systems, Inc. All rights reserved.
67
This document is for the sole use of Firuz Shomahmadov of Nxp
Optional Arguments
procedure( name( [argument_list] [@optional argument_list] ) body… )
=> s_funcName
@optional designates optional arguments.
● procedure( offset( pt dx @optional dy )
list( xCoord( pt ) + dx
yCoord( pt ) + or( dy dx )))
Default expressions are supported.
● procedure( offset( pt dx @optional (dy 0) )
list( xCoord( pt ) + dx
yCoord( pt ) + dy )))
Defaults may reference parameters to the left in SKILL++ but not in SKILL®.
● procedure( offset( pt @optional (dx 0) (dy dx) )
list( xCoord( pt ) + dx
yCoord( pt ) + dy )))
68
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
68
This document is for the sole use of Firuz Shomahmadov of Nxp
Optional Arguments: Order of Arguments
The order at the call site is important.
Examples
● procedure( offset( pt @optional (dx 0) (dy dx) )
list( xCoord( pt ) + dx
yCoord( pt ) + dy ))
● offset( '(3 5) ) => (3 5)
● offset( '(3 5) .1 ) => (3.1 5)
● offset( '(3 5) .1 .2 ) => (3.1 5.2)
The call site cannot specify dy without also specifying dx.
Use @key to avoid this limitation.
69
© Cadence Design Systems, Inc. All rights reserved.
This feature, where an optional argument can refer to a prior optional argument, only works with
SKILL++. So this code must be in a .iLS file or specify top-level ‘ils prior to testing the code in the
CIW.
© Cadence Design Systems, Inc. All rights reserved.
69
This document is for the sole use of Firuz Shomahmadov of Nxp
Keyword Arguments
procedure( name( [argument_list…] [@key argument_list…] ) body… )
=> s_funcName
● @key designates keyword arguments.
● Default values are supported.
● Defaults may reference parameters to the left.
procedure( offset( pt @key (dx 0)(dy dx) )
list( xCoord( pt ) + dx
yCoord( pt ) + dy )
)
● Optionally, specify the keyword by beginning it with
? at the call site. For example:
The order of keyword parameters at the call site is
less important.
Examples
● offset( '(3 5))
=> (3 5)
● offset( '(3 5) ?dx .1 )
=> (3.1 5)
● offset( '(3 5) ?dy .2 )
=> (3 5.2)
● offset( '(3 5) ?dy .2 ?dx .1 ) => (3.1 5.2)
● offset( '(3 5) ?dx .1 ?dy .2 ) => (3.1 5.2)
offset( '(3 5) ?dy .2 ?dx .1)
70
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
70
This document is for the sole use of Firuz Shomahmadov of Nxp
Keyword Argument Evaluation
The default is not evaluated if the keyword is given at the call site.
● procedure( myDbOpen(
lib cell view
@key (mode "r")
(cellViewType (when view=="layout“ "maskLayout“)))
dbOpenCellViewByType( lib cell view cellViewType)
)
● myDbOpen( "des" "cel3" "layout“ )
● myDbOpen( "des" "cel3" "layout" ?cellViewType nil )
● myDbOpen( "des" "cel3" "sch" ?cellViewType "schematic“ )
71
© Cadence Design Systems, Inc. All rights reserved.
You may distinguish the case of a keyword given explicitly as nil vs. a keyword not given. In the above
example, myDbOpen called with ?cellViewType nil behaves differently than myDbOpen called without
?cellViewType. The analogous behavior also applies to @optional defaults; the default expression is not
evaluated if a corresponding argument is provided at the call site.
© Cadence Design Systems, Inc. All rights reserved.
71
This document is for the sole use of Firuz Shomahmadov of Nxp
Rest Arguments
procedure( name( [argument_list…] [@rest arg] ) body… )
=> s_funcName
● @rest designates rest/var-args arguments.
Examples
● Default values are not supported.
● procedure( offset( pt @rest delta )
list( nil
'pt pt
'delta delta))
▪ procedure( offset(pt @rest delta)
list( nil 'pt pt 'delta delta))
● Only one @rest parameter is allowed.
● All otherwise unconsumed arguments are
combined in a list.
● offset( '(3 5) )
=> (nil pt (3 5) delta nil)
● offset( '(3 5) .1 )
=> (nil pt (3 5) delta (0.1))
● offset( '(3 5) .1 .2 )
=> (nil pt (3 5) delta (0.1 0.2))
72
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
72
This document is for the sole use of Firuz Shomahmadov of Nxp
Combining Optional Arguments
● @key and @optional cannot be used together.
● @key, @optional, and @rest may be used with or without the required arguments.
● @rest may be used with @optional or @key.
Examples
● procedure( offset( pt @key dx (dy 0) @rest delta )
list( nil
'dx dx
'dy dy
'delta delta))
● offset( '(3 5) ?dx .1 ?dy .2 )
=> (nil dx 0.1 dy 0.2 delta nil)
● offset( '(3 5) ?dx .1 ?dz .3 )
=> (nil dx 0.1 dy 0 delta (?dz 0.3))
● offset( '(3 5) ?dx .1 ?dz .3 ?dy .2 ?dx .4 )
=> (nil dx 0.1 dy 0.2 delta (?dz 0.3 ?dx 0.4))
73
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
73
This document is for the sole use of Firuz Shomahmadov of Nxp
Functions That Can Use Optional Arguments
@optional, @key, and @rest arguments may be used in the following function definitions:
● defun
● procedure
● defmacro
● defgeneric
● lambda
● defglobalfun
74
© Cadence Design Systems, Inc. All rights reserved.
There are many different ways to define functions in SKILL++. These will be seen later. However, any
function may make use of optional arguments.
© Cadence Design Systems, Inc. All rights reserved.
74
This document is for the sole use of Firuz Shomahmadov of Nxp
Required Arguments and Keyword Parameters
procedure( name( arg_list )
body… )
procedure( name( @key arg_list )
body… )
The dbCreateLabel function has eight required
arguments, most of which we do not normally care
about. This is difficult to use.
An alternative is to write myCreateLabel that accepts
@key parameters and internally calls
dbCreateLabel with the eight positional arguments.
dbCreateLabel(
d_cellView
txl_layer
l_point
t_label
t_just
t_orient
t_font
x_height
)
procedure( myCreateLabel(cellView
@key (layer "text" ) (xy '(0 0) )
theLabel
(justify "lowerLeft" )
(orient "R0" )
(font "stick" )
(height 1.0 ) "dglttttn" )
dbCreateLabel( cellView layer xy
theLabel
justify orient font
height )
)
75
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
75
This document is for the sole use of Firuz Shomahmadov of Nxp
Required Arguments and Keyword Parameters (continued)
● We have to call dbCreateLabel like this and
provide all the required parameters:
(dbCreateLabel cvId "text" 5:6
"some text" "lowerLeft" "R0"
"stick" 1.0)
● We can then call myCreateLabel like this:
(myCreateLabel cvId ?theLabel
"some text“ ?xy 5:6))
● Thus, we can specify the arguments we care about
and take the defaults for the ones we do not care
about.
● And we do not have to remember the meaning of
the 6th, 7th, and 8th, arguments of
dbCreateLabel.
76
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
76
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Summary
In this module, you
● Worked with the arglist function
● Developed simple type templates
● Examined the following arguments:
▪ @key
▪ @optional
▪ @rest
77
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
77
This document is for the sole use of Firuz Shomahmadov of Nxp
Lab
Lab 6-1 Implementing Your Own Variable Argument Function
78
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
78
This document is for the sole use of Firuz Shomahmadov of Nxp
Assert
Module
7
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
15 minutes
● Lab
30 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
79
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objective
In this module, you
● Examine how assert is used in software testing
80
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
80
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is an Assert Function?
A new macro named an assert function is used to create software tests. It tests the return
value of the expression but does not test the side effects.
If the expression returns nil:
Examples
● An error is thrown, the error message is printed,
and the expression is returned.
● Test for the return value →
assert( myFunction( 12.3 "abc" ) )
If the expression returns non-nil:
● Test for equivalence →
assert( 2 + 5 == 7 )
● Assert does not throw an error, and nil is
returned.
● Test for nil →
assert( !myOddp( 8 ) "Value is even." )
The syntax for the assert function is:
assert( expression {"error string“})
81
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
81
This document is for the sole use of Firuz Shomahmadov of Nxp
Lab
Lab 7-1 Examining the assert Function Hands-On to Design a Software Test
82
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
82
This document is for the sole use of Firuz Shomahmadov of Nxp
Scoping
Module
8
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
1 hour
● Lab
1 hour
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
83
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Determine the scope of a variable
● Compare binding and assignment
● Hide data with SKILL++ closures
● Examine the following constructs
▪ prog1
▪ prog2
▪ progn
▪ let
▪ letseq
▪ letrec
84
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
84
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is the Scope of a Variable?
The scope of a variable is where the variable has a particular value. As a procedure or
method calls another method, the scope determines if the variable is available in the nested
context and if the value is local to the current context or comes from a higher-level context.
● When a variable is "in scope", it is visible.
● Global variables are always in scope, except when they are shadowed by a local variable.
● The scope of a local variable defined by the let statement is the body of the let, where it comes from.
▪ The variable can be seen by code within the ()s.
▪ In SKILL++, when the let statement to which the variable was bound completed, the variable leaves the scope and is
de-referenced.
● SKILL++ is easy: the scope is determined by the text.
▪ Lexical scope
▪ Easy to understand
▪ Easy to debug
85
© Cadence Design Systems, Inc. All rights reserved.
The scope of a variable is where the variable has a particular value. As a procedure or method calls
another method, the scope determines if the variable is available in the nested context and if the value is
local to the current context or comes from a higher-level context. This will also determine which
contexts are affected when the value is changed in the nested context. Dynamic scoping is supported by
SKILL and can introduce errors when a variable value change unanticipated. SKILL++ supports lexical
scoping, which helps minimize these bugs.
When a variable is in scope, its value is available through the variable. If the variable is out of scope, the
variable no longer refers to that value. When the let statement to which the variable was bound is
completed, the variable leaves the scope and is de-referenced.
© Cadence Design Systems, Inc. All rights reserved.
85
This document is for the sole use of Firuz Shomahmadov of Nxp
Binding Variables in a let Statement
let( ( var1 var2 … ) body )
● The let statement creates a block structure in code.
Example code using let statement:
▪ Groups expressions in the body.
● It declares local variables.
▪ Body of let is the scope of the local variables.
▪ Declared in the first form of the let statement.
let( ( ( x 2 ) ( y 3 ) )
x*y
) ; let
=> 6
▪ Body statements are executed.
● The scope of the variable is determined if the code
is executed in the SKILL® environment or the
SKILL++ environment.
● Return value is the return value of the last
executed expression in the statement.
86
© Cadence Design Systems, Inc. All rights reserved.
The let statement creates a block of code with local variables. The first form after the let declares the
variables. These are local variables that exist only for the scope of the let statement. Once all the
expressions in the body are completed, the local variables are de-referenced (SKILL forgets about
them), and the memory is marked for reuse (garbage collected).
The code in the body can use these local variables; the scoping of the variable will be determined if it is
executing in the SKILL environment or the SKILL++ environment. The expressions in the body are
executed, and the value of the last expression is returned as the result of the let statement.
© Cadence Design Systems, Inc. All rights reserved.
86
This document is for the sole use of Firuz Shomahmadov of Nxp
Binding Variables in a let Statement (continued)
● Variables have values. The binding of variables is done when they are declared.
let(((layer "Metal" )…) )
let(( layer ) … )
If no value is given, the default is nil.
● Variables bound in the let may be reassigned within the let body.
let(( rectId )
…
rectId = dbCreateRect(cvId layer bBox)
)
87
© Cadence Design Systems, Inc. All rights reserved.
The environment in which the let statement is created determines the scope of the variables. If the let is
defined in a .il file, it is loaded in the SKILL environment. If it is defined in a .ils file, it is loaded in the
SKILL++ environment.
The variables are declared in the let statement. The variables become local variables to the let statement.
If this statement is in a nested SKILL let, a new declaration of an existing variable hides the existing
variable, and changes are only reflected in the local variable.
A variable can be declared with or without a bound value. If the variable is declared as just a name, the
variable is assigned the value nil. The value is bound by declaring a list, the variable, and its binding
value or expression. The binding value can be static or maybe an expression that is computed each time
the block is executed.
© Cadence Design Systems, Inc. All rights reserved.
87
This document is for the sole use of Firuz Shomahmadov of Nxp
Binding Variables in a let Statement (continued)
● Binding values can be computed expressions.
let((( cvId deGetEditCell())) …body…)
● All initial values are computed before any variable becomes bound.
● Any variable exterior to the let may be used in the computed expressions, including:
▪
Parameters to the procedure/defun
▪
Variables declared in an outer let
▪
Global variables
● Variables may be shadowed by reusing the name.
let(((a 100))
let(((a 200))
;;; here a is 200
...
)
;; here a is 100
)
88
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
88
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Assigning and Binding Variables in a let Statement
procedure( SKcreateLib( libName )
let((libDir
(directory getWorkingDir())
(project SKgetProj( libName))
Binding
) ; BODY
sprintf( libDir "%s/%s/%s"
Assignment
directory project libName )
SKgetLib( libDir libName )
) ; let
) ; procedure
libDir is set based on the directory and project defined in the let statement.
89
© Cadence Design Systems, Inc. All rights reserved.
In the above procedure definition, the single argument is the variable libName. The let statement
declares three variables, libDir which is not given an initial value and default to nil, the variable
directory bound to the value returned by getWorkingDir, and the variable project bound to the value
returned from SKgetProj called with the value bound to the procedure argument variable libName.
libDir is assigned a value using sprintf based on the values of directory, project, and libName. This
value could not be computed during the variable binding because it refers to other variables whose
values are not yet bound when it would be computed. There are other forms, letseq and letrec, that
enable this.
The value of the variables is now initialized in the scope of the let statement. When the last expression
in the let statement
SKgetLib( libName) is executed, and its return value becomes the return value for the let statement.
© Cadence Design Systems, Inc. All rights reserved.
89
This document is for the sole use of Firuz Shomahmadov of Nxp
Binding Variables in a letseq Statement (Enhanced Binding)
letseq(((s_var1 initExp1) (s_var2 initExp2)……) body )
● A letseq expression can be used in both SKILL and SKILL++ modes.
● The bindings and evaluations are performed sequentially from left to right.
● It controls the order of evaluation of initialization expressions.
● This form is equivalent to a corresponding sequence of nested let expressions.
Nested let expression:
let( ( ( x 1 ) )
let( ( ( y x+1 ) )
y
)
)
Normal let statement:
let((a 5)
(b a+10)
(c b/a))
90
letseq((a 5)
(b a+10)
(c b/a))
…
… )
Output: y is 2
letseq expression:
*error*
)
Output: c is 3
© Cadence Design Systems, Inc. All rights reserved.
The block declaration letseq compute and bind the initial values of the declared variables sequentially.
This allows later variables to reference variables previously bound in the declaration.
© Cadence Design Systems, Inc. All rights reserved.
90
This document is for the sole use of Firuz Shomahmadov of Nxp
Binding Variables in a letrec Statement (Enhanced Binding)
letrec(((s_var1 initExp1) (s_var2 initExp2)……) body )
● A letrec expression can be used in SKILL++ mode only.
● All the bindings are in effect while their initial values are being computed.
● Thus, it allows mutually recursive definitions.
● Use letrec when you want to declare recursive local functions.
▪ For example, a lambda expression satisfies this restriction because its body gets executed only when called, not when
it’s defined.
● Each initialization expression can refer to the other local variables being declared when
▪
Each initialized expression must be executable without accessing any of those variables.
● This form is equivalent to a corresponding recursive let expression.
91
© Cadence Design Systems, Inc. All rights reserved.
The block declaration letrec initializes the bindings before computing the values (neat trick), so the
order does not have to be sequential, and the computation can be recursive.
© Cadence Design Systems, Inc. All rights reserved.
91
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Code for Binding Variables in a letrec Statement
This code shows the usage of the letrec statement in the SKILL++ environment.
letrec(
( ;;; variable list
( f
lambda( ( n )
if( n > 0 then n*f(n-1) else 1
) ; if
) ; lambda
) ; f
) ; variable list
f( 5 )
) ; letrec
=> 120
92
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
92
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is Lexical Scoping?
A program refers to a local variable only within certain textually defined regions of the
program. This region is called the lexical scope of the variable. SKILL++ uses lexical
scoping.
● If a function refers to non-local variables, they must be
global variables.
▪ Outside of a function, local variables are inaccessible.
● Whenever a variable is introduced (by procedure, let, and
so on), a "box" is created.
● Dereferencing a variable fetches the value in the box.
let( (number)
● Setting variable changes the value in the box.
● You find the right box by looking up the text of the
program.
procedure( counter1
number
Some global variable
named number
procedure( counter2
number
● If you do not find a box that way, use the global box.
● Procedures not defined in the box cannot see the variable.
93
© Cadence Design Systems, Inc. All rights reserved.
SKILL++ uses lexically scoped variables. Access to the variable is limited to the scope in which it is
defined, such as within a let statement. Functions defined within the lexical scope can access the
variable, reading and setting the value. Functions defined outside the lexical scope cannot refer to the
scoped variable; using the symbol name will refer to another variable that may be defined as a global
symbol.
The variable number in function counter1 is the variable defined in the enclosing let statement. Because
counter2 is defined outside the let, counter2 would never access the variable from the lexical scope but
rather access a global variable named number. This is true even if counter2 is called from within
counter1.
Variables declared inside a let in a function only exist within that function and cannot be accessed by
any other function.
© Cadence Design Systems, Inc. All rights reserved.
93
This document is for the sole use of Firuz Shomahmadov of Nxp
Lexical Scoping Is Easy: Example
It is easy to know which variable is referenced.
Examples
toplevel 'ils ; sets evaluation to SKILL++ mode
x = 15
procedure( GetX()
x
; this is the global x
)
procedure( LocalX()
let( (x)
x=random(); this is the x from the let
x
; this is the x from the let
GetX()
; returns global x (15) with lexical scoping
; but returns local x (random) with dynamic scoping
))
LocalX() => 15
94
© Cadence Design Systems, Inc. All rights reserved.
In the GetX procedure, the variable x refers to a global variable and would return 15.
In the LocalX procedure, x is scoped within the procedure by its declaration in the let statement.
In lexical scoping, the value of x would not be available to any function called by LocalX;
if LocalX called GetX, the value returned by GetX would be 15 and not the value from LocalX.
© Cadence Design Systems, Inc. All rights reserved.
94
This document is for the sole use of Firuz Shomahmadov of Nxp
Dynamic Scoping Is Different and Difficult: Example
With dynamic scoping, it is difficult to know which variable is referenced.
Examples
toplevel 'il ; sets evaluation to SKILL mode (default)
x = 15
procedure( GetX()
x
; this may be the global x, or some other x
)
GetX() => 15 ; returns 15
procedure( LocalX()
let( ( (x 1) )
GetX() ; returns 1
)
)
LocalX() => 1 ; returns 1
95
© Cadence Design Systems, Inc. All rights reserved.
In the GetX procedure, the variable x refers to a global variable and would return 15. In the LocalX
procedure, x is scoped within the procedure by its declaration in the let statement. In lexical scoping, the
value of x would not be available to any function called by LocalX; if LocalX called GetX, the value
returned by GetX would be 15 and not the value from LocalX.
© Cadence Design Systems, Inc. All rights reserved.
95
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are Closures?
A closure is a function object containing one or more free variables bound to data. Lexical
scoping makes closures possible.
● In SKILL, dynamic scoping prevents effective use
of closures, but a SKILL++ application can use
closures as software building blocks.
● let defines the box of a closure.
● Functions defined in the closure can access the
variables defined in the let.
let( ((secret 42))
defglobalfun( Guess (guess)
if( guess == secret
printf( "You guessed right!\n")
printf( "So sorry, try again\n"))
) ; defglobalfun
) ; let
● You can use this "textual lookup" to hide data.
96
© Cadence Design Systems, Inc. All rights reserved.
Here, we are declaring a variable secret, a value inside the scope of the let statement. It also defines a
global function Guess within the lexical scope. The function can access the variable when it is executed,
but functions defined outside the scope of the closure cannot see this value.
The defglobalfun statement defines a named function within a closure that is available globally.
© Cadence Design Systems, Inc. All rights reserved.
96
This document is for the sole use of Firuz Shomahmadov of Nxp
Closure Example: Counter and ResetCounter
● The function Counter increments the count variable.
● ResetCounter resets the value of the counter.
● No other functions can see or modify the count variable.
let( ((count 0))
defglobalfun( Counter ()
count++)
defglobalfun( ResetCounter (@optional ( new 0 ))
count = new)
) ; let
97
© Cadence Design Systems, Inc. All rights reserved.
This closure creates a counter by declaring a lexical scoped variable count and declaring two functions
that modify the variable. No other functions can access that variable.
© Cadence Design Systems, Inc. All rights reserved.
97
This document is for the sole use of Firuz Shomahmadov of Nxp
Closure Example: Multiple Counter
● We can also have more than one counter.
procedure( MakeCounter(count)
procedure( counter()
; a local function
count++
)
; count argument from MakeCounter
counter ; return the new function
)
toplevel ‘ils
counter1 = MakeCounter(10)
counter2 = MakeCounter(100)
counter1() → 10
counter2() → 100
counter1() → 11
counter2() → 101
98
© Cadence Design Systems, Inc. All rights reserved.
This is a more complex counter-implementation.
The procedure MakeCounter declares a local function and returns the function object. The variable
count is scoped within the function object.
The functions counter1 and counter2 are created from MakeCounter. Executing them (using either the
infix or prefix format (C or Lisp)) returns the value of their independent lexical scoped variable count.
© Cadence Design Systems, Inc. All rights reserved.
98
This document is for the sole use of Firuz Shomahmadov of Nxp
Other Block Statements: progn – Creates a Single Block
progn( sequence of statements )
or
{ sequence of statements }
● Simple means of grouping statements where multiple statements are required, but only one is expected.
● Evaluates expressions from left to right and returns the value of the last expression.
● Useful for grouping a sequence of expressions into a single expression.
● Short-hand notation for progn: curly braces ({ }).
99
© Cadence Design Systems, Inc. All rights reserved.
There are some commands that will only accept a single expression. In order to use multiple
expressions, they can be gathered into a progn block. The block statement progn groups multiple
expressions into one expression. The block consists only of expressions; there is no provision for local
variables (use let if you need local variables).
Braces {} can be used to delimit the block instead of using the progn command.
© Cadence Design Systems, Inc. All rights reserved.
99
This document is for the sole use of Firuz Shomahmadov of Nxp
progn Examples
Example 1
progn(
100
Example 2
{ println("expr 1")
println("expr 1")
println("expr 2")
println("expr 2") )
5 + 4 }
O/P → "expr 1"
O/P → "expr 1"
"expr 2"
"expr 2"
nil
9
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
100
This document is for the sole use of Firuz Shomahmadov of Nxp
Other Block Statements: prog1 and prog2
prog1( g_exp1 [g_exp2..] )
prog2( g_exp1 g_exp2 [g_exp3..] )
=> value of g_exp1
=> value of g_exp2
● The arguments may be any SKILL expression.
● The arguments may be any SKILL expression.
● Evaluates expressions from left to right and returns
the value of the first expression.
● Evaluates expressions from left to right and returns
the value of the second expression.
● No block variables are allowed.
● No block variables are allowed.
prog2(
prog1(
x = 5
x = 12
y = 7 )
y = 10
z = 8 )
=> 5
=> 10
101
© Cadence Design Systems, Inc. All rights reserved.
Although not used much, prog1 and prog2 are very useful block statements. Often a block computes the
return value and has to continue processing before the block is completed. Using a let statement, the
return value would be captured in a local variable, and its value would be returned at the end of the
block. With prog1 and prog2, the local variable would be unnecessary.
© Cadence Design Systems, Inc. All rights reserved.
101
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Block Structure for SKILL Testing
Create an assert with blocks of code to set up the test, execute the test, and then cleanup after the
test. The prog2 returns the results of the test block.
assert( prog2(
; Return the value of the 2nd expression
{ ; Setup block start
cvId = deGetEditCellView()
numInsts = cvId~>anyInstCount
} ; Setup block end
{ ; Test block start
TrPlaceInstances( "testPcell" 3)
cvId~>anyInstCount == numInsts + 3
} ; Test block end – return t or nil
{ ; Cleanup block
dbRefreshCellView()
} ; End of cleanup block
) ; prog2
"Wrong number of instances!" ; Error message
102
)
© Cadence Design Systems, Inc. All rights reserved.
The assert function is useful for testing your procedures. It will evaluate the expression and then if the
result is nil, cause an error.
assert( 1 == 2 ) => causes an error
This use of assert is a complete test that includes a setup blockl and uses prog2 and progn to create a test
case that includes a setup block, the assertion test, and a cleanup block. The value tested by assert is the
return value of the prog2, the return value of the second expression. This is the test block. It will return
nil or non-nil value. The cleanup block will execute after the test block, and then the prog2 will return
the value from the test block to assert.
This test structure works like this:
▪ Set up conditions for the test (Start block)
▪ Execute the code and test the results (Test block)
▪ Cleanup afterward (Cleanup block)
If the test block returns nil, the assert generates an error and prints the error message; if the return value
is a non-nil value, the assert command finishes without an error.
© Cadence Design Systems, Inc. All rights reserved.
102
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: prog1 with Dynamic Scoping
let(((nullport outfile( "/dev/null")))
prog1(
let(((errport nullport))
errset(1/0 t) ; get info from the error port
20*50
)
close(nullport)
)
)
Note: You can use dynamicLet() in SKILL++ code to give you dynamic scoping.
103
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
103
This document is for the sole use of Firuz Shomahmadov of Nxp
Quick Reference Guide: Scoping
SKILL: Dynamic Scoping
● Local variables can be accessed and changed by any function that gets called while executing the let.
● Dynamic variables cease to exist once the let returns.
SKILL++: Lexical Scoping
● Only functions within the text of the let can see the variables.
● Dynamic scoping available via inSkill function.
104
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
104
This document is for the sole use of Firuz Shomahmadov of Nxp
Quick Reference Guide: Block Statements
Block Statements
let( ( variable bindings) body )
letseq( ( variable bindings ) body )
letrec( ( variable bindings ) body )
Remarks
Variable bindings can initialize a variable.
● Variables are bound sequentially.
● Use the values in subsequent bindings.
● Variables are bound recursively.
● Use with recursive or out of order bindings.
progn( statements ) or { statements } Gathers multiple statements into a single statement.
105
prog1( statements )
Returns first expression values.
prog2( statements )
Returns second expression values.
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
105
This document is for the sole use of Firuz Shomahmadov of Nxp
Quick Reference Guide: Closures
● Protect data and interface functions in a closure.
● Internal variables can only be accessed by the internal functions.
● Interface functions are exported to external variables.
▪ Use the variables as functions to access the closure data.
● Changes in the internal data format do not affect the interfaces.
▪ Updates without causing maintenance problems.
106
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
106
This document is for the sole use of Firuz Shomahmadov of Nxp
Lab
Lab 8-1 Examining the Scope of a Variable in SKILL and SKILL++
107
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
107
This document is for the sole use of Firuz Shomahmadov of Nxp
destructuringBind
Module
9
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
15 minutes
● Lab
15 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
108
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Examine how destructuringBind simplifies your code
● Extract/destructure data from hierarchical lists
● Write readable code to destructure complex structures
109
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
109
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is destructuringBind?
destructuringBind enables you to bind values to variables in a list. It simplifies the code.
● The old way is to use a let or procedure statement and then append the lists to the variables and print
the variables.
● The scope of the variables depends on the environment in which the destructuringBind statement is
evaluated.
110
Old way:
Destructuring:
let((first second third)
first = car( list1 )
second = cadr( list1 )
third = caddr( list1 )
println( first )
println( second )
println( third )
)
destructuringBind(
( first second third )
list1
println( first )
println( second )
println( third )
)
© Cadence Design Systems, Inc. All rights reserved.
Functions or expressions often return lists that have to be taken apart and assigned to variables used in
equations and other statements. destructuringBind is a macro that assigns the values in a list to a set of
variables that are then used as local variables in the statements in the body of the statement.
The scope of the variables depends on whether the destructuringBind statement is evaluated in a
SKILL® procedure, where it is dynamically scoped, or a SKILL++ procedure, where it is lexically
scoped.
© Cadence Design Systems, Inc. All rights reserved.
110
This document is for the sole use of Firuz Shomahmadov of Nxp
destructuringBind Syntax
destructuringBind( (list of variables) expression
body..
)
destructuringBind
● Evaluates the expression.
Variables are local to
the body.
Expression is
evaluated and
returns a list.
● Binds the returned list values to the variables.
● Executes the body expression with the variables as local
variables.
● Returns the return value of the last expression evaluated.
destructuringBind( ( list of variables ) expression
body expressions… )
masterId =
destructuringBind( (lib cell view @optional viewType)
parseString( master "/" )
dbOpenCellViewByType( lib cell view viewType "r" ))
111
© Cadence Design Systems, Inc. All rights reserved.
destructuringBind operates by evaluating the expression which returns a list. The elements of the list are
then assigned to the variables in the list of variables argument. These variables are then treated as local
variables during the evaluation of the body statements. The return value of that last expression evaluated
is returned from the destructuringBind statement.
The example code assigns the results of the parseString to the variables lib, cell, view, and viewType,
which are used by the dbOpenCellViewByType command. When the destructuringBind block exits, the
value returned by dbOpenCellViewByType is assigned to the variable masterId. The variables lib, cell,
view, and viewType are out of scope when the block exits.
© Cadence Design Systems, Inc. All rights reserved.
111
This document is for the sole use of Firuz Shomahmadov of Nxp
destructuringBind: Examples
● Destructure a list from a database query:
figId~>bBox return value: (( 0.0 0.0 ) ( 0.125 0.175))
destructuringBind( ( llPoint urPoint ) figId~>bBox
dbCreateRect( cvId implantLayer
list( rodAddToPoint( llPoint -iodx:-iody)
rodAddToPoint( urPoint iodx:iody))
)
)
● Destructure the return value of a method or procedure:
destructuringBind( ( metalShape diffShape nodeId )
MyCreateCutRegion( device cvId terminal
cutRegionParams ))
MyTagPinShape( device metalShape )
MyTagShape( device nodeId "currentNode" )
)
112
© Cadence Design Systems, Inc. All rights reserved.
destructuringBind simplifies coding because it automatically assigns the elements of a list to variables
that can then be used in the body statement. These variables are local and do not have to be declared in
an enclosing let or prog statement.
In the first statement, the bounding box is destructured into the variables llPoint and urPoint. These
variables are used in the scope of the destructuringBind statement as local variables.
pcoCreateCutRegion is a user function that creates a contact region of a top and bottom layer filled with
cut shapes. It returns three arguments, the top shape, the bottom shape, and the fig group of all the
shapes. These are assigned to the three arguments to the destructuringBind and are local variables for
the rest of the expression.
© Cadence Design Systems, Inc. All rights reserved.
112
This document is for the sole use of Firuz Shomahmadov of Nxp
destructuringBind: Complex Bindings
figId~>bBox return value: (( 0.0 0.0 ) ( .125 .175) )
Destructuring supports complex binding:
destructuringBind( ( (llx lly) (urx ury) ) figId~>bBox
minX = min( minX llx )
minY = min( minY lly )
maxX = max( maxX urx )
maxY = max( maxY ury )
)
● The bBox is destructed into the four variables.
● The format for the variable list matches the return value.
113
© Cadence Design Systems, Inc. All rights reserved.
In this statement value returned by the expression figId~>bBox is a bounding box in the format: list(
list( x y) list( x y) ). This value is destructured into the four variables: llx, lly, urx, and ury. The format of
the variable list is the same as the return value. Note that on the previous slide, the return value was
destructed into two points matching the format of the list of variables.
© Cadence Design Systems, Inc. All rights reserved.
113
This document is for the sole use of Firuz Shomahmadov of Nxp
destructuringBind: Optional Bindings
Returned value: ( 0.03 0.4 3 )
● If the length of the returned value varies, include @optional variables.
destructuringBind(
( length width @optional (fingers 1))
MyCalcSizes( device )
…
)
● Use @rest to capture the rest of the list.
destructuringBind( ( length width @rest others)
MyCalcSizes( device )
…
)
114
© Cadence Design Systems, Inc. All rights reserved.
Expressions can return values that vary in length. If the returned value is to be used, it can be captured
with an optional variable using @optional. The optional variables are assigned by the position of the
value in the list. A default value for the optional variable can be specified.
If the return value will vary greatly and only the first values in the list are used, capture the rest of the
list using an @rest variable. After the first values in the return list are destructured into their variables,
the rest of the values are assigned as a list to the @rest variable.
The @rest variable can be included with @optional and @key variables as well.
© Cadence Design Systems, Inc. All rights reserved.
114
This document is for the sole use of Firuz Shomahmadov of Nxp
destructuringBind: Keyed Variable Bindings
● Values can be captured in keyed variables.
● Variables are declared as @key variables.
● Return value includes the variable keys (using ? prefix).
● Use @rest to capture extra keys.
● Non-keyed variables require values.
destructuringBind(( nodeId @key metalShape diffShape
@rest _ignore )
MyGenNextNode( device "source" )
…
)
MyGenNextNode return value:
=> ( nodeId ?metalShape dbId ?diffShape dbId … )
115
© Cadence Design Systems, Inc. All rights reserved.
Keyed variables identify the values returned by the expression. The variable is defined in the @key
statement; the expression returns the value list that includes a key/value pair: the variable prefixed with
a question mark and the value. If the list does not include a value for one of the keys, the variable is
assigned its default value if one is declared or nil.
Declaration: arg1
Return value: ?arg1 "value"
The return value can contain non-keyed values preceding the keyed values. The variable list must be
formatted appropriately. A value is assigned to these non-keyed variables in the return list.
If there are additional keyed arguments that may not be returned by the function, use the @rest
statement to capture these arguments.
© Cadence Design Systems, Inc. All rights reserved.
115
This document is for the sole use of Firuz Shomahmadov of Nxp
Lab
Lab 9-1 Destructuring the Lists Using the destructuringBind Expression
116
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
116
This document is for the sole use of Firuz Shomahmadov of Nxp
Methods (Primary)
Module
10
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
45 minutes
● Lab
30 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
117
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Create generic functions
● Create primary methods and apply them to classes
● Control the execution of methods using callNextMethod
118
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
118
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are Methods?
Methods are like procedures in which they do something (side effects) and return a value.
They define the actions taken on objects.
● Methods, like procedures, have a name.
● Unlike procedures, multiple methods can have the
same name.
● Methods are executed like procedures:
▪ Called directly with arguments.
▪ Using callNextMethod() to call the method of the
superclass.
● Method calls (which method is executed) are
qualified by the specializers on the arguments.
▪ The object passed into specialized arguments
determines which method is executed.
119
defmethod( createLib ( ( lib library ))
;; Create a library
…
)
© Cadence Design Systems, Inc. All rights reserved.
The real power of class inheritance is methods. Methods are like procedures in that they do something
(side effects) and return a value. In Virtuoso®, we are often more interested in the side effects than the
return value.
A method has a name and is called by its name. There may be multiple methods with the same name,
but each applies to a different class. The method is called with the class in an argument. If the method
was defined for that class, it is executed from that class; otherwise, the superclass hierarchy is searched
till the method is found and that method is executed for that class. A currently executing method can
then execute the method of its superclass using the callNextMethod function.
© Cadence Design Systems, Inc. All rights reserved.
119
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are Methods?(continued)
In some OO programming languages, methods are components inside classes.
● There are often syntactical and semantic differences between calling a method versus calling a normal
function.
In SKILL++, methods are components of generic functions.
● There is no syntactical nor semantic difference between calling a generic function versus calling a normal
function.
120
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
120
This document is for the sole use of Firuz Shomahmadov of Nxp
Behavior of a Method
The behavior of a generic function/method is determined by which methods are applicable for a given
set of arguments at run time.
The SKILL++ programmer (who creates an API)
● Customizes the generic function behavior by writing methods specializing in their classes.
The SKILL++ programmer (who uses the API)
● Need not know whether a function is a normal function or a generic function.
121
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
121
This document is for the sole use of Firuz Shomahmadov of Nxp
How to Create Methods for the Class
Before methods can be created for a class, the class itself has to be created and loaded into
Virtuoso®. Defining a method without a class will generate a warning.
The steps to create the method are:
1. Create a class that will use the method.
2. Define a generic function.
(defclass library ()
((name)
(owner)))
Define a class
called library.
a. Erases all existing methods of this name.
b. Sets the required arguments.
c. Can be the last method called in the method hierarchy.
i.
Could generate an error when invoking a
generic function that has no default method.
ii. Could return a default value such as nil.
defgeneric( createLib ( obj)
defmethod( createLib ( ( lib library ))
Declare a generic
function that creates a
method template.
Define a method
specialized on
classes.
3. Define class-specific methods.
a. Methods are specialized on the classes.
122
© Cadence Design Systems, Inc. All rights reserved.
Before methods can be created for a class, the class itself has to be created and loaded into Virtuoso.
Defining a method without a class will generate a warning. The next step is to create a generic function.
This function is the template for the methods that share the name. The generic function sets the required
arguments; methods can only specialize on required arguments. The generic function is executed if none
of the method specializers match when the function is called. It often generates an error. The classspecific methods are created using specializers that determine when they will be executed. Primary,
@before, and @after methods can be created.
© Cadence Design Systems, Inc. All rights reserved.
122
This document is for the sole use of Firuz Shomahmadov of Nxp
Generic Function Declaration
defgeneric( methodName ( specializer ) )
● Generic function declaration creates the template.
● Specialized arguments are declared as required arguments.
● Following arguments are available:
▪ @key
▪ @optional
▪ @rest
● @rest can be used to extend the method calls with additional keyed or optional arguments.
;; Generic function can define a default behavior
defgeneric( createLib ( obj)
error( "no createLib method defined for %s." className( classOf(obj) )))
123
© Cadence Design Systems, Inc. All rights reserved.
The generic function is declared using defgeneric. This establishes the name of the method and the
required arguments. All methods with the same name (derived methods) will have these required
arguments. A method can only specialize on the required arguments. If the generic function declares any
@optional or @key arguments, all derived methods must have the same @optional or @key arguments.
The @rest argument should always be included in a generic function definition. This allows the derived
methods to extend the argument list with additional @optional or @key arguments.
A good practice is to always include an @rest argument when defining a generic method.
The generic function can also have a body consisting of a set of expressions. By convention, the generic
function expressions should never be called, so this set is often just an error message or returns nil.
Note: It is recommended that additional arguments be created as @key arguments instead of @optional
arguments. This is especially true with methods.
© Cadence Design Systems, Inc. All rights reserved.
123
This document is for the sole use of Firuz Shomahmadov of Nxp
Primary Method Declaration
defmethod( methodName ( ( varName className ))
;; Create a library
…
)
● Primary methods specialize on the required
arguments.
● Method executed determined by matching
specializer.
● Method specializes on class of instance.
● Must match library class.
Method name
Method specializes
on class library
defmethod( createLib ( ( lib library ))
;; Create a library
…
)
A variable name can be different
from a generic function variable.
124
© Cadence Design Systems, Inc. All rights reserved.
The primary methods specialize on the class of the instance passed in to the required argument(s). The
class is declared in the method argument paired with the variable. The method is called with an object;
if the class of the object or any superclass of the object matches the specializer class, the method is
available to be executed. It will be executed if it is the most specific method or is a candidate to be
called using callNextMethod.
© Cadence Design Systems, Inc. All rights reserved.
124
This document is for the sole use of Firuz Shomahmadov of Nxp
Primary Method Execution
defmethod( methodName ( ( varName className )) ……)
instName = makeInstance( 'className )
methodName( instName )
● Method defined for class: library
defmethod( createLib ((lib library))
…
Class
library
)
● Function called with an instance of designLib.
userLib
desLib = makeInstance( 'designLib )
createLib( desLib )
designLib
● Method for superclass library executes.
125
© Cadence Design Systems, Inc. All rights reserved.
The createLib method was defined for the class: library. If there is no primary method for the designLib
class or the userLib class, the method for the superclass library is executed when the specialized
argument is an instance of the designLib object.
© Cadence Design Systems, Inc. All rights reserved.
125
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Primary Method Execution
● Methods defined on classes: library and designLib
defmethod( createLib ((lib library ))
…)
Class
library
defmethod( createLib ((lib designLib))
… )
userLib
● Function called with an instance of designLib.
desLib = makeInstance( 'designLib )
createLib( desLib )
designLib
● Only method for designLib is executed
without explicit execution of inherited class
methods.
126
© Cadence Design Systems, Inc. All rights reserved.
The createLib method was defined for both the library and the designLib classes. The method was
called with an object of the class designLib. This executes the method specific to the class. If that class
does not explicitly execute the methods of the super classes, it will not execute the library method.
© Cadence Design Systems, Inc. All rights reserved.
126
This document is for the sole use of Firuz Shomahmadov of Nxp
Primary Method Execution with callNextMethod()
● Methods defined on classes: library and designLib
defmethod( createLib ((lib library ))
…)
defmethod( createLib ((lib designLib))
callNextMethod()
…)
● Function called with an instance of designLib.
desLib = makeInstance( 'designLib )
createLib( desLib )
● Method for designLib class is executed, call
to callNextMethod() executes the next most
specific method (library class).
Class
library
userLib
designLib
Changing the value of a specialized
argument will give unpredictable results.
Call either with all arguments or none, but
never with a partial argument list.
127
© Cadence Design Systems, Inc. All rights reserved.
To execute the methods from the superclasses, a method can call the function callNextMethod. This
executes the next most specific method from the superclasses. That method can call callNextMethod(),
continuing to execute the next most specific method until it gets to a method that does not use
callNextMethod or the first or generic method. Once that final method has been completed, it returns up
the stack to finally reach the first method that was called, which then completes.
The callNextMethod function can be used at the beginning of a method, in the end, or the middle,
depending on when the code specific to the class should be executed.
The value returned from callNextMethod is the value returned by the method itself.
The order of execution for the method specializers with callNextMethod is calculated when the first
method is executed. If an argument used as specializer changes in the current method, callNextMethod
will still call the pre-calculated method, which may be incorrect.
© Cadence Design Systems, Inc. All rights reserved.
127
This document is for the sole use of Firuz Shomahmadov of Nxp
Flow of the Primary Method Execution with callNextMethod()
Class
Method
Default: createLib( anyObj )
Least
specialized
library
callNextMethod()
createLib( libraryInst )
userLib
createLib not defined
for class userLib
callNextMethod()
createLib( designLibInst )
Time
128
designLib
Most
specialized
© Cadence Design Systems, Inc. All rights reserved.
Methods execute from the most specific class to the least specific class. The function callNextMethod()
is executed inside the method, then the method on the superclass is called.
In this case, the execution of createLib on designLib does some computing, then calls the next method
using callNextMethod(). Because createLib is not defined for class userLib, the next method in the
hierarchy is for the class library, and that method is called. Class library is a base class, and its execution
of callNextMethod() calls the first primary method or generic function version of createLib.
If any method does not execute callNextMethod, the method execution ends with that method. If
createLib for class designLib did not call the next method, createLib for the class library would not be
executed.
When a method has been completed for a class, control is passed to the subClass method, which called
it. designLib->library->designLib
© Cadence Design Systems, Inc. All rights reserved.
128
This document is for the sole use of Firuz Shomahmadov of Nxp
Methods on Invalid Class Names
SKILL++ allows you to define a
method on a class that does not yet
exist, making it easier to build multifile applications.
● You do not need to define all the classes before
the methods.
● However, this presents a potentially obscure bug in
your program if you misspell a class name.
● When you define a method that does yet exist,
defmethod issues a warning which is expected if
you will be defining the class later.
● SKILL++ cannot distinguish between misspelled
class name vs. a not-yet-defined class.
● Execution of the code may not proceed as
expected because the method will not be called if
the class does not exist.
129
● Here is an example class/methods definition that
might be a bug in your program:
defmethod( Fun2 ((a Class_A))
; method on not-yet-defined class
(do_something a))
defclass( Class_A ()
; late class definition
())
defmethod( Fun1 ((a ClassA))
; method on misspelled class name
(do_something_else a))
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
129
This document is for the sole use of Firuz Shomahmadov of Nxp
Lab
Lab 10-1 Examining the Primary Methods on a Given Class
130
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
130
This document is for the sole use of Firuz Shomahmadov of Nxp
Access SKILL® Data Structures with setf
Module
11
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
15 minutes
● Lab
30 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
131
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Identify the usage of a setf macro
● Build and modify hierarchical lists and structures
● Define and build setf-Able functions
132
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
132
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is a setf Macro?
The setf function assigns a new value
to an existing storage location,
destroying the value that was
previously in that location.
● It provides an easy and consistent syntax for
reading and writing SKILL® objects.
● It works with many SKILL built-in data structures,
such as Lists, dbobjects, and Hash tables.
The syntax for the setf function is:
setf( g_place g_value) or
g_place := g_value
● g_place specifies the storage location.
● g_value specifies the new value.
Example
● We access the first element of a list, mylist, with the
syntax:
▪ (car mylist)
● Therefore, we change the first element to 42 using
the syntax:
▪ setf((car mylist) 42 )
133
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
133
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: setf Macro Code
mydpl = (list nil 'left_most 23:98'right_most 56:87)
mydpl → (nil left_most (23 98) right_most (56 87))
mydpl->left_most → (23 98)
yCoord( mydpl->left_most ) → 98
setf( yCoord( mydpl->left_most ) 33)
yCoord( mydpl->left_most ) → 33
mydpl → (nil left_most (23 33) right_most (56 87))
134
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
134
This document is for the sole use of Firuz Shomahmadov of Nxp
setf-Able Function
setf_expanderName( g_new (g_cell))
=>g_result
● An expander function for setf, which returns the
result of the corresponding setf operation.
The following is an example of the helper function for
getSKILLPath function:
● This function is used to abstract the implementation
of data storage.
defun(setf_getSkillPath (new)
● In the above syntax, in the place of the
expanderName, you can write the functions such
as setf_car, setf_cdr, setf_slotValue, etc.
▪ You can also create your own setf helper functions.
if(listp(new)
setSkillPath(new)
setSkillPath(list(new))))
; alters the skill path with setf
setf(getSkillPath()
"/home/user/temp")
; now skill path changed to "/home/user/temp"
135
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
135
This document is for the sole use of Firuz Shomahmadov of Nxp
setf-Able Function (continued)
Another example shows the usage of the setf_helper function by creating our own setf helper
function.
let( (secret used)
defglobalfun( secret_value () secret )
defglobalfun( setf_secret_value (new_value)
when( member( new_value used)
error( "%L already used" new_value ))
push( new_value used )
secret = new_value
)
(setf (secret_value) 0)
)
secret_value() → 0
setf_secret_value(2)
secret_value() → 2
136
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
136
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Summary
In this module, you
● Examined the usage of setf macro
● Built hierarchical lists and structures and modified it
● Defined and built setf-Able functions
137
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
137
This document is for the sole use of Firuz Shomahmadov of Nxp
Lab
Lab 11-1 Using the setf Function to Access List Data
138
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
138
This document is for the sole use of Firuz Shomahmadov of Nxp
Methods (Intermediate)
Module
12
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
30 minutes
● Lab
15 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
139
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Use @before, @after, and @around methods
● Identify the order of execution of these methods
● Illustrate the use of accessor methods
140
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
140
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are Methods?
Methods are like procedures in which they do something (side effects) and return a value.
They define the actions taken on objects.
● Like procedures, methods have a name.
● Unlike procedures, multiple methods can have the same name.
● Methods are executed like procedures.
▪ Called directly with arguments.
▪ Using callNextMethod() to call the method of the superclass.
● Method calls (which method is executed) are qualified by the specializers on the arguments.
▪ The object passed into specialized arguments determines which method is executed.
141
© Cadence Design Systems, Inc. All rights reserved.
The real power of class inheritance is methods. Methods are like procedures in that they do something
(side effects) and return a value. In Virtuoso®, we are often more interested in the side effects than the
return value.
A method has a name and is called by its name. There may be multiple methods with the same name,
but each applies to a different class. The method is called with the class in an argument. If the method
was defined for that class, it is executed from that class; otherwise, the superclass hierarchy is searched
till the method is found and that method is executed for that class. A currently executing method can
then execute the method of its superclass using the callNextMethod function.
© Cadence Design Systems, Inc. All rights reserved.
141
This document is for the sole use of Firuz Shomahmadov of Nxp
Why @before and @after Methods?
● Sometimes, you want to preset conditions before executing the primary methods.
▪ For example, change the design rules based on a Pcell parameter.
● And sometimes, you want to do something after the primary methods are completed.
▪ Like adding implants and wells to the drawn layers.
● SKILL++ supports this by implementing qualified methods:
▪ @before
▪ @after
142
© Cadence Design Systems, Inc. All rights reserved.
SKILL++ supports more than the primary methods. Based on the common Lisp object system,
SKILL++ includes the additional method types of @before and @after methods. These are useful for
executing code to set up for the primary methods or cleaning up after the primary methods.
© Cadence Design Systems, Inc. All rights reserved.
142
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are @before Methods?
@before methods are used to
preprocess the data before executing
the primary methods.
Example
● @before methods have the same name as the
primary methods.
Characteristics:
● @before qualifier is used to declare @before
methods.
● Method defined with the same name as a primary
method and an @before qualifier.
● Method selected by matching the specializer.
● Methods are chosen based on the class
specializer.
● All applicable @before methods are executed
before any primary methods.
▪ Not allowed to call callNextMethod() in a @before
method.
▪ Return values are ignored.
● Execution is from most specific to least specific
methods.
143
Method name
Qualifier
Method specializes
on class library
defmethod( createLib @before ( ( lib library ) )
let(((path getPath( lib ))
unless( isDir( path )
createDirHier( path )
) ; unless
) ; let
) ; defmethod
© Cadence Design Systems, Inc. All rights reserved.
@before methods perform operations before the execution of the primary methods. They can set up or
modify conditions for the execution of the primary methods. Use a primary method to ensure that the
required directory structure is created or to reset the values of slots on the class.
Like the primary methods, the @before methods are selected based on the specializers of the class. The
methods have the same template as the generic function defined with defgeneric. All the applicable
@before methods are executed in the most specific to least specific order before any of the primary
methods.
The @before method for a set of specializers (usually the class) may exist even if there is no primary
method for that set of specializers.
Like the primary method, the @before method is defined with the same name as the generic method
with the addition of the @before qualifier. The required arguments are set by the template generic
function; additional keyed or optional arguments can be defined if the generic function includes @rest.
The list of @before methods is determined by matching the specializers on the methods; they are
executed from the most specific to the least specific order.
© Cadence Design Systems, Inc. All rights reserved.
143
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are @after Methods?
@after methods are used to postprocess the data after executing the
primary methods.
Characteristics:
● Method defined with the same name as a primary
method and an @after qualifier.
● Methods are chosen based on the class
specializer.
● All applicable @after methods are executed after
any primary methods.
▪ Not allowed to call callNextMethod() in a @after
method.
▪ Return values are ignored.
● Execution is from least specific to most specific
methods.
144
Example
● @after methods have the same name as the primary
methods.
● @after qualifier is used to declare @after methods.
● Method selected by matching the specializer.
Method name
Qualifier
Method specializes
on class library
defmethod( createLib @after ( ( lib refLib )
unless( assoc( "pcoCheckUsers"
ddGetTriggerList( "preCheckOut" ))
ddRegTrigger( "preCheckOut"
‘pcoCheckUsers )
); unless
); defmethod
)
© Cadence Design Systems, Inc. All rights reserved.
@after methods perform operations after the execution of the primary methods. They can set up or
modify conditions for the execution of the primary methods. Use a primary method to ensure that the
required directory structure is created or to reset the values of slots on the class.
Like the primary methods, the @after methods are selected based on the specializers of the class. The
methods have the same template as the generic function defined with defgeneric. All the applicable
@after methods are executed in the most specific to least specific order after any of the primary
methods.
The @after method for a set of specializers (usually the class) may exist even if there is no primary
method for that set of specializers.
Like the primary method, the @after method is defined with the same name as the generic method with
the addition of the @after qualifier. The required arguments are set by the template generic function;
additional keyed or optional arguments can be defined if the generic function includes @rest.
The list of @after methods is determined by matching the specializers on the methods; they are
executed from the least specific to the most specific order.
© Cadence Design Systems, Inc. All rights reserved.
144
This document is for the sole use of Firuz Shomahmadov of Nxp
Execution Order: @before and @after Qualifiers and Primary
Methods
Below diagram and table illustrates the execution of @before, primary and @after methods.
● All applicable @before methods are ordered from most specific to least specific and executed in that order.
● The applicable primary methods are ordered the same and will be evaluated only if the methods execute
callNextMethod or callAs.
● The applicable @after methods are ordered from least specific to most specific, and all are executed in that
order.
Class
Method
Qualifier
Specializer
library
createLib
@before
designLib
userLib
@before
designLib
145
primary
@after
createLib
@before
library
createLib
primary
designLib
createLib
primary
library
createLib
@after
userLib
createLib
@after
designLib
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
145
This document is for the sole use of Firuz Shomahmadov of Nxp
Execution Order: @before and @after Qualifiers and Primary
Methods (continued)
@before
primary
@after
library
userLib
callNextMethod()
designLib
146
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
146
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are @around Methods?
The @around methods are executed first when they are defined. It invokes
callNextMethod, and executes the next most specific @around method, with all its
callNextMethod methods.
● @around methods have the same name as the
primary methods.
● @around qualifier is used to distinguish @around
methods.
● The method is selected by matching the
specializer.
● Called before any @before, @after, or primary
method.
● callNextMethod() calls the next @around method if
there is one.
Method name
Qualifier
Method specializes
on class library
defmethod( createLib @around ( ( lib library ) )
unless( ddGetObj( getLibName( lib ) )
callNextMethod()
) ; unless
) ; defmethod
● Otherwise, it calls the normal
@before/@after/primary.
147
© Cadence Design Systems, Inc. All rights reserved.
The return value of the generic function is the return value of the most-specific @around method. It's a
way of overriding the behavior of the generic function by wrapping it in something else.
© Cadence Design Systems, Inc. All rights reserved.
147
This document is for the sole use of Firuz Shomahmadov of Nxp
Execution Order with @around, @before, primary and @after
Qualifiers
148
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
148
This document is for the sole use of Firuz Shomahmadov of Nxp
Important Method Rules
● The generic function defines the template for the methods:
▪ Method name
▪ Required arguments
● The methods can specialize only on the required arguments.
● Add @rest to the generic function to allow for future additions such as @key or @optional arguments.
● @before and @after methods have the same required arguments as the generic function.
● @before and @after methods are selected for execution by matching their specializers.
● All applicable @before methods are executed before any of the primary methods.
▪ @before methods execute from most specific to least specific.
● All applicable @after methods are executed after any of the primary methods.
▪ @after methods execute from least specific to most specific.
● Primary methods are applicable if their specializers match the arguments.
● Primary methods execute only from the most specific method to the least specific method.
● Primary methods will execute the next method only if the current method calls the function callNextMethod()
or executes the method directly.
149
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
149
This document is for the sole use of Firuz Shomahmadov of Nxp
Slot Direct Access Versus Accessor Methods
setSlotValue/slotValue or dash
arrow(->) is the slot direct accessing
techniques.
● Direct access techniques can be used as discrete
statements.
● For fast and simple access.
● The programmer should know the name of the slot
to use these statements.
value1 = slotValue( instA 'name )
=> "testLib2"
value2 = slotValue( instA 'owner)
Methods with @reader and @writer
keywords are called slot accessing
methods.
● Accessor methods should be used in defclass only.
● For augmenting the behavior of the class.
● If the underlying data structure changes, it will
update to the new structure automatically.
(defclass library ()
(( name @initarg libName
@reader getLibName
@writer setLibName)))
=> "Your Name Here"
150
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
150
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Slot Direct Access Versus Accessor Methods
● Here is an example to set and read the circle radius using the direct access and accessor methods.
defclass( Circle ()
((radius @initarg r @reader circle_radius @writer set_circle_radius )
)
C = makeInstance('Circle ?r 14.6)
R1 = C->r
C->r = 10.3
R2 = circle_radius(C)
set_circle_radius(C 19.9)
● To force the radius to be returned as a float, define an @around method.
defmethod( circle_radius @around ((c Circle))
float( callNextMethod() ))
● To limit the values a slot can take, define a primary method. The subclass Circle_fixed now has a
constant radius.
defclass( Circle_fixed (Circle)
()
)
defmethod( set_circle_radius ((c Circle_fixed) value)
if( circle_radius( c ) == value
then value
else error( "cannot set c of %A to %L" c value)))
151
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
151
This document is for the sole use of Firuz Shomahmadov of Nxp
Slot Access Using the setf-Able Function
(defmethod setf_circle_radius (value (c Circle))
(if (plusp value)
c->value = value
(error "circle does not support non-positive
radius: %L" value)))
setf_circle_radius is the
setf-Able function.
As an alternative to using @writer:
● Make the @reader into a setf-Able place.
● Prepend setf_ onto the name of the @reader function.
● Create a method specializing on the second argument.
Now (circle_radius), the @reader function, is setf-Able.
152
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
152
This document is for the sole use of Firuz Shomahmadov of Nxp
Slot Access Using setf-Able Function (continued)
● Set the values of C1 and C2.
C1 = (makeInstance 'Circle ?r 14.0)
(circle_radius C1)
→ 14.0
C2 = (makeInstance 'Circle ?r 1.0)
(circle_radius C2)
→ 1.0
● You can also change the C1 value using the setf function.
(setf (circle_radius C1) 12.0)
(circle_radius C1)
→ 12.0
153
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
153
This document is for the sole use of Firuz Shomahmadov of Nxp
Slot Access Also Works with incf, swapf, etc.
(Incf (circle_radius C1))
(circle_radius C1)
→ 13.0
(Swapf (circle_radius C1) (circle_radius C2))
(circle_radius C1)
→ 1.0
(circle_radius C2)
→ 13.0
(decf (circle_radius C1))
→ *ERROR* circle does not support non-positive radius: 0.0
154
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
154
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Summary
In this module, you
● Used @before, @after, and @around methods
● Identified the order of execution of these methods
● Illustrated the use of accessor methods
155
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
155
This document is for the sole use of Firuz Shomahmadov of Nxp
Labs
Lab 12-1 Using the @before and @after Methods in SKILL++ Code
Lab 12-2 Using Lazy Slots
156
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
156
This document is for the sole use of Firuz Shomahmadov of Nxp
Introduction to Macros
Module
13
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
30 minutes
● Lab
30 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
157
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Identify the instances of macro creation
● Use macros in SKILL® code
● Implement simple macros
● Create and debug more complex macros
● Examine argument evaluation and return values
158
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
158
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is a Macro?
A macro is a function that allows you to
adapt the normal SKILL function call
syntax to the needs of your
application.
Characteristics:
To define a macro in SKILL, use defmacro.
Example
If you want to check the value of a variable to be a string
before calling printf and you don’t want to write the code
to perform the check at every place where printf is
called, you might consider writing a macro:
● A macro is a code that writes additional code.
▪
Return value is a SKILL or SKILL++ expression.
● Macros help as powerful extensions to the language.
▪
Capable beyond C++ macros.
● Macros are evaluated on first execution.
▪
Code is embedded in the calling procedure.
● The SKILL macros can be used in various situations:
159
▪
To gain speed by replacing function calls with in-line code.
▪
To expand constant expressions for readability.
▪
As convenience wrappers on top of existing functions.
(defmacro myPrintf (arg) `when((stringp ,arg)
printf( "%s" ,arg)))
As you can see, the macro myPrintf returns an
expression constructed using backquote, which is
substituted for the call to myPrintf at the time a function
calling myPrintf is defined.
© Cadence Design Systems, Inc. All rights reserved.
Macros are an integral part of SKILL, useful for extending the language in ways that are not supported
in C-based languages. A macro is a program that returns a SKILL expression embedded in the program
that calls the macro when the program is defined.
© Cadence Design Systems, Inc. All rights reserved.
159
This document is for the sole use of Firuz Shomahmadov of Nxp
Importance of Using Macro in Your Program
● Minimize repeated coding:
● Do things you cannot do in a procedure
▪ The for loop in SKILL allows only to increment by a
value of 1.
▪ To increment by a value other than 1, you need a
while loop.
▪ Non-evaluated (or multiply evaluated) arguments
▪ until( sqrt(x)>20 x++ y--)
● Create domain-specific languages
▪ So, in this case, a macro would allow you to use
enhanced for loop syntax (like C).
▪ Target design-specific problems
(defmacro TrCFor (initExpr testExpr
incrExpr @rest bodyExprs)
`(progn
,initExpr
(while ,testExpr
,@bodyExprs
,incrExpr
; user specified
increment
)))
Use it as: TrCFor( i=1
b=i*i println(b) )
=> prints 1 9 25 49 81
160
i<10
i=i+2
© Cadence Design Systems, Inc. All rights reserved.
There are many reasons to use macros. Simple macros can make the source code clearer; using a macro
urY to return the upper right Y value of a bounding box is easier to understand than using cadadr.
Because it is a macro, there is no overhead as you would get with procedure calls. Macros can replace
repeated code; the macro almostEq compares two floating point numbers and returns t if they are within
a small fraction of each other. A macro like trTransformPoints expands into a series of commands that
transforms the points in a pointList rather than calling a function with its overhead, including copying
the pointList to the program stack and returning the modified list; the pointList is modified in-line.
There are some things you cannot do in a procedure that can only be done in a macro. Procedure calls
always interpret their arguments; macros do not.
Macros make it very easy to create domain-specific languages. These languages simplify solving
problems within a fixed problem domain. An example of a domain-specific language would be a
language tailored to creating pcell and CDF parameters. This is a very advanced topic that is not part of
this training course.
For more on domain-specific languages:
http://en.wikipedia.org/wiki/Domainspecific_language
http://www.c2.com/cgi/wiki?DomainSpecificLanguage
© Cadence Design Systems, Inc. All rights reserved.
160
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is the Use of SKILL Programs?
The SKILL programs are the SKILL data because the commands that are evaluated are lists.
● SKILL is made up of list-based expressions.
▪ Lists of symbols, numbers, arrays, strings, etc.
● The SKILL expressions are lists where:
sstatus( printinfix nil )
'( x + y + z)

(plus x y z)
▪ The first element is the function to evaluate.
car( '( x + y + z))
▪ The other elements are the arguments to that
command.

plus
equal( list( 'difference 'x 'y 'z)
'(x – y – z))

161
t
© Cadence Design Systems, Inc. All rights reserved.
SKILL commands are actually lists that are evaluated. The first element in the list is the function to
evaluate, the other elements are the arguments to that command. A command evaluation can be built up
as just such a list.
© Cadence Design Systems, Inc. All rights reserved.
161
This document is for the sole use of Firuz Shomahmadov of Nxp
How to Write a Function That Returns a Program (Macro)
The function which returns a closure
with its own variable and named
function is called a Macro. Treating
functions as data allows creative
solutions.
Let us write a function that will write functions
like Count:
/* Or use backquote ` with , for evaluation. This
approach provides a more readable macro as it more
closely resembles the final SKILL code. */
Approach 2:
defun( WriteCount (name starting_num)
‘( let ((count ,starting_num) )
and_so_on))
Approach 1:
defun( WriteCount (name starting_num)
list( 'let list(
WriteCount( 'Count 0)
 (let ((count 0)) and_so_on)
list( 'count
starting_num))'and_so_on))
162
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
162
This document is for the sole use of Firuz Shomahmadov of Nxp
How to Write a Function That Returns a Program (Macro)
Approach 2
Continuing to write the function, we define the increment function Count.
● The old placeholder has been replaced with a function definition that takes the name based on the WriteCount argument.
● To further fill in the functionality, we have to find the API for incrementing the value; it is postincrement.
defun( WriteCount (name starting_num)
`(let ( ( count ,starting_num))
( defglobalfun ,name nil
count_plus_plus)))
WriteCount( 'Count 0)
 (let ((count 0))
(defglobalfun Count ()
count_plus_plus)))
'( count++ )
(postincrement count)
163
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
163
This document is for the sole use of Firuz Shomahmadov of Nxp
How to Write a Function That Returns a Program (Macro)
Approach 2 (continued)
Now we can finish the WriteCount function.
● This function creates a closure with a named function and a starting count.
● Executing the named function increments the closure variable.
WriteCount('Count 0)
(let ((count 0))
(defglobalfun Count ()
(postincrement count)))
eval( WriteCount('Count 10) theEnvironment() )
Count
list( Count() Count() Count())
(10 11 12)
164
© Cadence Design Systems, Inc. All rights reserved.
How would you create another counter closure named Counter2 that starts at 7?
© Cadence Design Systems, Inc. All rights reserved.
164
This document is for the sole use of Firuz Shomahmadov of Nxp
Write a Macro by Using defmacro
defmacro( s_macroName (
l_formalArglist )
g_expr1 ... )
=> s_macroName
(defmacro DefineCounter (funName initialCount)
‘(let ((count ,initialCount))
(defglobalfun ,funName ()
(++count))))
 DefineCounter
When we use the defmacro function it:
● Takes pieces of a program as input.
DefineCounter(Count10 10)
● Returns pieces of a program as output.
 Count10
The output gets used in place of the "macro call".
Count10()
This replacement happens when the SKILL code is
first executed:
 11
● Really at "macro-expansion time".
Count10()
● For most purposes, this is when the file is loaded.
 12
● Changing the macro means reloading not just the
macro but also the functions that use the macro.
Note: Use `backquote for the list and var to evaluate
funName and initialCount.
165
© Cadence Design Systems, Inc. All rights reserved.
Macros in SKILL are a standard way of writing programs that write functions. Like the WriteCount
function, they return the code that is then inserted in the calling function in place of the macro call. This
insertion occurs when the file is loaded; all macros are expanded at load time. This means that once a
function that calls a macro is loaded, the macro is expanded, and changing the macro will not affect the
function. You have to reload the function after you have loaded the new macro definition so it can be
expanded again.
We will use the same code in the macro to create counters.
© Cadence Design Systems, Inc. All rights reserved.
165
This document is for the sole use of Firuz Shomahmadov of Nxp
Bug in First Macro
Bug: Count10 starts counting at 11.
What do we do now?
● Let us look at the program DefineCounter created.
● Sometimes, it’s useful to set printinfix.
(sstatus printinfix t)
 t
(expandMacro '(DefineCounter Count10 10))
 let( ((count 10))
defglobalfun( Count10 ()
++count
))
166
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
166
This document is for the sole use of Firuz Shomahmadov of Nxp
Arguments and Return Values of Macros
● Macros can compute anything from their arguments.
▪ "Arguments" are pieces of source code.
▪ Some code can be executed in the macro.
● Return value is code that is evaluated.
(defmacro Macro1 (var @key n @rest forms)
(printf "Var is %L, n is %L, forms %L\n“ var n forms)
`(for ,var ,n (random 65535) ,@forms)
Return value
Executed
code
)
(Macro1 x ?n 1
(printf "X is %d\n" x))
;; Var is x, n is 1,forms ((printf "X is %d\n" x))
;; X is 1
;; X is 2
 t
167
© Cadence Design Systems, Inc. All rights reserved.
Macros may be easier to visualize using Lisp syntax as the first element in a list is a function, and all the
other elements are arguments.
Code not quoted is evaluated in the macro; the return value is quoted, so it is not evaluated but returned.
If the macro call is in a function, the returned code is inserted into the function. In this case, the macro is
evaluated at the top level, so the code is evaluated immediately.
© Cadence Design Systems, Inc. All rights reserved.
167
This document is for the sole use of Firuz Shomahmadov of Nxp
Selectively Evaluate Arguments in Macros
● All arguments are not evaluated.
● Use backquote, comma, and comma-at to selectively evaluate arguments.
(defmacro Macro1 (var @key n @rest forms)
(printf "Var is %L, n is %L, forms %L\n“ ) var n forms )
`(for ,var ,n (random 65535) ,@forms)
Unevaluated arguments
Evaluated arguments
)
(Macro1 x ?n 1 (printf "X is %d\n" x))
;; Var is x, n is 1, forms ((printf "X is %d\n" x))
;; X is 1
;; X is 2
 t
168
© Cadence Design Systems, Inc. All rights reserved.
Macros may be easier to visualize using Lisp syntax as the first element in a list is a function, and all the
other elements are arguments. The comma and comma-at inside the back quoted list cause the
arguments to be evaluated.
© Cadence Design Systems, Inc. All rights reserved.
168
This document is for the sole use of Firuz Shomahmadov of Nxp
Function Calls as Arguments in Macros
● Function calls can be passed in as arguments.
● Comma-at evaluates the function call.
(defmacro Macro1 (var @key n @rest forms)
(printf "Var is %L, n is %L, forms %L\n"
var n forms)
`(for ,var ,n (random 65535),@forms)
)
(Macro1 x ?n 1 (printf "X is %d\n" x) )
;; Var is x, n is 1, forms ((printf "X is %d\n" x))
;; X is 1
;; X is 2
 t
169
© Cadence Design Systems, Inc. All rights reserved.
The function call to (printf "") is passed as a list to the macro. Inside the macro, it is interpreted in the
back quoted list using the @comma-at.
© Cadence Design Systems, Inc. All rights reserved.
169
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Summary
In this module, you
● Identified the instances of macro creation
● Used macros in SKILL code
● Implemented simple macros
● Created and analyzed more complex macros
● Examined argument evaluation and return values
170
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
170
This document is for the sole use of Firuz Shomahmadov of Nxp
Labs
Lab 13-1 Implementing SKILL Code with Macros
Lab 13-2 Implementing Macros and Defclass
171
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
171
This document is for the sole use of Firuz Shomahmadov of Nxp
Local Functions
Module
14
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
30 minutes
● Lab
30 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
172
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Identify the usage of local function
● Implement the flet function in a code to define a local function
● Examine the use of labels for recursion
173
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
173
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is a Local Function?
The function in which the scope of each variable is limited to that function only is called a
local function.
● Functions defined within a lexical scope.
▪ Function is only usable within the containing let().
▪ Function can access variables within the lexical scope.
● Create special function for use within the scope of the current function.
flet
Local function able to call global function with the same name
labels
Local function that can be recursive
procedure or defun
Local declaration within the lexical scope
flet( ((foo (x) (list x)))(foo 1))
=> (1)
174
© Cadence Design Systems, Inc. All rights reserved.
Local functions are valuable for simplifying your code. A function encapsulates a set of steps and
equations, assigning a name and arguments. The function is called by its name, assigning the values for
the arguments. The steps in the function are executed, and a value is returned. This methodology is
already used, creating procedures in SKILL®. These are global procedures; the name exists in the
global memory space and can be called by any other function or by the user. Sometimes, the set of steps
is specific to the calling function, such as toggling between the "source" and "drain" node in the MOS
device. Instead of creating a global function, a local function can be defined and used within the calling
function. The local function is named, and the name is local to the lexical scope in which the function is
declared. When the function is executed in that scope, that function is executed. Outside the lexical
scope, the name may refer to a global function or to another lexically scoped local function without the
names clashing.
The declarations for local functions are flet, labels, and procedure, or defun can also be used to declare
local functions; they act like the labels declaration.
© Cadence Design Systems, Inc. All rights reserved.
174
This document is for the sole use of Firuz Shomahmadov of Nxp
flet: Local Function Creation
flet((
(local_function_name (arg list)
local…function…expressions
)
)
body…function…expressions
local_function_name( argValue
listValue )
more…body…expressions
)
let((currentNode
(firstNode MyGetVal( device 'firstNode
)))
;; local function to swap the source and drain
flet(( (swapSD( node )
currentNode = if( node == "drain"
then "source"
else "drain" )))
MOSdrawFirstNode( device cvId firstNode
0 leftAbut )
swapSD( firstNode )
for( i 2 fingers
MOSdrawNextNode( device cvId currentNode i)
swapSD( currentNode )
) ; ** for i **
) ; flet
) ; let
● Declares local function and sets the limits of its visibility.
● Function name is not known within its own definition.
▪ A call to the function inside the definition executes the function from the containing lexical scope
(maybe a global function).
175
© Cadence Design Systems, Inc. All rights reserved.
Flet declares functions whose definitions are only available within the body of the flet statement. These
functions encapsulate code that would be reused within the block, simplifying the code. Variables
defined in the scope containing the flet are accessible within the local functions. The local functions are
created in the same manner as global functions, with argument lists that can include @optional or @key
optional arguments as well as @rest to capture extra arguments passed in. The body of the local function
can be enclosed by let or prog block style statements, and the function will return the value of the last
statement executed (excepting prog1 or prog2 blocks).
In this example, a local function, swapSD, is created to swap the value of the variable currentNode
between "source" and "drain". Note that the variable currentNode is used in the local function; since the
function and the variable are defined within the same scope, the function can access the variable.
The set of statements to swap the values is used in more than one place in the containing procedure;
encapsulating them into a local function simplifies the code and makes the function easier to debug.
© Cadence Design Systems, Inc. All rights reserved.
175
This document is for the sole use of Firuz Shomahmadov of Nxp
flet: Calling Global Functions
● A local function defined within a flet cannot call itself.
● Executing the function name within the local function calls the global function.
● Use the local function to compute arguments for the global function.
flet( ((dbMoveFig ( listOfFigs cvId transform )
unless( listp(listOfFigs)
listOfFigs = ncons(listOfFigs))
foreach( fig listOfFigs
;; call to global function
dbMoveFig( fig cvId transform ))
))
…
)
176
© Cadence Design Systems, Inc. All rights reserved.
The local function defined within a flet cannot be recursive; it cannot call itself. If the function name is
executed, it will execute the global function of the same name (or generate an error if the global
function does not exist). The local function can manipulate the arguments for the global function and
then call the global function. The example local function modifies the local call to dbMoveFig to take a
list of figures instead of a single figure.
© Cadence Design Systems, Inc. All rights reserved.
176
This document is for the sole use of Firuz Shomahmadov of Nxp
labels: Recursive Local Functions
(labels (
(local_function_name (arg list)
local…function…expressions
labels( ((getPropInfo (prop)
list( prop~>name
prop~>valueType
prop~>value ))
(getPropInfoList (propList)
sortcar(
mapcar( getPropInfo propList )
‘alphalessp)
)
)
local_function_name( arg1 list1)
)
)
body…function…expressions
local_function_name( argValue
listValue )
more…body…expressions
)
let(((sel geGetSelectedSet()))
getPropInfoList(sel~>master~>parameters
~>value)
) ; ** let **
) ; ** labels **
● Labels create named local functions like flet.
● Functions created inside labels can call themselves.
● The local function has no access to the same named global function.
177
© Cadence Design Systems, Inc. All rights reserved.
The labels statement creates local functions that are callable within the lexical scope in which they were
defined, just like flet. The difference between flet and labels is that the function defined in labels can
call itself. In a flet-defined function, the call to the same function name executes the global version of
that function if that exists. The labels defined function will call itself.
This example uses labels to declare two local functions, getPropInfo and getPropInfoList. They were
declared with labels because getPropInfoList calls getPropInfo inside the lambda.
© Cadence Design Systems, Inc. All rights reserved.
177
This document is for the sole use of Firuz Shomahmadov of Nxp
procedure: Declared Local Functions
● This is the same as the previous example but implemented using the procedure to define the local
functions. It may be easier to understand when written this way; there is no difference in
performance.
let((sel)
procedure(getPropInfo(prop)
list( prop~>name
prop~>valueType
prop~>value)
)
procedure(getPropInfoList(propList)
sortcar( mapcar( getPropInfo propList)
alphalessp)
)
sel = geGetSelectedSet()
getPropInfoList( sel~>master~>parameters~>value)
) ; ** let **
178
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
178
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Summary
In this module, you
● Identified local function usage
● Implemented flet function to define a local function
● Examined the use of labels and procedure functions for recursion
179
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
179
This document is for the sole use of Firuz Shomahmadov of Nxp
Lab
Lab 14-1 Implementing Local Functions in the SKILL Programs
180
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
180
This document is for the sole use of Firuz Shomahmadov of Nxp
Packages
Module
15
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
15 minutes
● Lab
15 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
181
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Identify package contents
● Define the package
● Define and implement stack package in SKILL++
182
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
182
This document is for the sole use of Firuz Shomahmadov of Nxp
What Are Packages?
A package is a collection of functions
and data.
● SKILL++ facilitates two approaches to packages.
▪ It can explicitly represent the package as a collection of
function objects and data.
o Different packages can have functions with the same name.
● Functions within a package share private data
and private functions that are not accessible
outside the package.
● A package hides the implementation details from
the client application.
o Clients use the arrow(->) operator to retrieve the package
functions.
▪ You can reimplement a collection of SKILL® functions as
a SKILL++ package.
o Because informal SKILL packages have no opportunity to
hide private functions or data.
▪ Interface to the package is through the package
programming interface.
Notes: You can reimplement a collection of SKILL functions
as a SKILL++ package because informal SKILL packages
have no opportunity to hide private functions or data.
183
© Cadence Design Systems, Inc. All rights reserved.
A package is a group of functions and data that provide a programming interface to client applications.
The package is self-contained, hiding the implementation details from the client applications. The
package supplies procedures to access the data in the package. The data in a package is hidden and
usually only accessible through the programming interface provided by the public functions in the
package. The package may include helper functions that are private and can only be executed by the
public functions of the package.
© Cadence Design Systems, Inc. All rights reserved.
183
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Implementing SKILL++ Stack Package
The local variable contents is a shared private lexically scoped variable.
procedure( TrMakeStack(@key initialContents)
let( (( contents initialContents ))
procedure( popStack( )
let( (( v car( contents )))
The local variable,
contents, is a shared
private lexically scoped
variable.
contents = cdr( contents )
v))
Local Functions
procedure( pushStack( value )
contents = cons( value contents )
value)
list(nil
'pop
popStack
'push pushStack
)))
184
pop and push are
returned and access the
local functions.
© Cadence Design Systems, Inc. All rights reserved.
The stack package declares a local variable named contents. Two local functions are declared: push and
pop. They are exported in the disembodied property list return value.
© Cadence Design Systems, Inc. All rights reserved.
184
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Implementing SKILL++ Stack Package (continued)
● Independent stacks can be created using TrMakeStack.
● Each manages its own contents.
stack1 = TrMakeStack( ?initialContents list( 1 2 3 4 5))
stack1->pop() => 1
stack1->push( 7 ) => contents now: (7 2 3 4 5)
185
© Cadence Design Systems, Inc. All rights reserved.
The function TrMakeStack creates a new instance of the stack. The variable contents are local to the
stack as push and pop functions. The functions are evaluated using the variable holding the stack
definition returned by TrMakeStack.
© Cadence Design Systems, Inc. All rights reserved.
185
This document is for the sole use of Firuz Shomahmadov of Nxp
Labs
Lab 15-1 Implementing a Simple Counter Data Type in the SKILL Language
Lab 15-2 Implementing a SKILL++ Counter Data Type
Lab 15-3 Re-Implementing the Counter Data Type (Optional)
186
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
186
This document is for the sole use of Firuz Shomahmadov of Nxp
Indirect Function Calls
Module
16
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
30 minutes
● Lab
30 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
187
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Analyze indirect function calls with apply and funcall statements
● Create anonymous functions using the lambda function
● Use anonymous functions with sort and mapping functions
188
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
188
This document is for the sole use of Firuz Shomahmadov of Nxp
apply: Evaluate a Function on a List of Arguments
apply(slu_func [g_arg..] l_args)
=> g_result
The apply function applies the given function to the given arguments.
● apply takes two or more arguments.
● The first argument should be a function or an object name or list containing lambda/nlambda expression.
● The last argument to apply must always be a list.
Example
apply(plus (list 1 2))
; Apply plus to its argument
=> 3
189
© Cadence Design Systems, Inc. All rights reserved.
The apply function is used to evaluate a function on a list of arguments; it is useful for evaluating
lambda functions or named functions. The list of arguments are assigned to the argument list of the
function, with keyed or optional arguments mapped to the keyed arguments of the function. The last
element in the list must be a list.
© Cadence Design Systems, Inc. All rights reserved.
189
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Evaluate a Function on a List of Arguments
procedure( sumTail(1) apply(plus cdr(1)))
=> sumTail
; Define a procedure
sumTail( ‘(1 2 3)
=> 5
setOfNumbers = '(1 2 5 -2 3 9 18 -7 0)
sum = apply(plus setOfNumbers)
=> 29
theMin = apply(min setOfNumbers) => -7
theMax = apply(max setOfNumbers) => 18
Note: In SKILL® mode, call apply with a quoted function
name.
sum = apply(‘plus setOfNumbers)
190
© Cadence Design Systems, Inc. All rights reserved.
The sort commands iterate over a list and use a comparison function to compare each element in the list
two at a time. The comparison function takes two arguments and returns t if they are in the proper order
or nil if they are not. In the example, the function is an anonymous lambda function that compares the y
values of the two arguments and returns t if the y value of the second point in the list is less than the first
one.
How would you write a lambda sort that sorts by X and Y, where the results are sorted by the X
coordinate and, if they are equal, are sorted by the Y coordinate?
© Cadence Design Systems, Inc. All rights reserved.
190
This document is for the sole use of Firuz Shomahmadov of Nxp
funcall: Evaluating a Function
funcall(slu_func [arg……])
=> g_result
The funcall function calls a function with the set of given arguments.
● This function is similar to the apply function.
● The first argument should be a function or an object name or lambda/nlambda expression.
● The rest of the arguments are to be passed to the slu_func.
● If the slu_func is a lambda function, then:
▪ The length of the arg should match the number of formal arguments unless keywords or optional arguments exist.
▪ The arg is bound directly to the single formal parameter of the function.
Example
funcall(plus 1 2)
; Apply plus to its argument
=> 3
191
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
191
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Creating Match and Iterator Functions Using funcall
Here we create our own Match and Iterator functions.
;; Match function
procedure( TrShapeMatches( shapeId )
shapeId~>layerName == "metal1" &&
shapeId~>objType == "rect"
)
;; Iterator function
procedure(TrIterator(cv matchFunc moveOrCopyFunc
@optional (transform '((0 0) "R0" 1)))
foreach( mapcan shape cv~>shapes
when( funcall(matchFunc shape)
list( funcall(moveOrCopyFunc shape cv transform))
) ; when
) ; foreach
) ; procedure
192
© Cadence Design Systems, Inc. All rights reserved.
We will use these two functions next.
© Cadence Design Systems, Inc. All rights reserved.
192
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Using TrIterator with TrShapeMatches and dbCopyFig
; Create a cellview with several shapes on several layers
cv = dbOpenCellViewByType( "master" "copytest" "layout" "maskLayout" "w")
dbCreateRect( cv "metal1" list(0:0 10:10)) ; create a rectangle on metal1
dbCreateRect( cv "metal2" list(20:0 30:10)) ; create a rectangle on metal2
dbCreatePath( cv "metal1" list(0:0 20:0 20:30) 1.0) ; create a path on metal1
; Query the data – there should be three shapes in the cellview
foreach( mapcar shape cv~>shapes
list( shape~>layerName shape~>objType ))
=> (("metal1" "rect")
("metal2" "rect")
("metal1" "path"))
; Copy the metal1 rectangles (see TrShapeMatches on prior slide)
; This will copy just the one metal1 rectangle shape that matches in this case
TrIterator( cv ‘TrShapeMatches ‘dbCopyFig) => (db:0x16fed11d)
; Query again - there should now be four shapes in the cellview including two metal1 shapes. Examine the
bBox for each to see they have the same coordinates
foreach( mapcar shape cv~>shapes
list( shape~>layerName shape~>objType shape~>bBox))
=> (("metal1" "rect" ( (0.0 0.0)
(10.0 10.0) ))
("metal2" "rect“ ( (20.0 0.0) (30.0 10.0) ))
("metal1" "path" ( (0.0 -0.5) (20.5 30.0) ))
("metal1" "rect" ( (0.0 0.0)
(10.0 10.0) )))
193
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
193
This document is for the sole use of Firuz Shomahmadov of Nxp
lambda: Creating Anonymous Functions
lambda((s_formalArgument) g_expr1……) or (lambda(s_formalArgument) g_expr1……)
=> U_result
The lambda creates a function object.
● (lambda((x y) x + y ) 5 6)
● lambda is the constructor for a function.
● trAddWithMessageFun = lambda((x y)
=> 11
● Declares unnamed function object.
printf(“Adding %d and %d = %d\n” x y x+y)
● It can be used for immediate use, like
x+y
▪ Sort functions
)
▪ Mapping functions
=> funobj:0x1814b90
● Function object can be saved in variables.
● apply( trAddWithMessageFun ‘(4 5))
=> 9
● Can pass into other functions.
194
© Cadence Design Systems, Inc. All rights reserved.
Lambda declares an unnamed function. These functions are useful for immediate use, such as in map or
sorting functions. The function object can be saved in a variable and executed using apply or funcall.
© Cadence Design Systems, Inc. All rights reserved.
194
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Sorting Using lambda Functions
● Sort command iterate over a list.
● It uses comparison to compare two elements at a time.
▪ Returns t, if the elements are in order.
▪ Returns nil, if they are not in order.
● Sort points by Y.
sort( pointList
lambda( ( p1 p2) yCoord(p1) < yCoord(p2))
Sort comparison function
lambda( ( p1 p2) yCoord(p1) < yCoord(p2))
Arguments
195
Body
© Cadence Design Systems, Inc. All rights reserved.
The sort commands iterate over a list and use a comparison function to compare each element in the list
two at a time. The comparison function takes two arguments and returns t if they are in the proper order
or nil if they are not. In the example, the function is an anonymous lambda function that compares the y
values of the two arguments and returns t if the y value of the second point in the list is less than the first
one.
How would you write a lambda sort that sorts by X and Y, where the results are sorted by the X
coordinate and, if they are equal, are sorted by the Y coordinate?
© Cadence Design Systems, Inc. All rights reserved.
195
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Mapping Across a List Using lambda Function
● mapcar evaluates the function over a list.
● The function is applied to each element in the list.
● The return value is determined by the mapping function.
newPtList = mapcar(
lambda(( xy )
dbTransformPoint( xy transform ))
pointList )
lambda
list
● Equivalent foreach( mapcar… expression)
newPtList = foreach( mapcar xy pointList
dbTransformPoint( xy transform ))
196
© Cadence Design Systems, Inc. All rights reserved.
The map functions in SKILL are map, mapc, mapcan, mapcar, and maplist. These are non-destructive
mapping functions that apply a function to each element in a list. They can be used with fo reach but are
faster used standalone. The lambda function is useful for creating the processing function. The example
function iterates over the list of points and applies dbTransformPoint to each point. The transform is a
variable set outside the mapcar call.
To see the difference between using mapcar and foreach, measure the time each iterates over a large list
of data using the function measureTime.
© Cadence Design Systems, Inc. All rights reserved.
196
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: lambda Functions as Variables
● lambda functions can be stored in variables.
● apply or funcall can be used to execute the function.
● The function can be passed in as an argument to a procedure.
hypt = (lambda (x y) (sqrt (x*x + y*y)))
apply(hypt '(2 8))
funcall(hypt 2 8)
Both in SKILL and SKILL++ mode
or
hypt(2 8)
197
Only in SKILL++ mode
© Cadence Design Systems, Inc. All rights reserved.
The function object created by lambda can be stored in a variable. This variable can be used as any
other variable; it can be passed into another function. Use apply or funcall to evaluate the function.
© Cadence Design Systems, Inc. All rights reserved.
197
This document is for the sole use of Firuz Shomahmadov of Nxp
Mapping Functions: Mapping for Side Effect (mapc/map)
mapc( u_func l_arg1 [l_arg2…])
map( u_func l_arg1 [l_arg2…])
=> l_arg1
=> l_arg1
● Primarily used with the u_func, which has side effects.
● This function does not preserve the values returned by
this function.
● Applies the given function to successive sub lists of the
argument lists.
● Returns the first argument list.
● Generally used for side effects, not for the return value.
● Returns the first argument list.
● Not same as standard Scheme map function.
u_func
Function to apply the argument lists
u_func
u_arg1
Function to apply successive sub lists
Argument list
u_arg2
u_arg1
Argument list
Additional argument list (length same as
u_arg1)
u_arg2
l_arg1
Additional argument list (length same as
u_arg1)
The first argument list
l_arg1
The first argument list
Note: See the notes section for examples.
198
© Cadence Design Systems, Inc. All rights reserved.
Examples for mapc and map functions:
mapc:
mapc( '(lambda (x y) (print (list x y))) '(1 2 3) '(9 8 7) )
=> (1 9) (2 8) (3 7) ; prints three lists as side effects
(1 2 3)
; actual return value
mapc( lambda((@rest args) println(args)) '(4 3 5) '(6 7 6) '(1 2 3))
=>(4 6 1)
(3 7 2)
(4 6 3)
; the three lists are side effects
(4 3 4)
; actual return value
map:
map( '(lambda (x y) (print (append x y))) '(1 2 3) '(9 8 7) )
=> (1 2 3 9 8 7) (2 3 8 7) (3 7)
; the three lists are side effects
(1 2 3)
; actual return value
map( lambda((@rest args) println(args)) '(4 3 5) '(6 7 6) '(1 2 3))
=> ((4 3 4) (6 7 6) (1 2 3))
((3 4) (7 6) (2 3))
((4) (6) (3))
; the three lists are side effects
(4 3 5)
; actual return value
© Cadence Design Systems, Inc. All rights reserved.
198
This document is for the sole use of Firuz Shomahmadov of Nxp
Mapping Functions: Mapping for Accumulation (mapcar/maplist)
mapcar( u_func l_arg1 [l_arg2…])
maplist( u_func l_arg1 [l_arg2…])
=> l_result
=> l_result
● Applies the u_func to the successive elements of the
argument list.
● Applies the given function to successive sub lists of the
argument lists.
● Returned values are put into a list.
● Returns a list of the corresponding results.
● If argument lengths are different, mapcar iterates till the
end of the shortest list.
● The returned values of the successive function calls are
concatenated using the list function.
u_func
Function to apply the argument lists
u_func
u_arg1
Function to apply the argument lists
Argument list
u_arg1
u_arg2
Argument list
Additional argument list
u_arg2
l_arg1
Additional argument list (length same as u_arg1)
List of results from applying to successive
elements of the argument list
l_arg1
The first argument list
mapcar( ‘plus ‘(4 3 5 7) ‘(6 7 6))
 (10 10 11)
mapcar( evenp ‘(4 3 5 7))
 (t nil nil nil)
199
maplist( ‘list ‘(2 3 4) ‘(8 7 6))
 (((2 3 4) (8 7 6)) ((3 4) (7 6)) ((4) (6)))
maplist( copy ‘(4 3 5 7))
 ((4 3 5 7) (3 5 7) (5 7) (7))
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
199
This document is for the sole use of Firuz Shomahmadov of Nxp
Mapping Functions: Mapping for Concatenation (mapcan/mapcon)
mapcan( u_func l_arg1 [l_arg2…])
mapcon( u_func l_arg1 [l_arg2…])
=> l_result
=> l_result
● The first argument must designate a function that returns
a list.
● The first argument must designate a function that returns
a list.
● The lists are concatenated as if by nconc.
● The lists are concatenated as if by nconc.
● mapcan example:
● mapcon example:
u_func
Function to apply the argument lists
u_func
Function to apply the argument lists
u_arg1
Argument list
u_arg1
Argument list
u_arg2
Additional argument list (length same as u_arg1)
u_arg2
Additional argument list (length same as u_arg1)
l_arg1
List consisting of concatenated results
l_arg1
The first argument list
mapcan(( lambda (x) (println x) (list x x))
'(1 2 3))
;; prints the following
1
2
3
Returns → (1 1 2 2 3 3)
200
mapcon((lambda (x) (println x) (copy (cdr
x)))
'(1 2 3))
;; prints the following
(1 2 3)
(2 3)
(3)
Returns → (2 3 3)
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
200
This document is for the sole use of Firuz Shomahmadov of Nxp
Mapping Functions with Multiple Arguments
● The mapping functions are usually called with exactly two arguments.
▪ An iteration function.
▪ A list of values to pass iteratively to that function.
● Any mapping function may be called with multiple arguments.
● Mapping function will iterate until the shortest list is exhausted.
(mapc (lambda (@rest x) (println x))
'(1 2 3) '(x y z) '(10 20 30 40 50))
;; prints the following
(1 x 10)
(2 y 20)
(3 z 30)
201
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
201
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Summary
In this module, you
● Analyzed different functions, including:
▪ apply/funcall
▪ lambda
▪ mapc
▪ mapcar
▪ mapcon
● Implemented SKILL code using the above-listed functions for creating your own iteration and matching
procedures
● Implemented anonymous functions with sort and mapping functions
202
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
202
This document is for the sole use of Firuz Shomahmadov of Nxp
Labs
Lab 16-1 Creating Extended Built-In Functions: Rod and Hi
Lab 16-2 Implementing the mapappend Function
Lab 16-3 Implementing Flatten and Deep-Copy
203
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
203
This document is for the sole use of Firuz Shomahmadov of Nxp
Initializing Objects
Module
17
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
15 minutes
● Lab
30 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
204
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objective
In this module, you
● Create an instance of a class by using:
▪ makeInstance function
▪ initializeInstance @after method (for more flexibility in creating instances)
205
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
205
This document is for the sole use of Firuz Shomahmadov of Nxp
What a makeInstance Function Does
The makeInstance function creates an instance of a class.
● makeInstance
▪ Makes a new object of that class
▪ Initializes the instance's slots by calling the
initializeInstance method internally on the
class
o Assigns the slot values using @initform and
@initarg values
us_class
Class object or a symbol denoting a class
object. The class must be either
standardObject or a subclass of
standardObject.
u_?initArg1 value1
u_?initArg2 value2
The symbol u_initArg1 is specified in one of
the slot specifiers in the defclass declaration
of either us_class or a superclass of
us_class. value1 is the initial value for that
slot. Similarly for the pair u_initArg2 value2
and so forth.
g_instance
The instance which is created. The print
representation of the instance resembles
stdobj:xxxx, where xxxx is a hexadecimal
number.
▪ Returns the initialized instance
● makeInstance syntax:
makeInstance(
us_class
[ u_?initArg1
[ u_?initArg2
)
=> g_instance
206
value1 ]
value2 ] ...
© Cadence Design Systems, Inc. All rights reserved.
Objects are instances of classes. makeInstance creates an instance of a class by allocating the object and
initializing the slots on the instance with the values assigned to the @initform and @initarg for the slots.
The slot initialization is executed by calling the initializeInstance method on the pre-allocated instance.
This method can be overwritten or enhanced for the class to initialize the slots with more complex data
structures.
To create an empty instance where the slots are not initialized, use allocateInstance.
© Cadence Design Systems, Inc. All rights reserved.
206
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: makeInstance
defclass( Circle ( GeometricObject )
(( center @initarg c ) ( radius @initarg r )) ) => t
P = makeInstance( 'Point ?name "P" ?x 3 ?y 4 )
=> stdobj:0x1d003c
C = makeInstance( 'Circle ?c P ?r 5.0 )
=> stdobj:0x1d0048
makeInstance( 'fixnum )
*Error* unknown: non-instantiable class - fixnum
Note: When the slot initialization depends on other slots, we use initializeInstance @after methods
207
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
207
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is an initializeInstance @after Method?
An initializeInstance @after method is a class-specific initialization method.
● When an instance of the class is initialized, the
initializeInstance @after method is called.
Characteristics of initializeInstance @after
Method:
● This is the object constructor function for a class.
● Complex slot value calculations
● Self-referential slot setup
Syntax:
(defmethod initializeInstance @after
((self designLib ) @rest initargs )
… )
▪ Get values from other slots
● Additional processing on input arguments
● Interface with other data
▪ Read data from disk
● Create or modify related data
▪ Create a library or cell
208
© Cadence Design Systems, Inc. All rights reserved.
Create class-specific initialization methods by creating an initalizeInstance method for the class. This
method is called when an instance of the class is initialized. If the method is defined as a primary
method, it is more specific than the default primary method and will be called on an instance that
contains uninitialized slots. The default value for the slot, specified by the @initform for the slot, will
not be assigned without the user method executing callNextMethod. Any @initarg passed into the call to
initializeInstance will be assigned to the proper slot.
Another methodology for initializing the instance is to create an @after method rather than the primary
method. The default primary method will execute initializing the @initarg and @initform slots; then,
the class-specific initialize method will execute after the completion of all the primary methods.
© Cadence Design Systems, Inc. All rights reserved.
208
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: initializeInstance @after Method
Example 1: Pass the newly created object as the first argument.
(defmethod initializeInstance @after
((curInst library ) @rest initargs )
ddCreateLib( getLibName( curInst ) getPath( curInst ) )
)
Example 2: Set the value of a slot based on an existing slot value.
(defmethod initializeInstance @after
((curInst designLib) @rest initargs )
setProject( TRprojectLookup( getLibName( curInst )))
)
209
© Cadence Design Systems, Inc. All rights reserved.
The initializeInstance is executed after the object is created. Any @initarg arguments are used to
initialize the slots before calling the initializeInstance method. The initial values for the slots may be set
depending on whether the generic primary function is executed. This may be done by directly setting the
initial value, using callNextMethod if there are overriding primary methods, or by writing @after
methods. The initial values set with @initform are not available if the initializeInstance method is an
@before method.
© Cadence Design Systems, Inc. All rights reserved.
209
This document is for the sole use of Firuz Shomahmadov of Nxp
Initializing Objects Summary
● Simple instance initialization can be done using the slot descriptors:
▪ @initform
▪ @initarg
● More complex initialization should be done with initializeInstance @after, for example:
▪ Slot initialization which depends on the order of slots initialized.
▪ Slots that depend on other slots.
210
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
210
This document is for the sole use of Firuz Shomahmadov of Nxp
Lab
Lab 17-1 Exploring Instance Initialization Examples
211
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
211
This document is for the sole use of Firuz Shomahmadov of Nxp
Multiple Inheritance
Module
18
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
15 minutes
● Lab
15 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
212
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Analyze the mechanics of multiple inheritance
● Create a class that inherits from multiple classes
● Analyze the order of inheritance of classes
● Identify the order of inheritance for slot values
● Plan and develop classes using multiple inheritance
213
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
213
This document is for the sole use of Firuz Shomahmadov of Nxp
Single Versus Multiple Inheritance
Single Inheritance is a feature defined
as when a class inherits from a single
superclass.
● The class hierarchy is built in a linear fashion.
● The subclass inherits slots and methods from only
one superclass.
A
Multiple Inheritance is a feature defined
when a class inherits from multiple
immediate superclasses.
● The subclass inherits the slots and methods from
each of the superclasses.
● It is determined by the order of the subclass
declaration.
B
h
C
214
Super
Classes
Sub Class
© Cadence Design Systems, Inc. All rights reserved.
SKILL++ has always supported single inheritance. Single inheritance means that a class can have only
one superclass. The class hierarchy is built in a linear fashion, with each class inheriting methods and
slots from its direct superclass. Single Inheritance is often the only hierarchy allowed by some
languages.
IC615 supports both single and multiple inheritance. A class with multiple immediate superclasses uses
multiple inheritance. The subclass inherits the slots and methods from each of the superclasses
determined by the order of the subclass declaration.
© Cadence Design Systems, Inc. All rights reserved.
214
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Multiple Class Inheritance
ZZtop
A
defclass( A () (…) )
defclass( B (A) (…) )
defclass( C (B) (…) )
XX
defclass( XX () (…) )
B
ZZ
C
h
designClass
defclass( ZZtop () (…) )
defclass( ZZ (ZZtop)(…) )
defclass(
designClass (C XX ZZ)
(…)
)
instDC = makeInstance( 'designClass )
215
© Cadence Design Systems, Inc. All rights reserved.
Multiple inheritance is created using the same command as single inheritance. The superclasses are
specified as a list.
The order of the list determines the order of inheritance, the most specific and the first class in the
superclass list, and its inherited superclasses. Then the designClass inherits the classes (and their
superclasses) in the order of the list. The instance of designClass inherits all the slots of the superclasses.
© Cadence Design Systems, Inc. All rights reserved.
215
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Multiple Class Inheritance (continued)
ZZtop
A
XX
B
ZZ
C
h
Most Specific
designClass
C
B
A
XX
ZZ
ZZtop
Least Specific
designClass
superclassesOf( classOf( instDC ) )
(Class:designClass class:C class:B class:A
Class:XX class:ZZ class:ZZtop
class:standardObject class:t)
216
© Cadence Design Systems, Inc. All rights reserved.
It initially looks hard to determine the most specific to the least specific inherited classes. This order
determines the initial value of the slots and the order of method evaluation. Use the information
provided by superclassesOf and subclassesOf to determine the graph for the class hierarchy.
The inheritance rule applied to the example is that the first class in the superclasses list is the most
specific, and the classes it inherits from are more specific than the next class in the superclass list. This
continues down the list of superClasses
defclass( designClass
( C XX ZZ )
(…)
)
C is the first superclass; it is the most specific of the superclasses of designClass. The superclasses of C
and their hierarchy are more specific than XX. XX is more specific than ZZ, which is more specific than
ZZtop. The least specific are the built-in standardObject and t classes.
© Cadence Design Systems, Inc. All rights reserved.
216
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Multiple Slot Inheritance
(counter …)
Classes sharing
slot names (counter…)
ZZtop
A
XX
B
(counter …)
ZZ
C
h
● All slots are inherited from all the classes.
● Slot @initargs are merged.
● All reader and writer accessors are usable on the appropriate class.
designClass
● @initform value from the most specific declaration.
217
© Cadence Design Systems, Inc. All rights reserved.
A class inherits the slots from its superclasses. Just like in single inheritance, classes used multiple
inheritance may declare the same slot name. The duplicate slots can be set using any of the @initargs
for that slot; this is very helpful when writing hierarchical initialization methods. The readers and
writers are also usable.
The @initform takes the value from the most specific class that specifies it.
© Cadence Design Systems, Inc. All rights reserved.
217
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Multiple Slot Inheritance (continued)
(counter …)
Most Specific
designClass
C
B
A
XX
ZZ
ZZtop
ZZtop
A
XX
B
(counter …)
ZZ
C
h
Least Specific
designClass
(defclass B (A)
((counter @initarg counter
@initform 0)))
(defclass ZZtop ()
((counter @initarg index
@initform 1)))
218
© Cadence Design Systems, Inc. All rights reserved.
In the example, the counter slot is declared in both class B and class ZZtop. designClass inherits from
both classes but only has one slot named counter. It will have the @initargs of ?counter and ?index. The
initial form, if not specified when the instance is created, is taken from the most specific @initform
declared. In this example, the value is 0; class B is more specific than ZZtop. If the slot definition in
class B did not have an @initform, the initial default value would be 1.
Note that if you create an instance of class C (or B), only @initarg will counter, and the @initform is 0.
If you create an instance of class ZZ, the counter value is independent of any other instance, and the
@initform is 1.
© Cadence Design Systems, Inc. All rights reserved.
218
This document is for the sole use of Firuz Shomahmadov of Nxp
Multiple Inheritance Method Execution (Primary Methods)
ZZtop
A
XX
B
ZZ
C
h
Method
Qualifier
Specializer
createLib
designClass
createLib
C
createLib
A
createLib
XX
createLib
ZZtop
designClass
Method execution from most specialized to least specialized.
219
© Cadence Design Systems, Inc. All rights reserved.
Multiple inheritance creates a method hierarchy which is often confusing, this is why some languages
avoid it completely, but it is very powerful. The general rule is that the methods are evaluated from the
most specific specializers to the least specific specializers. In the case of class specializers, the most
specific class to the least specific class.
In this diagram, the classes with the yellow spots have specialized on a method, myMethod. Executing
myMethod specialized on designClass, the callNextMethod evaluates myMethod as specialized by class
C. This continues down the class C hierarchy, evaluating myMethod(A). The callNextMethod executed
in myMethod( A ) executes myMethod for class, the next most specific class. That method can stop the
execution by not using callNextMethod or executing the method specialized on ZZtop using
callNextMethod. The last method to execute in the callNextMethod line is the first method for that
generic function.
A method for a class will only be executed once as the "next method". If the class is a superclass to
multiple classes, a method specializing on it will be in the same order as listed in the superclass.
@before and @after methods execute based on the same superclass order, the @before methods
evaluating from most to least specific and the @after methods evaluating from the least specific to the
most specific.
© Cadence Design Systems, Inc. All rights reserved.
219
This document is for the sole use of Firuz Shomahmadov of Nxp
Multiple Inheritance with @before and @after Methods
ZZtop
A
XX
B
ZZ
C
h
designClass
@before
primary
@after
220
Method
Qualifier
Specializer
createLib
@before
designClass
createLib
@before
C
createLib
@before
A
createLib
@before
XX
createLib
designClass
createLib
C
createLib
XX
createLib
ZZtop
createLib
@after
ZZtop
createLib
@after
ZZ
createLib
@after
B
createLib
@after
C
© Cadence Design Systems, Inc. All rights reserved.
Although it looks complex, the order of method execution follows the rules for single inheritance. The
applicable @before methods are all evaluated, from the most specialized to the least specialized. The
primary methods are evaluated from most specialized to least specialized if they all use
callNextMethod. The @after methods are ordered from least specialized to most specialized and
evaluated in that order.
There is an error in this table. Can you spot it?
© Cadence Design Systems, Inc. All rights reserved.
220
This document is for the sole use of Firuz Shomahmadov of Nxp
Multiple Inheritance and Object-Oriented Pcells
Object-oriented Pcells use inheritance to combine capabilities required for PDK-specific devices.
Family class
PDK class
Dummies
DFM
h
Component classes
Device class:
NMOS
Family class:
MOS
withSymmetricSD
withSDconnectivity
PDK class:
withNdoping
withCMOS
Component classes:
withDummies
MOSwithDFM
withDFM
Device class
221
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
221
This document is for the sole use of Firuz Shomahmadov of Nxp
Diamond Class Definitions Perfectly Legal and Useful
● Multiple classes inherit from the same class.
● Multiply inherited classes appear only once in the class hierarchy.
● The hierarchy order is most specific to least specific.
baseClass
A
ZZtop
XX
B
ZZ
C
superclassesOf( classOf( instTC ) )
(class:designClass class:C class:B class:A
class:baseClass
class:XX class:ZZ class:ZZtop
class:standardObject class:t)
h
designClass
222
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
222
This document is for the sole use of Firuz Shomahmadov of Nxp
Multiple Inheritance Overview
● SKILL++ supports multiple inheritance.
● A class can have more than one direct superclass.
● All the slots in all the inherited classes are merged.
▪ All @initargs are usable.
▪ The most specific @initform determines the default value.
● Primary methods (other than most specific methods) are executed only if callNextMethod is used.
▪ Considering Execution Order: From most specific to least specific methods.
● @before methods execute before any primary methods.
▪ Considering Execution Order: From most specific to least specific methods.
● @after methods execute after primary methods are complete.
▪ Considering Execution Order: From least specific to most specific.
223
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
223
This document is for the sole use of Firuz Shomahmadov of Nxp
Lab
Lab 18-1 Implementing Multiple Class Inheritance in SKILL++ Code
224
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
224
This document is for the sole use of Firuz Shomahmadov of Nxp
Methods (Advanced)
Module
19
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
30 minutes
● Lab
45 minutes
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
225
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objectives
In this module, you
● Use optional arguments to build methods
● Create methods that dispatch on more than one argument
● Create methods that specialize on arguments other than classes
▪ Analyze the usage of the generic specializers for the methods
226
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
226
This document is for the sole use of Firuz Shomahmadov of Nxp
Adding Arguments to Methods
defgeneric(s_func (s_arg1 [ @rest s_arg2..]) [g_exp..])
=> t
● The generic function specifies the name of the
method and the required arguments for the
methods.
● Some methods may need additional data passed
as arguments.
▪ It can be done by adding @optional or @key
arguments.
● Generic function should be included with @rest
argument to add @optional or @key.
● Methods may only specialize on required
arguments.
● Only one method with a particular set of specializers
can be defined.
▪ Additional keyed arguments are not additional
specializers.
▪ Do not define two methods with the same specializers
with different sets of keyed arguments.
o Only the last one defined will be used.
● If the generic function declares an @rest variable,
all derived methods should declare an @rest
variable.
227
© Cadence Design Systems, Inc. All rights reserved.
The generic function specifies the name of the method and the required arguments for the methods. The
methods can only specialize on the required arguments. Methods for some classes may need additional
data passed in as arguments. This can be done by adding the new arguments as @optional or @key
arguments to the method. However, to do so, either these arguments are specified on the generic
function and applied to all methods derived from that function, or the generic function includes the
@rest argument. If the generic function includes @rest, all the derived methods must have an @rest
argument defined as well. Including @rest allows methods to define their own @key or @optional
arguments independent from other methods. When a method is executed, if some of the additional
arguments are not in its argument list, those arguments are assigned to the @rest variable and essentially
ignored.
It is recommended that the named arguments defined by @key be used instead of the positional
arguments defined by @optional. Using @optional arguments makes the methods depend on each
other’s positional argument definition. In this class, we will teach using @key and ignore @optional.
© Cadence Design Systems, Inc. All rights reserved.
227
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Adding Arguments to Methods
(defgeneric pcoDraw (device cvId @rest _ignore))
(defmethod pcoDraw ((device MOS) cvId @rest _ignore ))
…)
(defmethod pcoDraw ( ( device withHV ) cvId
@key termNode finger
@rest _ignore )
…)
228
© Cadence Design Systems, Inc. All rights reserved.
Methods are defined by their name and their specializers. Adding additional arguments, such as keyed
arguments, to a new method will overwrite the definition of a method with the same specializer
arguments.
© Cadence Design Systems, Inc. All rights reserved.
228
This document is for the sole use of Firuz Shomahmadov of Nxp
Using apply and callNextMethod with Methods
Changing argument values (especially optional arguments) for callNextMethod.
(defmethod genSHparamName (device (shape dbobject)
@key (layer shape~>layerName)
@rest initargs)
(unless shape~>isShape
(error "You cannot put a stretch handle on a %s"
shape~>objType )
(apply callNextMethod device t
?layer layer
initargs))
229
© Cadence Design Systems, Inc. All rights reserved.
Apply is very useful with object-oriented methods. Multiple methods can share the same name; they are
specialized by their required arguments. In this example, the method dtlGenSHparamName is evaluated
when a second argument is a database object. If the object has a layer, the next method is called with an
extra keyed argument ?layer and the value of the shape’s layer.
© Cadence Design Systems, Inc. All rights reserved.
229
This document is for the sole use of Firuz Shomahmadov of Nxp
Method Rules: Additional Arguments
● The generic function can have the following arguments:
▪ @optional
▪ @key
▪ @rest
● The @rest argument supports creating additional method arguments.
● @optional and @key arguments can be added to any method where the generic method has an @rest
argument.
▪ @key arguments are preferred.
● The optional arguments cannot be used to specialize the method.
▪ Specializers only work only on required arguments.
● Any argument not consumed by previous arguments stored in @rest argument.
230
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
230
This document is for the sole use of Firuz Shomahmadov of Nxp
What Is Multi-Method Dispatch?
With multi-method dispatch, all arguments of a method are treated equally, and the method to be
applied is decided at runtime, based on the dynamically-determined types of arguments.
● When you define more than one method with the same name in your code, and when the method call is
made, instead of one parameter specializer determining the method to be applied, it is determined by multiple
parameter specializers.
● The method is applicable if all required arguments match the corresponding declared specializers.
● The generic function sets the required arguments.
● Any or all those arguments can be used as a specializer.
(defmethod add ((x WholeNumber) (y WholeNumber))
(makeInstance 'WholeNumber
?sign (GetSign x)
?digits (addDigits (GetDigits x) (GetDigits y))
)
)
231
© Cadence Design Systems, Inc. All rights reserved.
Methods in SKILL++ can have more than one specializer. The specializers can only be set on the
required arguments as defined in the generic function. All of the specialized arguments are tested for a
match before the method is executed. Any of the required arguments can have a specializer;
unspecialized arguments are not tested to determine if the method is executed.
© Cadence Design Systems, Inc. All rights reserved.
231
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Multi-Method Dispatch
(defgeneric add ( _arg1 _arg2 @rest _ignore ))
Required arguments for this method (potential specializers)
(defmethod add ( (arg1 wholeNumber) arg2 @rest _ignore )
… ; Specializes on arg1 being class wholeNumber
callNextMethod()
)
(defmethod add ( arg1 (arg2 rational) @rest _ignore )
… ; Specializes on arg2 being class rational
callNextMethod()
)
(defmethod add ( (arg1 wholeNumber) (arg2 rational)
@rest _ignore )
… ; arg1 a wholeNumber and arg2 a rational
callNextMethod()
)
232
© Cadence Design Systems, Inc. All rights reserved.
The generic function defines the potential specializer arguments as required arguments. The methods
can then specialize on those arguments, individually or more than one.
A method is called when all the specializer arguments match the call. The specializer tests the value of
the argument and determines if there is a match. If it matches, that specializer is true. Non-specialized
arguments are not tested for matching when the method is chosen for execution.
The method with the most matching specialized arguments is the most specific method and is the first
primary method executed; then, the order of execution is determined by the position of the matching
arguments.
© Cadence Design Systems, Inc. All rights reserved.
232
This document is for the sole use of Firuz Shomahmadov of Nxp
Multi-Method Dispatch: Method Execution Order
add( wholeNumberObject rationalObject )
add( (arg1 wholeNumber) (arg2 rational) )
callNextMethod()
add( (wholeNumber A) arg2)
callNextMethod()
Most specific
First argument
more specific than
second argument
add( arg1 (rational B))
callNextMethod()
Least specific
add( arg1 arg2 )
233
© Cadence Design Systems, Inc. All rights reserved.
The method execution order (for @before and primary methods) is from most specific to least specific.
The order is determined by the order of the specializer in the argument list in the method. In this
example, add is called with both a wholeNumber object as the first argument and a rational object as the
second argument. The first method executed has both matching specializers. Then the method that
specializes on argument one is executed with callNextMethod. This is because the specializer is on the
first argument, which is more specific than the method that specializes on the second argument. The
method with the argument on the second argument is executed next, and finally, the method that does
not specialize on any argument is executed.
© Cadence Design Systems, Inc. All rights reserved.
233
This document is for the sole use of Firuz Shomahmadov of Nxp
Multi-Method Dispatch: Method Rules
● Methods can specialize on more than the first argument.
● Methods can specialize only on required arguments.
● Additional specializers are added to the method.
▪ Execute method only if all the specializer requirements are fulfilled.
● Method becomes more specialized, and the order of specializer declaration determines the method execution
order.
234
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
234
This document is for the sole use of Firuz Shomahmadov of Nxp
Quick Reference Guide: Method Specialization
● All objects in SKILL® and Virtuoso® have a class.
● Methods can specialize on the SKILL classes.
Examples
235
Class Name That Is
Returned
className(classOf( 5 ) )
fixnum
className(classOf(3.4))
flonum
className(classOf( "this string" )
string
className(classOf( ‘mySymbol ))
symbol
className(classOf( ‘(nil x 1 y 2 )))
list
className(classOf( list( 0:0 8:12)))
list
className(classOf( nil )))
list
className(classOf(makeTable…))
assocTable
className(classOf( lambda(…)))
funobj
© Cadence Design Systems, Inc. All rights reserved.
Everything known in SKILL has a class. These classes can be used as specializers on methods, but be
aware that all database objects return the class dbobject.
© Cadence Design Systems, Inc. All rights reserved.
235
This document is for the sole use of Firuz Shomahmadov of Nxp
Generic Specializers
● Generic specializer functions are focused on different objects.
● You can have multiple implementations of the same function by using generic specializer functions.
▪ Makes the code easier to maintain and develop, as it avoids having function calls within the code to switch between
different objects.
● Some of the generic specializers are:
236
Generic Specializer
Description
ilArgMatchesSpecializer
Determines whether the arguments passed at runtime match a
particular class so that then it knows which method should be called.
ilEquivalentSpecializers
Defines a method to check if two specializers are equal. This would
be required during method redefinition.
ilGenerateSpecializer
Returns SKILL expression that makes an instance of given
specializer class and optionally sets the slots.
ilSpecMoreSpecficp
Checks if spec1 is more specific than spec2. For this, you need to
define all the required ilSpecMoreSpecficp methods.
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
236
This document is for the sole use of Firuz Shomahmadov of Nxp
Method Rules: Specializers
● Class – Methods may be specialized on class (by name).
● eqv – Tests the value of argument and must satisfy eqv comparison.
237
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
237
This document is for the sole use of Firuz Shomahmadov of Nxp
Labs
Lab 19-1 Implementing the Methods by Adding Additional Arguments for Extended Capabilities
Lab 19-2 Implementing Equivalence Specializers
Lab 19-3 Implementing objType Specializers
238
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
238
This document is for the sole use of Firuz Shomahmadov of Nxp
Control Flow (Optional)
Module
20
Revision
2.0
Version
IC 6.1.8/ ICADVM 20.1
Estimated time:
● Lecture
30 minutes
● Lab
NA
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
239
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Objective
In this module, you
● Analyze the following control flow operators
▪ prog/return
▪ exists/forall
▪ errset
▪ unwindProtect
▪ catch/throw
240
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
240
This document is for the sole use of Firuz Shomahmadov of Nxp
Using prog and return
prog( localVar ((s_label) expr1) ……)
=>g_result/nil
● The prog statement allows local variables bindings and permits abrupt exits on control jumps.
● The argument to prog:
localVar
List of variables declared to be local within the prog
s_label
Labels a statement inside the prog
expr1
Expressions are executed sequentially unless one control transfer statements like go, or return is encountered
● If no return statement is executed.
▪ It evaluates to the value nil, and control simply falls through the prog after the last expression is executed.
● If a return is executed within a prog.
▪ The prog immediately returns with the value of the argument given to the return statement.
● Unless multiple return points are necessary or you are using the go functions, the let should be used over
prog.
241
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
241
This document is for the sole use of Firuz Shomahmadov of Nxp
Example: Using prog and return
Examples showing the usage of prog and return
Example 1
(prog (a)
a = (prog ()
...
(return 42))
;; a has the value 42
...)
Example 2
x = "hello” => "hello"
prog( (x y) ; Declares local variables x and y.
x = 5
; Initialize x to 5.
y = 10
; Initialize y to 10.
return( x + y )
)
=> 15
x
=> "hello“
;The global x keeps its original value.
Note:
1. The return and the prog need not be in the same function, but this is considered poor style., and
2. Prog also allows zero or more named variables to be bound to nil.
242
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
242
This document is for the sole use of Firuz Shomahmadov of Nxp
Using catch and throw
catch(tag form) and throw(tag value) or
(catch tag form) and (throw tag value)
● This is similar to prog/return except that throw names the catch tag, which it returns to.
● The second argument of throw indicates the value that the corresponding catch should return.
Example
(catch 'tag_break
(for k 1 100
(catch 'tag_next
(when (test1 K)
(throw 'tag_next nil)) ;; next K
(when (test2 K)
(throw 'tag_break K)) ;; break out of the for loop
(println K)))
243
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
243
This document is for the sole use of Firuz Shomahmadov of Nxp
Using exists and forall
exists(varName mylist expr1)
forall(varName mylist expr1)
=> g_result
=> t/nil
● exists halts iteration when the test condition becomes
true.
● forall checks if expr1 evaluates to non-nil for every
element in myList.
● Returns the first tail of mylist whose car satisfies a
predicate expression.
● Returns t, if expr1 evaluates to non-nil for every
element in myList.
● Returns nil, if none of the elements in mylist satisfies
the expr1.
● Returns nil, if the above condition does not satisfy.
exists(x '(1 2 3 4) (x>1))
forall(x '(1 2 3 4) (x>0))
 (2 3 4)
t
exists(x '(1 2 3 4) (x>4))
forall(x '(1 2 3 4) (x<4))
 nil
 nil
These are iteration constructs that halt iteration on particular conditions.
244
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
244
This document is for the sole use of Firuz Shomahmadov of Nxp
Using errset
errset(expr1) or (errset expr1)
=>g_result/nil
● The errset statement encapsulates the execution of an expression in an environment the same as the error
mechanism.
● If an error occurs in evaluating the given expression, control always returns to the command, following the
errset instead of returning to the nearest top-level.
● If the result is non-nil, error messages are issued; otherwise, they are suppressed.
● In either case, information about the error is placed in the errset property of the errset symbol.
● Programs can therefore access this information with the errset.errset construct after determining that errset
returned nil.
When working in the CIW, ensure that the errset.errset variable is not modified internally in the Virtuoso®
design environment, do not separate errset and errset.errset. For example, see the last example above.
245
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
245
This document is for the sole use of Firuz Shomahmadov of Nxp
Examples: Using errset
246
errset(1+2)
→(3)
errset(sqrt(‘x))
→nil
errset(sqrt(‘x)),errset.errset
→("sqrt" 0 t nil("*Error* sqrt: can't handle sqrt(x)
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
246
This document is for the sole use of Firuz Shomahmadov of Nxp
Using unwindProtect
unwindProtect((unsafe)(cleanup)) or (unwindProtect unsafe (cleanup))
=>g_result
● Attempts to evaluate unsafe, which may or may not
be complete.
● Evaluates cleanup whether unsafe completed or
not.
Example
(unwindProtect 1/D
(printf "attempted to divide by
%L\n" D))
● Returns the value of unsafe if it is completed.
● Invokes the error otherwise.
● Returns the quotient if D is not zero.
● Useful for cleanup of temporary files, etc.
● Prints the message in any case.
● Invokes the error if D is zero.
247
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
247
This document is for the sole use of Firuz Shomahmadov of Nxp
Using unwindProtect (continued)
unwindProtect can be used in the mode of try/except to execute the except form only if the
try form fails.
(let ((finished nil))
(unwindProtect (progn (myGenerateLogFile "/tmp/my.log" )
finished = t)
(unless finished
(deleteFile "/tmp/my.log" ))))
● This code attempts to generate a log file.
● If myGenerateLogFile returns, finished will be set to t.
● If the cleanup form finds the finished as nil yet, it will delete the file.
248
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
248
This document is for the sole use of Firuz Shomahmadov of Nxp
Module Summary
In this module, you
● Analyzed the following control flow operators
▪ prog/return
▪ exists/forall
▪ errset
▪ unwindProtect
▪ catch/throw
249
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
249
This document is for the sole use of Firuz Shomahmadov of Nxp
Next Steps
Module
21
Revision
2.0
Version
IC 6.1.8 / ICADVM 20.1
Estimated Time:
● Lecture
5 minutes
● Lab
NA
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
250
This document is for the sole use of Firuz Shomahmadov of Nxp
Learning Maps
Cadence® Training Services learning maps provide a comprehensive visual overview of the learning
opportunities for Cadence customers.
Click here to see all our courses in each technology area and the recommended order in which to
take them.
251
© Cadence Design Systems, Inc. All rights reserved.
Go here to view the learning maps:
http://www.cadence.com/Training/Pages/learning_maps.aspx
© Cadence Design Systems, Inc. All rights reserved.
251
This document is for the sole use of Firuz Shomahmadov of Nxp
Cadence Learning and Support
Cadence Support now includes over 2000 product/language/methodology
videos (“Training Bytes”)!
252
© Cadence Design Systems, Inc. All rights reserved.
Click here to view the demo of Cadence Learning and Support.
© Cadence Design Systems, Inc. All rights reserved.
252
This document is for the sole use of Firuz Shomahmadov of Nxp
Wrap Up
● Complete Post Assessment, if provided
● Complete the Course Evaluation
● Get a Certificate of Course Completion
Thank you!
253
© Cadence Design Systems, Inc. All rights reserved.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
253
This document is for the sole use of Firuz Shomahmadov of Nxp
© Cadence Design Systems, Inc. All rights reserved worldwide. Cadence, the Cadence logo, and the other Cadence marks found at https://www.cadence.com/go/trademarks are trademarks or registered trademarks of Cadence Design
Systems, Inc. Accellera and SystemC are trademarks of Accellera Systems Initiative Inc. All Arm products are registered trademarks or trademarks of Arm Limited (or its subsidiaries) in the US and/or elsewhere. All MIPI
specifications are registered trademarks or service marks owned by MIPI Alliance. All PCI-SIG specifications are registered trademarks or trademarks of PCI-SIG. All other trademarks are the property of their respective owners.
This page does not contain notes.
© Cadence Design Systems, Inc. All rights reserved.
254
Download