Skill语言实现将一个table中的坐标point(x,y)按照x和y进行从小到大排序的函数

本文介绍了一种用于对表格中的点按X或Y坐标进行排序的算法。该算法首先复制原始表格,然后使用冒泡排序法根据指定的坐标类型对点进行排序。提供了两个示例,分别展示了按X坐标和Y坐标排序的结果。
/*****************
对table中的point进行排序,按照type值将x或者y从小到大排
*******************/
defun(TableSort (table type)
	table_len=length(table)
	let((sortedTable)
		sortedTable=makeTable("table")
		for(i 0 table_len-1
			sortedTable[i]=table[i]
		)
		for(i 0 table_len-2
			for(j i+1 table_len-1
				if(type=="x" && car(sortedTable[i])>car(sortedTable[j]) then
					temp=sortedTable[i] 
					sortedTable[i]=sortedTable[j] 
					sortedTable[j]=temp
					
					else if(type=="y" && nth(1 sortedTable[i])>nth(1 sortedTable[j]) then
						temp=sortedTable[i] 
						sortedTable[i]=sortedTable[j] 
						sortedTable[j]=temp
					)
				)
					
			)
				
		)
		sortedTable=sortedTable
	)
)
mytable=makeTable("table")
mytable[0]=3:1
mytable[1]=1:2
mytable[2]=2:3
table1=TableSort(mytable "x")
table1_len=length(table1)
for(i 0 table1_len-1 axlUIWPrint(nil "table1[%d]=%P" i table1[i]))
/*
执行结果:
table1[0]=1:2
table1[1]=2:3
table1[2]=3:1
*/
mytable[0]=1:3
mytable[1]=2:2
mytable[2]=3:1
table1=TableSort(mytable "y")
table1_len=length(table1)
for(i 0 table1_len-1 axlUIWPrint(nil "table1[%d]=%P" i table1[i]))
/*
执行结果:
table1[0]=3:1
table1[1]=2:2
table1[2]=1:3
*/

 

