close

Cadence skill語言簡介

 

Cadence提供二次開發的SKILL語言,它是一種基於通用人工智慧語言—Lisp的互動式高級編程語言(LISPList Processing-表處理,是最早和最重要的符號處理編程語言之一,它於1958年由美國的J. McCarthy提出,LISP在人工智慧AI方面獲得廣泛應用)

SKILL語言支援一套類似C語言的語法,大大降低了初學者學習的難度,同時高水準的編程者可以選擇使用類似Lisp語言的全部功能。所以SKILL語言既可以用作最簡單的工具語言,也可以作為開發任何應用的、強大的編程語言。SKILL可以與底層系統交互,也提供了訪問Cadence各個工具的豐富介面。用戶可以通過Skill語言來訪問,並且可以開發自己的基於Cadence平臺的工具。

1. Skill語言和Lisp語言的關係

Skill函數提供兩種表示法,一種是代數表示法,現在大多數語言採取這種方式,即 func( arg1 arg2 ...),另一種是首碼表示法,類似於Lisp語言,即(func arg1 arg2 ...)。這裏舉個例子作為對比:

1.代數表示法

procedure( fibonacci(n)

if( (n == 1 || n == 2) then

1

else fibonacci(n-1) + fibonacci(n-2)

)

)

2.首碼表示法

(defun fibonacci (n)

(cond

((or (equal n 1) (equal n 2)) 1)

(t (plus (fibonacci (difference n 1))

(fibonacci (difference n 2))))

)

)

這裏可以看到類似Lisp語言的表示法後面有很多右括弧,而且函數和參數容易混淆,所以一般推薦還是用常用的類C語言代數表示法

Skill程式就像一個list表,類似Lisp語言,程式的操作就像運算元據(list)一樣,可以生成,修改,求值等

2. 關於Skill函數

SKILL語言支援一套類似C語言的語法,初學者有了一定的C語言基礎,入門是很容易的。Cadence的工具可以通過CIWBindkeyFormMenu等多種方式調用skill函數,送到skill語言的解釋器來執行各種操作。

 

 

 

其中CIW(Command Interpreter Window),即啟動Icfb的第一個視窗,包含一些常用的menu,一個輸入行,以及一個輸出區域,這裏是常用的debug skill程式的地方,當然cadence也提供了Tools->Skill Development,有興趣的話可以深入研究一下

2.1 Skill函數的查閱方法

Skill語言有n多函數,加上眾多工具的介面函數,可以用成千上萬來形容,初學者可能會感到暈頭轉向,無從下手。其實只要瞭解基本的變數,控制語句,輸入輸出以及一些常用工具的基本函數就可以了,大多數函數都可以用到再查閱。開始學習skill時可以仔細看看SKILL Language User Guide其他的可以用到時再查閱,這裏列出幾個經常會用到的文檔:SKILL Language Reference Skill語言相關的函數,Cadence User Interface SKILL Functions ReferenceCadence應用程式圖形介面介面函數,Design Framework II SKILL Functions ReferenceSKILL Custom Layout ReferenceSKILL Schematic Composer Reference分別是CadenceDesign Framework II,版圖,電路的介面函數。

當然還有其他眾多工具的介面函數,因此Skill需要方便的函數查閱方法,這裏列出3種:

1.最簡單的方法,看~/CDS.log檔或者CIW的輸出區域,把Options-> LogFilter都選上。這裏一般可以查閱在圖形介面下運行的函數,如圖,我們可以看到畫path線的函數以及輸出結果等

 

2.在CIW裏輸入命令startFinder,或者在Terminal上輸入cdsFinder& . Finder適用於至少知道函數名的一部分,這裏可以查到函數的用法簡介。例如上圖我們看到畫path的函數是leHiCreatePath(),但這是圖形方式的函數,對應skill方式的函數呢用法呢,可以在Finder中輸入CreatePath,這樣我們就可以看到包含有CreatePath的所有函數,如圖,leCreatePath即是我們想找的函數,這裏可以看到簡單的用法介紹

 

 

3.上面我們查到的關於函數用法的介紹很簡單,如何知道其詳細介紹呢。當然如果你知道函數在那個文檔裏,直接打開就行了,如果不知道,就需要打開helpsearch功能,這裏可以查到詳細的功能用法。

