Skill语言一些常见函数(一)

  1. procedure
  • procedure 是用于定义函数(或称为过程)的关键字。函数定义以 procedure 开始,后跟函数名和参数列表,然后是函数体,最后返回函数体中最后一个表达式的值。

基本语法和结构

  • 函数定义格式:procedure(function_name(parameters) function_body)。例如,定义一个加法函数:procedure(add_2(x y) printf("Adding %d and %d \n" x y) x + y)
  • 函数调用:通过 function_name(arguments) 调用,如 add_2(3 2)
  • 返回值:函数返回值是函数体中最后一条执行语句的值,而非显式 return 语句。

参数类型和灵活性

  • 基本参数:直接在括号中列出,如 (x y)
  • 可选参数:使用 @optional 关键字定义,提供默认值。例如:procedure(trBuildBBox(height width @optional (xCoord 0) (yCoord 0)) ...)
  • 关键字参数:使用 @key 关键字,允许调用时按名称传递参数,顺序无关。例如:procedure(trBuildBBox(@key (height 0) (width 0) ...))
  • 任意数量参数:使用 @rest 关键字,将多余参数收集为列表。例如:procedure(trTrace(fun @rest args) ...)

局部变量和作用域

  • 局部变量:使用 let 函数定义局部变量,变量在函数执行后不会保留值。例如:let((var1 var2) var1 = 10 var2 = 20 ...)
  • 变量作用域:Skill变量默认为全局变量,但建议使用局部变量避免冲突。

实用示例

  • 简单函数:计算矩形面积。
    procedure(cal_box_area(bBox)
      let((ll ur lly llx ury urx)
        ll = lowerLeft(bBox)
        ur = upperRight(bBox)
        lly = yCoord(ll)
        llx = xCoord(ll)
        ury = yCoord(ur)
        urx = xCoord(ur)
        abs((lly - ury) * (llx - urx))
      )
    )
    
  • 带参数处理的函数:支持可选和关键字参数。
    procedure(trBuildBBox(@key (height 0) (width 0) (xCoord 0) (yCoord 0))
      list(xCoord:yCoord (xCoord + width):yCoord + height)
    )
    

调试和最佳实践

  • 调试函数:使用 sstatus(debugModet) 启用调试模式,然后用 whereIs(function_name) 查找函数定义位置(仅适用于自定义函数)。
  • 注意事项:
    • procedure 与括号间不能有空格,函数名与括号间也不能有空格。
    • 避免全局变量冲突,优先使用局部变量。
    • 函数名与左括号间禁止空格,否则会报错。

