Skill语言学习_6🦽

使用Skill语言,完成差分对的匹配和Dummy管的添加

image-20260304155052028

Skill版本:

getSkillVersion
"SKILL35.00"
> 

学习参考:

[ Skill ] Cadence Skill 语言入门 - YEUNGCHIE - 博客园

脚本思路:

1、将框选区域所有器件按照器件名字分为两个列表;

2、按照ABBA,BAAB的匹配形式将两个列表的器件重新排列为两个新列表;

3、设定间距x,y;

4、按照设定的间距排布器件,并使得上下列器件的栅极生成于中间;

5、在上下两列器件两端加入Dummy器件。

设计操作:

1、将框选区域所有器件按照器件名字分为两个列表;

获取当前处于编辑状态的 CellView 的数据库 id,赋值给 cv;

cv = geGetEditCellView()

获取当前在版图窗口中被鼠标选中的所有对象的id列表;

instList = geGetSelSet()

提取每个对象的 baseName 属性;

bNameList = instList~>baseName

得到bNameList,并观察结果:

bNameList = instList~>baseName
("NM123.1" "NM123.2" "NM123.3" "NM123.4" "NM1.1" "NM1.2" "NM1.3" "NM1.4")
>

可知可根据baseName"."号之前的字符串将所有器件分为两类。

获取器件名称中第一个点号(.)之前的部分保存在nameList列表中;

nameList = foreach(mapcar bName bNameList car(parseString(bName ".")))

得到nameList,并观察结果:

nameList = foreach(mapcar bName bNameList car(parseString(bName ".")))
("NM123" "NM123" "NM123" "NM123" "NM1" "NM1" "NM1" "NM1")
>

使用mapcar函数将器件ID和器件nameList匹配;

