The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Parse::Liberty - Parser for Synopsys Liberty files

SYNOPSIS

    use Parse::Liberty;
    my $parser = new Parse::Liberty (verbose=>0, indent=>4, file=>"test.lib");
    print 'indent: ', $parser->{indent}, "\n";

    ## get root 'library' group
    my $library = $parser->library;
    print $library->type;       # => library
    print $library->get_names;  # => testlib

    ## set new name for group
    $library->set_names('my_testlib');

    ## all 'cell'-type groups
    my @cells = $library->get_groups('cell');
    ## or
    my @cells = grep {$_->type eq 'cell'} $library->get_groups;
    ## get cells by name
    my @cells = $library->get_groups('cell', 'SDFFRHQX2', 'NAND.*X4');

    ## get one cell
    my $cell = $library->get_groups('cell', 'NAND2X1');

    ## cell attributes
    my @attributes = $cell->get_attributes;
    ## by name
    my @attributes = $cell->get_attributes(qw(area cell_leakage_power), 'dont_.*');
    my $area = $cell->get_attributes('area');
    print $area->get_values->value;

    ## cell 'pin'-type groups
    my @pins = $cell->get_groups('pin');
    my $pin = $cell->get_groups('pin', 'Y');

    ## pin function
    my $function = $pin->get_attributes('function')->get_values;
    print $function->type   # => string
    print $function->value  # => "(!(A B))"

DESCRIPTION

Parse::Liberty may be used to extract and modify information from Synopsys Liberty files. Liberty format is widely used standard for keeping various information for EDA applications.

Parse::Liberty build on top Perl-C SWIG interface to Open Source Liberty liberty_parse functions.

To use Parse::Liberty, we need to build liberty_parse package from Open Source Liberty (links in "SEE ALSO" section).

Liberty format

Every Liberty file consists of comments, empty lines, groups, attributes and defines.

Each group can contain comments, empty lines, attributes and other groups.

There is the root group called 'library', which contains library-level attributes, cell groups and library-wide groups such operating conditions, voltages, and table templates.

Comment syntax
    /* ... */
Group syntax
    type(name) {
        ...
    }

or with multiple names (for ex. 'ff(IQ,IQN)' groups in flip-flop cells)

    type(name1 [, name2, ...]) {
        ...
    }

Common types is 'cell' for 'library' group and 'pin' in 'cell'-type groups.

A new, non-predefined group can be created with 'define_group' statement (see below).

Attribute syntax

Simple attribute:

    name : value ;

Complex attribute:

    name(value1 [, value2, ...]) ;

Attribute value can be one of several types (see "Value types").

Example of complex attribute is 'values()' table, where each value represent one row and looks like comma-separated "string".

A new, non-predefined attribute can be created with 'define' statement (see below).

Define syntax

New group:

    define_group (name, allowed_group_name);

New attribute:

    define (name, allowed_group_name, type);

Can be used to create new groups and attributes. Type is one of the "Value types".

Common properties

object_type

Type of object (string, see "Object types")

parser

Reference to main parser object (Parse::Liberty)

parent

Reference to parent object (Parse::Liberty::Attribute or Parse::Liberty::Group)

si2_object

Reference to underlying SWIG-C object (SI2DR object)

depth

Object depth (integer >= 0)

Common methods

methods

Return object avaible methods (string)

lineno

Return line number, associated with object (integer)

comment

Return comment, associated with object or undef (string, without /**/)

remove

Remove object, return 1

extract

Return object representation string (with indentation = indent*depth and trailing newline)

Parse::Liberty methods

new

Create new Parse::Liberty object

Arguments:

file

path to Liberty file (string, mandatory)

indent

intent to write out Liberty portions (integer, default 2)

verbose

enable verbose messages (any True or False value, default 0)

library

Return root group (Parse::Liberty::Group object)

write_library

Write library to a file. This is preferred and much faster way to output the full library, than extract method

Arguments:

file

path to the file to write

Parse::Liberty::Attribute methods

type

Return attribute type - simple or complex (string)

name

Return attribute name (string)

is_var

Return true if simple attribute is variable declaration (boolean)

get_values

Return attribute values (list of Parse::Liberty::Value objects, or 1st object in scalar context)

set_values

Set attribute values. Input format: (type1, value1[, type2, value2, ...]). Return 1

Parse::Liberty::Define methods

type

Return define type (string, see "Value types")

name

Return define name (string)

allowed_group_name

Return define allowed group name (string)

Parse::Liberty::Group methods

type

Return group type (string)

get_names

Return group names (list of strings, or string of names joined with comma in scalar context, or '' if nameless group)

set_names

Set group names. Input format: (name1[, name2, ...]). Return 1

get_attributes

Get group attributes (list of matched Parse::Liberty::Attribute objects, or 1st matched object in scalar context, or empty list if no attributes in group)

Arguments:

<none>

return all Parse::Liberty::Attribute objects

(name1[, name2, ...])

return all matched objects by name(s)

get_defines

Get group attributes (list of matched Parse::Liberty::Define objects, or 1st matched object in scalar context, or empty list if no defines in group)

Arguments:

<none>

return all Parse::Liberty::Define objects

(name1[, name2, ...])

return all matched objects by name(s)

get_groups

