第六章 dc - shell综合脚本(3)

2019-08-31 10:45

9 current_design active_design

10 set_attribute active_design level\\

current_level –type integer –quiet

11 filter (find(reference,”*”),”@is_hierarchical==true”) 12 local_refs=dc_shell_status

13 foreach(design_element, local_refs) {

14 reference_name=reference_element

15 foreach(design_element, unlabeled_designs) {

16 design_name=design_element

17 if(design_name==reference_name) {

18 set_attribute active_design \\

level-1 –type integer –quiet

19 break } }

20 if (get_attribute(-quiet active_design,level)==-1) {

21 break

} }

}

22 filter unlabeled_designs “@level==-1” 23 unlabeled_designs=dc_shell_status 24 current_level=current_level+1 }

第7行说明只要unlabeled_designs非空,就初始化运行一个while循环。第8-24行是while循环的主体。第8行初始化一个嵌套的foreach循环。把unlabeled_designs每个设计按顺序列表给active_design 。第9-21行是foreach循环的主体,第9行把变量current_design变成active_design参数化的设计。第7-9行揭示了许多关于这个脚本的根本的算法 。这个脚本重复操作未作标志设计中的每一个设计直到所有的设计都贴上标志。

第10行改变了active_design的层次level的属性,从初始值-1变为包含在current_level变量的值。第11-12行把在active_design所有层次reference的列表赋给变量local_refs。第13行启动一个foreach循环,把在local_refs中的每个reference赋给reference_element变量。第14行把reference_element赋给变量reference_name.第13-14行和第15-16行类似。但第15-16行把在unlabeled_designs中的每个设计名字赋给design_name变量。

第17行比较当前的reference_name和design_name。如果匹配,就执行if循环体(第18-19行)。第18行改变active_design层次level属性的值,原来current_level为-1。第19-21行退出两个内部的foreach循环(如果在17找到未作标志的设计的reference)。第10-19行揭示基本算法的实质。这个脚本简单地体现了以上所提的层次规则。当且仅当当前设计的reference都做标志时,对于每一个unlabeled_design,才给current_level设置层次level的属性。第17-18 行保证在更高层设计之前,更低层的设计要做层次level属性的标志。

第22-24 行更新unlabeled_designs和current_level变量,这两变量提供作while循环控制参数服务。第22行返回设计表,其层次属性设置为-1(表示未作标志)。第23行赋值此表给unlabeled_designs属性。注意没有22-23 行,while 循环是无限的循环,但它们做了更多的while循环的约束。它们也修剪了设计的集合 (按顺序通过循环)。第24行current_level的增量为1。这行和第10行和第18行一起工作保证设计的下一层也做层次的标志。

考虑一下当这个脚本运行在前面的top设计树,会发生什么。首先通过循环current_level为0,unlabeled_designs为{top,A,1,2,B},及这些设计都有层次属性值为-1。Top会把active_design和top’level的属性设置为0。接着local_refs的集合为{A,B},在unlabeled_designs列表的每一个design_name和在local_refs中的每个reference_name作比较。由于unlabeled_designs和 local_refs非空交集。Top设计层次level属性设置为-1。

在19 和21 行的break 命令提高脚本的执行速度。只要unlabeled_designs和 local_refs非空交集,层次level属性恢复设置为-1和嵌套的foreach循环要被打破(正在执行交集的分析)。并不必要判定reference B是否为unlabeled_design。事实上,reference A是unlabeled_design足以判定top不应贴上0层的设计标志。

在top设计被解析之后,设计A有类似的结果。接着设计1被解析。Active_design变量设置为1,其层次属性设为0。第11行的find(reference “*”)命令返回一个reference 地集合(单元)与unlabeled_designs无交集。在通过while循环后,仅设计1和2层次属性从-1变为0。unlabeled_designs会更新为{top,A,B}. current_level的增量为1。

在第二次通过循环时,设计A被贴层次1的标志。在第三次通过循环时,设计B被贴层次2 的标志。在第四次通过循环体时,设计top要贴层次3的设计标签。在第四次通过循环体后,unlabeled_designs为空集,current_level为4。循环终止,脚本完成任务。

6-5-3 有序搜寻:根首先(root-first)和叶首先(leaf-first)