運行cdsdoc&, 點擊Search打開Cadence help的搜索功能,工具會自動啟動一個http服務,同時打開搜索網頁,啟動服務後,你也可以在windowsIE裏輸入http://hostname:9000/search.htm,同樣可以打開搜索頁面,需要注意的是,在C:\WINNT\system32\drivers\etc\hosts檔中需要加入hostname對應的ip,如:

127.0.0.1 localhost

10.0.10.2 host1

Cadence help的搜索功能默認是用Netscape打開搜索網頁,如果沒有裝Netscape,可能會打不開網頁。可以先打開firefoxmozila等流覽器,再啟動cadence doc搜索http服務,這樣就可以打開搜索網頁了

 

 

3. Skill語言簡介

Skill語言的很多地方和C語言差不多,如變數,函數,控制結構,輸入輸出等,詳細的介紹可以參考User Guide,這裏只作簡單介紹。

3.1. Skill的變數不需要事先聲明,Skill第一次用到是會自動生成變數。變數可以由字元、數位、“_”  “?” 組成,注意第一個字元不能是數位和”?”。由於Cadence所開發的Skill中的變數、函數都是第一個字母小寫,以_為開頭的是Cadence的專用函數,為了避免衝突,建議大家函數和變數命名都以大寫字母開頭

3.2. Skill的函數的調用方式有三種,

strcat( "Hello" "," " everyone" "!" ) ;常見的類C格式

( strcat "Hello" "," " everyone" "!" ) ;Lisp語言的格式

strcat "Hello" "," " everyone" "!" ;上面的括弧可以省略

返回的結果都是 => "Hello, everyone!"

推薦使用第一種方式,需要注意的是函數和第一個括弧之間沒有空格,否則會報錯

如: strcat ( "Hello" "," " everyone" "!" )

=> *Error* eval: not a function - "Hello"

這是調用skill函數的一個常見問題,其他的問題還有:

a. 軟體沒回應,比如在CIW中輸入段代碼,軟體沒有反映,什麼結果也沒有,一般是因為( )或者” “不成對造成的,一般可以通過鍵入 來解決,它表示補充完不對稱的括弧(可以代替任意多個右括弧),如果還沒有回應,鍵入 “] 這時大部分情況下,系統會有回應

b. 資料類型不匹配,如:

strcat( "Mary had a" 5 )

=>*Error* strcat: argument #2 should be either a string

or a symbol (type template = "S")  5

3.3. Skill ListSkill基於Lisp(List Processing)語言的表現,它是skill資料物件的一個有序集合,skill資料甚至程式本身都可以看作是一個list,這是C語言中所沒有的概念。下面是skill list的簡單例子

List Explanation

(1 2 3) A list containing the integer constants 1, 2, and 3

(1) A list containing the single element 1

( ) An empty list (same as the special atom nil)

(1 (2 3) 4) A list containing another list as its second element

A). 創建list有以下幾種基本的方法:

              􀂾Specify all the elements of the list literally with the single quote ( ‘ ) operator.

              􀂾Specify all the elements as evaluated arguments to the list function.

              􀂾Add an element to an existing list with the cons function.

              􀂾Merge two lists with the append function.

 

1).用  list 定義一個list,注意兩者的差別

a = 1 => 1

b = 2 => 2

'( a b 3 ) => ( a b 3 )

list( a b 3 ) => ( 1 2 3 )

 

 

2).用cons命令添加一個元素到一個list的頭部

result = '( 2 3 ) => ( 2 3 )

result = cons( 1 result ) => ( 1 2 3 )

3).用append命令合併兩個list

Lista = '( 4 5 6 ) => ( 4 5 6 )

Listb = '( 1 2 3 ) => ( 1 2 3 )

Listc = append( Lista Listb) => ( 4 5 6 1 2 3 )

B). 訪問list或者list中某些元素的方法:

car訪問list的第一個元素

numbers = '( 1 2 3 ) => ( 1 2 3 )

car( numbers ) => 1

cdr訪問list除了第一個元素外的其他元素,注意返回仍然是個list

numbers = '( 1 2 3 ) => ( 1 2 3 )

cdr( numbers ) => ( 2 3 )

nth用索引訪問list的某個元素,注意索引從0開始

numbers = '( 1 2 3 ) => ( 1 2 3 )

nth( 1 numbers ) => 2

member檢查指定的元素是否在指定的list中,它只檢查頂層元素的元素,返回值是從搜到值開始到結尾的list

numbers = '( 1 2 3 ) => ( 1 2 3 )

member( 4 numbers ) => nil

member( 2 numbers ) => ( 2 3 )

length計算list所包含元素的個數

numbers = '( 1 2 3 ) => ( 1 2 3 )

length( numbers ) => 3

C). 關於xy座標或者bBox邊界list的訪問

在版圖設計中,關於座標的list是最長見的,它是一組2維的list,常見的表示方法有:

 表示一個座標的list,其結果和list命令一樣,用xCoordyCoord命令可以訪問xy座標

xValue = 300

yValue = 400

aCoordinate = xValue:yValue => ( 300 400 )

xCoord( aCoordinate ) => 300

yCoord( aCoordinate ) => 400

list命令和 來表示一個bBoxlist命令先計算變數或者運算式,然後賦給list表示的list和字面的一樣,不會計算變數或者運算式的值

bBox = list( 300:400 500:450 ) ;含有 bBox

含有變數用list

lowerLeft = 300:400

upperRight = 500:450

bBox = list( lowerLeft upperRight )

表示的list嚴格按字面意思

bBox = '(( 300 400 ) ( 500 450 ))

通過carcdr的組合可以訪問bBox每一個元素,而且有相關的簡化函數,如下表:

 

 

 

Using car and cdr with Bounding Boxes

Functions

Meaning

Example

Expression

car

car( ... )

lower left corner

ll = car( bBox)

cadr

car( cdr( ... ) )

upper right corner

ur = cadr( bBox)

caar

car( car( ... ) )

x-coord of lower left corner

llx = caar( bBox)

cadar

car( cdr( car( ... ) ) )

y-coord of lower left corner

lly = cadar( bBox)

caadr

car( car( cdr( ... ) ) )

x-coord of upper right corner

urx = caadr( bBox)

cadadr

car( cdr( car( cdr( ...]

y-coord of upper right corner

ury = cadadr( bBox)

List的相關操作有很多,這裏就不詳細介紹了,可以參考User Guide裏的Advanced List Operations

 

3.4. Skill的輸入輸出

1). 輸出顯示資料:

print  println 函數都可以用來顯示單個資料,println可以在顯示的資料後多加一個回車

for( i 1 3 print( "hello" )) ;Prints hello three times.

"hello""hello""hello"

for( i 1 3 println( "hello" )) ;Prints hello three times.

"hello"

"hello"

"hello"

printf 函數是格式化的輸出,下面的例子是一定格式輸出圖形層的統計

printf( "\n%-15s %-15s %-10d %-10d %-10d %-10d"

layerName purpose rectCount labelCount lineCount miscCount

)

對應參數的意義如下,printf需要注意輸出類型的對應

%[-][width][.precision]conversion_code

[-] = left justify

[width] = minimum number of character positions

[.precision] = number of characters to be printed

conversion_code 

d - decimal(integer)

f - floating point

s - string or symbol

c - character

n - numeric

L - list (Ignores width and precision fields.)

P - point list (Ignores width and precision fields.)

B - Bounding box list (Ignores width and precision.)

 

 

2). 輸出資料到一個檔:outfile定義輸出介面檔,print println fprintf輸出到介面檔, close關閉打開的介面,見下面的例子

myPort = outfile( "/tmp/myFile1" )

for( i 1 3

println( list( "Number:" i) myPort )

)

close( myPort )

輸出到檔 /tmp/myFile1.

("Number:" 1)

("Number:" 2)

("Number:" 3)

myPort = outfile( "/tmp/myFile2" )

for( i 1 3

fprintf( myPort "Number: %d\n" i ) ;注意printf函數不能輸出到port

)

close( myPort )

輸出到檔/tmp/myFile2.

Number: 1

Number: 2

Number: 3

3). 從檔讀取資料:intfile定義輸入介面檔,gets一次從介面檔讀取一行字串,fscanf根據指定的格式從介面檔讀取,close關閉打開的介面

打開~/.cshrc,輸出檔的每一行

inPort = infile( "~/.cshrc" )

when( inPort

while( gets( nextLine inPort )

println( nextLine )

)

close( inPort )

)

