Cadence Allegro SKILL语言讨论和交流

本文由 shirdon 于 2014-6-7 11:57 发布在  Skill    

本文作者 网友 zm0202  来源于 Eda365

 

一、目的方法:

1、如何理解cadence allegro SKILL程序设计语言?
SKILL语言是Cadence提供给用户的一个开发接口,利用其本身提供的接口函数和SKILL语言完成自动化操作的功能。例如:自动化检查,出报告、布局,布线等(在此只讨论pcb Editor的自动化操作)。

2、什么样的人适合使用SKILL语言进行自动化操作?
PCB工程师(具有需求的人,通过编程来实现),EDA二次开发工程师(熟悉编程的人,实现特定的业务需求)

3、SKILL语言能使得PCB设计提高多少效率?
举个很简单的例子,FPM这个自动化建库工具,可以自动生成几千个封装库, 如果一个库需要5分钟,那么,我们建这么多的封装库就需要10000多分钟,利用工具仅仅需要1个小时左右,看到这些,我想大家应该明白了,自动化的操作至少为我们提高效率5倍,当然,质量的保证更是潜在的价值。

4、如何学习SKILL语言?
照猫画虎,我将在后面的帖子中利用Cadence网站上的SKILL函数实例为大家讲解SKILL在PCB设计中的妙用!

 

二、学习入门

1、如何在pcb Editor环境下启动SKILL命令行解释器界面?
直接输入set  telskill , 然后你就会看到一个新的界面, 这个界面就是用来运行SKILL函数和命令的解释器。当然,如果你不觉得界面太小,可以直接在命令行中输入skill , 然后运行SKILL函数和命令, 也可以正常执行,退出可以直接输入exit。

2、如何执行写在文件中的SKILL函数和命令?
首先,我们按照上面的方法运行SKILL命令行解释器,然后输入getSkillPath(), 回车后,可以看到返回一个路径的列表,如果我们的SKILL文件放在这些路径下,就可以直接使用load()函数加载使用,如果你的SKILL文件没有在其中的一个路径下,就需要带上绝对路径,这个地方大家需要注意‘/’和‘\’的区别,我不想做什么理论描述,看看下面的例子:

假如你有一个文件放在C:下,名字为test.il, 一般SKILL文件都以.il为后缀
使用Ultra-Editor打开文件,输入如下内容:
procedure( tr_Example_1()
prog( ()
      ;打印一串字符
      printf("Let's go today.\n")

     ;弹出一个对话框
      axlUIConfirm("Hello, SKILL...\n")

    return(t)

))

然后在SKILL解释器界面下加载SKILL文件如下:
load("C:/test.il")
或者
load("C:\\test.il")

接下来运行tr_Example_1(), 回车,看看什么结果。

3、总结上面的例子(我们学到了什么?)
一、SKILL文件的扩展名一般为.il,通过load()函数可以加载SKILL文件
二、SKILL文件放在一些特定的路径下可以直接加载,不需要输入绝对路径,直接输入文件名即可, load("test.il")
三、带绝对路径加载SKILL文件,一般输入一个/来隔开路径, 如果需要使用\,则需要输入两个,\代表转义,\\表示一个\。
四、使用procedure可以定义一个SKILL函数,上面的例子, 函数名为tr_Example_1,注意函数名后的括号和函数名之间不要有空格。
五、我们可以很方便的在SKILL解释器中单步调试SKILL语句,例如:上面函数体中的printf("Let's go today.\n")可以直接在SKILL解释器下运行,当然axlUIConfirm("Hello, SKILL...\n")也可以,其中函数体中的注释为以分号开始的行,此为单行注释。
六、我们还可以使用像C语言的注释一样/* */来进行模块注释,但是不要出现两个/* */注释的嵌套。

4、我写这么清楚,相信大家还会输入错误,下面有一个附件,大家可以下载直接加载, 哈哈, 注意一切都是英文的逗号,引号!

5、和大家开个玩笑,如果让我知道了SKILL可以单行运行,我就会将它的所有函数在SKILL命令行运行一次,他的函数在什么地方, 请直接参考文档:(在你allegro的安装路径下搜索如下路径)
D:\cadence\SPB_16.6\doc\sklangref\sklangref.pdf

初学者文档:
D:\Cadence\SPB_16.6\doc\sklanguser\sklanguser.pdf


