Hi Matthias,
I downloaded new version of LEF.rbm module from your site at it doesn't work.
Opening LEF file I don't see any layers and shapes at all.
Previous version I downloaded about 2 years ago (LEF.rb) works good.
Modules comparison (tkdiff) shows that new version was created from this previous I have.
And I hoped it will be better. But...
Any ideas what can be the problem?
Best regards,
-- Eugene Stolbikov
Comments
Hi Eugene,
I have just tried the script myself and at least with a simple testcase it works.
The script was contributed by other users, so I am not aware of limitations or bugs. Neither am I user of that script since I rarely see any LEF files. The new version supports polygons, so it should work better than the old ones.
Is there any error message? Is there a chance to send at least a partial LEF file where that problem can be reproduced?
Best regards,
Matthias
No, there are no any error messages.
I see just cell name in Cell window.
Here is a small LEF example that looks OK in my old LEF.rb and doesn't in new LEF.rbm:
##############################################################
VERSION 5.5 ;
DIVIDERCHAR "/" ;
BUSBITCHARS "[]" ;
MACRO test
CLASS BLOCK ;
FOREIGN test 0 0 ;
ORIGIN 0.000 0.000 ;
SIZE 142.800 BY 61.600 ;
SYMMETRY X Y R90 ;
PIN A[0]
DIRECTION INPUT ;
PORT
LAYER m2 ;
RECT 99.540 0.000 99.820 0.900 ;
LAYER m3 ;
RECT 99.540 0.000 99.820 0.900 ;
END
END A[0]
OBS
LAYER m3 ;
RECT 0.000 0.000 142.000 61.000 ;
END
END test
END LIBRARY
##############################################################
I use Unix 64bits version of KLayout.
-- Eugene Stolbikov
If I use workable old version of LEF.rb (by copying it in $KLAYOUT_PATH), the latest KLayout ignores some other ruby modules (like tech_manager.rbm) and do not open GDS from command line. :(
-- Eugene Stolbikov
Version 0.19.3 with old LEF.rb loads layers property file defined by $lvlyp variable correctly, but does not load through Load Layer property menu.
I am using release 0.21.6 and 0.21.13 w/ a slightly different code and I tried it w/ your lef and it worked (distribution: Centos 5.5 64bits - Gnome - Qt-4.7.2 - Ruby 1.8).
Except I have a strange message in 0.21.13 each time I click on 'open lef' to display the browser that
I do not have in 0.21.6 but that does not affect the behavioural of the tool.
And I do not have when I open a GSD file.
Message:
(<unknown>:31608): libgnomevfs-CRITICAL **: gnome_vfs_get_uri_from_local_path: assertion `g_path_is_absolute (local_full_path)' failed
Message who disapear if I start klayout w/ a Gtk style: klayout -style=GtkStyle
The difference between the 2 codes is I have added the purpose of the layers because I want to be able to differentiate a metal who is part of an Obstruction from another who is part of a Pin.
Regards,
Jo
Code:
# Ruby file for KLayout for work with LEF.
# klayout -r LEF.rb
######################################
class MenuHandler < RBA::Action
def initialize( title, shortcut, &action )
self.title = title
self.shortcut = shortcut
@action = action
end
def triggered
@action.call( self )
end
private
@action
end
######################################
class LEFCell
def initialize(macro)
@name = macro
@bb = LEFShape.rect("prBoundary:bnd", 0, 0, 0, 0)
@pins = Array.new
@obs = Array.new
@cell = $layout.add_cell(@name)
end
def render
@bb.draw
@pins.each { |pin|
pin.draw
pin.label
}
@obs.each { |blockage|
blockage.draw
}
end
def name
return @name
end
def pins
return @pins
end
def obs
return @obs
end
def cell
return @cell
end
def bb(rect)
@bb = rect
return @bb
end
end
######################################
class LEFShape
def LEFShape.rect(layer, x1, y1, x2, y2)
LEFShape.new.set_rect(layer, x1, y1, x2, y2)
end
def LEFShape.polygon(layer, p)
LEFShape.new.set_polygon(layer, p)
end
def set_rect(layer, x1, y1, x2, y2)
@layer = layer
@rect = RBA::DBox.new(x1, y1, x2, y2)
@polygon = nil
return self
end
def set_polygon(layer, points)
@layer = layer
@rect = nil
@polygon = RBA::DPolygon.new(points.collect { |xy| RBA::DPoint.new(xy[0], xy[1]) })
return self
end
def draw
@layer_id = 1000
@layer_id = $lid[@layer]
if ! @layer_id
@layer_id = create_layer(@layer, 0x000000, 0x0000ff, 3)
end
if @rect
@intbox = RBA::Box.from_dbox(@rect)
$layout.cell($cell).shapes(@layer_id).insert_box(@intbox)
end
if @polygon
@intpolygon = RBA::Polygon.from_dpoly(@polygon)
$layout.cell($cell).shapes(@layer_id).insert(@intpolygon)
end
end
def layer
return @layer
end
def rect
return @rect
end
def polygon
return @polygon
end
end
######################################
class LEFPin < LEFShape
def initialize(name, shape)
@name = name
@layer = shape.layer
@rect = shape.rect
@polygon = shape.polygon
end
def label
@orig = nil
if @rect
@orig = RBA::DTrans.new(@rect.center.x, @rect.center.y)
end
if @polygon
@polygon.each_point_hull do |p|
@orig = RBA::DTrans.new(p.x + 5, p.y + 5)
break
end
end
if @orig
@text = RBA::Text.new(@name, RBA::Trans.from_dtrans(@orig))
@layer_tmp = @layer + ":text"
@layer_id = $lid[@layer_tmp]
if ! @layer_id
@layer_id = create_layer(@layer_tmp, 0xffffff, 0xffffff, 1)
end
$layout.cell($cell).shapes(@layer_id).insert_text(@text)
end
end
def name
return @name
end
end
######################################
def get_layers
lyr_file = RBA::Application.instance.get_config("default-layer-properties")
if lyr_file != ""
f = $cv.load_layer_props(lyr_file)
l = $cv.begin_layers
while ! l.at_end?
l.current.name =~ /^\s*(\S+)\s*/
$lid[$1] = l.current.source_layer_index(0)
l.next
end
end
end
######################################
def create_layer(name, frame, fill, stipple)
$lid[name] = $layout.insert_layer(RBA::LayerInfo.new)
ln = RBA::LayerPropertiesNode::new
ln.name = name
ln.dither_pattern = stipple
ln.fill_color = frame
ln.frame_color = fill
ln.width = 1
ln.source_layer_index = $lid[name]
$cv.insert_layer($cv.end_layers, ln)
return $lid[name]
end
#####################################
def stringToPoints(s, coeff)
points = []
x = nil
s.split(/\s+/).each do |c|
if x
points.push([ x, c.to_f * coeff ])
x = nil
else
x = c.to_f * coeff
end
end
return points
end
#####################################
def parseLEF(lef)
cellList = Array.new
cell = 0
layer = ""
shape = 0
pin_name = ""
scope = ""
flag = 0
macro = 0
coeff = 1000
x1 = 0
y1 = 0
x2 = 0
y2 = 0
x_origin = 0
y_origin = 0
in_polygon = false
poly_points = []
lef.each { |line|
case line
when /^\s*DATABASE\s+MICRONS\s+(\d+)/
coeff = $1.to_f
flag = 0
when /^\s*MACRO\s+(\S+)/
macro = LEFCell.new($1)
cellList.push(macro)
flag = 0
when /^\s*FOREIGN\s+\S+\s+(\S+)\s+(\S+?)\s*;/
x1 = $1.to_f * coeff
y1 = $2.to_f * coeff
flag = 0
when /^\s*ORIGIN\s+(\S+)\s+(\S+?)\s*;/
x_origin = $1.to_f * coeff
y_origin = $2.to_f * coeff
flag = 0
when /^\s*SIZE\s+(\S+)\s+BY\s+(\S+?)\s*;/
if macro != 0
x2 = $1.to_f * coeff - x_origin
y2 = $2.to_f * coeff - y_origin
macro.bb(LEFShape.rect("prBoundary:bnd", x1, y1, x2, y2))
end
flag = 0
when /^\s*LAYER\s+(\S+?)\s*;/
layer = $1
layer = $1 + scope
flag = flag & 3
when /^\s*LAYER\s+(\S+)/
layer_name = $1
@layer_id = 0
print "Warning: we should not be here ..."
layer_name = $1 + ":err"
@layer_id = $lid[layer_name]
if ! @layer_id
create_layer(layer_name, 0x000000, 0x0000ff, 2)
end
flag = 10
when /^\s*RECT\s+(\S+)\s+(\S+)\s+(\S+)\s(\S+?)\s*;/
shape = LEFShape.rect(layer, ($1.to_f * coeff), ($2.to_f * coeff), ($3.to_f * coeff), ($4.to_f * coeff))
flag = flag | 4
when /^\s*POLYGON\s+(.*?)\s*;/
points = stringToPoints($1, coeff)
shape = LEFShape.polygon(layer, points);
flag = flag | 4
when /^\s*POLYGON\s*$/
in_polygon = true
poly_points = []
when /^\s*POLYGON\s+(.*)\s*$/
in_polygon = true
poly_points = stringToPoints($1, coeff)
when /^\s*PIN\s+(\S+)/
scope = ":pin"
pin_name = $1
flag = 1
when /^\s*END\s+(\S+)/
if flag == 1
if $1 == pin_name then flag = 0 end
elsif flag == 10
if $1 == layer_name then flag = 0 end
end
when /^\s*OBS/
scope = ":obs"
flag = 2
when /^\s*END\s*$/
if flag == 6 || flag == 2
flag = 2
elsif flag == 5
flag = 1
end
when /^\s*([\d+\-\s\.]*)\s*;/
if in_polygon
in_polygon = false
stringToPoints($1, coeff).each { |p| poly_points.push(p) }
shape = LEFShape.polygon(layer, poly_points);
flag = flag | 4
end
when /^\s*([\d+\-\s\.]*)\s*$/
if in_polygon
stringToPoints($1, coeff).each { |p| poly_points.push(p) }
end
else
flag = flag & 3
end
# print flag.to_s, " - ", line
case flag
when 5
pin = LEFPin.new(pin_name, shape)
macro.pins.push(pin)
# print pin_name, "\n"
when 6
macro.obs.push(shape)
end
}
return cellList
end
######################################
def openLEF
$clv = $mw.create_layout(0)
$cv = $mw.current_view
$layout = $cv.cellview(0).layout
$lid = Hash.new
file = RBA::FileDialog.get_open_file_name("Open LEF", ".", "LEF File (*.lef *.plef)")
if file.has_value? == false
return
end
get_layers()
lef = IO.readlines(file.value)
$cellList = parseLEF(lef)
$cellList.each { |item|
$cell = item.cell
item.render
}
$cv.select_cell_path( [$cell], 0 )
$cv.zoom_fit
$cv.max_hier
end
######################################
$app = RBA::Application.instance
$mw = $app.main_window
######################################
menu = $mw.menu
$open_LEF = MenuHandler.new("Open LEF", "Ctrl+Shift+L") { openLEF }
menu.insert_item("file_menu.#6", "LEFreader", $open_LEF)
#$app.exec