NAME
Parse::Liberty - Parser for Synopsys Liberty files
SYNOPSIS
use
Parse::Liberty;
my
$parser
= new Parse::Liberty (
verbose
=>0,
indent
=>4,
file
=>
"test.lib"
);
'indent: '
,
$parser
->{indent},
"\n"
;
## get root 'library' group
my
$library
=
$parser
->library;
$library
->type;
# => library
$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'
);
$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;
$function
->type
# => string
$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
orParse::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
objectArguments:
- 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
methodArguments:
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:
- 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:
- 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:
- 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
Attribute types
Value types
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
);
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"
);
$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
$_
->name.
' | '
.
$_
->value.
"\n"
for
@attrs
;
my
@cells
=
$parser
->cells;
# all cell-type groups
my
@cells
=
$parser
->cells(
'BUF2'
,
'DFF'
);
my
$cell
=
$parser
->cells(
'INV3'
);
$cell
->name;
# cell name
$cell
->attr(
'area'
);
$_
->name
for
$cell
->pins;
my
$pin
=
$cell
->pins(
'Q.*'
);
$pin
->name;
# pin name
$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)