三、Allegro Automation基础问题?

1、Allegro Automation应该掌握的知识,你知道吗?
        ENV File
        Keyboard Shortcuts
                Single key or combinations followed by <Enter>
                Less used functions or windows (C+<Enter> for Color and Visibility Palette popup window)
        Function Keys
                Instantaneous commands
                Typically for most used functions (Toggle, Next, Oops, etc.)
        Scripts
                Record a linear series of repetitive routines
                Play back later
                Playback using keyboard shortcut or function key
        Menu alterations
        Extracta Command
        Strokes
        SKILL

2、Sub-Drawing文件的内容就是SKILL脚本,你知道吗?
        /*在"REF DES/SILKSCREEN_TOP"层创建了一条线,归属于'line _clp_sym对象*/
        _clpDBCreateLine(
                list(_clpAdjustPt(0:0 _clp_cinfo)  _clpAdjustPt(20:20 _clp_cinfo) )
                _clpMKSConvert(15.000000 _clp_cinfo->t_from_units _clp_cinfo->t_to_units)
                "REF DES/SILKSCREEN_TOP"
                'line _clp_sym
        )

3、经常要查看Brd所在的文件夹,如何才能快速找到?
        奉献一个快捷键,看到的人或许会用到:
        alias ~E 'shell explorer .'

4、一键切换pcb光标大小显示的快捷键?
        很像格点显示的切换,其实很简单,你对Allegro了解有多少
        alias ~1 'settoggle pcb_cursor infinite cross'

5、修改了ENV文件,如何在不启动Allegro的情况下让更改生效?
        看看你对Allegro的命令和变量了解多少
        source -q $localenv/env


 四、Allegro Skill 语法

大纲:
    (一)、SKILL基础
    (二)、利用AXL接口操作allegro pcb对象
    (三)、注册和使用自定义Allegro命令
    (四)、Allegro UI界面设计和响应
   
一、SKILL基础
1、简介
    SKILL是基于cadence软件平台的一种二次开发语言,所有的Cadence软件都可以使用SKILL进行二次开发,同样,我们使用的Allegro PCB软件同样可以。
2、启动和退出SKILL解释窗口
    A、在Allegro命令行输入 set telskill
    B、点击Setup - User Preferences...菜单,勾选SKILL类别中的telskill,选择OK按钮确认
    C、在Allegro命令行输入 skill
    使用 exit 退出SKILL解释窗口
