### Liberty to ALF data conversion ### sub ALF_LibertyData2ALF { local($parent) = @_; print("# System Message:\tstarted creating ALF view in Liberty database ",&DateTime,"\n"); foreach $library (&ALF_FindMatchingLibertyObjects($parent,'library')) { &ALF_ecsmDefine2ALF($library) if defined(&ALF_ecsmDefine2ALF); &ALF_LibertyLibrary2ALF($library); &ALF_ecsmData2ALF($library) if defined(&ALF_ecsmData2ALF); &ALF_CheckLiberty2ALFTranslation($library); } print("# System Message:\tfinished creating ALF view in Liberty database ",&DateTime,"\n"); 1; } sub ALF_CheckLiberty2ALFTranslation { local($object) = @_; if ($ALF_Hidden{$object}) { print("# ALF Data Info:\tobject is not subject to translation:\t",&ALF_ObjectInfoText($object),"\n") if $ALF_Debug; } elsif ($ALF_Type{$object}) { foreach $child (&Array($ALF_Children{$object})) { &ALF_CheckLiberty2ALFTranslation($child); } } elsif ($ALF_LibertyType{$object}) { local $hidden = &ArraySize($ALF_Children{$object})? 'ALF' : 0; foreach $child (&Array($ALF_Children{$object})) { if ($ALF_Type{$child}) { &ALF_CheckLiberty2ALFTranslation($child); } elsif (!$ALF_Hidden{$child}) { &ALF_CheckLiberty2ALFTranslation($child); $hidden = 0; } } $ALF_Hidden{$object} = $hidden; } } ### generic data ### sub ALF_Liberty2ALFConstant { local($attribute) = @_; local $syntax = $ALF_LibertySyntax{$attribute}; local $type = $ALF_LibertyType{$attribute}; local $value = $ALF_LibertyValue{$attribute}; local $return; if (!&StringMatch($syntax,'simple_attribute')) { print("# ALF Data Error:\terroneous Liberty syntax \47$syntax\47 instead of \47simple_attribute\47 for attribute:\t",&ALF_ObjectInfoText($attribute,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } elsif (!defined($value)) { print("# ALF Data Error:\tmissing valuetype for attribute:\t",&ALF_ObjectInfoText($attribute,'ALF_LibertyType'),"\n"); } elsif (!&ALF_LexicalMatch('number',$value)) { print("# ALF Data Error:\twrong valuetype for attribute:\t",&ALF_ObjectInfoText($attribute,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } else { $ALF_Type{$attribute} = 'CONSTANT'; $ALF_Name{$attribute} = $type; $ALF_Value{$attribute} = $value; $return = $attribute; } $return; } sub ALF_LibertyGenericObjects2ALF { local($parent) = @_; local $return; foreach $child (&Array($ALF_Children{$parent})) { local $syntax = $ALF_LibertySyntax{$child}; if (&StringMatch($syntax,'simple_attribute')) { $return = &ALF_LibertySimpleAttribute2ALF($child); } elsif (&StringMatch($syntax,'complex_attribute')) { $return = &ALF_LibertyComplexAttribute2ALF($child); } } $return; } sub ALF_LibertySimpleAttribute2ALF { local($attribute) = @_; local $parent = $ALF_Parent{$attribute}; local $type = &Unquote($ALF_LibertyType{$attribute}); local $value = $ALF_LibertyValue{$attribute}; if (&ALF_SyntaxMatch('single_value_annotation',$type,$parent)) { $ALF_Type{$attribute} = $type; $ALF_Value{$attribute} = $value; } elsif (!defined($ALF_Type{$attribute}) && !$ALF_Hidden{$attribute}) { local $property = &ALF_FindMatchingObject($parent,'PROPERTY') || &ALF_CreateObject($parent,'PROPERTY'); &ALF_RedefineObject($attribute,$property,$type,undef,$value); } $attribute; } sub ALF_LibertyComplexAttribute2ALF { local($attribute) = @_; local $parent = $ALF_Parent{$attribute}; local $type = &Unquote($ALF_LibertyType{$attribute}); local $value = $ALF_LibertyValue{$attribute}; if (&ALF_SyntaxMatch('multi_value_annotation',$type,$parent)) { $ALF_Type{$attribute} = $type; $ALF_Value{$attribute} = $ALF_LibertyValue{$attribute}; } elsif (!defined($ALF_Type{$attribute}) && !$ALF_Hidden{$attribute}) { local $property = &ALF_FindMatchingObject($parent,'PROPERTY') || &ALF_CreateObject($parent,'PROPERTY'); &ALF_RedefineObject($attribute,$property,$type,undef,$value); } $attribute; } sub ALF_LibertyDefine2ALF { local($define) = @_; local $return = $define; local $define_type = $ALF_LibertyType{$define}; local ($attribute_name,$group_type,$attribute_type) = &Array($ALF_LibertyValue{$define}); local $already_defined = &ALF_FindMatchingObject($ALF_Parent{$define},'KEYWORD',&Unquote($attribute_name)); if ($already_defined) { $ALF_Hidden{$define} = 'ALF'; } else { $ALF_Type{$define} = 'KEYWORD'; $ALF_Value{$define} = $define_type eq 'define_group' ? 'annotation_container' : 'single_value_annotation'; if (defined($attribute_name)) { $ALF_Name{$define} = &Unquote($attribute_name); &ALF_DefineKeywordRule($define); } else { print("# ALF Data Error:\tmissing attribute name in Liberty define:\t",&ALF_ObjectInfoText($define,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } } if (defined($attribute_type) && $define_type eq 'define') { local $libvaluetype = &Unquote($attribute_type); local $alfvaluetype = &StringMatch($libvaluetype,'boolean')? 'boolean_value' : &StringMatch($libvaluetype,'string')? 'string_value' : &StringMatch($libvaluetype,'integer')? 'integer' : &StringMatch($libvaluetype,'float')? 'number' : undef; if (!defined($alfvaluetype)) { print("# ALF Data Error:\tinvalid attribute type in Liberty define:\t",&ALF_ObjectInfoText($define,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } elsif (defined($attribute_name)) { $return = &ALF_InsertObject($define,'SEMANTICS',&Unquote($attribute_name)); &ALF_CreateObject($return,'VALUETYPE',undef,$alfvaluetype); } } elsif ($define_type eq 'define') { print("# ALF Data Error:\tmissing attribute type in Liberty define:\t",&ALF_ObjectInfoText($define,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } elsif (defined($attribute_type)) { print("# ALF Data Error:\tattribute type not allowed in Liberty define:\t",&ALF_ObjectInfoText($define,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } if (defined($group_type)) { $libcontext = &Unquote($group_type); local $alfcontext = &StringMatch($libcontext,'library')? 'LIBRARY' : &StringMatch($libcontext,'cell')? 'CELL' : &StringMatch($libcontext,'pin')? 'PIN' # : &StringMatch($libcontext,'timing','internal_power')? 'VECTOR' : undef; if (defined($alfcontext)) { &ALF_CreateObject($define,'CONTEXT',undef,$alfcontext); } else { print("# ALF Data Error:\tinvalid group name \42$libcontext\42 in Liberty define:\t",&ALF_ObjectInfoText($define,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } } else { print("# ALF Data Error:\tmissing group name in Liberty define:\t",&ALF_ObjectInfoText($define,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } $return; } ### global technology data ### sub ALF_LibertyLibrary2ALF { local($library) = @_; $ALF_Type{$library} = 'LIBRARY'; $ALF_Name{$library} = &Unquote($ALF_LibertyName{$library}); $ALF_Prepend{$library} = 1; &ALF_CreateObject($library,'INCLUDE',&Doublequote(&Unquote($ALF_LibertyGlobalFile))) if defined($ALF_LibertyGlobalFile); local $property = &ALF_CreateObject($library,'PROPERTY'); &ALF_Liberty2ALFInformation($library); $ALF_Prepend{$library} = 0; &ALF_LibertyLibraryAttributes2ALF($library); &ALF_LibertyTimingThresholds2ALF($library); foreach $define (&ALF_FindMatchingLibertyObjects($library,'define_group'),&ALF_FindMatchingLibertyObjects($library,'define')) { &ALF_LibertyDefine2ALF($define) unless $ALF_Hidden{$define}; } if (defined($ALF_LibertyGlobalFile)) { foreach $operating_conditions (&ALF_FindMatchingLibertyObjects($library,'operating_conditions')) { &ALF_LibertyOperatingConditions2ALF($operating_conditions); } } if (defined($ALF_LibertyScalingFile)) { foreach $scaling_factors (&ALF_FindMatchingLibertyObjects($library,'scaling_factors')) { &ALF_LibertyScalingFactors2ALF($scaling_factors); } } &ALF_LibertyTransitionDegradation2ALF($library); foreach $wire_load_table (&ALF_FindMatchingLibertyObjects($library,'wire_load_table')) { &ALF_LibertyWireLoadTable2ALF($wire_load_table); } foreach $wire_load_selection (&ALF_FindMatchingLibertyObjects($library,'wire_load_selection')) { &ALF_LibertyWireLoadSelection2ALF($wire_load_selection); } local $firstcell; foreach $cell (&ALF_FindMatchingLibertyObjects($library,'cell')) { $firstcell = $cell unless defined($firstcell); &ALF_LibertyCell2ALF($cell); } &ALF_LibertyGenericObjects2ALF($library); $ALF_Hidden{$property} = 1 unless defined($ALF_Children{$property}); $ALF_Prepend{$library} = 1; &ALF_InsertObject($firstcell,'INCLUDE',&Doublequote(&Unquote($ALF_LibertyScalingFile))) if defined($ALF_LibertyScalingFile); 1; } sub ALF_Liberty2ALFInformation { local($library) = @_; local %alftype = ( 'revision','VERSION', 'date','DATETIME', 'comment','TITLE', ); local $information; foreach $object (&Array($ALF_Children{$library})) { local $type = $ALF_LibertyType{$object}; local $value = $ALF_LibertyValue{$object}; if (&StringMatch($type,'revision','date','comment')) { if (!defined($value)) { print("# ALF Data Error:\tmissing value for Liberty attribute:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType'),"\n"); } elsif (!&ALF_LexicalMatch('liberty_string_value',$value)) { print("# ALF Data Error:\terroneous value for Liberty attribute:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } else { $information = &ALF_CreateObject($library,'INFORMATION') unless defined($information); $ALF_Hidden{$object} = 1; &ALF_CreateObject($information,$alftype{$type},undef,&Doublequote(&Unquote($value))); } } elsif (&StringMatch($type,'technology')) { local ($product) = &Array($value) if defined($value); if (!defined($product)) { print("# ALF Data Error:\tmissing value for Liberty attribute:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType'),"\n"); } elsif (&StringMatch($product,'cmos','fpga')) { $information = &ALF_CreateObject($library,'INFORMATION') unless $information; $ALF_Hidden{$object} = 1; &ALF_CreateObject($information,'PRODUCT',undef,"\42$product\42"); } else { print("# ALF Data Error:\terroneous value for Liberty attribute:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } } } $information; } sub ALF_LibertyTimingThresholds2ALF { local($library) = @_; local($delay_from_rise,$delay_from_fall,$delay_to_rise,$delay_to_fall); local($slew_from_rise,$slew_from_fall,$slew_to_rise,$slew_to_fall); local ($delay_insert,$slew_insert); foreach $object (&Array($ALF_Children{$library})) { local $type = $ALF_LibertyType{$object}; local $value = $ALF_LibertyValue{$object}; local ($delay,$slew); if (&StringMatch($type, 'input_threshold_pct_rise','input_threshold_pct_fall', 'output_threshold_pct_rise','output_threshold_pct_fall', )) { $delay = $object; $delay_insert = $object; } elsif (&StringMatch($type, 'slew_lower_threshold_pct_rise','slew_upper_threshold_pct_rise', 'slew_lower_threshold_pct_fall','slew_upper_threshold_pct_fall', )) { $slew = $object; $slew_insert = $object; } if (defined($delay) || defined($slew)) { if (!defined($value)) { print("# ALF Data Error:\tmissing value for Liberty attribute:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } elsif (!&ALF_LexicalMatch('number',$value)) { print("# ALF Data Error:\terroneous value for Liberty attribute:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } elsif ($value <= 0 || $value >= 100) { print("# ALF Data Error:\tvalue out of range (0..100) for Liberty attribute:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } else { $value = $value/100; $delay_from_rise = $value if &StringMatch($type,'input_threshold_pct_rise'); $delay_from_fall = $value if &StringMatch($type,'input_threshold_pct_fall'); $delay_to_rise = $value if &StringMatch($type,'output_threshold_pct_rise'); $delay_to_fall = $value if &StringMatch($type,'output_threshold_pct_fall'); $slew_from_rise = $value if &StringMatch($type,'slew_lower_threshold_pct_rise'); $slew_from_fall = $value if &StringMatch($type,'slew_upper_threshold_pct_fall'); $slew_to_rise = $value if &StringMatch($type,'slew_upper_threshold_pct_rise'); $slew_to_fall = $value if &StringMatch($type,'slew_lower_threshold_pct_fall'); $ALF_Hidden{$object} = 'ALF'; } } } &ALF_LibertyDelaySlewThresholds2ALF($slew_insert,'SLEWRATE',$slew_from_rise,$slew_from_fall,$slew_to_rise,$slew_to_fall); &ALF_LibertyDelaySlewThresholds2ALF($delay_insert,'DELAY',$delay_from_rise,$delay_from_fall,$delay_to_rise,$delay_to_fall); } sub ALF_LibertyDelaySlewThresholds2ALF { local($insert,$modeltype,$from_rise,$from_fall,$to_rise,$to_fall) = @_; local $library = $ALF_Parent{$insert}; if (defined($from_rise) && defined($from_fall) && defined($to_rise) && defined($to_fall)) { local $model = &ALF_FindMatchingObject($library,$modeltype,0) || &ALF_InsertObject($insert,$modeltype); local $from = &ALF_CreateObject($model,'FROM'); local $from_threshold = &ALF_CreateObject($from,'THRESHOLD'); &ALF_CreateObject($from_threshold,'RISE',undef,$from_rise); &ALF_CreateObject($from_threshold,'FALL',undef,$from_fall); local $to = &ALF_CreateObject($model,'TO'); local $to_threshold = &ALF_CreateObject($to,'THRESHOLD'); &ALF_CreateObject($to_threshold,'RISE',undef,$to_rise); &ALF_CreateObject($to_threshold,'FALL',undef,$to_fall); } elsif (defined($from_rise) || defined($from_fall) || defined($to_rise) || defined($to_fall)) { print("# ALF Data Error:\tincomplete threshold specification for $modeltype in Liberty library:\t",&ALF_ObjectInfoText($library,'ALF_LibertyType','ALF_LibertyName'),"\n"); } else { print("# ALF Data Warning:\tno threshold specification for $modeltype in Liberty library:\t",&ALF_ObjectInfoText($library,'ALF_LibertyType','ALF_LibertyName'),"\n"); } 1; } sub ALF_LibertyLibraryAttributes2ALF { local($library) = @_; local $return; local %unit2object = ( 'time_unit','TIME', 'pulling_resistance_unit','RESISTANCE', 'capacitive_load_unit','CAPACITANCE', 'voltage_unit','VOLTAGE', 'current_unit','CURRENT', 'leakage_power_unit','POWER', ); local %parameter2object = ( 'nom_process','Liberty_PROCESS', 'nom_voltage','VOLTAGE', 'nom_temperature','TEMPERATURE', ); local $savereturn; foreach $object (&Array($ALF_Children{$library})) { $savereturn = $return; $return = $object; local $type = $ALF_LibertyType{$object}; if (&StringMatch($type,'slew_derate_from_library')) { &ALF_LibertySlewDerateFromLibrary2ALF($object); } elsif (&StringMatch($type,keys %unit2object)) { &ALF_LibertyUnit2ALF($object,$unit2object{$type}); } elsif (&StringMatch($type,keys %parameter2object)) { &ALF_Liberty2ALFConstant($object); } elsif (&StringMatch($type,@ALF_Liberty_K_Factors)) { &ALF_Liberty2ALFConstant($object); } elsif (&StringMatch($type,@ALF_Liberty_Default_Values)) { &ALF_Liberty2ALFConstant($object); } elsif (&StringMatch($type,'default_operating_conditions') && defined($ALF_LibertyScalingFile)) { $ALF_Type{$object} = 'Liberty_OPERATING_CLASS'; $ALF_Value{$object} = &Unquote($ALF_LibertyValue{$object}); } else { $return = $savereturn; } } $return; } sub ALF_LibertyUnit2ALF { local($object,$alftype) = @_; local ($multiplier,$base); local $syntax = $ALF_LibertySyntax{$object}; local $value = $ALF_LibertyValue{$object}; if (&StringMatch($syntax,'simple_attribute') && &ALF_LexicalMatch('liberty_string_value',$value)) { ($multiplier,$base) = &ALF_LibertyUnit(&Unquote($value)); } elsif (&StringMatch($syntax,'complex_attribute')) { ($multiplier,$base) = &Array($value); } if (defined($multiplier) && defined($base)) { $ALF_Hidden{$object} = 1; local $parent = $ALF_Parent{$object}; local $alfobject = &ALF_FindMatchingObject($parent,$alftype,0) || &ALF_InsertObject($object,$alftype); local $unit = $multiplier*&ALF_MultiplierPrefix2Number($base); &ALF_CreateObject($alfobject,'UNIT',undef,$unit); } else { print("# ALF Data Error:\tinvalid Liberty value:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType'),"\n"); } } sub ALF_LibertyUnit { local($unit) = @_; $unit =~ /([0-9]+)([a-z,A-Z]+)/; local ($multiplier,$base) = ($1,$2); $base = '1'.$base unless &ALF_LexicalMatch('multiplier_prefix_value',$base); ($multiplier,$base); } sub ALF_LibertySlewDerateFromLibrary2ALF { local($attribute) = @_; local $library = $ALF_Parent{$attribute}; local $slewrate = &ALF_FindMatchingObject($library,'SLEWRATE',0) || &ALF_InsertObject($attribute,'SLEWRATE'); local $timeunit = &ALF_FindMatchingObject(&ALF_FindMatchingObject($library,'TIME'),'UNIT'); if (!defined($ALF_LibertyValue{$attribute})) { print("# ALF Data Error:\tmissing valuetype for slew derate attribute:\t",&ALF_ObjectInfoText($attribute,'ALF_LibertyType'),"\n"); } elsif (!&ALF_LexicalMatch('number',$ALF_LibertyValue{$attribute})) { print("# ALF Data Error:\twrong valuetype for attribute:\t",&ALF_ObjectInfoText($attribute,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } elsif (!$timeunit) { print("# ALF Data Warning:\tmissing time unit in library:\t",&ALF_ObjectInfoText($library,'ALF_LibertyType','ALF_LibertyName'),"\n"); } elsif (!defined($ALF_Value{$timeunit})) { print("# ALF Data Error:\tmissing valuetype for time unit:\t",&ALF_ObjectInfoText($timeunit,'ALF_LibertyType'),"\n"); } elsif (!&ALF_LexicalMatch('number',$ALF_Value{$timeunit})) { print("# ALF Data Error:\twrong valuetype for time unit:\t",&ALF_ObjectInfoText($timeunit,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } else { $ALF_Hidden{$attribute} = 'ALF'; &ALF_CreateObject($slewrate,'UNIT',undef,$ALF_LibertyValue{$attribute}*$ALF_Value{$timeunit}); } } sub ALF_LibertyOperatingConditions2ALF { local ($operating_conditions) = @_; local %parameter2object = ( 'process','Liberty_PROCESS', 'voltage','VOLTAGE', 'temperature','TEMPERATURE', 'tree_type','Liberty_TREE_TYPE', ); $ALF_Type{$operating_conditions} = 'CLASS'; $ALF_Name{$operating_conditions} = &Unquote($ALF_LibertyName{$operating_conditions}); foreach $object (&Array($ALF_Children{$operating_conditions})) { local $type = $ALF_LibertyType{$object}; if (&StringMatch($type,keys %parameter2object)) { $ALF_Type{$object} = $parameter2object{$type}; $ALF_Value{$object} = &Unquote($ALF_LibertyValue{$object}); } } $ALF_Prepend{$operating_conditions} = 1; &ALF_CreateObject($operating_conditions,'USAGE',undef,'Liberty_OPERATING_CLASS'); } sub ALF_LibertyScalingFactors2ALF { local ($scaling_factors) = @_; $ALF_Type{$scaling_factors} = 'CLASS'; $ALF_Name{$scaling_factors} = &Unquote($ALF_LibertyName{$scaling_factors}); foreach $object (&Array($ALF_Children{$scaling_factors})) { local $type = $ALF_LibertyType{$object}; if (&StringMatch($type,@ALF_Liberty_K_Factors)) { &ALF_Liberty2ALFConstant($object); } } $ALF_Prepend{$scaling_factors} = 1; &ALF_CreateObject($scaling_factors,'USAGE',undef,'Liberty_SCALING_CLASS'); } ### cell data ### sub ALF_LibertyCell2ALF { local($cell) = @_; $ALF_Type{$cell} = 'CELL'; $ALF_Name{$cell} = &Unquote($ALF_LibertyName{$cell}); $ALF_Prepend{$cell} = 1; &ALF_LibertyCellAttributes2ALF($cell); $ALF_Prepend{$cell} = 0; local @function; foreach $pin (&ALF_FindMatchingLibertyObjects($cell,'pin')) { &ALF_LibertyPin2ALF($pin); local $function = &ALF_FindMatchingLibertyObject($pin,'function'); $function[$#function+1] = $function if $function; } &ALF_LibertyFunction2ALF($cell,@function) if ($#function >= 0); foreach $pin (&ALF_FindMatchingLibertyObjects($cell,'pin')) { foreach $child (&Array($ALF_Children{$pin})) { if ($ALF_LibertyType{$child} eq 'timing') { &ALF_LibertyTiming2ALF($child); } elsif ($ALF_LibertyType{$child} eq 'internal_power') { &ALF_LibertyInternalPower2ALF($child); } } } foreach $pin (&ALF_FindMatchingLibertyObjects($cell,'pin')) { &ALF_LibertyTimingType2SignalType($pin); } $ALF_Prepend{$cell} = 1; &ALF_LibertyGenericObjects2ALF($cell); foreach $pin (&ALF_FindMatchingLibertyObjects($cell,'pin')) { $ALF_Prepend{$pin} = 1; &ALF_LibertyGenericObjects2ALF($pin); } 1; } sub ALF_LibertyCellAttributes2ALF { local($cell) = @_; local @usage; local $default_cell_leakage_power = 1; foreach $object (&Array($ALF_Children{$cell})) { local $type = $ALF_LibertyType{$object}; local $syntax = $ALF_LibertySyntax{$object}; local $value = $ALF_LibertyValue{$object}; if (&StringMatch($type,'area','cell_leakage_power','cell_footprint','dont_use','dont_touch')) { local $error = 0; unless (&StringMatch($syntax,'simple_attribute')) { $error = 1; if (defined($syntax)) { print("# ALF Data Error:\terroneous Liberty syntax \47$syntax\47 instead of \47simple_attribute\47:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } else { print("# ALF Data Error:\tmissing Liberty syntax instead of \47simple_attribute\47:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } } if (!defined($value)) { $error = 1; print("# ALF Data Error:\tmissing Liberty value:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType'),"\n"); } elsif (&StringMatch($type,'area','cell_leakage_power') && !&ALF_LexicalMatch('number',$value)) { $error = 1; print("# ALF Data Error:\tinvalid Liberty value \47$value\47 instead of a number:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType'),"\n"); } elsif (&StringMatch($type,'cell_footprint') && !&ALF_LexicalMatch('string_value',$value)) { $error = 1; print("# ALF Data Error:\tinvalid Liberty value \47$value\47 instead of a string:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType'),"\n"); } elsif (&StringMatch($type,'dont_use','dont_touch') && !&StringMatch($value,'true','false')) { $error = 1; print("# ALF Data Error:\tinvalid Liberty value \47$value\47 instead of \47true\47 or \47false\47:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType'),"\n"); } if ($error) { # print("# ALF Data Info:\tLiberty object will not be translated:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType'),"\n"); } elsif (&StringMatch($type,'area')) { $ALF_Type{$object} = 'AREA'; $ALF_Value{$object} = $value; } elsif (&StringMatch($type,'cell_leakage_power')) { $ALF_Type{$object} = 'POWER'; $ALF_Name{$object} = 'cell_leakage_power'; $ALF_Value{$object} = $value; &ALF_CreateObject($object,'MEASUREMENT',undef,'static'); $default_cell_leakage_power = 0; } elsif (&StringMatch($type,'cell_footprint')) { $ALF_Type{$object} = 'SWAP_CLASS'; $ALF_Value{$object} = &Unquote($value); } elsif (&StringMatch($type,'dont_use','dont_touch')) { $ALF_Hidden{$object} = 1; $usage[$#usage+1] = $type if &StringMatch($value,'true'); } } } @usage = ('synthesis','layout') unless defined(@usage); &ALF_CreateObject($cell,'RESTRICT_CLASS',undef,&CreateArray(@usage)); if ($default_cell_leakage_power && defined(&ALF_FindMatchingLibertyObject($ALF_Parent{$cell},'default_cell_leakage_power'))) { local $object = &ALF_CreateObject($cell,'POWER','cell_leakage_power','default_cell_leakage_power'); &ALF_CreateObject($object,'MEASUREMENT',undef,'static'); } } sub ALF_LibertyPin2ALF { local($pin) = @_; $ALF_Type{$pin} = 'PIN'; $ALF_Name{$pin} = &Unquote($ALF_LibertyName{$pin}); local $library = $ALF_Parent{$ALF_Parent{$pin}}; local ($direction,$signaltype); foreach $child (&Array($ALF_Children{$pin})) { $direction = &ALF_LibertyDirection2ALF($child) if &StringMatch($ALF_LibertyType{$child},'direction'); $signaltype = &ALF_LibertyClock2ALF($child) if &StringMatch($ALF_LibertyType{$child},'clock'); $signaltype = &ALF_LibertyNextStateType2ALF($child) if &StringMatch($ALF_LibertyType{$child},'nextstate_type'); } local $cap = &ALF_FindMatchingLibertyObject($pin,'capacitance'); local $risecap = &ALF_FindMatchingLibertyObject($pin,'rise_capacitance'); local $fallcap = &ALF_FindMatchingLibertyObject($pin,'fall_capacitance'); if ($risecap || $fallcap) { local $alfcap = &ALF_CreateObject($pin,'CAPACITANCE',undef); &ALF_CreateObject($alfcap,'DEFAULT',undef,$ALF_LibertyValue{$cap}) if ($cap); &ALF_CreateObject($alfcap,'RISE',undef,$ALF_LibertyValue{$risecap}) if $risecap; &ALF_CreateObject($alfcap,'FALL',undef,$ALF_LibertyValue{$fallcap}) if $fallcap; } elsif ($cap) { &ALF_CreateObject($pin,'CAPACITANCE',undef,$ALF_LibertyValue{$cap}); } else { local $defaultcaptype = &StringMatch($direction,'input')? 'default_input_pin_cap' : &StringMatch($direction,'output')? 'default_output_pin_cap' : &StringMatch($direction,'both')? 'default_inout_pin_cap' : undef; local $defaultcap = &ALF_FindMatchingObject($library,'CONSTANT',$defaultcaptype) if $defaultcaptype; &ALF_CreateObject($pin,'CAPACITANCE',undef,$defaultcaptype) if $defaultcap; } local $mincap = &ALF_FindMatchingLibertyObject($pin,'min_capacitance'); local $maxcap = &ALF_FindMatchingLibertyObject($pin,'max_capacitance'); local $mintrans = &ALF_FindMatchingLibertyObject($pin,'min_transition'); local $maxtrans = &ALF_FindMatchingLibertyObject($pin,'max_transition'); local $defaultmaxtrans = &ALF_FindMatchingObject($library,'CONSTANT','default_max_transition') if (!defined($maxtrans) && &StringMatch($direction,'input','both')); local $minpulselow = &ALF_FindMatchingLibertyObject($pin,'min_pulse_width_low'); local $minpulsehigh = &ALF_FindMatchingLibertyObject($pin,'min_pulse_width_high'); local $minperiod = &ALF_FindMatchingLibertyObject($pin,'min_period'); if ($mincap || $maxcap || $mintrans || $maxtrans || $defaultmaxtrans || $minpulselow || $minpulsehigh) { local $limit = &ALF_CreateObject($pin,'LIMIT'); if ($mincap || $maxcap) { local $caplimit = &ALF_CreateObject($limit,'CAPACITANCE'); &ALF_CreateObject($caplimit,'MIN',undef,$ALF_LibertyValue{$mincap}) if $mincap; &ALF_CreateObject($caplimit,'MAX',undef,$ALF_LibertyValue{$maxcap}) if $maxcap; } if ($mintrans || $maxtrans || $defaultmaxtrans) { local $slewlimit = &ALF_CreateObject($limit,'SLEWRATE'); &ALF_CreateObject($slewlimit,'MIN',undef,$ALF_LibertyValue{$mintrans}) if $mintrans; &ALF_CreateObject($slewlimit,'MAX',undef,$ALF_LibertyValue{$maxtrans}) if $maxtrans; &ALF_CreateObject($slewlimit,'MAX',undef,'default_max_transition') if $defaultmaxtrans; } if ($minpulselow || $minpulsehigh) { local $pulselimit = &ALF_CreateObject($limit,'PULSEWIDTH'); if ($minpulselow) { local $low = &ALF_CreateObject($pulselimit,'LOW'); &ALF_CreateObject($low,'MIN',undef,$ALF_LibertyValue{$minpulselow}); } if ($minpulsehigh) { local $high = &ALF_CreateObject($pulselimit,'HIGH'); &ALF_CreateObject($high,'MIN',undef,$ALF_LibertyValue{$minpulsehigh}); } } if ($minperiod) { local $periodlimit = &ALF_CreateObject($limit,'PERIOD'); &ALF_CreateObject($periodlimit,'MIN',undef,$ALF_LibertyValue{$minperiod}); } } foreach $object ($cap,$risecap,$fallcap,$mincap,$maxcap,$mintrans,$maxtrans,$minpulselow,$minpulsehigh,$minperiod) { $ALF_Hidden{$object} = 'ALF' if defined($object); } 1; } sub ALF_LibertyDirection2ALF { local($direction) = @_; local $pin = $ALF_Parent{$direction}; local $value = $ALF_LibertyValue{$direction}; local $alfvalue = (&StringMatch($value,'input' ))? 'input' : (&StringMatch($value,'output' ))? 'output' : (&StringMatch($value,'inout' ))? 'both' : (&StringMatch($value,'internal'))? 'none' : undef; if ($alfvalue) { $ALF_Type{$direction} = 'DIRECTION'; $ALF_Value{$direction} = $alfvalue; } else { print("# ALF Data Error:\tinvalid Liberty pin attribute \47direction\47 = \47$value\47:\t",&ALF_ObjectInfoText($pin,'ALF_LibertyType','ALF_LibertyName'),"\n"); } $alfvalue; } ### signaltype based on timing arcs ### sub ALF_LibertyTimingType2SignalType { local($pin) = @_; #print("ALF_LibertyTimingType2SignalType\t",&ALF_ObjectInfoText($pin),"\n"); local @out = ('out_enable','scan_out_enable'); local @data = ('data','scan_data','control','enable','scan_enable','address','select',@out); local @clock = ('clock','scan_clock','master_clock','slave_clock','scan_master_clock','scan_slave_clock'); local @set_clear = ('set','clear'); local $signaltype = &ALF_FindMatchingObject($pin,'SIGNALTYPE'); local $signaltype_value = $ALF_Value{$signaltype} if defined($signaltype); local ($proposed_signaltype,$proposed_timing,@possible_signaltype); foreach $related_pin (&Array(&ALF_SearchForObjects( &CreateArray(), $ALF_Parent{$pin}, 'ALF_LibertyObjectMatch','related_pin',undef,$ALF_LibertyName{$pin} ))) { local $related_pin_value = $ALF_LibertyValue{$related_pin}; local $related_timing = $ALF_Parent{$related_pin}; local $related_timing_type = &ALF_FindMatchingLibertyObject($related_timing,'timing_type'); local $related_timing_type_value = $ALF_LibertyValue{$related_timing_type} if defined($related_timing_type); if (!defined($related_timing_type)) { @possible_signaltype = undef; print("# ALF Data Warning:\tmissing attribute \47timing_type\47 in Liberty object $related_timing\n") if ($ALF_LibertyType{$related_timing} eq 'timing'); } elsif (&StringMatch($related_timing_type_value,'setup_rising','setup_falling','hold_rising','hold_falling')) { @possible_signaltype = @clock; } elsif (&StringMatch($related_timing_type_value,'recovery_rising','recovery_falling','removal_rising','removal_falling')) { @possible_signaltype = @clock; } elsif (&StringMatch($related_timing_type_value,'preset','clear')) { @possible_signaltype = @set_clear; } elsif (&StringMatch($related_timing_type_value,'combinational','rising_edge','falling_edge')) { @possible_signaltype = (@data,@clock); } elsif (&StringMatch($related_timing_type_value,'three_state_enable','three_state_disable')) { @possible_signaltype = @out; } #print("ALF_LibertyTimingType2SignalType\trelated_timing_pin = ",$ALF_LibertyName{$ALF_Parent{$related_timing}},"\trelated_timing = $related_timing\trelated_timing_type = $related_timing_type_value\tpossible_signaltype = (@possible_signaltype)\n"); if (!&Array(@possible_signaltype)) { } elsif (defined($signaltype_value)) { print("# ALF Data Warning:\tincompatibility between actual signaltype \42$signaltype_value\42 of pin $pin and possible signaltype (@possible_signaltype) based on timing arc:\t",&ALF_ObjectInfoText($related_timing,'ALF_LibertyType','ALF_LibertyName'),"\n") unless &StringMatch($signaltype_value,@possible_signaltype); } elsif (defined($proposed_signaltype)) { print("# ALF Data Warning:\tIncompatibility between proposed signaltype \42$proposed_signaltype\42 of pin $pin based on timing arc $proposed_timing and possible signaltype (@possible_signaltype) based on timing arc:\t",&ALF_ObjectInfoText($related_timing,'ALF_LibertyType','ALF_LibertyName'),"\n") unless &StringMatch($proposed_signaltype,@possible_signaltype); } else { $proposed_signaltype = $possible_signaltype[0]; $proposed_timing = $related_timing; } } foreach $timing (&ALF_FindMatchingLibertyObjects($pin,'timing')) { local $timing_type = &ALF_FindMatchingLibertyObject($timing,'timing_type'); local $timing_type_value = $ALF_LibertyValue{$timing_type} if defined($timing_type); if (&StringMatch($timing_type_value,'recovery_rising','recovery_falling','removal_rising','removal_falling')) { @possible_signaltype = @set_clear; } elsif (&StringMatch($timing_type_value,'setup_rising','setup_falling','hold_rising','hold_falling')) { @possible_signaltype = @data; } elsif (&StringMatch($timing_type_value,'preset','clear')) { @possible_signaltype = @data; } elsif (&StringMatch($timing_type_value,'combinational','rising_edge','falling_edge')) { @possible_signaltype = @data; } elsif (&StringMatch($timing_type_value,'three_state_enable','three_state_disable')) { @possible_signaltype = @data; } #print("ALF_LibertyTimingType2SignalType\ttiming = $timing\ttiming_type = $timing_type_value\tpossible_signaltype = (@possible_signaltype)\n"); if (defined($signaltype_value) && defined($timing)) { print("# ALF Data Warning:\tdiscrepancy between actual signaltype \42$signaltype_value\42 of pin $pin and possible signaltype (@possible_signaltype) based on timing arc:\t",&ALF_ObjectInfoText($timing,'ALF_LibertyType','ALF_LibertyName'),"\n") unless &StringMatch($signaltype_value,@possible_signaltype); } elsif (defined($proposed_signaltype)) { print("# ALF Data Warning:\tDiscrepancy between proposed signaltype \42$proposed_signaltype\42 of pin $pin based on timing arc $proposed_timing and possible signaltype (@possible_signaltype) based on timing arc:\t",&ALF_ObjectInfoText($timing,'ALF_LibertyType','ALF_LibertyName'),"\n") unless &StringMatch($proposed_signaltype,@possible_signaltype); } else { $proposed_signaltype = $possible_signaltype[0]; $proposed_timing = $related_timing; } } &ALF_CreateObject($pin,'SIGNALTYPE',undef,$proposed_signaltype) if defined($proposed_signaltype); } ### signaltype based on function ### sub ALF_LibertyClock2ALF { local($clock) = @_; local $pin = $ALF_Parent{$clock}; local $value = &Unquote($ALF_LibertyValue{$clock}); local $alfvalue; if (&StringMatch($value,'true')) { $ALF_Type{$clock} = 'SIGNALTYPE'; $alfvalue = 'clock'; $ALF_Value{$clock} = $alfvalue; } elsif (&StringMatch($value,'false')) { $ALF_Hidden{$clock} = 'ALF'; } else { print("# ALF Data Error:\tinvalid Liberty pin attribute \47clock\47 = \47$value\47:\t",&ALF_ObjectInfoText($pin,'ALF_LibertyType','ALF_LibertyName'),"\n"); } $alfvalue; } sub ALF_LibertyNextStateType2ALF { local($nextstatetype) = @_; local $pin = $ALF_Parent{$nextstatetype}; local $value = $ALF_LibertyValue{$nextstatetype}; local $alfvalue = (&StringMatch($value,'data' ))? 'data' : (&StringMatch($value,'preset' ))? 'set' : (&StringMatch($value,'clear' ))? 'clear' : (&StringMatch($value,'load'))? 'enable' : (&StringMatch($value,'scan_in'))? 'scan_data' : (&StringMatch($value,'scan_enable'))? 'scan_enable' : undef; if ($alfvalue) { $ALF_Type{$nextstatetype} = 'SIGNALTYPE'; $ALF_Value{$nextstatetype} = $alfvalue; &ALF_CreateObject($pin,'ACTION',undef,'synchronous') if &StringMatch($alfvalue,'set','clear'); } else { print("# ALF Data Error:\tinvalid Liberty pin attribute \47nextstate_type\47 = \47$value\47:\t",&ALF_ObjectInfoText($pin,'ALF_LibertyType','ALF_LibertyName'),"\n"); } $alfvalue; } ### function data ### sub ALF_LibertyFunction2ALF { local($cell,@function) = @_; local $function = &ALF_CreateObject($cell,'FUNCTION'); local $behavior = &ALF_CreateObject($function,'BEHAVIOR'); $ALF_Prepend{$cell} = 1; foreach $function (@function) { &ALF_LibertyCombinational2ALF($function,$behavior); } local @latch = &ALF_FindMatchingLibertyObjects($cell,'latch'); foreach $latch (@latch) { &ALF_LibertyLatch2ALF($latch,$behavior); } local @ff = &ALF_FindMatchingLibertyObjects($cell,'ff'); foreach $ff (@ff) { &ALF_LibertyFlipflop2ALF($ff,$behavior); } local $celltype = ($#ff==-1 && $#latch==-1)? 'combinational' # no latch, no flipflop : ($#ff== 0 && $#latch==-1)? 'flipflop' : ($#ff==-1 && $#latch== 0)? 'latch' : 'block'; # more than 1 latch or flipflop &ALF_CreateObject($cell,'CELLTYPE',undef,$celltype); $ALF_Prepend{$cell} = 0; } sub ALF_LibertyCombinational2ALF { local($function,$behavior) = @_; local $pin = $ALF_Parent{$function}; local $boolean = &ALF_LibertyBoolean2ALF($ALF_LibertyValue{$function}); &ALF_CreateObject($behavior,&Unquote($ALF_LibertyName{$pin}),undef,$boolean); $ALF_Hidden{$function} = 'ALF'; } sub ALF_LibertyLatch2ALF { local($latch,$behavior) = @_; local $enable = &ALF_FindMatchingLibertyObject($latch,'enable'); local $data_in = &ALF_FindMatchingLibertyObject($latch,'data_in'); local $trigger; if ($enable && $data_in) { $trigger = &ALF_LibertyBoolean2ALF($ALF_LibertyValue{$enable}); &ALF_LibertySequentialAttribute2ALF($latch,$enable,'clock'); } &ALF_LibertySequential2ALF($latch,$behavior,$trigger,$data_in); } sub ALF_LibertyFlipflop2ALF { local($flipflop,$behavior) = @_; local $clocked_on = &ALF_FindMatchingLibertyObject($flipflop,'clocked_on'); local $clocked_on_also = &ALF_FindMatchingLibertyObject($flipflop,'clocked_on_also'); local $next_state = &ALF_FindMatchingLibertyObject($flipflop,'next_state'); local $trigger; if ($clocked_on && $next_state) { $trigger = &ALF_Boolean2Edge(&ALF_LibertyBoolean2ALF($ALF_LibertyValue{$clocked_on})); if ($clocked_on_also) { &ALF_LibertySequentialAttribute2ALF($flipflop,$clocked_on,'master_clock'); &ALF_LibertySequentialAttribute2ALF($flipflop,$clocked_on_also,'slave_clock'); $trigger = $trigger.' ~> '.&ALF_Boolean2Edge(&ALF_LibertyBoolean2ALF($ALF_LibertyValue{$clocked_on_also})); } else { &ALF_LibertySequentialAttribute2ALF($flipflop,$clocked_on,'clock'); } } &ALF_LibertySequential2ALF($flipflop,$behavior,$trigger,$next_state); } sub ALF_LibertySequential2ALF { local($sequential,$behavior,$data_trigger,$data_value) = @_; local ($iq,$iqn) = &ALF_LibertyStorageVariable2ALF($sequential); local ($control_statement,$clear_trigger,$preset_trigger); $ALF_Prepend{$behavior} = 1; if ($data_trigger && $data_value) { local $d = &ALF_LibertyBoolean2ALF($ALF_LibertyValue{$data_value}); $control_statement = &ALF_CreateControlStatement($behavior,$data_trigger,$iq,$d,$iqn,&ALF_Inverted($d)); &ALF_LibertySequentialAttribute2ALF($sequential,$data_value,'data'); } local ($clear,$preset,$clear_preset_var1,$clear_preset_var2) = &ALF_LibertyClearPresetInfo($sequential); if ($clear) { $ALF_Type{$control_statement} = ':' if $control_statement; $clear_trigger = &ALF_LibertyBoolean2ALF($ALF_LibertyValue{$clear}); $control_statement = &ALF_CreateControlStatement($behavior,$clear_trigger,$iq,0,$iqn,1); &ALF_LibertySequentialAttribute2ALF($sequential,$clear,'clear'); } if ($preset) { $ALF_Type{$control_statement} = ':' if $control_statement; $preset_trigger = &ALF_LibertyBoolean2ALF($ALF_LibertyValue{$preset}); $control_statement = &ALF_CreateControlStatement($behavior,$preset_trigger,$iq,1,$iqn,0); &ALF_LibertySequentialAttribute2ALF($sequential,$preset,'set'); } if ($clear && $preset && $clear_preset_var1 && $clear_preset_var2) { $ALF_Type{$control_statement} = ':'; local $x1 = &ALF_LibertyBoolean2ALF($ALF_LibertyValue{$clear_preset_var1}); local $x2 = &ALF_LibertyBoolean2ALF($ALF_LibertyValue{$clear_preset_var2}); $control_statement = &ALF_CreateControlStatement($behavior,"$preset_trigger && $clear_trigger",$iq,$x1,$iqn,$x2); } $ALF_Prepend{$behavior} = 0; $ALF_Hidden{$sequential} = 'ALF'; $ALF_Type{$control_statement} = '@'; $control_statement; } sub ALF_LibertyStorageVariable2ALF { local($sequential) = @_; local ($variable1,$variable2) = split(/\,\s*/,&Unquote($ALF_LibertyName{$sequential})); local $function = &ALF_FindMatchingObject($ALF_Parent{$sequential},'FUNCTION'); local $iq = &ALF_InsertObject($function,'PIN',$variable1); &ALF_CreateObject($iq,'DIRECTION',undef,'none'); &ALF_CreateObject($iq,'VIEW',undef,'none'); &ALF_CreateObject($iq,'ATTRIBUTE',undef,&CreateArray('non_inverted')); local $iqn = &ALF_InsertObject($function,'PIN',$variable2); &ALF_CreateObject($iqn,'DIRECTION',undef,'none'); &ALF_CreateObject($iqn,'VIEW',undef,'none'); &ALF_CreateObject($iqn,'ATTRIBUTE',undef,&CreateArray('inverted')); ($variable1,$variable2); } sub ALF_LibertyClearPresetInfo { local($sequential) = @_; local $clear = &ALF_FindMatchingLibertyObject($sequential,'clear'); local $preset = &ALF_FindMatchingLibertyObject($sequential,'preset'); local $clear_preset_var1 = &ALF_FindMatchingLibertyObject($sequential,'clear_preset_var1'); local $clear_preset_var2 = &ALF_FindMatchingLibertyObject($sequential,'clear_preset_var2'); ($clear,$preset,$clear_preset_var1,$clear_preset_var2); } sub ALF_LibertySequentialAttribute2ALF { local($sequential,$attribute,$signaltype) = @_; #print("ALF_LibertySequentialAttribute2ALF\tsignaltype=$signaltype\t",&ALF_ObjectInfoText($attribute,'ALF_LibertyType','ALF_LibertyValue'),"\n"); local $attribute_type = $ALF_LibertyType{$attribute}; local ($first,$second,@third) = split(/\s/,&ALF_LibertyBoolean2ALF($ALF_LibertyValue{$attribute})); local ($pinname,$polarity); if (defined(@third)) { } elsif (defined($second)) { $pinname = $second; if (&StringMatch($first,'!','~')) { $polarity = &StringMatch($attribute_type,'clocked_on','clocked_on_also')? 'falling_edge' : &StringMatch($attribute_type,'enable','preset','clear')? 'low' : undef; } } elsif (defined($first)) { $pinname = $first; $polarity = &StringMatch($attribute_type,'clocked_on','clocked_on_also')? 'rising_edge' : &StringMatch($attribute_type,'enable','preset','clear')? 'high' : undef; } local $pin = &ALF_FindMatchingLibertyObject($ALF_Parent{$sequential},'pin',$pinname) || &ALF_FindMatchingLibertyObject($ALF_Parent{$sequential},'pin',&Doublequote($pinname)) if defined($pinname); if ($pin && $signaltype && $polarity) { local $existing_signaltype = &ALF_FindMatchingObject($pin,'SIGNALTYPE'); local $existing_polarity = &ALF_FindMatchingObject($pin,'POLARITY'); local $existing_signaltype_value = $ALF_Value{$existing_signaltype} if $existing_signaltype; local $existing_polarity_value = $ALF_Value{$existing_polarity} if $existing_polarity; if ($existing_signaltype && $existing_polarity) { if ( &StringMatch($existing_signaltype_value,'slave_clock') && &StringMatch($signaltype,'master_clock') || &StringMatch($existing_signaltype_value,'master_clock') && &StringMatch($signaltype,'slave_clock') ) { $ALF_Value{$existing_signaltype} = 'clock'; $ALF_Value{$existing_polarity} = 'double_edge' unless &StringMatch($polarity,$existing_polarity_value); } else { print("# ALF Data Error:\tconflicting signaltype values \47$existing_signaltype_value\47 and \47$signaltype\47 instead of \47master_clock\47 and \47slave_clock\47:\t",&ALF_ObjectInfoText($pin,'ALF_LibertyName','ALF_LibertyValue'),"\n"); } } else { if ($existing_signaltype) { print("# ALF Data Error:\tconflicting signaltype values \47$existing_signaltype_value\47 and \47$signaltype\47:\t",&ALF_ObjectInfoText($pin,'ALF_LibertyName','ALF_LibertyValue'),"\n") unless &StringMatch($signaltype,$existing_signaltype_value); } else { &ALF_CreateObject($pin,'SIGNALTYPE',undef,$signaltype); } if ($existing_polarity) { print("# ALF Data Error:\tconflicting polarity values \47$existing_polarity_value\47 and \47$polarity\47:\t",&ALF_ObjectInfoText($pin,'ALF_LibertyName','ALF_LibertyValue'),"\n") unless &StringMatch($polarity,$existing_polarity_value); } elsif (!&StringMatch($signaltype,'data','scan_data','address','control')) { &ALF_CreateObject($pin,'POLARITY',undef,$polarity); } } &ALF_CreateObject($pin,'ACTION',undef,'asynchronous') if &StringMatch($signaltype,'set','clear'); } elsif (&StringMatch($attribute_type,'next_state','data_in')) { # no op } #print("ALF_LibertySequentialAttribute2ALF\tsignaltype=$signaltype\tpolarity=$polarity\t",&ALF_ObjectInfoText($pin),"\n"); $pin; } sub ALF_LibertyBoolean2ALF { local($expression) = @_; local @liberty = split(/\s+/,&Unquote($expression)); local @alf; foreach $liberty (@liberty) { if (&Ending($liberty,1) eq "\47") { local $l = length($liberty); $alf[$#alf+1] = '!'; $alf[$#alf+1] = &Beginning($liberty,$l-1); } elsif (&Beginning($liberty,1) eq "!") { local $l = length($liberty); $alf[$#alf+1] = '!'; $alf[$#alf+1] = &Ending($liberty,$l-1); } elsif (&StringMatch($liberty,'*')) { $alf[$#alf+1] = '&&'; } elsif (&StringMatch($liberty,'+')) { $alf[$#alf+1] = '||'; } else { $liberty =~ s/\*/\&/g; $liberty =~ s/\+/\|/g; $alf[$#alf+1] = $liberty; } } #print("liberty = (@liberty)\talf = (@alf)\n"); ($expression eq 'L')? '0' : ($expression eq 'H')? '1' : join(' ',@alf); } ### interconnect data ### sub ALF_LibertyTransitionDegradation2ALF { local ($library) = @_; local ($wire,$frompin,$topin); local $rise_transition_degradation = &ALF_FindMatchingLibertyObject($library,'rise_transition_degradation'); local $fall_transition_degradation = &ALF_FindMatchingLibertyObject($library,'fall_transition_degradation'); local $insert = defined($rise_transition_degradation)? $rise_transition_degradation : $fall_transition_degradation; if (defined($insert)) { $wire = &ALF_InsertObject($insert,'WIRE','transition_degradation_'.&AutoName); &ALF_CreateObject($wire,'WIRETYPE',undef,'interconnect'); $frompin = 'driver_node'; local $driver = &ALF_CreateObject($wire,'NODE',$frompin); &ALF_CreateObject($driver,'NODETYPE',undef,'driver'); $topin = 'receiver_node'; local $receiver = &ALF_CreateObject($wire,'NODE',$topin); &ALF_CreateObject($receiver,'NODETYPE',undef,'receiver'); } &ALF_LibertyWireDelay2ALF($wire,$rise_transition_degradation,'01',$frompin,$topin) if defined($rise_transition_degradation); &ALF_LibertyWireDelay2ALF($wire,$fall_transition_degradation,'10',$frompin,$topin) if defined($fall_transition_degradation); } sub ALF_LibertyWireDelay2ALF { local ($wire,$transition_degradation,$edge,$frompin,$topin) = @_; local $vector_expression = "( $edge $frompin -> $edge $topin )"; local $vector = &ALF_CreateObject($wire,'VECTOR',$vector_expression); $ALF_Type{$transition_degradation} = 'SLEWRATE'; &ALF_CreateObject($transition_degradation,'PIN',undef,$topin); local %attribute = ( 'pin', $topin, 'related_pin', $frompin, 'timing_type', 'combinational', 'timing_sense', 'positive_unate', ); &ALF_LibertyArithmeticModel2ALF($transition_degradation,%attribute); &ALF_CopyObject($transition_degradation,$vector); $ALF_Hidden{$transition_degradation} = 'ALF'; } sub ALF_LibertyWireLoadTable2ALF { local ($wireloadtable) = @_; local %alftype = ( 'fanout_length','LENGTH', 'fanout_capacitance','CAPACITANCE', 'fanout_resistance','RESISTANCE', 'fanout_area','AREA', ); $ALF_Type{$wireloadtable} = 'WIRE'; $ALF_Name{$wireloadtable} = &Unquote($ALF_LibertyName{$wireloadtable}); &ALF_CreateObject($wireloadtable,'WIRETYPE',undef,'estimated'); foreach $modeltype (keys %alftype) { &ALF_LibertyFanoutModel2ALF($wireloadtable,$modeltype,$alftype{$modeltype}); } } sub ALF_LibertyFanoutModel2ALF { local ($wireloadtable,$modeltype,$alftype) = @_; local %model; local @models = &ALF_FindMatchingLibertyObjects($wireloadtable,$modeltype); foreach $model (@models) { $ALF_Hidden{$model} = 'ALF'; local ($key,$value) = &Array($ALF_LibertyValue{$model}); $model{$key} = $value; } local @keys = sort(Ascending keys %model); local @table; foreach $key (@keys) { $table[$#table+1] = $model{$key}; } if (defined(@models)) { local $model = &ALF_CreateObject($wireloadtable,$alftype); local $header = &ALF_CreateObject($model,'HEADER'); local $fanout = &ALF_CreateObject($header,'FANOUT'); local $fanout_table = &ALF_CreateObject($fanout,'TABLE',undef,&CreateArray(@keys)); local $table = &ALF_CreateObject($model,'TABLE',undef,&CreateArray(@table)); } } sub ALF_LibertyWireLoadSelection2ALF { local ($wire_load_selection) = @_; $ALF_Type{$wire_load_selection} = 'CLASS'; $ALF_Name{$wire_load_selection} = &Unquote($ALF_LibertyName{$wire_load_selection}); $ALF_Prepend{$wire_load_selection} = 1; &ALF_CreateObject($wire_load_selection,'USAGE',undef,'select_class'); foreach $wire_load_from_area (&ALF_FindMatchingLibertyObjects($wire_load_selection,'wire_load_from_area')) { local ($minarea,$maxarea,$wirename) = &Array($ALF_LibertyValue{$wire_load_from_area}); $wirename = Unquote($wirename); $ALF_Type{$wire_load_from_area} = 'AREA'; $ALF_Name{$wire_load_from_area} = join('_',$wirename,$minarea,$maxarea); &ALF_CreateObject($wire_load_from_area,'WIRE',undef,$wirename); &ALF_CreateObject($wire_load_from_area,'MIN',undef,$minarea); &ALF_CreateObject($wire_load_from_area,'MAX',undef,$maxarea); local $wire = &ALF_FindMatchingObject($ALF_Parent{$wire_load_selection},'WIRE',$wirename); local $select_class = &ALF_FindMatchingObject($wire,'SELECT_CLASS'); unless (defined($select_class)) { $ALF_Prepend{$wire} = 1; $select_class = &ALF_CreateObject($wire,'SELECT_CLASS'); $ALF_Value{$select_class} = &CreateArray(); } local $refvalue = $ALF_Value{$select_class}; local $refname = $ALF_Name{$wire_load_selection}; &AppendArray($refvalue,$refname) unless &FindArrayKey($refvalue,$refname); } } ### cell timing & power data ### sub ALF_LibertyTiming2ALF { local ($timing) = @_; local $cell_rise = &ALF_FindMatchingLibertyObject($timing,'cell_rise'); local $cell_fall = &ALF_FindMatchingLibertyObject($timing,'cell_fall'); local $rise_transition = &ALF_FindMatchingLibertyObject($timing,'rise_transition'); local $fall_transition = &ALF_FindMatchingLibertyObject($timing,'fall_transition'); local $rise_constraint = &ALF_FindMatchingLibertyObject($timing,'rise_constraint'); local $fall_constraint = &ALF_FindMatchingLibertyObject($timing,'fall_constraint'); &ALF_LibertyCellDelay2ALF($timing,$cell_rise,$rise_transition) if defined($cell_rise); &ALF_LibertyCellDelay2ALF($timing,$cell_fall,$fall_transition) if defined($cell_fall); &ALF_LibertyCellConstraint2ALF($timing,$rise_constraint) if defined($rise_constraint); &ALF_LibertyCellConstraint2ALF($timing,$fall_constraint) if defined($fall_constraint); } sub ALF_LibertyInternalPower2ALF { local ($internal_power) = @_; local $rise_power = &ALF_FindMatchingLibertyObject($internal_power,'rise_power'); local $fall_power = &ALF_FindMatchingLibertyObject($internal_power,'fall_power'); &ALF_LibertyCellEnergy2ALF($internal_power,$rise_power) if defined($rise_power); &ALF_LibertyCellEnergy2ALF($internal_power,$fall_power) if defined($fall_power); } sub ALF_LibertyCellDelay2ALF { local ($timing,$delay,$slewrate) = @_; local %attribute = &ALF_Liberty_TimingInfo($timing); local $timing_type = $attribute{'timing_type'}; local $timing_sense = $attribute{'timing_sense'}; local $pin = $attribute{'pin'}; local $related_pin = $attribute{'related_pin'}; local $related_output_pin = $attribute{'related_output_pin'}; local $when = $attribute{'when'}; unless (defined($timing_type)) { $timing_type = 'combinational'; print("# ALF Data Info:\tassuming default \47timing_type\47 = \47$timing_type\47:\t",&ALF_ObjectInfoText($timing,'ALF_LibertyType','ALF_LibertyName'),"\n") if $ALF_Debug; } local ($fromedge,$toedge) = &ALF_Liberty_MapEdges2ALF($ALF_LibertyType{$delay},$timing_type,$timing_sense); local $vector_expression = "( $fromedge $related_pin -> $toedge $pin )"; $vector_expression = "( $vector_expression ) && $when )" if $when; local $cell = $ALF_Parent{$ALF_Parent{$timing}}; local $vector = &ALF_CreateObject($cell,'VECTOR',$vector_expression); &ALF_RedefineObject($delay,$vector,'DELAY'); &ALF_CreateAnnotationContainer($delay,'FROM','PIN',$related_pin); &ALF_CreateAnnotationContainer($delay,'TO','PIN',$pin); &ALF_LibertyArithmeticModel2ALF($delay,%attribute); if ($slewrate) { &ALF_RedefineObject($slewrate,$vector,'SLEWRATE'); &ALF_CreateObject($slewrate,'PIN',undef,$pin); &ALF_LibertyArithmeticModel2ALF($slewrate,%attribute); } } sub ALF_LibertyCellEnergy2ALF { local ($internal_power,$energy) = @_; local %attribute = &ALF_Liberty_InternalPowerInfo($internal_power); local $pin = $attribute{'pin'}; local $related_pin = $attribute{'related_pin'}; local $related_output_pin = $attribute{'related_output_pin'}; local $when = $attribute{'when'}; local %match_attribute; $match_attribute{'related_pin'} = "\42".$related_pin."\42"; $match_attribute{'related_output_pin'} = "\42".$related_output_pin."\42" if defined($related_output_pin); $match_attribute{'when'} = "\42".$when."\42" if defined($when); local $timing = &ALF_FindMatchingLibertyObject($ALF_Parent{$internal_power},'timing',undef,undef,%match_attribute); local $match_type = $ALF_LibertyType{$energy} eq 'rise_power' ? 'cell_rise' : $ALF_LibertyType{$energy} eq 'fall_power' ? 'cell_fall' : undef; local $delay = $match_type? &ALF_FindMatchingLibertyObject($timing,$match_type) : undef; local $vector = $delay? $ALF_Parent{$delay} : undef; unless ($vector) { local $toedge = $ALF_LibertyType{$energy} eq 'rise_power' ? '01' : $ALF_LibertyType{$energy} eq 'fall_power' ? '10' : '?!'; local $fromedge = defined($related_pin)? '?!' : undef; local $vector_expression = (defined($fromedge) && defined($when))? "( ( $fromedge $related_pin -> $toedge $pin ) && $when )" : defined($fromedge)? "( $fromedge $related_pin -> $toedge $pin )" : defined($when)? "( $toedge $pin && $when )" : "( $toedge $pin )"; local $cell = $ALF_Parent{$ALF_Parent{$internal_power}}; $vector = &ALF_CreateObject($cell,'VECTOR',$vector_expression); } &ALF_RedefineObject($energy,$vector,'ENERGY'); &ALF_LibertyArithmeticModel2ALF($energy,%attribute); } sub ALF_LibertyCellConstraint2ALF { local ($timing,$constraint) = @_; local %attribute = &ALF_Liberty_TimingInfo($timing); local $timing_type = $attribute{'timing_type'}; local $timing_sense = $attribute{'timing_sense'}; local ($fromedge,$toedge) = &ALF_Liberty_MapEdges2ALF($ALF_LibertyType{$constraint},$timing_type,$timing_sense); local $pin = $attribute{'pin'}; local $related_pin = $attribute{'related_pin'}; local $when = $attribute{'when'}; local ($frompin,$topin,$alftype); if (&StringMatch($timing_type,'setup_rising','setup_falling')) { $frompin = $pin; $topin = $related_pin; $alftype = 'SETUP'; } elsif (&StringMatch($timing_type,'hold_rising','hold_falling')) { $frompin = $related_pin; $topin = $pin; $alftype = 'HOLD'; } elsif (&StringMatch($timing_type,'recovery_rising','recovery_falling')) { $frompin = $pin; $topin = $related_pin; $alftype = 'RECOVERY'; } elsif (&StringMatch($timing_type,'removal_rising','removal_falling')) { $frompin = $related_pin; $topin = $pin; $alftype = 'REMOVAL'; } if ($alftype) { local $vector_expression = "( $fromedge $frompin -> $toedge $topin )"; $vector_expression = "( $vector_expression ) && $when )" if $when; local $cell = $ALF_Parent{$ALF_Parent{$timing}}; local $vector = &ALF_CreateObject($cell,'VECTOR',$vector_expression); &ALF_RedefineObject($constraint,$vector,$alftype); &ALF_CreateAnnotationContainer($constraint,'FROM','PIN',$frompin); &ALF_CreateAnnotationContainer($constraint,'TO','PIN',$topin); &ALF_LibertyArithmeticModel2ALF($constraint,%attribute); } } ### auxiliary functions for timing and power ### sub ALF_Liberty_MapEdges2ALF { local ($object_type,$timing_type,$timing_sense) = @_; local ($fromedge,$toedge); if (&StringMatch($timing_type,'combinational','rising_edge','falling_edge','preset','clear')) { $toedge = &StringMatch($object_type,'cell_rise','rising_edge') ? '01' : &StringMatch($object_type,'cell_fall','falling_edge') ? '10' : '?!'; } elsif (&StringMatch($timing_type,'three_state_enable')) { $toedge = &StringMatch($object_type,'cell_rise') ? 'Z1' : &StringMatch($object_type,'cell_fall') ? 'Z0' : 'Z?'; } elsif (&StringMatch($timing_type,'three_state_disable')) { $toedge = &StringMatch($object_type,'cell_rise') ? '0Z' : &StringMatch($object_type,'cell_fall') ? '1Z' : '?Z'; } elsif (&StringMatch($timing_type,'setup_rising','setup_falling','recovery_rising','recovery_falling')) { $toedge = &StringMatch($timing_type,'setup_rising','recovery_rising')? '01' : '10'; $fromedge = &StringMatch($object_type,'rise_constraint') ? '01' : &StringMatch($object_type,'fall_constraint') ? '10' : '?!'; } elsif (&StringMatch($timing_type,'hold_rising','hold_falling','removal_rising','removal_falling')) { $fromedge = &StringMatch($timing_type,'hold_rising','removal_rising')? '01' : '10'; $toedge = &StringMatch($object_type,'rise_constraint') ? '01' : &StringMatch($object_type,'fall_constraint') ? '10' : '?!'; } if (&StringMatch($timing_type,'combinational','three_state_enable','three_state_disable','preset','clear')) { $fromedge = &ALF_Liberty_MapTimingSense2ALF($timing_sense,$toedge); } elsif (&StringMatch($timing_type,'rising_edge')) { $fromedge = '01'; } elsif (&StringMatch($timing_type,'falling_edge')) { $fromedge = '10'; } ($fromedge,$toedge); } sub ALF_Liberty_MapTimingSense2ALF { local($timing_sense,$edge) = @_; &StringMatch($timing_sense,'non_unate')? '?!' : &ALF_IsRisingEdge($edge) && &StringMatch($timing_sense,'positive_unate')? '01' : &ALF_IsRisingEdge($edge) && &StringMatch($timing_sense,'negative_unate')? '10' : &ALF_IsFallingEdge($edge) && &StringMatch($timing_sense,'positive_unate')? '10' : &ALF_IsFallingEdge($edge) && &StringMatch($timing_sense,'negative_unate')? '01' : '?!'; } sub ALF_Liberty_TimingInfo { local($timing) = @_; local ($related_pin,$timing_type,$timing_sense,$when,$related_output_pin); foreach $object (&Array($ALF_Children{$timing})) { local $type = $ALF_LibertyType{$object}; local $value = $ALF_LibertyValue{$object}; $timing_type = $value if &StringMatch($type,'timing_type'); $timing_sense = $value if &StringMatch($type,'timing_sense'); $when = &ALF_LibertyBoolean2ALF($value) if &StringMatch($type,'when'); $related_pin = &Unquote($value) if &StringMatch($type,'related_pin'); $related_output_pin = &Unquote($value) if &StringMatch($type,'related_output_pin'); $ALF_Hidden{$object} = 'ALF' if &StringMatch($type,'timing_type','timing_sense','when','related_pin','related_output_pin'); } print("# ALF Data Warning:\tmissing Liberty attribute \47timing_type\47:\t",&ALF_ObjectInfoText($timing,'ALF_LibertyType','ALF_LibertyName'),"\n") unless defined($timing_type); print("# ALF Data Warning:\tmissing Liberty attribute \47timing_sense\47:\t",&ALF_ObjectInfoText($timing,'ALF_LibertyType','ALF_LibertyName'),"\n") unless defined($timing_sense); print("# ALF Data Warning:\tmissing Liberty attribute \47related_pin\47:\t",&ALF_ObjectInfoText($timing,'ALF_LibertyType','ALF_LibertyName'),"\n") unless defined($related_pin); ( 'pin', &Unquote($ALF_LibertyName{$ALF_Parent{$timing}}), 'related_pin', $related_pin, 'timing_type', $timing_type, 'timing_sense', $timing_sense, 'when', $when, 'related_output_pin', $related_output_pin, ); } sub ALF_Liberty_InternalPowerInfo { local($internal_power) = @_; local ($related_pin,$when,$related_output_pin); foreach $object (&Array($ALF_Children{$internal_power})) { local $type = $ALF_LibertyType{$object}; local $value = $ALF_LibertyValue{$object}; $when = &ALF_LibertyBoolean2ALF($value) if &StringMatch($type,'when'); $related_pin = &Unquote($value) if &StringMatch($type,'related_pin'); $related_output_pin = &Unquote($value) if &StringMatch($type,'related_output_pin'); $ALF_Hidden{$object} = 'ALF' if &StringMatch($type,'when','related_pin','related_output_pin'); } local $pin = $ALF_Parent{$internal_power}; local @related_pin = split(/\s+/,$related_pin); if ($#related_pin > 0) { local $groupname = join('_',@related_pin); local $group = &ALF_FindMatchingObject($ALF_Parent{$pin},'GROUP',$groupname) || &ALF_CreateObject($ALF_Parent{$pin},'GROUP',$groupname,&CreateArray(@related_pin)); $related_pin = $groupname; } ( 'pin', &Unquote($ALF_LibertyName{$pin}), 'related_pin', $related_pin, 'when', $when, 'related_output_pin', $related_output_pin, ); } ### lookup table data ### sub ALF_LibertyArithmeticModel2ALF { local($object,%attribute) = @_; $ALF_Name{$object} = $ALF_LibertyType{$object}; local $templatename = $ALF_LibertyName{$object}; local $values = &ALF_FindMatchingLibertyObject($object,'values'); if ($templatename eq 'scalar') { $ALF_Value{$object} = &ArrayVal($ALF_LibertyValue{$values},0); $ALF_Children{$object} = undef unless &ArraySize($ALF_Children{$object}) > 1; $ALF_Hidden{$values} = 'ALF'; } else { local $template = &ALF_FindMatchingLibertyObject(&ALF_FindAncestor($object,'LIBRARY'),undef,$templatename); if ($template) { $ALF_Hidden{$template} = 'ALF'; local $header = &ALF_CreateObject($object,'HEADER'); $ALF_Children{$header} = &CreateArray(); local $maxindex = 0; for $i (reverse 1..3) { local $libvar = &ALF_FindMatchingLibertyObject($template,"variable_$i"); local $libindex = &ALF_FindMatchingLibertyObject($object,"index_$i"); unless ($libindex) { $libindex = &ALF_FindMatchingLibertyObject($template,"index_$i"); } $ALF_Hidden{$libindex} = 'ALF'; if ($libvar && $libindex) { $maxindex = $i unless $maxindex; &ALF_LibertyHeader2ALF($header,$libvar,$libindex,%attribute); } elsif ($libvar && !$libindex) { print("# ALF Data Error:\tmissing index in Liberty template $template:\t",&ALF_ObjectInfoText($header,'ALF_LibertyType','ALF_LibertyName'),"\n"); } elsif (!$libvar && $libindex) { print("# ALF Data Error:\tmissing variable in Liberty template $template:\t",&ALF_ObjectInfoText($header,'ALF_LibertyType','ALF_LibertyName'),"\n"); } elsif ($maxindex > $i) { print("# ALF Data Error:\tmissing variable and index in Liberty template $template:\t",&ALF_ObjectInfoText($header,'ALF_LibertyType','ALF_LibertyName'),"\n"); } } local $table = &ALF_CreateObject($object,'TABLE',undef,$ALF_LibertyValue{$values}); &ALF_DefineTableFormat($table); $ALF_Hidden{$values} = 'ALF'; } else { print("# ALF Data Error:\tincomplete translation of Liberty arithmetic model:\t",&ALF_ObjectInfoText($object,'ALF_LibertyType','ALF_LibertyName'),"\n"); } } } sub ALF_LibertyHeader2ALF { local($header,$libvar,$libindex,%attribute) = @_; local $object = $ALF_Parent{$header}; local $libtype = $ALF_LibertyValue{$libvar}; local $alftype = ($libtype eq 'input_net_transition' )? 'SLEWRATE' : ($libtype eq 'input_transition_time' )? 'SLEWRATE' : ($libtype eq 'constrained_pin_transition' )? 'SLEWRATE' : ($libtype eq 'related_pin_transition' )? 'SLEWRATE' : ($libtype eq 'output_pin_transition' )? 'SLEWRATE' : ($libtype eq 'connect_delay' )? 'DELAY' : ($libtype eq 'total_output_net_capacitance')? 'CAPACITANCE' : ($libtype eq 'related_out_total_output_net_capacitance')? 'CAPACITANCE' : undef; if ($alftype) { local $alfvar = &ALF_CreateObject($header,$alftype,$libtype); $ALF_Children{$alfvar} = &CreateArray(); local $pin = $attribute{'pin'}; local $related_pin = $attribute{'related_pin'}; local $related_output_pin = $attribute{'related_output_pin'}; local $pin_annotation = ($libtype eq 'total_output_net_capacitance')? $pin : ($libtype eq 'constrained_pin_transition' )? $pin : ($libtype eq 'input_net_transition' )? ($related_pin or $pin) : ($libtype eq 'input_transition_time' )? ($related_pin or $pin) : ($libtype eq 'related_pin_transition' )? $related_pin : ($libtype eq 'output_pin_transition' )? $related_pin : ($libtype eq 'related_out_total_output_net_capacitance')? $related_output_pin : undef; local ($from_annotation,$to_annotation) = ($libtype eq 'connect_delay')? ($related_pin,$pin) : undef; if ($pin_annotation) { &ALF_CreateObject($alfvar,'PIN',undef,$pin_annotation); } elsif ($from_annotation && $to_annotation) { local $from = &ALF_CreateObject($alfvar,'FROM'); &ALF_CreateObject($from,'PIN',undef,$from_annotation); local $to = &ALF_CreateObject($alfvar,'TO'); &ALF_CreateObject($to,'PIN',undef,$to_annotation); } else { print("# ALF Data Error:\tcannot create pin annotation for Liberty arithmetic model argument:\t",&ALF_ObjectInfoText($libvar,'ALF_LibertyType','ALF_LibertyValue'),"\n"); } &ALF_CreateObject($alfvar,'TABLE',undef,$ALF_LibertyValue{$libindex}); } } 1;