Skill语言学习_1 🦽
使用Skill语言将不同层的两条PathSeg连通并打孔

Skill版本:
getSkillVersion
"SKILL35.00"
>
学习参考:
https://mp.weixin.qq.com/s/85i0Y4TsJZYy4Ixz-e4Yug
[ Skill ] Cadence Skill 语言入门 - YEUNGCHIE - 博客园
脚本思路:
1、查询所选Path的层属性和首尾坐标;
2、计算不同层Path的相交点(x y);
3、延长各Path至相交点;
4、在相交点打孔。
设计操作:
1、查询所选Path的层属性和首尾坐标;

geGetSelSet()~>??
((db:0x169fa1a8 cellView db:0x169fc09a objType "pathSeg"
prop nil bBox
((62.965 7.89)
(65.62 8.27)
) children
nil groupMembers nil isAnyInst nil
isShape t matchPoints nil net
nil parent nil pin nil
purpose "drawing" textDisplays nil assocTextDisplays
nil markers nil figGroup nil
isUnshielded nil shieldedNet1 nil shieldedNet2
nil layerName "M1" layerNum 61
lpp
("M1" "drawing") connRoutes nil routeStatus
"normal" width 0.38 beginExt 0.0
endExt 0.0 beginPt
(62.965 8.08) endPt
(65.62 8.08) boundary
((62.965 7.89)
(62.965 8.27)
(65.62 8.27)
(65.62 7.89)
) beginStyle "truncate"
endStyle "truncate" topology "none" isOrthogonal
t route db:0x169fbd29
)
(db:0x169fa1a9 cellView db:0x169fc09a objType "pathSeg"
prop nil bBox
((67.085 9.185)
(67.465 10.855)
) children
nil groupMembers nil isAnyInst nil
isShape t matchPoints nil net
nil parent nil pin nil
purpose "drawing" textDisplays nil assocTextDisplays
nil markers nil figGroup nil
isUnshielded nil shieldedNet1 nil shieldedNet2
nil layerName "M2" layerNum 62
lpp
("M2" "drawing") connRoutes nil routeStatus
"normal" width 0.38 beginExt 0.0
endExt 0.0 beginPt
(67.275 9.185) endPt
(67.275 10.855) boundary
((67.085 9.185)
(67.085 10.855)
(67.465 10.855)
(67.465 9.185)
) beginStyle "truncate"
endStyle "truncate" topology "none" isOrthogonal
t route db:0x169fbd28
)
)
>
通过仔细观察可以找到我们所需要的关键信息:
(1)Path的ID:(db:0x169fa1a8)和(db:0x169fa1a9);(type:list)
(2)Path的layerName :("M1")和("M2");(type:list)
(3)Path的beginPt和endPt:((62.965 8.08) ),((65.62 8.08))和 ((67.275 9.185) ),((67.275 10.855));(type:list)
通过代码将上述观察到的关键信息提取出来:
selSet = geGetSelSet()
path1 = car(selSet)
path2 = cadr(selSet)
layer1 = path1~>layerName
layer2 = path2~>layerName
pts1 = list(path1~>beginPt path1~>endPt)
pts2 = list(path2~>beginPt path2~>endPt)
(db:0x169fa1a8 db:0x169fa1a9)
Debug 5>
db:0x169fa1a8
Debug 5>
db:0x169fa1a9
Debug 5>
"M1"
Debug 5>
"M2"
Debug 5>
((62.965 8.08)
(65.62 8.08)
)
Debug 5>
((67.275 9.185)
(67.275 10.855)
)
Debug 5>
2、计算不同层Path的相交点(x y);
将Path的首位坐标分别提取数值:
x1 = caar(pts1)
y1 = cadar(pts1)
x2 = caar(cdr(pts1))
y2 = cadar(cdr(pts1))
x3 = caar(pts2)
y3 = cadar(pts2)
x4 = caar(cdr(pts2))
y4 = cadar(cdr(pts2))
基于向量叉积和参数方程的原理,通过判断两条线段是否相交,并计算出交点坐标:
denom = (y4 - y3)*(x2 - x1) - (x4 - x3)*(y2 - y1)
if( denom == 0.0
then
println("Error:2 Path no X.")
else
ua = ((x4 - x3)*(y1 - y3) - (y4 - y3)*(x1 - x3)) / denom
ub = ((x2 - x1)*(y1 - y3) - (y2 - y1)*(x1 - x3)) / denom
x = x1 + ua * (x2 - x1)
y = y1 + ua * (y2 - y1)
list1 = list(x y)
)
3、延长各Path至相交点;
计算延长后的各Path首位坐标:
a1 = min(x1 x2 x)
b1 = min(y1 y2 y)
a2 = max(x1 x2 x)
b2 = max(y1 y2 y)
a3 = min(x3 x4 x)
b3 = min(y3 y4 y)
a4 = max(x3 x4 x)
b4 = max(y3 y4 y)
point11 = list(a1 b1)
point12 = list(a2 b2)
point22 = list(a3 b3)
point21 = list(a4 b4)
延长各Path至相交点:
path1~>beginPt = point11
path1~>endPt = point12
path2~>beginPt = point21
path2~>endPt = point22
使用不同方向的Path验证算法:

出现问题:

分析问题:以第二种情况为例
path1的原始:
beginPt为(72.915 23.64);
endPt为(70.26 23.64) ;
计算后:
交叉点为(74.11 23.64);
point11为(70.26 23.64) ;
point12为(74.11 23.64);
使用延长算法:
path1~>beginPt = point11
由于此时path1的endPt的坐标为(70.26 23.64) ;
算法的BegingPt设置会失去作用;
此时beginPt依旧为(72.915 23.64);
path1~>endPt = point12
将endPt更新为(74.11 23.64);
延长算法后Path1坐标:
beginPt为(72.915 23.64);
endPt为(74.11 23.64);
造成延长效果的失败。
修改算法:
path1~>beginPt = point11
path1~>endPt = point12
path1~>beginPt = point11
path2~>beginPt = point21
path2~>endPt = point22
path2~>beginPt = point21
再次使用不同方向的Path验证算法:

结果符合预想:

更多不同位置的Path验证算法:

4、在相交点打孔。
确定打孔层次;
sort1 = sort( list(layer2 layer1) 'alphalessp) ;基于alphalessp对layerName进行标准化排序
if(sort1 == list("M1" "M2")
viaType = "M2_M1"
)
if(sort1 == list("M2" "M3")
viaType = "M3_M2"
)
调用交叉点坐标,使用dbCreateVia函数实现打孔功能;
cvID = geGetEditCellView() ; 获取当前编辑的版图视图
tech = techGetTechFile(cvID) ;获取工艺技术文件
viaDefId = techFindViaDefByName(tech viaType) ;查找指定的过孔定义
viaParams = list(list("cutRows" 2) list("cutColumns" 1)) ;设置过孔参数:2行1列
dbCreateVia(cvID viaDefId list1 "R0" viaParams) ;创建过孔
使用不同层进行测试;

整合上述功能:
;主程序
procedure(createViaAtPathIntersection()
let((selSet path1 path2 layer1 layer2)
selSet = geGetSelSet()
when(length(selSet) != 2
println("Error:Please chose 2 Path.")
)
path1 = car(selSet)
path2 = cadr(selSet)
layer1 = path1~>layerName
layer2 = path2~>layerName
pts1 = list(path1~>beginPt path1~>endPt)
pts2 = list(path2~>beginPt path2~>endPt)
intersectPt = calculateIntersection(pts1 pts2)
when( intersectPt == nil
println("Error:2 Path no X.")
return()
)
CreateVia(list1) ;调用打孔模块打孔
path1~>beginPt = point11
path1~>endPt = point12
path1~>beginPt = point11
path2~>beginPt = point21
path2~>endPt = point22
path2~>beginPt = point21
)
)
;辅助计算交叉点和Path拉伸坐标点
procedure(calculateIntersection(pts1 pts2)
let((x1 y1 x2 y2 x3 y3 x4 y4 denom ua ub x y)
x1 = caar(pts1)
y1 = cadar(pts1)
x2 = caar(cdr(pts1))
y2 = cadar(cdr(pts1))
x3 = caar(pts2)
y3 = cadar(pts2)
x4 = caar(cdr(pts2))
y4 = cadar(cdr(pts2))
denom = (y4 - y3)*(x2 - x1) - (x4 - x3)*(y2 - y1)
if( denom == 0.0
then
println("Error:2 Path no X.")
else
ua = ((x4 - x3)*(y1 - y3) - (y4 - y3)*(x1 - x3)) / denom
ub = ((x2 - x1)*(y1 - y3) - (y2 - y1)*(x1 - x3)) / denom
x = x1 + ua * (x2 - x1)
y = y1 + ua * (y2 - y1)
list1 = list(x y)
a1 = min(x1 x2 x)
b1 = min(y1 y2 y)
a2 = max(x1 x2 x)
b2 = max(y1 y2 y)
a3 = min(x3 x4 x)
b3 = min(y3 y4 y)
a4 = max(x3 x4 x)
b4 = max(y3 y4 y)
point11 = list(a1 b1)
point12 = list(a2 b2)
point22 = list(a3 b3)
point21 = list(a4 b4)
)
)
)
;辅助打孔模块
procedure(CreateVia(list1)
let((cvID tech visDefId viaParams newVia)
cvID = geGetEditCellView()
tech = techGetTechFile(cvID)
sort1 = sort( list(layer2 layer1) 'alphalessp)
if(sort1 == list("M1" "M2")
viaType = "M2_M1"
)
if(sort1 == list("M2" "M3")
viaType = "M3_M2"
)
viaDefId = techFindViaDefByName(tech viaType)
viaParams = list(list("cutRows" 2) list("cutColumns" 1))
dbCreateVia(cvID viaDefId list1 "R0" viaParams)
)
)
;将该函数写为快捷键
hiSetBindKey("Layout" "Ctrl<Key>1" "createViaAtPathIntersection()")
将该脚本写入.cdsinit文件自动load
在桌面打开Terminal,输入:
cd
gedit .cdsinin
在.cdsinit文件内,load脚本的全路径:
load("/home/work/project/xian/createViaAtPathIntersection.il")
如下:


浙公网安备 33010602011771号