3、SKILL语言的数据类型
    整  型:        integer         x           1
    浮  点:        flonum          f           1.0
    数  字:        number          n           2或2.5
    符  号:        symbol          s           'C
    字符串:        string          S           "Count"
    列  表:        list            l           (1 2 3 "Test")
    I/O端口:       port            p           port:"C:/Test.txt"(使用infile或outfile)
      .
      .
      .
      
    SKILL变量数据类型判断相关的函数有:
    type
    typep
    listp
    floatp
    inportp
    fixp
    integerp
    portp
    stringp
    symbolp
   
    通过help函数在SKILL解释窗口查看帮助,例如:help abs
    arglist('abs)  查看abs函数的参数
   
4、在SKILL解释窗口对变量赋值并进行数学运算
    1
    96.54
    'a
    "I hava a dream."
   
    1 + 0.5         对应        plus(1  0.5)
    96.2 - 1        对应        difference(96.2  1)
    5 ** 2          对应        expt(5  2)
    6.2 * 5.1       对应        times(6.2  5.1)
    3.3 / 5.5       对应        quotient(3.3  5.5)
   
    Number = 1.35
    type(Number)
    numberp(Number)
    Number = Number + 1
   
5、在SKILL命令行显示数据
    printf("Hello, World.\n")
    println(5.9867614)
   
    Variable = 25
    printf("%d\n"  Variable)
    println(Variable)
   
    Variable = 98.25468
    printf("%f\n"  Variable)
    println(Variable)
   
    Variable = "Hello, SKILL, I get it, today."
    printf("%s\n"  Variable)
    println(Variable)
   
6、函数调用及其常见问题
    ;正确调用,函数名和左括号之间没有空格
    strcat("I "  "have "  "a "  "question.")
   
    ;出错了... ...
    strcat ("I "  "have "  "a "  "question.")
   
7、SKILL中最伟大的数据类型之一 list 登场了
    ;创建一个列表
    list(1 2 3 4 5 6)
    '(1 2 3 4 5 6)
   
    ;在列表前插入一个元素
    Variable = list(5 6 4 7)
    Variable = cons("Front"  Variable)
   
    ;在列表后追加一个元素
    Variable = list(5 6 4 7)
    Variable = append1(Variable  "End")
   
    ;合并两个列表
    Variable = list(5 6 4 7)
    Variable = append(Variable  list("End"))
   
    ;统计列表中的元素个数
    Variable = list(5 6 4 7)
    length(Variable)
   
    ;访问列表中的元素
    Variable = list(5 6 4 7)
    car(Variable)
    cdr(Variable)
    nth(0  Variable)
    nthelem(0  Variable)
    last(Variable)
   
    ;怎么返回列表最后一个元素
    Variable = list(5 6 4 7)
    car(last(Variable))
    nth(0  last(Variable))
    nthelem(1  last(Variable))
   
    ;倒序一个列表
    Variable = list(5 6 4 7)
    reverse(Variable)
   
8、开发一个SKILL函数并加载运行
    ;自定义函数模板
    procedure( FunName()
    prog( ()
        ;添加你的功能代码
        
        return(t)
        
    ))
   
    注:prog中可以声明局部变量,在其中返回值
   
    ;例子
    procedure( HelloWorld()
    prog( ()
        ;添加你的功能代码
        printf("Hello, World.\n")
        
        return(t)
        
    ))
   
    使用load函数加载SKILL文件, 假设上面的例子保存在D盘下的Test.il文件中
    load("D:/Test.il")
    load("D:\\Test.il")
   
    放在getSkillPath()路径下的SKILL文件不用写文件路径,直接写名称就可以了
   
    在SKILL解释窗口输入 HelloWorld() 调用函数, 和使用系统函数一样... ...
   
9、在函数中使用条件控制和循环
    ;成绩登记打印
    Variable = list(98  70  68  40  82  60.5  53)
   
    procedure( ScoreLevelPrint(ScoreList)
    prog( (Item)
        ;遍历成绩列表
        foreach(Item  ScoreList
            ;使用cond函数条件判断
            cond(
                ((Item < 60)
                    printf("cond  ==>  %.1f  ==>  D"  Item)
                )
               
                (((Item >= 60) && (Item < 75))
                    printf("cond  ==>  %.1f  ==>  C"  Item)
                )
               
                (((Item >= 75) && (Item < 90))
                    printf("cond  ==>  %.1f  ==>  B"  Item)
                )
               
                ((Item >= 90)
                    printf("cond  ==>  %.1f  ==>  A"  Item)
                )
            )
            
            ;使用if函数条件判断
            if( (Item < 60)
            then
                printf("if  ==>  %.1f  ==>  D"  Item)
            )
            
            if( ((Item >= 60) && (Item < 75))
            then
                printf("if  ==>  %.1f  ==>  C"  Item)
            )
            
            if( ((Item >= 75) && (Item < 90))
            then
                printf("if  ==>  %.1f  ==>  B"  Item)
            )
            
            if( (Item >= 90)
            then
                printf("if  ==>  %.1f  ==>  A"  Item)
            )
        )
        
        return(t)
        
    ))
   
10、文件读写操作
    Variable = list("arc"  "arc"  "cline"  "text"  "via"
                    "arc"  "arc"  "cline"  "text"  "via"
                    "arc"  "arc"  "cline"  "text"  "via")
                    
    procedure( type_count(element_list)
    prog( (cline_count  arc_count  via_count  text_count  NoCline  total_count
            elmnt  FileName  FilePort)
        cline_count = arc_count = via_count = text_count = 0
        NoCline = total_count = 0
   
        ;遍历列表
        foreach(elmnt  element_list
            if( (elmnt == "cline")
            then
                cline_count++
            else
                NoCline++
            )
            
            if( (elmnt == "arc")
            then
                arc_count++
            )
            
            if( (elmnt == "via")
            then
                via_count++
            )
            
            if( (elmnt == "text")
            then
                text_count++
            )
        )
        
        total_count = cline_count + arc_count + via_count + text_count
        
        
        ;结果写入文件
        FileName = "C:\\Test.txt"
        FilePort = outfile(FileName  "w")
        
        ;操作
        fprintf(FilePort  "Total Elements: %d\n"  total_count)
        fprintf(FilePort  "Cline Elements: %d\n"  cline_count)
        fprintf(FilePort  "Arc   Elements: %d\n"  arc_count)
        fprintf(FilePort  "Text  Elements: %d\n"  text_count)
        fprintf(FilePort  "Via   Elements: %d\n"  via_count)
        fprintf(FilePort  "NoCline       : %d\n"  NoCline)
        
        close(FilePort)
        
        ;显示文件中的信息到命令行
        FileName = "C:\\Test.txt"
        FilePort = infile(FileName)
        
        ;临时字符串变量
        TmpString = ""
        
        while( gets(TmpString  FilePort)
            printf(TmpString)
        )
        
        close(FilePort)
        
        return(t)
        
    ))
   
11、SKILL中的注释
    ;行注释
   
    /*
        模块注释
        This is a test.
    */
   
12、参考文档
    %CDSROOT%\doc
   
    ;例子
    D:\DesignAdvance\Cadence\SPB_15.2\doc
   
    参考手册列表
    sklanguser              SKILL用户手册
    sklangref               SKILL函数参考手册(encrypt加密SKILL文件)
    skdevref                SKILL语言开发函数参考手册
    skipcref                SKILL调用其他进程参考手册
    skoopref                SKILL面向对象开发参考手册

 



二、利用AXL接口操作Allegro PCB对象
1、简介
    Allegro PCB中是以DBID的方式描述相关对象的(例如:dbid:59252472),通常我们可以使用
    两种方法来获取到Brd文件中的相关信息,其中第一种是使用axlDBGetDesign()接口函数获取
    顶层设计,然后不断使用访问属性的方式获取到其他对象;另一种类似Show Element功能一样
    的操作方式,通过设置对象过滤器,选择高亮对象,获取高亮对象三个步骤获取对象列表,接
    下来,我们就通过两种方法来介绍通过AXL接口函数操作Allegro PCB对象。
   
2、使用axlDBGetDesign()方式访问PCB对象(实例:获取单板上所有的二极管器件名称列表)
    需求:
        获取单板上所有的二极管器件名称列表
        
    分析:
        二极管就是名称以D开头和数字结束的器件
        
    设计:
        正则表达式:  "^D[0-9]+$" 模式匹配以D开头和数字结束的字符串
        
    实现:
   
    procedure( GetAllDiodeCompsNameList()
    prog( (Design  Components  Item  CompName  DiodeCompsNameList)
        ;获取等曾设计ID并赋值给Design
        Design = axlDBGetDesign()
        
        ;获取设计中的所有器件(通过 -> 访问标识的属性)
        Components = Design->components
        
        ;遍历所有的器件
        foreach(Item  Components
            ;获取器件爱你的名称
            CompName = Item->name
            
            ;当器件名称满足二极管条件
            if( rexMatchp("^D[0-9]+$"  upperCase(CompName))
            then
                DiodeCompsNameList = cons(CompName  DiodeCompsNameList)
            )
        )
        
        ;翻转DiodeCompsNameList中的元素
        DiodeCompsNameList = reverse(DiodeCompsNameList)
        
        return(DiodeCompsNameList)
        
    ))
   
   
    同样访问网络的方式(课后习题可以实现一个寻找含有GND的网络名称列表,正则表达式匹配模式为: "GND")
    Nets = Design->nets
    NetNumber = length(Nets)
   
3、通过设置过滤器和Select函数操作brd对象(设置过滤器 -- 设置显示层并选择对象 -- 获取高亮东西 -- 清理现场)
    需求:
        删除ETCH/TOP层所有的TEXT
   
    分析:
        axlDeleteObject接口函数可以删除对象
        
    设计:
        通过使用设置过滤器和Select函数操作brd对象
        
    实现:
   
    procedure( DeleteAllTextsOnEtchTopLayer()
    prog( (CurVis  AllText)
        ;设置过滤器
        axlSetFindFilter(?enabled list("TEXT")  ?onButtons "TEXT")
        
        ;设置显示层并选择对象
        CurVis = axlVisibleGet()
        
        axlVisibleDesign(nil)
        axlVisibleLayer("ETCH/TOP")
        axlUIWUpdate(nil)
        
        axlAddSelectAll()
        
        ;获取高亮东西
        AllText = axlGetSelSet()
        
        ;删除操作
        axlDeleteObject(AllText)
        
        ;清理现场
        axlClearSelSet()
        axlSetFindFilter(?enabled "NOALL"  ?onButtons "NOALL")
        
        axlVisibleSet(CurVis)
        axlUIWUpdate(nil)
        
        return(t)
        
    ))
   
4、参考文档
    %CDSROOT%\doc
   
    例子:
    D:\DesignAdvance\cadence\SPB_15.2\doc
   
    参考手册列表:
    algroskill          AXL接口函数参考手册
三、注册和使用自定义Allegro命令
1、注册Allegro命令
    axlCmdRegister("CmdTest"  'RegisterCmdTestFun)
   
    procedure( RegisterCmdTestFun()
    prog( ()
        axlUIConfirm("Allegro Cmd Register Test...")
        
        return(t)
        
    ))
   
2、赋快捷键
    alias ~1 CmdTest                            (使用Allegro alias命令)
    axlSetAlias("~1"  "CmdTest")                (使用AXL接口函数axlSetAlias)
   
3、菜单编辑
    点击Setup - User Preferences...菜单,选择UI_Paths类别中的menupath,查看Allegro菜单可以存在的路径
    Allegro软件系统的菜单文件都位于%CDSTOOT%\share\pcb\text\cuimenus文件夹下
   
    当前常用的Editor涉及两个菜单,一个是allegro.men(打开brd文件使用);另一个是xlibsymbol.men(打开
    dra文件使用)
   
    //描述菜单的起始(其中//为注释)
    BEGIN
   
    END
   
    //描述弹出下拉子菜单
    POPUP
        BEGIN
   
        END
        
    //描述一个菜单项(&表示热键,第一个字母为菜单名,中间一个逗号,后面为命令)
    MENUITEM    "$New...",      "new"
   
    //描述菜单分栏
    MENUITEM    SEPARATOR
   
    //如果你定义了快捷键,那么菜单上就会显示出来, 这个是系统的功能
   
    另外, 惨淡格式支持条件加载(见#ifndef或#ifdef), 他们后面紧跟一个环境变量名, 探索吧... ...
   
4、SKILL文件的自动加载
    getSkillPath函数返回的路径列表下的Allegro.ilinit文件中添加load文件的命令,对应的文件在Allegro启动
    时自动加载,基于这个功能,我们可以不同每次在使用自定义功能前,先加载SKILL文件。
   
5、参考文档
    %CDSROOT%\doc
   
    例子:
    D:\DesignAdvance\cadence\SPB_15.2\doc
   
    参考手册列表:
    algroskill          AXL接口函数参考手册
四、Allegro UI界面设计和响应
1、简介
    界面是交互设计中不可缺少的一部分,很多时候我们无法只让程序孤芳自赏地运行
   
2、基于文本描述的SKILL界面设计
    例子:Example.form(简单的几段文字已经勾勒出我们想要的界面)
   
    FILE_TYPE=FORM_DEFN VERSION=2
    FORM
    FIXED
    PORT 26 20
   
    HEADER "FINDER..."
    TILE
    TEXT "COMPONENT LIST"
    TLOC 1 1
    FSIZE 25 3
    ENDTEXT
   
    FIELD Placed_List
    FLOC 1 3
    LIST "" 24 16
    OPTION sort
    ENDFIELD
    FIELD done
    FLOC 9 33
    MENUBUTTON "  OK  " 10 3
    ENDFIELD
    ENDTILE
    ENDFORM
   
3、测试Form的方法
    Form测试接口函数axlFormTest(s_formPath)
   
    示例:
        axlFormTest("C:\\Example.form")
   
    功能:
        利用这个函数可以检查Form文件的语法以及Form的显示效果, 编辑界面时不断使用,使你的界面更加漂亮
        
    Tips:
        A、Allegro所有的Form文件都放在Setup - User Preferences...菜单,选择UI_Path列别中的formpath。
           查看Allegro所有界面文件,很好的界面重用资源
           
        B、将自定义的Form文件放在formpath下可以不用写绝对路径调用,不信试试
        
4、界面工具开发ABCDE
    A、创建界面文件并使用axlFormCreate或axlMiniStatusLoad打开Form句柄(注意卸磨杀驴)
    B、使用axlFormSetField初始化界面区域
    C、axlFormDisplay显示界面
    D、在axlFormCallback中定义用户交互和区域响应
    E、使用axlFormClose关闭界面窗口
   
    /*
        功能:通过选择界面列表框中的器件名称浏览器件
        命令:OverviewComps
    */
   
    ;注册命令
    axlCmdRegister("OverviewComps"  'TestFormAppMainModule)
   
    ;创建界面文件并显示界面(主模块)
    procedure( TestFormAppMainModule()
    prog( (FileName  FilePort)
        ;写文件生成界面文件
        FileName = "TestForm.form"
        FilePort = outfile(FileName  "w")
               
        fprintf(FilePort  "FILE_TYPE=FORM_DEFN VERSION=2\n")
        fprintf(FilePort  "FORM\n")
        fprintf(FilePort  "FIXED\n")
        fprintf(FilePort  "PORT 26 20\n\n")
        
        fprintf(FilePort  "HEADER \"FORM TEST...\"\n\n")
        
        fprintf(FilePort  "TILE\n\n")
        
        fprintf(FilePort  "TEXT \"ComponentList:\"\n\n")
        fprintf(FilePort  "TLOC 1 1\n")
        fprintf(FilePort  "FSIZE 25 3\n")
        fprintf(FilePort  "ENDTEXT\n\n")
        
        fprintf(FilePort  "FIELD ComponentList\n")
        fprintf(FilePort  "FLOC 1 3\n")
        fprintf(FilePort  "LIST \"\" 24 16\n")
        fprintf(FilePort  "OPTION sort\n")
        fprintf(FilePort  "ENDFIELD\n\n")
        
        fprintf(FilePort  "FIELD Quit\n")
        fprintf(FilePort  "FLOC 9 33\n")
        fprintf(FilePort  "MENUBUTTON \"EXIT\" 10 3\n")
        fprintf(FilePort  "ENDFIELD\n\n")
        
        fprintf(FilePort  "ENDTILE\n\n")
        
        fprintf(FilePort  "ENDFORM\n\n")
        
        close(FilePort)
        
        ;创建界面句柄,删除界面文件(卸磨杀驴...)
        fw = axlFormCreate(gensym()  FileName  '("E"  "OUTER")  'TestFormAppCallBack  t)
        deleteFile(FileName)
        
        ;界面区域初始化
        TestFormFieldInit(fw)
        
        ;显示界面
        axlFormDisplay(fw)
        
        return(t)
        
    ))
   
    ;界面区域初始化
    procedure( TestFormFieldInit(fw)
    prog( (CompsNameList)
        ;获取所有的器件名称
        CompsNameList = axlDBGetDesign()->components~>name
        
        ;设置器件列表区域
        axlFormSetField(fw  "ComponentList"  CompsNameList)
        
        return(t)
    ))
   
    ;界面区域响应回调函数
    procedure( TestFormAppCallBack(fw)
    prog( (CompName  CompId)
        case(fw->curField
            ("ComponentList"
                CompName = fw->curValue
                CompId = axlSelectByName("COMPONENT"  CompName)
               
                ;定位到对象
                axlZoomToDbid(CompId  t)
               
                ;显示对象详细信息
                axlShowObject(CompId)
            )
            
            ("Quit"
                ;清理现场
                axlClearSelSet()
                axlSetFindFilter(?enabled "NOALL"  ?onButtons "NOALL")
               
                axlFormClose(fw)
            )
        )  
        
        return(t)
        
    ))
   
5、参考文档
    %CDSROOT%\doc
   
    例子:
    D:\DesignAdvance\cadence\SPB_15.2\doc
   
    参考手册列表:
    algroskill          AXL接口函数参考手册
   
    Tips:
        看看下面的路径下是什么东西,保证乐死你... ...
        %CDSROOT%\share\pcb\example\skill
6、课后习题
    搞懂%CDSROOT%\share\pcb\example\skill路径下所有的程序代码,然后恭喜你入门了... ...

 

标签: Skill 语言 入门

发表评论:

电子布局网  |  手机版  |  RSS  |  我要留言

All Rights Reserved. Powered by 电子布局--

sitemap