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::AttributeorParse::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::LibertyobjectArguments:
- 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::Groupobject) - write_library
-
Write library to a file. This is preferred and much faster way to output the full library, than
extractmethodArguments:
- 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::Valueobjects, 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::Attributeobjects, or 1st matched object in scalar context, or empty list if no attributes in group)Arguments:
- get_defines
-
Get group attributes (list of matched
Parse::Liberty::Defineobjects, or 1st matched object in scalar context, or empty list if no defines in group)Arguments:
- get_groups
-
Get group subgroups (list of matched
Parse::Liberty::Groupobjects, or 1st matched object in scalar context, or empty list if no subgroups in group)Arguments:
- This last three get_ methods can accept regular expressions
-
This expression placed into
m/^ $/, so patternNAND.*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)