高级特性

  • 匿名函数:使用 lambda 定义,无需函数名。例如:sum = lambda((a b) a + b)
  • 函数作为数据:Skill支持代码即数据,函数可被动态操作。
  1. let和prog
  • `let和prog是两种用于定义局部变量的构造,它们在语法和行为上存在关键差异。

语法结构上, let和prog都接受一个局部变量列表作为第一个参数,该列表可包含变量名或变量绑定(如(var init))。例如,let((x 1)(y 2) ...)prog((x 1)(y 2) ...)均声明局部变量x和y,初始值分别为1和2;若未指定初始值,变量默认初始化为nil

主要区别在于执行行为和效率: let的主体由一系列表达式组成,返回最后一个表达式的值,且不支持显式控制转移(如returngo),适用于简单场景,执行效率较高;prog则支持returngo,允许从内部直接返回值或跳转,但需显式使用return指定返回值,否则默认返回nil,其灵活性适用于复杂控制流(如循环),但效率低于let。

选择建议: 一般优先使用let以提升效率;当需要显式控制转移(如从嵌套结构中提前返回)时,应选择prog。

  1. geGetEditRep
  • geGetEditRep:这个函数用于获取当前编辑的表示(representation)。在Cadence工具中,编辑表示通常与当前正在操作的电路或版图视图相关联。例如,它可以返回当前编辑的单元视图或相关数据结构,便于后续操作。
  1. boundp
  • boundp:这个函数用于检查一个符号(变量名)是否已被绑定到一个值。在SKILL中,变量在使用前需要通过绑定来赋值;boundp 返回真(t)如果变量已绑定,否则返回假(nil)。这常用于条件判断,避免未定义变量错误。
  1. geGetEditCellView
  • geGetEditCellView 是一个常用函数,用于获取当前编辑模式下的CellView标识符(cvId),该标识符是操作当前版图或原理图数据的核心引用。

函数功能与用途: geGetEditCellView 不接受参数,直接返回当前处于编辑状态的 CellView 的 cvId,例如在Virtuoso环境中,如果用户正在编辑某个版图,该函数即可获取其对应标识符,后续可结合dbOpenCellViewByType 等函数进行数据读取或修改。 其他类似函数包括 geGetWindowCellView(获取当前窗口的 CellView)和 geGetTopLevelCellView(获取起始层的 CellView),但 geGetEditCellView 专指编辑层。

使用示例: 基本用法如下:

cv = geGetEditCellView()

此代码将当前编辑 CellView 的 cvId 赋值给变量 cv,之后可传递给其他函数,如 dbFindOpenCellViewlceClearLogicalConn,以执行具体操作(如清除连接关系)。

注意事项: SKILL 语言对语法要求严格,例如函数名与参数间不应有空格,否则可能导致解析错误;命名风格推荐驼峰命名法(如 geGetEditCellView),以保持代码一致性。 此外,该函数仅在存在活动编辑窗口时有效,否则可能返回空值。

  1. unless和hiIsForm
    在Cadence的SKILL语言中,hiIsForm是一个用于检查指定标识符是否为一个有效表单的函数。它通常与unless语句结合使用,以条件性地执行代码块,例如在表单创建或显示逻辑中。

unless是SKILL中的一个控制结构,其基本语法为(unless condition body),当condition为假(即nil)时,执行body中的代码。在表单操作中,这常用于确保表单仅在未创建或未显示时才被初始化或显示,从而避免重复操作。

例如,在表单管理中,常见的模式是:

unless( form form = hiCreateLayoutForm( 'custom_form "Custom Form" hiCreateFormLayout ... ))
unless( form form = hiDisplayForm(form) )

这里,hiIsForm隐含在form变量的检查中(通过unless判断form是否为假),以确保表单在显示前已正确创建。

这种模式有助于维护表单状态的完整性,特别是在交互式脚本中。

  1. `ddsUpdateSyncWithForm 是 Skill 语言中用于数据同步的函数,其功能是将表单(Form)与数据源(如数据库或外部系统)进行同步更新。该函数通常用于确保表单中的数据与后端数据保持一致。以下是关键点:

关键功能
数据同步‌:实时更新表单数据,确保用户界面与后端数据一致。
表单集成‌:与 Skill GUI 应用程序中的表单(如 createAppForm)结合使用,实现动态数据加载和保存。
应用场景‌:适用于需要实时数据更新的场景,如在线表单、实时数据展示等。
使用示例
skill
Copy Code
; 创建表单并同步数据
createAppForm() {
; 创建表单
ddsSyncWithForm(skillGUI(), 'Library', 'Cell', 'Cellview', 'Browse')
; 同步更新数据
ddsUpdateSyncWithForm(skillGUI())
}

注意事项
数据一致性‌:确保数据源(如数据库)与表单字段匹配,避免数据冲突。
性能优化‌:对于大数据量,需考虑同步频率和数据量控制,避免性能瓶颈。
相关函数
ddsSyncWithForm:初始化表单与数据源的同步关系。
ddsUpdateSyncWithForm:触发数据同步更新。

通过这些函数,开发者可以实现高效的数据同步机制,提升用户体验。

posted @ 2025-12-24 10:52  sdadad1  阅读(119)  评论(0)    收藏  举报