已经做了层次属性的标签,有可能控制设计搜寻的顺序。开发的方法可以作任何层次的编译,约束可以加在设计的根树下,然后沿着树向下特征化的贯穿,直到衍生的约束贯穿到叶设计的部分。

一旦约束存在设计树的最低层,每个设计都可被编译。编译的过程开始于最低层,返回于最高层。脚本贯穿设计的层次从顶至下的方式叫根首先搜寻(root-first-search,RFS),从低向上的方式叫叶首先搜寻(leaf-first-search,LFS)。典型的计算机科学算法叫按宽度首先(breadth-first)和深度首先(depth-first)顺序的搜寻树。脚本是类似的,因此仅根首先(root-first)详细分析阐述。 1 max_level=-1

2 foreach(design_element,find(design,”*”)) {

3 get_attribute design_element level-quiet 4 current_level=dc_shell_status 5 if(current_level>max_level) {

6 max_level=current_level 7 root_design=design_element } }

8 current_level=max_level

第1-7行循环通过树中每一个设计,决定根设计的名字和根设计层次属性的值。不同于label_hierarchy脚本,这个脚本没有假定current_design为层次的根(如做了这个假设,max_level是current_design的简单层次)。当变量max_level用来初始化current_level变量时,根设计的层次被保存。变量current_level用来控制在每一个层次while循环寻找设计。

9 while(current_level>=0) {

10 filter find(design,”*”) “@level==current_level” 11 design_list=dc_shell_status

12 foreach(active_design,design_list) {

13 echo active_design 14 RFS_operation }

15 current_level=current-1 }

16 current_design root_design

当current_level的值为正时,层次的current_level设计的列表赋值给变量design_list。第12行启动一个循环,把design_list地每一个元素赋值给变量active_design 。第13行用echo命令列举active_design.第14行执行了RFS_operation命令。在跳到15行之前,在循环结束前current_level在减少,以便RFS_operation准确按树中宽度首先(breadth-first)的 顺序执行脚本。第16行简单地把current_design的状态恢复到root_design。

RFS_operation是什么?它不是预先的定义的设计编译器命令,而是一个别名。这个脚本的功能有用户定义。这个脚本执行一个操作,针对做好标签的设计树的每个设计,按照宽度首先(breath-first)的顺序进行执行。执行设计的具体的操作,可通过简单改变RFS_operation的别名进行变化。对CRWC方法,运行的脚本描述了有关当前设计的单元的特征。这个设计的特征的任务非琐碎的,因而RFS_operation调用另一个脚本发出必须命令的顺序: alias RFS_operation “characterize_active_design” alias characterize_active_design\\

“include characterize_active.scr”

在你分析characterize_active_design脚本之前,回头看宽度首先的搜寻脚本。要把这个脚本变成深度首先(depth-first)的脚本,需作那些变化呢?仅有4行需要改变: 8 current_level=0

9 while(current_level<=max_level) 14 LFS_operation

15 current_level= current_level+1

取代开始于max_level和current_level减少为0,深度首先(depth-first)脚本开始于0,current_level 增加为max_level。第14行变化仅保证有脚本反映其意义的脚本执行操作的名字。 6-5-4 描述active_design的特征

根首先(root-first)搜寻的脚本控制设计层次的特征化的顺序,有一个重要的课题需要阐明,CRWC方法可以合适

地描述任意设计层次的特征。回头看一下top设计的特征。

根首先(root-first)搜寻的脚本设计按一定的顺序特征化:top,B,A,1和2(1和2可能保留)。但设计A哪一个应该特征化?设计A有两个父top和B。对这个问题有三个可能的答案。这个脚本能描述有关设计A的top设计单元特征。或者,脚本使用uniquify命令复制设计A变成设计A_1和A_2以及特征化。

一般而言,假设设计在这次没有被特征化是安全的。在层次被修剪和做标签前,设计应该特征化。(特征化的设计有效的深度和层次属性)。哪一个设计应该特征化,没有唯一的答案。CRWC方法必须具有构造能力来保证方法的一般使用。这个问题最好的解决方案允许两种具体设计的结构。

首先,一般的方法决定characterize_me的属性是否存在树中非独特设计的示例。这允许按照示例具体的基础回答“哪个设计”的问题。

