Cadence Skill语言-自定义函数

EDA软件 0 1472 佚名 收藏

关于Skill的自定义函数

定义方法:

a. 大部分自定义函数用procedure就够了,如:

procedure( trAdd( x y )
printf( "Adding %d and %d ... %d \n" x y x+y )
    x+y
)        => trAdd 定义函数trAdd
trAdd( 6 7 )  => 13 调用函数trAdd

b. lambda用来定义一个没有函数名的函数,它在一些很小的函数里很方便,例如:

signalList = '(
    ( nil strength 1.5 )
    ( nil strength 0.4 )
    ( nil strength 2.5 )
)
sort( signalList
    'lambda( ( a b ) a->strength <= b->strength )
    ;定义一个用来按signalList的strength属性排序的内置函数,它没有具体的函数名
)

参数:函数的参数是在调用函数时用来传递一定的参数,Skill的参数除了基本的参数传递功能外,还有其他的@option来控制参数传递的方法:

@rest, 调用函数时允许任意多个参数传递给函数,

procedure( trTrace( fun @rest args )
let( ( result )
    printf( "\nCalling %s passing %L" fun args )
    result = apply( fun args )
    printf( "\nReturning from %s with %L\n" fun result )
    result
) ; let
) ; procedure

调用函数及返回结果:

trTrace( 'plus 1 2 3 ) => 6 ;返回值
 =>Calling plus passing (1 2 3)
  Returning from plus with 6

@optional, 可以传递一个可选参数,否则会用默认值,

procedure( trBuildBBox( height width @optional
                        ( xCoord 0 ) ( yCoord 0 ) )
list(
    xCoord:yCoord ;;; lower left
    xCoord+width:yCoord+height ) ;;; upper right
) ; procedure

调用函数及返回结果:

trBuildBBox( 1 2 )         => ((0 0) (2 1))
trBuildBBox( 1 2 4 )       => ((4 0) (6 1))
trBuildBBox( 1 2 4 10)     => ((4 10) (6 11))

@key,可以指定参数是如何传递的,应此调用是参数的顺序不固定

procedure( trBuildBBox(
    @key ( height 0 ) ( width 0 ) ( xCoord 0 ) ( yCoord 0 ) )
    list(
     xCoord:yCoord ;;; lower left
     xCoord+width:yCoord+height ) ;;; upper right
) ; procedure
trBuildBBox()                          => ((0 0) (0 0))
trBuildBBox( ?height 10 )              => ((0 0) (0 10))
trBuildBBox( ?width 5 ?xCoord 10 )     => ((10 0) (15 0))

其中@key和@optional不能同时出现在一个函数的定义中,另外的情况可以组合在一起:

procedure(functionname([var1 var2 ...]
    [@optional opt1 opt2 ...]
    [@rest r])
..
)

procedure(functionname([var1 var2 ...]
    [@key key1 key2 ...]
    [@rest r])
..
)

局部变量, Skill中的变量默认都是全局变量,为了避免命名冲突,要尽量减少全局变量的使用,而采用局部变量。Skill可以用let和prog定义局部变量,如下面的例子:

procedure( trGetBBoxHeight( bBox )
    let( ( ( ll car( bBox ) ) ( ur cadr( bBox ) ) lly ury )
      lly = cadr( ll )
      ury = cadr( ur )
      ury - lly
    ) ; let
) ; procedure


局部变量默认初始化为nil,当然也可以初始化为别的值或表达式,表达式中不能有别的局部变量,prog和let的区别在于,prog支持函数go和return,可以显示的循环和返回多个值,而let返回值是最后一个表达式的值,例子的返回值是ury – lly. 除了有必要用prog,一般用let,更加简洁快速。


相关推荐:

网友留言:

您需要 登录账户 后才能发表评论

我要评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。
验证码