LEF.rbm does not work

edited November 2011 in General
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

  • edited November 2011

    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

  • edited 8:46PM
    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
  • edited 8:46PM
    And one more issue :)

    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
  • edited 8:46PM
    Looks like the problem is in layers property file loading in the latest version of KLayout comparing to 0.19.3 version. The latest version loads default layers with old LEF.rb, even if $lvlyp is defined, or do not load any with new LEF.rbm.
    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.
  • edited November 2011
    Hi Eugene,

    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
Sign In or Register to comment.