其二,这种方法应该提供一种机理覆盖characterize命令衍生的设计属性。正如上面所讨论一样,revise_script用作这个目的。Characterize脚本采用下面的惯例:

1:如果在设计层次中有多个示例,仅有一个示例将被特征化。为决定要被特征化的示例,脚本选择单个示例(单元),把characterize_me的属性设置为真。如果有多个示例把characterize_me的属性设置为真,要随机选择一个示例特征化。设计应该特征化,或者单个设计示例要被赋予characterize_me的属性。这种随机选择的机理不应该用在实践中。

2:这个脚本衍生的约束,是有active_design变量鉴别的设计的示例的一种约束。这种衍生的约束将被来写一个脚本文件,其名字为design_name.wscr。design_name是active_design的名字,.wscr后缀代表write_script。对于任意给定的设计衍生的约束可能不反映真实的设计目标,这个脚本文件名为design_name.wscr,若它已存在在写出write_script之前修改衍生的约束。.wscr后缀缚在设计的名字后用来创建revise_script,其文件名代表revise_script。正如上面所解释的,revise_script提供一种在CRWC方法中包进时序预算的机理。

为记住这个脚本的目的,考虑随后的实现: 1 if (current_level

2 active_name= “ ”

3 active_name=active_design 4 reference_name=“ ” 5 possible_cell_list={ } 6 selected_cell_count=0 7 selected_cell_list={ }

8 filter find(design,“*”) “@level>current_level”

9 higher_levels =dc_shell_status

这个脚本假定它是被上面编写的宽度首先(breadth-first)的脚本所调用。在执行单命令前,比较脚本的其中两个变量。如果active_design是设计树的根,就无需特征化active_design。第一行确保在这种情况下脚本立即返回。第2-9行初始化命令。第8-9行值得特别注意,它们按照下面规则修剪设计的空间。

层次属性的定义保证n层不能包含任意层次属性高于n-1的设计。当在设计树中搜寻active_design示例时必须寻找更高层次的设计的示例。第8-9行利用这个事实,通过修剪搜寻空间减少脚本的运行时间。 10 foreach (design_element,higher_levels) {

11 current_design design_element 12 cell_list={ }

13 filter (find(reference,\ 14 local_refs=dc_shell_status

15 foreach(reference_element,local_refs) {

16 reference_name=reference_element 17 if (active_name==reference_name) {

18 filter find(cell,“ *”) “@ref_name==active_name” 19 cell_list=dc_shell_status 20 break

}

} 21 if (cell_list!={ } ) {

22 parent_design=current_design

23 filter cell_list “@characterize_me==true” 24 possible_cell_list=dc_shell_status 25 if (possible_cell_list !={ })

{

26 selected_cell_count=1

27 selected_cell_list= possible_cell_list 28 break 29 } else {

30 selected_cell_list= selected_cell_list+cell_list 31 foreach instance,cell_list)

{

32 selected_cell_count= selected_cell_count+1

}

} } }

第10-32 行在设计层次中寻找和计算active_design所有的示例。第18行使用这个事实,单元的ref_name属性与设计的名字相同。第13-17行和20行可以从脚本中删除,不会影响它的功能。它们仅提供一个目的。

在多数设计中有远比单元少的多的参量。第18-19行可由第13-20行代替,但在higher_level设计的每个单元可以用来过滤寻找active_design中少的示例。同第13-17行和20行相关,在每个层次的参考量过滤判定包含在active_design设计的位置。这个过程确保第18-19行运行设计,仅是同active_design相关的设计。

第22行存储了含在active_design的名字。在特征化之前把current_design变成active_design的parent_design是必须的。如果发现active_design的示例不止一个,用来特征化active_design的parent_design是最后一个被找到的。(对parent_design随后的任务还会复写前面的任务)。

第23-25行决定active_design的示例是否要把characterize_me属性设置为真。如果是的,第26-28行就会被执行。第26行把selected_cell_count变为1。第27行覆写要把characterize_me属性设置为真的单元,这些单元的列表同子集有关。

第28行立即退出搜寻的路径。如果找到有characterize_me属性active_design的示例,不必再找设计层次的其他示例。注意:脚本可作这样的假设,在设计的层次中,active_design仅有一个示例把characterize_me属性设置为真 。如果不是这种情况,脚本会用其中一个characterize_me的示例,但它不会警告用户――鉴别的多个示例需被特征化。这个脚本可以改进给出那样一个警告,但它折中运行时间(当发现一个characterize_me的示例它预先退出搜寻的循环)。

如果active_design无示例标有characterize_me属性,active_design的所有的示例按第30-32行计算。搜寻继续进行或找到标有characterize_me属性的示例。

33 foreach (selected_cell, selected_cell_list) { } 34 if (selected_cell_count>1)

{

35 echo “ ”

36 echo “Multiple cells were found for the \\

following design : ”

37 echo active_name

38 echo “An arbitrary instance will be characterized.” 39 echo “Consider placing the Boolean attribute:” 40 echo “characterize_me”

41 echo “on a cell to force which cell is \\

characterized,or”

42 echo “uniquify the hierarchy so that all cells will\\

be characterized.”

43 echo “ ”

}

第33行是一个空的foreach循环。这个循环的目的是在设计树找到的active_design 最后的示例的值赋给变量selected_cell。最后设计的选择是任意的(空循环容易选择的)。若示例标有characterize_me属性,selected_cell_list仅包含有这个属性的示例。第33行成功选择适当地示例,不管它是否标有characterize_me属性。

第34-43行没有增加这个脚本的任何功能。他们仅警告用户如果找到非特殊化的设计,其示例也不包有

characterize_me属性。好的脚本执行错误检查保证他们不被错误使用。 44 current_design parent_design

45 characterize –constraints find(cell,selected_cell) 46 current_design active_design 47 script_file=“ ” 48 revise_file=“ ”

49 script_file=active_name 50 revise_file= active_name

51 script_file= script_file+“.wscr” 52 revise_file= revise_file+“.rscr” 53 which revise_file

54 if (dc_shell_status !={ })

{

55 include revise_file

}

56 active_design > script_file

}

第44-45行为active_design执行characterize命令。第47-52行为revise_file和write_script文件决定适当地文件名。第53-54行判定revise_file是否存在。如果结果非空集,第55行就执行在revise_file的读操作,以便覆盖部分或全部衍生的约束。最后,第56行对于active_design,把衍生的修改的约束写进active_design文件中。 6-5-5 编译active_design

在描述了设计层次的特征后,其中包过对于每一个设计做了一个revise_script和写了一个write_script,CRWC方法最后的步骤是读设计的策略脚本和编译设计层次。叶首先搜寻(leaf-first-search)脚本控制编译的顺序,调用一个compile_active_design脚本来读策略脚本,执行编译active_design的每一设计层次。 1 active_name =“ ”

2 active_name =active_design

3 script_file= active_design “ ” 4 revise_file=“ ” 5 strategy_file=“ ”

6 script_file= active_name 7 revise_file= active_name 8 strategy_file= active_name

9 script_file= script_file+“.wscr” 10 revise_file= revise_file+“.rscr” 11 strategy_file=strategy_file

12 default_script =“default.scr”

脚本开始执行初始化必需的变量。四个脚本的文件:default_script、script_file(write_script)、revise_file(revise_script)、strategy_file (strategy_script)都在编译的脚本之中。如果编译脚本的顺序是按照特征化脚本的顺序执行,revise_script不起作用。

既然在characterize脚本生成write_script之前已包进revise_script,在revise_script中的所有的信息存在于write_script。但是,运行编译的脚本紧跟write_script是不必要的。为使得编译和特征化的脚本单位化,独立化,脚本加进revise_script可以保证最新的时序预算应用在active_design。 13 current_design active_design 14 which default_script

15 if (dc_shell_status !={ })

{

16 include default_script

}

17 which script_file 18 if (dc_shell_status)

{

19 include script_file

}

20 which revise_file 21 if (dc_shell_status)

{

22 include revise_file

}

23 which strategy_file 24 if (dc_shell_status)

{

25 include strategy_file

}

26 compile

27 set_don't_touch active_design

第13-25行简单地检查四个脚本文件的存在性。第26行是CRWC方法的最高点,它编译active_design。第27行在active_design设置don't_touch属性,避免在更高层子设计中被再次编译。 6-5-6 编译设计体系:整体编译

以上编写的脚本折衷了CRWC方法的条款。最后两个脚本帮助聚在一块。第一使用别名的命令创建了用户定义的命令,可以执行上面编写的脚本。第二按顺序执行执行这些命令,编译在current_design地设计体系。图6.3演示了在compile_hierarchy脚本中CRWC脚本如何聚在一起。

图6.3 编译脚本层次

make_alias脚本mk_alias.scr给每一个CRWC脚本取一个命令名字的别名: 1 alias prune_designs include prune.scr

2 alias label_hierarchy include label_hir.scr 3 alias RFS include RFS.scr 4 alias LFS include LFS.scr

5 alias characterize_active_design include char_act.scr 6 alias compile_active_design include comp_hir.scr 7 alias compile_hierarchy include comp_hir.scr

compile_hierarchy脚本comp_hir.scr执行CRWC方法的七个步骤。在设计体系做了修剪和标签后,可以判定设计体系的根设计下default_scriptwrite_script,revise_script,strategy_script的文件是否存在。如果存在,脚本文件就会建立根层次的约束。如果不存在,compile_hierarchy脚本会简单假设已存的根层次的约束是合适的,开始执行charactrize/write_script/compile顺序(第15-18行)。一旦体系被编译,第19-21行就会以DB的格式写出新的编译设计体系信息。 1 prune_designs 2 label_hierarchy 3 script_file =“ ” 4 revise_file=“ ”

5 script_file =root_name 6 revise_file= root_name

7 script_file = script_file +“.wscr” 8 revise_file= revise_file+“.rscr” 9 default_script = “default.scr” 10 which default_script 11 if (dc_shell_status)

{

12 include default_script

}

13 which script_file 14 if (dc_shell_status)

{

15 include script_file

}

16 which revise_file 17 if (dc_shell_status)

{

18 include revise_file

}

19alias RFS_operation include characterize_active_design 20 include RFS

21 alias LFS_operation include compile_active_design 22 include LFS

23 current_design root_design 24 link

25 write –f db –hierarchy 6-5-7 增强和扩展CRWC脚本

以上编写的脚本有实际的限制。多数设计有许多层次体系,不需独立编译。当编译体系层次的接口时,高层的编译有个优点。设计编译器能反复定义接口两边的逻辑,它不受don't_touch的限制。

BSDO方法说明了较高层的编译也能产生高质量的结果。这种现象依赖于设计。通过隔离关键的路径,低层编译可能进行较快的设计。或通过屏蔽交叉体系边界的关键路径,它们也可能进行较慢地设计。正如在BSDO中AM2910所演示的例子一样,当同等价的低层编译比较时,高层的编译也可能进行较小规模的设计。认识到这个效果,许多设计者想在CRWC脚本中限制树贯串的深度,以便在体系结构中仅高层的设计特征化(编译)。

遗憾是,层次level的属性不能特别借来很好地改进这种算法。低层设计可能在设计体系的高层独占存在。为增强CRWC脚本,限制体系结构的贯穿深度,需要一种属性表明每个设计的层次深度(从顶至下计算),弥补层次的属性。Top体系结构的属性标志如下:

作设计深度标志的规则必需同设计层次的赋值规则相反。设计的深度是同设计相关体系结构的最高层的深度(或等价,有设计实例存在的最高体系级别)。在这个体系结构中设计A的深度为1,尽管它存在于深度为1和2的设计体系中。Top深度为0,A和B的深度为1,1和2的深度为2。

一个增强的 label_hierarchy脚本,它可以在设计树中设置层次和深度属性。由于定义了深度属性,“深度首先”

(depth-first)和“宽度首先”(breadth-first)脚本仅需作细小的修改就可在具体的深度“到底”(bottom out)-停止层次贯串。

上面虽然介绍了计算机科学术语深度首先(depth-first)和宽度首先(breadth-first),执行搜寻的脚本还是命名为根首先(root-first)和叶首先(leaf-first)。深度首先(depth-first)和宽度首先(breadth-first)保留用作增强的脚本,它是按深度而不是层次贯串,因增强的算法和典型的计算机科学的定义深度首先(depth-first)和宽度首先(breadth-first)更加一致。

两套脚本对于不同的应用是有用途的。增强的搜寻脚本继承原来脚本的优点而不是荒废它。在这些脚本中,变量depth_limit用来辨别搜寻的深度。对于不同的设计有不同的depth_limit是合适的,设计中设置limit属性表明每个设计有适当的depth_limit。深度首先(depth-first)和宽度首先(breadth-first)的脚本分别命名为DFS.scr和BFS.scr。

一般而言,每次一个子设计变化就要重新编译整个设计体系是不令人满意的。使用CRWC容易进行重新编译单个的设计。简单地把修改的设计读进设计编译器,其中设计的write_script文件采用前面修改的约束,它是由CRWC脚本的设计体系所衍生的。接着发出一个编译命令。可以编写文件自动执行这个过程。虽然提出这个方法,许多设计者从来没有使用过compile_hierarchy脚本。

通过删除最后的5行命令,compile_hierarchy脚本可以变成charactrize_hierarchy脚本。许多设计者发现使用这种方法是有益的,它可以解耦原来compile_hierarchy脚本的特征化和编译的步骤。这些脚本可以工作在设计体系的所有的层次,,去耦使得执行必要的特征化、编译的步骤很容易。

在应用说明的结尾增强的脚本似乎有价值,但它们不是实现CRWC最高效的方法。对于规模大的设计而言,特征化一个设计要求的时间限制了CRWC方法的优点。幸运的是,特征化单个设计的时间同特征化一系列设计所需的时间差的不多。

为改进CRWC方法的运行时间,重写characterize_active_design路线,以便特征化仅按每层去做而不是按每个设计去做。发展一种新的机理(如用户定义的属性),处理非特化的设计,或者在体系结构中发出uniquify的命令。用单个命令特征化整个设计体系如:

characterize –constraints filter(find(-hierarchy cell,“*”),\\“is_hierarchical==true”)

减少特征化时间数并不是改进CRWC方法的性能的唯一的途径。原先charactrize/write_script/compile方法的用户将会记得,这个技术超过charactrize/compile的优势是在编译低层设计前具有移开高层设计的能力。

改进存储器的利用总是好的主意。由于当今的工作战中I/O操作明显慢于CPU,当设计进出存储器交换时,特征化和编译的时间显著增加。修剪设计,有几种方法解决这个问题。设计应该是否,何时,怎么样从存储器中移开/装载,这种决定由用在项目的设计管理程序引导。对于CRWC方法,从存储器中移开高层的设计是不必要的。这种提高对读者而言是一个练习。

如果你一这种方式选择增强脚本,记住当设计从存储单元移开时,设计从变量移开。用一个目标类型变量存储设计,对于未来的参量用字符串变量存储其名字。 6-5-8 结论

这个应用说明介绍了一些dc_shell命令,可以帮助Synopsys用户认识设计编译器的功能和灵活性。详细阐述了设计目标,变量,属性,别名,控制流命令。

在介绍了dc_shell的基本特性后,使用dc_shell脚本发展了一种体系编译的方法。这种characterize/revise_script/write_script/compile(CRWC)方法建立在由Mikael Hakansson和David Gregory介绍的思想之上。

CRWC脚本解决了体系编译的难题,对于宽广范围的设计,任意设计的体系都可客户化,可操作化。在CRWC脚本介绍后,几个可能的脚本的增强和扩展的方法强调简单的事实,即没有一个通用的编译脚本适合所有的应用。这就是为什么dc_shell脚本有如此强的能力。

脚本允许设计者自动进行他们自己指定的设计或者指定方法的dc_shell的程序。创造性,你可能发现更简单,不一般的更适合你自己的设计方法。

在这个应用说明中解释了几个常见的错误,没有适当地警告就排除掉是不负责任的。使用dc_shell脚本你可能陷入麻烦。无限的while循环是一个好的例子。在等待无限脚本的完成,设计者浪费了宝贵的时间。

这儿常见的陷阱不完全。还有许多其它的陷阱可以避免。当写脚本时,遵循着合理的软件设计实践。文件化你的编码。用list和echo表明你的改进。若你在特定的结构上遇到困难,再尝试一次。发现每个命令的细微的差别可能要花一段时间。


第六章 dc - shell综合脚本(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:体操试题库

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: