Hi,
Is there any way to check the sapce and width between all polygon and paths within the same layer ?
Even with a maximum of checks (i.e. set in the settings such as 1000), it would be very useful for small layouts after a small change of 1 layer.
It cannot replace a full DRC, but help to avoid silly mistake.
Thanks, Rgds,
OkGuy
Comments
Hi,
well, having a width and spacing check would already be the very core of real DRC functionality. There is no such function (yet). You can mimic the effect with under/oversizing and XOR, i.e.
I am using the notation of the layer processing framework here. Please note that these operations are not quite efficient and will only work on small layouts.
Regards,
Matthias
Based my experience, klayout 0.23+ version is good for DRC. I use the Boolean operation to figure out the width/space Perato. Here is my example code:
########################################333
tileNo = 10 #define the tiles in 10um
borderNo = 0 #no border
threadNo = 4 #thread 4 core CPU
startTime=Time.new
## define width/space for boolean operation
widthset = [150,180,200,250,500] # <500nm
spaceset =[180,200,226,250,300,500,2500] # <2500nm
## define output layer
WidthOutPut ="1000"
SpaceOutPut= "2000"
WidthSpaceOut="3000"
## define layer alias matrix
wopt = Array.new ## store the widthset layer alias
sopt = Array.new ## store the spaceset layer alias
wsopt = Array.new ## store the width/space alias
## resort width/space from small to large distributions
widthset.sort
spaceset.sort
## define the widthset and spaceset temperates for ruby bug
wtemp=Array.new(widthset)
stemp=Array.new(spaceset)
## use tiles, borders and threads in Klyout v0.23+ DRC part
tiles(tileNo)
tile_borders(borderNo)
threads(threadNo)
## call RBA for active layout
ly=RBA::CellView::active.layout
## define topcell name
top_cell=ly.top_cell.name
##DRC file add time stamp to avoid DRC log file overwrite
timetemp=Time.new.to_a
timeStamp = timetemp[4]*timetemp[3]+timetemp[2]*timetemp[1]+timetemp[0] ##hours digit1 x hour digit2 + minute digit1 x minute digit2 + second digit
drcfile = "Agogo_"+top_cell+"_"+timeStamp.to_s+".log"
log_file(drcfile) ##define DRC file end
verbose(true)
layer1=input("1/0") #layer for DRC check
ww_old=layer1 ## for layer1 temp to minus
i=0
j=0
## widthset distribution
widthset.each do |widthset|
j=i+1
wopt[i] = WidthOutPut.to_s+"/"+j.to_s
woptalias = """W"+widthset.to_s+"nm ("+wopt[i].to_s+")"""
halfsize = widthset/2000.0 ##change nm to um
halfsize = halfsize.to_f
## Follow Matthias recommendation by using +/- sizing to figure the specific value.
ww = ww_old.sized(-halfsize).sized(halfsize)
w = ww_old - ww
w.output(woptalias)
layerArea=w.area
layerLength=layerArea/halfsize*2
## display on console
puts "W = #{widthset.to_s} nm; area = #{layerArea.to_s} ; mean length = #{layerLength}"
##store in log file
info "**W <= #{widthset.to_s} nm; area = #{layerArea.to_s} ; mean length = #{layerLength}"
i=i+1
ww_old=ww
end
widthCount=i ##widthset matrix number
##free memory
ww_old=nil
ww=nil
GC.start ## garbage collecting start
## spaceset distribution
i=0
j=0
ss_old=layer1
spaceset.each do |spaceset|
j=j+1
sopt[i] = SpaceOutPut.to_s+"/"+j.to_s
soptalias = """S"+spaceset.to_s+"nm ("+sopt[i].to_s+")"""
halfsize = spaceset/2000.0 ##change nm to um
halfsize = halfsize.to_f
ss = layer1.sized(halfsize).sized(-halfsize)
s = ss - ss_old
s.output(soptalias)
layerArea=s.area
layerLength=layerArea/halfsize*2
puts "S = #{spaceset.to_s} nm; area = #{layerArea.to_s} ; mean length = #{layerLength}"
##store in log file
info "**S <= #{spaceset.to_s} nm; area = #{layerArea.to_s} ; mean length = #{layerLength}"
i=i+1
ss_old=ss
end
spaceCount = i
ss=nil
ss_old=nil
i=0
j=0
k=0
######## the following codes are optional #################
## width / space ditribution for cross analysis
while i<widthCount do
w=input(wopt[i])
if w!=nil
w=w.sized(0.001) #minimun unit to interact with other space
k=0
while k<spaceCount do
s=input(sopt[k])
j=j+1
wsopt[j]=WidthSpaceOut.to_s + "/" + j.to_s
wsalias = """W"+wtemp[i].to_s + "S" + stemp[k].to_s+" ("+wsopt[j]+")"""
if s!=nil
ws=w.and(s)
if ws!=nil
ws.output(wsalias)
layerArea=ws.area
layerLength = layerArea/0.001/2
puts "W#{wtemp[i].to_s}S#{stemp[k].to_s} ; area = #{layerArea.to_s} ; length = #{layerLength.to_s}"
info "**W#{wtemp[i].to_s}S#{stemp[k].to_s} ; area = #{layerArea.to_s} ; length = #{layerLength.to_s}"
end
end
k=k+1
end
end
i=i+1
end
##free huge layout memory
w=nil
s=nil
ws=nil
layer1=nil
###### optional code end here ###############
flat
no_borders
saveFile=top_cell+"_drc.oas.gz"
opt = RBA::SaveLayoutOptions::new
opt.format="OASIS"
opt.oasis_compression_level=9
ly.write(saveFile, true, opt)
puts "filename: #{saveFile} saved."
info "drc layout saved in #{saveFile}"
endTime=Time.new
processTime=endTime.to_i - startTime.to_i
puts "Start #{startTime}, end #{endTime} Process time #{processTime}"
info "Start #{startTime}, end #{endTime} ,process time #{processTime} ,threads: #{threadNo}, tiles: #{tileNo}, borders: #{borderNo}"
##########end here########################################
arided