默认placeSpareModule只允许在place stdcell之后插入,place之前插会报错。
那么如果一定要place之前插怎么办呢,下面介绍用addInst -loc {x y}来手工插sparecell。
首先需要准备好一下sparecell list,如下:
set sparelist {
AND2_X2 100
NAND2_X2 100
OR2_X2 100
NOR2_X2 100
XOR2_X2 70
MX2_X2 30
AOI22_X2 30
AO22_X2 30
DFFSR_X1 20
ICG_X2 10
ICG_X4 10
DELAY2_X1 20
INV_X2 100
INV_X4 30
BUF_X2 30
BUF_X4 20
ANTENNA 80
}
然后,指定需要放sparecell的范围。
set stdcell_areas {
{x1 y1 x2 y2}
{x3 y3 x4 y4}
{x5 y5 x6 y6}
# ...
}
定义一个随机函数,用来在有效范围内随机一个坐标。如果随机的坐标不在有效范围内,就重新随机,直至找到有效位置。
proc rand2 {} {
return [expr rand()]
}
proc round2 {f} {
return [expr double([format "%.2f" $f])]
}
proc randloc {x1 y1 x2 y2 stdcell_areas} {
while 1 {
set x [round2 [expr ${x1} + [rand2] * (${x2}-${x1})]]
set y [round2 [expr ${y1} + [rand2] * (${y2}-${y1})]]
set check 0
foreach area ${stdcell_areas} {
set a1 [lindex $area 0]
set b1 [lindex $area 1]
set a2 [lindex $area 2]
set b2 [lindex $area 3]
if { $x > $a1 && $x < $a2 && $y > $b1 && $y < $b2 } {
set check 1
break
}
}
if { $check == 1 } {
break
}
}
return "$x $y"
}
最后写个脚本,用addInst来指定随机坐标。同时用attachTerm来把sparecell的输入pin接到1'b1。并指定sparecell的place属性为soft_fixed。
dict for {cell count} $sparelist {
for {set i 0} {$i < $count} {incr i} {
set loc [randloc $x1 $y1 $x2 $y2 ${stdcell_areas}]
addInst -cell $cell -inst "sparegate_$num" -place_status soft_fixed -loc "$loc"
set terms [dbGet [dbGet -p1 [dbGet -p1 head.libCells.name $cell].terms.isInput true].name]
foreach term ${terms} {
attachTerm "sparegate_$num" $term 1'b1
}
print "$cell: $loc"
incr num
}
}
经过实践,上面的这种插sparecell的效果可以。