Get group subgroups (list of matched Parse::Liberty::Group objects, or 1st matched object in scalar context, or empty list if no subgroups in group)

Arguments:

<none>

return all Parse::Liberty::Group objects

type

return all matched objects by type 'type'

(type, name1[, name2, ...])

return all matched objects by type 'type' and first name(s) 'name1'(, 'name2', ...)

This last three get_ methods can accept regular expressions

This expression placed into m/^ $/, so pattern NAND.* correspond to names, started with 'NAND'

Parse::Liberty::Value methods

type

Return value type (string, see "Value types")

value

Return value value (string)

Object types

group
attribute
define
value

Attribute types

simple
complex
unknown

Value types

boolean
integer
float
string
expression
undefined

DIAGNOSTICS

Errors

NO ERROR
INTERNAL SYSTEM ERROR
INVALID VALUE
INVALID NAME
INVALID OBJECTTYPE
INVALID ATTRTYPE
UNUSABLE OID
OBJECT ALREADY EXISTS
OBJECT NOT FOUND
SYNTAX ERROR
TRACE FILES CANNOT BE OPENED
PIINIT NOT CALLED
SEMANTIC ERROR
REFERENCE ERROR
UNKNOWN ERROR

EXAMPLES

Transpose NLDM/NLPM values tables

    sub transpose {
        my $columns = shift;
        my @list = @_;
        map { my $i = $_; [map $_->[$i], @list] } 0 .. $columns-1;
    }

    sub process_values {
        my @table = @_;
        my @values;
        foreach my $row (@table) {
            $row =~ s/\s+//g; # remove spaces
            $row =~ s/"(.*)"/$1/; # remove first and last '"'
            my @row = split /\s*,\s*/, $row; # values in row delimeted by ','
            push @values, \@row;
        }
        my $columns = scalar @{$values[0]}; # length of first row
        my @values_transposed = transpose($columns, @values);
        ## get list of strings instead arrays
        map {$_ = join ', ', @{$_}} @values_transposed;
    }

    sub process_group {
        my $group = shift;
        ## process templates
        if($group->type =~ m/.*_template/) {
            if(!$group->get_attributes('variable_3')
            && (my $variable_2_attr = $group->get_attributes('variable_2'))) {
                my $variable_1_attr = $group->get_attributes('variable_1');
                my $index_1_attr = $group->get_attributes('index_1');
                my $index_2_attr = $group->get_attributes('index_2');

                my $variable_1 = $variable_1_attr->get_values->value;
                my $variable_2 = $variable_2_attr->get_values->value;
                $variable_1_attr->set_values('string', $variable_2);
                $variable_2_attr->set_values('string', $variable_1);

                my $index_1 = $index_1_attr->get_values->value;
                my $index_2 = $index_2_attr->get_values->value;
                $index_1_attr->set_values('string', $index_2);
                $index_2_attr->set_values('string', $index_1);
            }
        }
        ## process values tables
        elsif(my $values_attr = $group->get_attributes('values')) {
            if(!$group->get_attributes('index_3')
            && (my $index_2_attr = $group->get_attributes('index_2'))) {
                my $index_1_attr = $group->get_attributes('index_1');

                my $index_1 = $index_1_attr->get_values->value;
                my $index_2 = $index_2_attr->get_values->value;
                $index_1_attr->set_values('string', $index_2);
                $index_2_attr->set_values('string', $index_1);

                my @values = map {$_->value} $values_attr->get_values;
                my @values_transposed = process_values(@values);
                $values_attr->set_values(map {('string', $_)} @values_transposed);
            }
        }
        process_group($_) for $group->get_groups;
    }

    use Parse::Liberty;
    my $parser = new Parse::Liberty (file=>"test.lib");
    my $library = $parser->library;
    process_group($library);
    print OUT $library->extract;

Get cells with 'dont_touch' attribute

    foreach my $cell ($library->get_groups('cell')) {
        if(my $attr = $cell->get_attributes('dont_touch')) {
            printf "%15s: %s %s\n", $cell->get_names, $attr->name, $attr->get_values->value;
        }
    }

Using Parse::Liberty::Simple

    my $parser = new Parse::Liberty::Simple ("test.lib");

    print $parser->name; # library name

    my @attrs = $parser->attrs; # all library-level attributes
    my @attrs = $parser->attrs('date', '.*_unit');
    my $attr = $parser->attrs('date'); # object (print $attr->value)
    my $attr = $parser->attr('date'); # value of an attribute
    print $_->name.' | '.$_->value."\n" for @attrs;

    my @cells = $parser->cells; # all cell-type groups
    my @cells = $parser->cells('BUF2', 'DFF');
    my $cell = $parser->cells('INV3');
    print $cell->name; # cell name
    print $cell->attr('area');
    print $_->name for $cell->pins;

    my $pin = $cell->pins('Q.*');
    print $pin->name; # pin name
    print $pin->attr('direction');

AUTHOR

Eugene Gagarin <mosfet07@ya.ru>

COPYRIGHT AND LICENSE

Copyright 2015 Eugene Gagarin

This library is free software; you may redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

http://www.opensourceliberty.org - Open Source Liberty

http://www.si2.org - Silicon Integration Initiative

Liberty::Parser - Liberty parser with different approach (probably faster)