pairedList = mapcar('list instList nameList)

得到pairedList,并观察结果:

pairedList = mapcar('list instList nameList)
(	(db:0x16387a1d "NM123") 
    (db:0x16387a1e "NM123") 
    (db:0x16387a1f "NM123") 
    (db:0x16387a20 "NM123") 
    (db:0x16387a21 "NM1")
    (db:0x16387a22 "NM1") 
    (db:0x16387a23 "NM1") 
    (db:0x16387a24 "NM1")	)
>

将nameList去重后,作为两个列表的区分依据:

uniqueList = ciUtilsMakeUnique(nameList)
("NM123" "NM1")
>

根据nameList将器id分为两个列表:

nm1List = setof(pair pairedList (cadr(pair) == car(uniqueList)))		
nm1List = mapcar('car nm1List)
nm0List = setof(pair pairedList (cadr(pair) == cadr(uniqueList)))
nm0List = mapcar('car nm0List)

得到nm0List和nm1List的id列表:

nm0List
nm1List
(db:0x16387a21 db:0x16387a22 db:0x16387a23 db:0x16387a24)
(db:0x16387a1d db:0x16387a1e db:0x16387a1f db:0x16387a20)
>

符合预期结果。

2、按照ABBA,BAAB的匹配形式将两个列表的器件重新排列为两个新列表;

abbaPattern = list(
    nth(0 nm0List) 
    nth(0 nm1List) 
    nth(1 nm1List)  
    nth(1 nm0List) 
)

baabPattern = list(
    nth(2 nm1List) 
    nth(2 nm0List) 
    nth(3 nm0List)
    nth(3 nm1List)
)

得到abbaPattern 和baabPattern两个id列表:

abbaPattern 
baabPattern
(db:0x16387a21 db:0x16387a1d db:0x16387a1e db:0x16387a22)
(db:0x16387a1f db:0x16387a23 db:0x16387a24 db:0x16387a20)
> 

3、设定间距x,y;

x = 2
y = 2

4、按照设定的间距排布器件,并使得上下列器件的栅极生成于中间;

确定器件的宽度和高度以及原始坐标;

bBox = car(nm0List)~>bBox     
instWidth = caadr(bBox) - caar(bBox)
instHeight = cadadr(bBox) - cadar(bBox)
originxy = car(nm0List)~>xy

排布器件,并按照设定生成栅极;

for(i 0 (length(abbaPattern)-1)
    let((currentItem newxy)
        currentItem = nth(i abbaPattern)
        dbReplaceProp(currentItem "connectGates" "string" "Bottom")
        newxy = list(car(originxy) + i*(x+instWidth) cadr(originxy))
        currentItem~>xy = newxy
        printf("num %d: value = %L\n" i currentItem~>xy)
    );let 
);for

for(i 0 (length(baabPattern)-1)
    let((currentItem newxy)
        currentItem = nth(i baabPattern)
        dbReplaceProp(currentItem "connectGates" "string" "Top")
        newxy = list(car(originxy) + i*(x+instWidth) cadr(originxy) - y - instHeight)
        currentItem~>xy = newxy
        printf("num %d: value = %L\n" i currentItem~>xy)
        ;println(i currentItem~>bBox)
    );let 
);for	

image-20260304165814389

5、在上下两列器件的左右两端加入Dummy器件。

参考Skill语言学习_5

let((targetInst bBox origin left right top bottom x1 y1 width x2 height dummyLib dummyCell masterCv spacing leftOrigin rightOrigin maxNum num newName leftInst rightInst)
    targetInst = car(abbaPattern)
    bBox = targetInst~>bBox
    origin = targetInst~>xy
    left = caadr(bBox)
    right = caar(bBox)
    top = cadadr(bBox)
    bottom = cadar(bBox)
    x1 = car(origin)
    y1 = cadr(origin)
    x2 = caar(last(abbaPattern)~>xy)
    width  = left - right
    height = top - bottom
    dummyLib  = targetInst~>libName      
    dummyCell = targetInst~>cellName    
    masterCv = dbOpenCellViewByType(dummyLib dummyCell "layout")

    spacing = x
    leftOrigin  = list(x1 - width - spacing, y1)
    rightOrigin = list(x2 + width + spacing, y1)

    maxNum = 0
    foreach(instName cv~>instances~>name
        if(rexMatchp("Dummy*" instName)
            then
                num = atoi(substring(instName strlen("Dummy")+1))
                if(num > maxNum then
                    maxNum = num
            );if
        );if
    );foreach
    newName = sprintf(str "Dummy%d" (maxNum+1))
    leftInst  = dbCreateInst(cv masterCv newName leftOrigin  "R0" 1)
    dbCopyProp(targetInst leftInst)

    newName = sprintf(str "Dummy%d" (maxNum+2))
    rightInst = dbCreateInst(cv masterCv newName rightOrigin "R0" 1)
    dbCopyProp(targetInst rightInst)
);let
		
let((selected targetInst bBox origin left right top bottom x1 y1 x2 width height dummyLib dummyCell masterCv spacing leftOrigin rightOrigin maxNum num newName leftInst rightInst)
    targetInst = car(baabPattern)
    bBox = targetInst~>bBox
    origin = targetInst~>xy
    left = caadr(bBox)
    right = caar(bBox)
    top = cadadr(bBox)
    bottom = cadar(bBox)
    x1 = car(origin)
    y1 = cadr(origin)
    x2 = caar(last(baabPattern)~>xy)
    width  = left - right
    height = top - bottom
    dummyLib  = targetInst~>libName      
    dummyCell = targetInst~>cellName    
    masterCv = dbOpenCellViewByType(dummyLib dummyCell "layout")

    spacing = x
    leftOrigin  = list(x1 - width - spacing, y1)
    rightOrigin = list(x2 + width + spacing, y1)

    maxNum = 0
    foreach(instName cv~>instances~>name
        if(rexMatchp("Dummy*" instName)
            then
                num = atoi(substring(instName strlen("Dummy")+1))
                if(num > maxNum then
                    maxNum = num
            );if
        );if
    );foreach
    newName = sprintf(str "Dummy%d" (maxNum+1))
    leftInst  = dbCreateInst(cv masterCv newName leftOrigin  "R0" 1)
    dbCopyProp(targetInst leftInst)

    newName = sprintf(str "Dummy%d" (maxNum+2))
    rightInst = dbCreateInst(cv masterCv newName rightOrigin "R0" 1)
    dbCopyProp(targetInst rightInst)
);let

整合上述代码,并绑定快捷键:

procedure(arrangeMultiplierDevicesAddDummy(x y)
	let((cv instList bNameList nameList pairedList uniqueList nm1List nm0List bBox instWidth instHeight abbaPattern baabPattern originxy)
		cv = geGetEditCellView()
		instList = geGetSelSet()
		bNameList = instList~>baseName
		nameList = foreach(mapcar bName bNameList car(parseString(bName ".")))
		pairedList = mapcar('list instList nameList)
		uniqueList = ciUtilsMakeUnique(nameList)
		nm1List = setof(pair pairedList 
		(cadr(pair) == car(uniqueList)))		
		nm1List = mapcar('car nm1List)
		
		nm0List = setof(pair pairedList 
		(cadr(pair) == cadr(uniqueList)))
		nm0List = mapcar('car nm0List)

		abbaPattern = list(
		    nth(0 nm0List) 
		    nth(0 nm1List) 
		    nth(1 nm1List)  
		    nth(1 nm0List) 
		)
        baabPattern = list(
		    nth(2 nm1List) 
		    nth(2 nm0List) 
		    nth(3 nm0List)
		    nth(3 nm1List)
		)
 
		bBox = car(nm0List)~>bBox     
		instWidth = caadr(bBox) - caar(bBox)
		instHeight = cadadr(bBox) - cadar(bBox)       
		originxy = car(nm0List)~>xy
		
		for(i 0 (length(abbaPattern)-1)
		    let((currentItem newxy)
		        currentItem = nth(i abbaPattern)
				dbReplaceProp(currentItem "connectGates" "string" "Bottom")
				newxy = list(car(originxy) + i*(x+instWidth) cadr(originxy))
				currentItem~>xy = newxy
				printf("num %d: value = %L\n" i currentItem~>xy)
			);let 
		);for

		for(i 0 (length(baabPattern)-1)
		    let((currentItem newxy)
		        currentItem = nth(i baabPattern)
				dbReplaceProp(currentItem "connectGates" "string" "Top")
				newxy = list(car(originxy) + i*(x+instWidth) cadr(originxy) - y - instHeight)
				currentItem~>xy = newxy
				printf("num %d: value = %L\n" i currentItem~>xy)
				;println(i currentItem~>bBox)
		    );let 
		);for	
		
		let((targetInst bBox origin left right top bottom x1 y1 width x2 height dummyLib dummyCell masterCv spacing leftOrigin rightOrigin maxNum num newName leftInst rightInst)
			targetInst = car(abbaPattern)
			bBox = targetInst~>bBox
			origin = targetInst~>xy
			left = caadr(bBox)
			right = caar(bBox)
			top = cadadr(bBox)
			bottom = cadar(bBox)
			x1 = car(origin)
			y1 = cadr(origin)
			x2 = caar(last(abbaPattern)~>xy)
			width  = left - right
			height = top - bottom
			dummyLib  = targetInst~>libName      
			dummyCell = targetInst~>cellName    
			masterCv = dbOpenCellViewByType(dummyLib dummyCell "layout")
			
			spacing = x
			leftOrigin  = list(x1 - width - spacing, y1)
			rightOrigin = list(x2 + width + spacing, y1)
			
			maxNum = 0
			foreach(instName cv~>instances~>name
				if(rexMatchp("Dummy*" instName)
					then
			        	num = atoi(substring(instName strlen("Dummy")+1))
			        	if(num > maxNum then
			        		maxNum = num
			        );if
				);if
			);foreach
			newName = sprintf(str "Dummy%d" (maxNum+1))
			leftInst  = dbCreateInst(cv masterCv newName leftOrigin  "R0" 1)
			dbCopyProp(targetInst leftInst)
			
			newName = sprintf(str "Dummy%d" (maxNum+2))
			rightInst = dbCreateInst(cv masterCv newName rightOrigin "R0" 1)
			dbCopyProp(targetInst rightInst)
		);let
		
		let((selected targetInst bBox origin left right top bottom x1 y1 x2 width height dummyLib dummyCell masterCv spacing leftOrigin rightOrigin maxNum num newName leftInst rightInst)
			targetInst = car(baabPattern)
			bBox = targetInst~>bBox
			origin = targetInst~>xy
			left = caadr(bBox)
			right = caar(bBox)
			top = cadadr(bBox)
			bottom = cadar(bBox)
			x1 = car(origin)
			y1 = cadr(origin)
			x2 = caar(last(baabPattern)~>xy)
			width  = left - right
			height = top - bottom
			dummyLib  = targetInst~>libName      
			dummyCell = targetInst~>cellName    
			masterCv = dbOpenCellViewByType(dummyLib dummyCell "layout")
			
			spacing = x
			leftOrigin  = list(x1 - width - spacing, y1)
			rightOrigin = list(x2 + width + spacing, y1)
			
			maxNum = 0
			foreach(instName cv~>instances~>name
				if(rexMatchp("Dummy*" instName)
					then
			        	num = atoi(substring(instName strlen("Dummy")+1))
			        	if(num > maxNum then
			        		maxNum = num
			        );if
				);if
			);foreach
			newName = sprintf(str "Dummy%d" (maxNum+1))
			leftInst  = dbCreateInst(cv masterCv newName leftOrigin  "R0" 1)
			dbCopyProp(targetInst leftInst)
			
			newName = sprintf(str "Dummy%d" (maxNum+2))
			rightInst = dbCreateInst(cv masterCv newName rightOrigin "R0" 1)
			dbCopyProp(targetInst rightInst)
		);let
    );let
);procedure

hiSetBindKey("Layout" "Ctrl<Key>2" "arrangeMultiplierDevicesAddDummy(2 2)")

PS:函数中的x代表器件的左右间距,y代表器件的上下间距,以(2 2)举例!!

测试该脚本:

image-20260305103034499

将该脚本写入.cdsinit文件自动load

在桌面打开Terminal,输入:
cd
gedit .cdsinin
在.cdsinit文件内,load脚本的全路径:
load("/home/~~/~~/~~/arrangeMultiplierDevicesAddDummy.il")
如下:

image-20260305103150938

综上完成了差分对的匹配和Dummy管的添加的功能🎉🎉🎉

posted @ 2026-03-05 10:34  StupidMonkey19  阅读(81)  评论(0)    收藏  举报