多年以来,Cadence 公司的 CAD 工具 一直是世界上使用最广泛,功能最强大的IC设计工具。而为了应对IC的复杂度越来越高, 设计的困难度也越来越高的情况,Cadence的CAD整合开发环境也越来越庞大,所提供的功能也日益强大,造成使用者在维护及管理上的一大负担。再则, 每一家的设计公司的在设计的流程中多多少少都会有一些小步骤,无法用 Cadence 工具提供的基本做法来达成; 或者是不同公司的工具之间资料转换的问题。工程师遇到此类问题可能需要通过人工的方式去完成连接设计流程中相连的两个步骤; 或是干脆去开发一些小软件来完成这些特定的工作,而此时使用者可能会面临如何将自己开发的软件的I/O 与Cadence 工具的整合环境相连结的问题。一般的做法是产生一些资料档来做资料交换的中介,这些资料档的格式可能是 Cadence 支持的一标准数据格式,也可以是使用者自订的数据格式。这样子是一种间接的做法,因为使用者无法直接去存取 Cadence 环境的内部资料,所以在处理上的弹性会小很多,也较不方便。 为了方便使用者使用整个 CADENCE tools 的整合开发环境,以解决上述的困扰,CADENCE 公司遂发展了 SKILL 语言SKILL 是一种高级的、交互式的语言,是用于 CADENCE tool 的整合开发环境内的命令语言(command language)SKILL 采用人工智能语言 LISP 的语法为蓝本,再加上常用的 C 语言的部份语法设计而成。 SKILL 语言提供许多的接口函数,能让使用者可以编程直接去存取CADENCE 整合环境内的电路资料内容; 也可以让使用者去开发将自己开发的应用程式并入CADENCE tool 的整合环境里。有了 SKILL 言,使用者可以让 CADENCE tool 更充份地融入整个设计流程之中,减少琐碎 的人工转换时间,提升公司的生产力。
<think>好的,我现在需要解决用户的问题:使用SKILL语言将库中的所有cell按Y方向排列到一个新cell中。首先,我需要明确用户的需求。用户希望合并库中的所有cell到一个新的cell,并且这些cell按照Y方向(垂直方向)排列。我需要回忆一下SKILL语言的相关知识,尤其是关于布局操作cell处理的函数。 首先,SKILL语言是Cadence设计工具中用于自动化扩展功能的脚本语言,常用于版图设计数据处理。用户提到的库(library)可能指的是Cadence设计库中的cell,每个cell可能代表一个设计单元,比如电路模块。用户需要将这些cell合并到一个新的cell中,并按Y方向排列。这可能涉及到获取库中的所有cell列表,创建新的cell,然后将每个原始cell作为实例添加到新cell中,并按Y坐标递增排列。 接下来,我需要考虑如何实现这一过程。首先,需要获取当前库中的所有cell。可以使用`ddGetObj`函数获取库对象,然后通过`ddGetCellList`获取库中的cell列表。但需要注意,有些库可能包含系统cell或其他不需要处理的cell,可能需要过滤,比如排除以"prBoundary"开头的cell,或者根据其他条件筛选。 然后,创建一个新的cell,使用`dbCreateCell`函数,并指定库cell名称。例如,用户可能希望新cell的名字是"merged_cell"或其他自定义名称。创建新cell后,需要打开它的版图视图,以便进行编辑。 接下来,需要遍历所有获取到的cell,并按Y方向排列。每个cell需要作为实例添加到新cell中。这里的关键是计算每个实例的位置,确保它们在Y方向上依次排列。可能需要计算每个cell的高度,以便确定下一个cell的Y坐标起始位置。或者,如果不需要考虑cell的实际大小,只是简单地在Y轴方向堆叠,可以将每个实例的Y坐标递增一个固定值或根据前一个实例的位置动态调整。 不过,考虑到版图设计中每个cell可能有不同的高度,正确的方法应该是获取每个cell的bounding box(边界框),然后根据其高度来确定下一个实例的位置。这样,每个实例的Y坐标是前一个实例的Y坐标加上其高度,从而避免重叠。这需要使用`dbComputeBBox`函数来获取每个cell的边界框信息,提取高度,然后累加Y坐标。 在添加实例时,使用`dbCreateInst`函数,指定目标cell、源cell、实例名称、位置方向。位置的X坐标可以固定为0(假设水平方向不偏移),Y坐标则根据之前累加的值确定。方向参数可能需要根据设计需求调整,比如是否旋转或镜像。 另外,用户提到按Y方向排列,可能需要考虑对齐方式。比如,所有实例在X轴方向左对齐,Y轴方向依次排列。因此,每个实例的原点(origin)的X坐标设为0,Y坐标依次递增。 代码结构大致如下: 1. 获取当前库中的所有cell,并过滤不需要的项。 2. 创建新的目标cell。 3. 初始化Y坐标起始位置(比如0)。 4. 遍历每个cell,获取其高度,创建实例,设置位置,然后更新Y坐标。 5. 保存并关闭新cell。 需要注意的错误点包括:确保库存在,处理空库的情况,正确获取cell的版图视图(layout),以及边界框的正确计算。此外,SKILL语言中的坐标通常以微米为单位,需要确认单位设置是否正确。 可能还需要考虑实例的方向(orientation),比如是否旋转或镜像,但用户没有特别说明,这里假设保持默认方向。此外,实例的放置可能需要考虑间距,用户没有提到,所以暂时按紧挨着排列处理,即下一个实例的Y坐标是前一个的Y坐标加上其高度。 现在,需要将这些步骤转化为具体的SKILL代码。例如: - 使用`libId = ddGetObj("库名")`获取库对象。 - 使用`cellList = setof(cv ddGetCellList(libId) ...)`过滤cell。 - 创建新cell:`newCellId = dbCreateCell(libId "NEW_CELL_NAME")`。 - 打开版图视图:`dbOpenCellViewByType(libId "NEW_CELL_NAME" "layout" "a")`。 - 遍历cellList,对于每个cell,获取其bBox:`bBox = dbComputeBBox(cellId->layout)`,高度为右上角Y坐标减去左下角Y坐标:`height = cadr(cadr(bBox)) - cadr(car(bBox))`。 - 创建实例:`dbCreateInst(newCellId cellId "instName" list(0 yPos) "R0")`。 - 更新yPos += height。 此外,需要处理可能的错误,例如库不存在,或者cell没有layout视图等。可能需要添加错误检查,比如使用`when`条件判断。 关于用户提供的参考内容中的flex布局,虽然与SKILL无关,但用户可能希望类似自动排列的功能,即根据每个cell的高度自动计算位置,类似于flex布局中的垂直排列。因此,在代码中需要动态计算每个实例的Y位置,确保不重叠,并按顺序排列。 最后,示例代码可能需要测试,确保在Cadence环境中运行无误。同时,用户可能需要根据实际库名称新cell名称修改代码中的变量。</think>以下是用SKILL语言实现库中所有Cell按Y方向排列的示例代码: ```skill procedure(mergeCellsY(libName newCellName) let((libId cellList newCellId yPos instName bBox height) ;;; 获取指定库对象 unless(libId = ddGetObj(libName) error("Library %s not found" libName)) ;;; 获取库中所有非prBoundary的单元 cellList = setof(cv ddGetCellList(libId) !equal("prBoundary" car(parseString(cv->name "_")))) ;;; 创建新单元 newCellId = dbCreateCell(libId newCellName) dbOpenCellViewByType(libId newCellName "layout" "a" "w") yPos = 0.0 ;;; 初始Y坐标 ;;; 遍历所有单元进行排列 foreach(cell cellList when(cell->layout ;;; 计算单元高度 bBox = dbComputeBBox(cell->layout) height = cadr(cadr(bBox)) - cadr(car(bBox)) ;;; 创建实例 instName = sprintf(nil "inst_%s" cell->name) dbCreateInst( newCellId ; 目标单元 cell->layout ; 源单元layout视图 instName ; 实例名称 list(0.0 yPos) ; XY坐标(X固定为0) "R0" ; 方向 ) ;;; 更新Y坐标 yPos = yPos + height + 0.2 ; 添加0.2微米间距 ) ) ;;; 保存并关闭 dbSave(newCellId) dbClose(newCellId) printf("Created merged cell %s with %d instances" newCellName length(cellList)) ) ) ;;; 调用示例:将mylib库中所有单元合并到merged_layout mergeCellsY("mylib" "merged_layout") ``` ### 关键功能说明: 1. **库获取与过滤**:使用`ddGetObj`获取库对象,通过`setof`过滤系统单元(如prBoundary) 2. **坐标计算**:通过`dbComputeBBox`获取单元高度,动态计算Y坐标位置 3. **实例创建**:采用`dbCreateInst`创建实例,X坐标固定为0,Y坐标按累计高度排列 4. **自动间距**:每个单元间添加0.2um间距防止重叠(可根据需要调整) ### 使用注意事项: 1. 确保目标库存在且有写权限 2. 默认使用layout视图,如需其他视图可修改`cell->layout` 3. 坐标系统基于版图单位(通常为微米) 4. 需要Cadence IC6.1.8或更新版本支持[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冲冲冲~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值