LoginSignup
1
0

Cadence Skillメモ

Last updated at Posted at 2021-10-29

個人用備忘録です。

公式掲示板

簡単な〇〇がやりたい、というのはこちらで調べる。
直接利用できなくても、部分的に参考になるのがとても役立つ。

日本語wiki

あまり情報量は多くないが取っ掛かりにはよいかも。

API Finder

CIWメニューのToolsからSKILL API Finderを選択。
用途のわからない関数はとりあえずこれで調べる。
上の公式掲示板でそれらしい関数を見つけて検索するとよさげ。

データ構造

変数(SKILLでは"symbol"や"variable"と呼ばれる)は

  • Print name
  • Value
  • Function binding
  • Property list
    という要素を持っている。valueとproperty listを同時に持つ、ということが可能。
    valueとfunction bindingを同時に持つことは推奨されない。

Disembodied Property List

変数のvalueに入れることのできるproperty list。
通常nilで始まり、name/valueペアが続くリストで表される。

Association Table

RubyのHash、PythonのDictionaryのようにkey/valueペアでデータを保持する。
Property Listのkeyはsymbolしか使えないが、Association Tableのkeyはinteger, float, stringなどが使える。

setq

変数を代入する関数

(setq x 100)
x
;=> 100

setof

Pythonのリスト内包表記に似た機能。戻り値がフィルターされた後のリストになる。
setofのみでは変数はセットされない。
foreachでも同じことができる。

x = setof(x '(1 2 3 4) (x > 2))
x
;=> (3 4)

x = foreach(mapcan x '(1 2 3 4) if(x > 2 list(x)))
x
;=> (3 4)

Arrow operator->

変数のvalueがsymbolであるときに、symbolのproperty listに間接的にアクセスする。

designator = 'U235
U235.x = 200 
U235.y = 300
designator->x ;=> 200
designator->y ;=> 300

U235.x = 200.はproperty listの要素にアクセスする演算子。
また、変数の値がdisembodied listの場合はその要素にアクセスする。

loc = '(nil x 100 y 200) ;=> (nil x 100 y 200)
loc->x ;=> 100

~>->の違い

procedure

関数定義用

procedure( myadd(a b)
	a + b
)
myadd(2 3)
;=> 5

split

parseString()が使える

s = "aaa/bbb/ccc"

parseString(s "/")
=> ("aaa" "bbb" "ccc")

append

リスト末尾に他のリストを加える

l = list()
l = append(l '(1 2))
l = append(l '(4 5))
l
;=> (1 2 4 5)

append()はnon-destractiveなのでprocedure()内からリストを操作するには使えない。

l = '(1 2)

procedure(myappend(list)
	list = append(list '("a" "b"))
)

myappend(l)
print(l)
;=> (1 2) : myappend関数内でappendされたリストは関数外には反映されない

lconc

lconc()を使うとdestracticveにリストに要素を追加できる。
一旦tconc()でリストのような構造を作ってから、lconc()を使って要素を追加、その後car()を使って取り出す。

x = tconc(nil 1)      ; x is initialized ((1) 1)
lconc(x '(2 3 4))     ; x is now ((1 2 3 4) 4)
lconc(x nil)          ; Nothing is added to x.
lconc(x '(5))         ; x is now ((1 2 3 4 5) 5)
x = car( x )          ; x is now (1 2 3 4 5)

pop

末尾にアクセスするには…
popと違い非破壊的

l = '(1 2 3 4)
reverse(cdr(reverse(l)))
=> (1 2 3)

list to string

buildString( '("test" "il") ".")      => "test.il"

if

if( 条件文 then
    Trueのときの処理1
    Trueのときの処理2
    ...
    else
    Falseのときの処理1
    Falseのときの処理2
    ...
)

リストに要素がふくまれているかどうかで条件分岐
member()を使う

if(member(1 '(1 2 3)) then 
         println("true"))

foreach

foreach内で使った変数は外では参照されない

i=100
foreach(i '(1 2 3 4) println(i))
;1
;2
;3
;4
println(i)
;100

zip

pythonのzipに相当する操作はforeachでできる
foreachのマニュアルに書かれているので参照するとよい

(foreach (x y) '(1 2 3) '(4 5 6) (println x+y))
5
7
9
=> (1 2 3)

map

リストからnilを取り除く。
foreachのそれぞれのループで返る値はlistにする必要があるので注意。

l = list("a" "b" nil "c")

foreach(mapcan s l if(s != nil list(s)))
; ("a" "b" "c")

let

ブロック内でのみ有効な関数の宣言

let( (x y)
    x = 3
    y = 5
    print(x + y)
)
; 8
x
; *Error* toplevel: undefined variable - x

parseString

文字列を分割してリストを返す。

parseString( "Now is the time" ) => ("Now" "is" "the" "time")
parseString( "~/exp/test.il" "./") => ("~" "exp" "test" "il")
Both . and / are break characters.
parseString( "-abc-def--ghi-" "-" )
=> ("abc" "def" "ghi")
parseString( "-abc-def--ghi-" "-" t )
=> ("" "abc" "def" "" "ghi" "")

cons

リストの先頭に要素を追加

cons(
g_element
l_list
)
=> l_result

###ファイル出力

cv = getCurrentWindow()~>cellView
tmpout = outfile("./inputPinList.txt")
foreach(terminal cv~>terminals if(terminal~>direction=="input" then fprintf(tmpout "%s\n" terminal~>name)))
close(tmpout)

ciUtilsMakeUnique

リストの重複する要素を除いて返す

ciUtilsMakeUnique('("a" "a" "b" "c" "a" "a" "b" "c"))
=> ("a" "b" "c") 

各種プロパティの値の取得

インスタンス名 instance~>name
セル名 instance~>cellName
CDFパラメータ cdfGetInstCDF(instance)~>c~>value
cellViewがRead-OnlyかEditableか cv~>mode

正規表現オブジェクトの作成とマッチ

pcreCompile()で正規表現オブジェクトを作って、pcreExecute()でマッチするかどうか比較する。
  PCRE(=Perl Compatible Regular Expression)

example.il
let( (namePat)
  namePat = pcreCompile("^(dff|lat)") ;; name begins with either 'dff' or 'lat'
  foreach(cell ddGetObj("shem")~>cells
    when(pcreExecute(namePat cell~>name)
      ;; do your processing here
    ): when
  ); foreach
); let

参考
https://community.cadence.com/cadence_technology_forums/f/custom-ic-skill/36833/regular-expressions

正規表現 バックスラッシュについて

pcreCompile("\\d")のように特殊文字を使うときはバックスラッシュが2つ必要らしい。

参考
https://community.cadence.com/cadence_technology_forums/f/custom-ic-skill/37602/regular-expression-replace-with-backslash

正規表現 キャプチャ

comPat = pcreCompile("^([a-z]+)_([a-z]+)")
pcreobj@0x3431b9a0
> 
pcreExecute(comPat "abc_def")
t
> 
pcreSubstitute("\\0")
"abc_def"
> 
pcreSubstitute("\\1")
"abc"
> 
pcreSubstitute("\\2")
"def"
> 

Sort

セル名でソート。アルファベット順。

insts = sort(insts (lambda (i1 i2) alphalessp(i1~>cellName i2~>cellName)))

nilガード

input = nil
nil
> 
s = (input || "")
""
> 

built-ins

dbGetInstByName() ;; maintained only for backward compatibility; you should now use dbFindAnyInstByName.
dbFindMemInstByName()
dbGetAnyInstSwitchMaster()

dbFindSigByName()
dbFindTermByName()

dbProduceMemName()

Screenshot

hiExportImage(?fileName "sample.png" ?window getCurrentWindow() ?bBox inst~>bBox ?scaleFactor 2)

テキストファイル読み込み

;; 関数定義
procedure( parseFile( file )
  let( ( table tokens fpFile )
    fpFile = infile( file )
    table = list()
    while( gets( line fpFile )
        tokens = parseString( line )
        tokens && ( table = cons( tokens table ) )
    );while
    close( fpFile )
    reverse( table )
  );let
);procedure

;tmp.txt
;0 aaa AAA
;1 bbb BBB
;2 ccc CCC

;; 各行が空白区切りでリストになって出てくる
parseFile("tmp.txt")
;(("0" "aaa" "AAA") 
;    ("1" "bbb" "BBB") 
;    ("2" "ccc" "CCC")
;)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0