打開~/.cshrc,輸出檔中的每一個字串

inPort = infile( "~/.cshrc" )

when( inPort

while( fscanf( inPort "%s" word )

println( word )

)

close( inPort )

)

 

 

 

 

 

 

 

 

 

3.5. Skill的控制結構

1). 關係操作符,如下表:

Sample Relational Operators

Operator

Arguments

Function

Example

Return Value

<

numeric

lessp

3 < 5

t

3 < 2

nil

<=

numeric

leqp

3 <= 4

t

>

numeric

greaterp

5 > 3

t

>=

numeric

geqp

4 >=3

t

==

numeric

equal

3.0 == 3

t

string list

abc == "ABc"

nil

!=

numeric

nequal

abc != "ABc"

t

string list

 

2). 邏輯操作符,如下表:

Sample Logical Operators

Operator

Arguments

Function

Example

Return Value

&&

general

and

3 && 5

5

5 && 3

3

t && nil

nil

nil && t

nil

||

general

or

3 || 5

3

5 || 3

5

t || nil

t

nil || t

t

 

SKILL中只有 nil 是假(FALSE),其餘的任何值都是真(TRUE)

/或邏輯操作只有在需要計算第二個運算式時,才計算第二個表運算式,比如&&操作,當第一個表達時為假時,就不會再計算第二個運算式,|| 操作,當第一個表達時為假時,才會再計算第二個運算式。

返回的結果是最後一個計算的運算式,因此與/或邏輯操作可以代替繁瑣的if / when等控制語句,例如:C語言中的操作符, a>b ? c=a : c=b; ca b中較大的一個Skill中沒有類似的操作符,可以用下面語句來完成此操作:

if( a>b then

c=a

else

c=b

)

也可以用邏輯操作符: c = (a>b)&&a || (a<b)&&b

當然Skill還提供的有max(a b …)的函數,舉這個例子是為了說明&& || 可以代替if then else之類的控制語句

 

3). 控制語句:if(…then…else….)whenunlesscasecond,迴圈語句forforecah等,控制語句和C語言類似,都是先判斷某個變數或者運算式是否為真,然後執行下面的操作,需要注意的是

              􀂾關鍵字(其實也是skill的函數)和左括弧之間不能有空格,

              􀂾if…then…elsethen是不能省略的(除了只有一個if,沒有else的情況)

              􀂾case的判斷可以是數位和字串,也可以是它們組成的list,但不支援變數和運算式

              􀂾如果有很多判斷語句,用cond代替if…then…else組合,代碼比較清晰而且執行效率比較高,下面的兩種代碼是等效的。

              􀂾把最可能出現的情況放在最前面,如果出現的幾率都一樣,把計算量最大的放在最後面,這樣可以有效的提高代碼效率。

 

cond(

( condition1 exp11 exp12 ... )

( condition2 exp21 exp22 ... )

( condition3 exp31 exp32 ... )

...

( t expN1 expN2 ... )

) ; cond

if condition1 then exp11 exp12 ...

else if condition2 then exp21 exp22 ...

else if condition3 then exp31 exp32 ...

...

else expN1expN2 ....

forforeach是迴圈控制語句,forC語言中的基本一樣,foreach經常用於對list的每個元素作迴圈操作,每個迴圈依次把各個元素的值賦給一個變數,如下面的例子,你會注意到foreach的返回值是迴圈的list

rectCount = lineCount = polygonCount = 0

shapeTypeList = '( "rect" "polygon" "rect" "line" )

foreach( shapeType shapeTypeList

case( shapeType

( "rect" ++rectCount )

( "line" ++lineCount )

( "polygon" ++polygonCount )

( t ++miscCount )

) ;case

) ; foreach

=> ( "rect" "polygon" "rect" "line" )

 

4. Skill語言中常用知識匯總列表

上面對skill語言作了一個大概的介紹,當然學習skill需要瞭解的很多,這裏就不再一一作詳細的介紹了,只是對一些需要注意的地方做一下總結,具體的還是要學習User Guide

1Skill中的特殊字元(除了字母數位以及 以外的其他字元)都有各自的含義,見下表,如果要用到這些字元的話,用可以去掉其特殊含義。

arrow
arrow
    文章標籤
    Allegro Skill
    全站熱搜

    熊熊 發表在 痞客邦 留言(0) 人氣()