### Liberty predefined data ### @ALF_Liberty_K_Factors = ( 'k_process_intrinsic_rise','k_temp_intrinsic_rise','k_volt_intrinsic_rise', 'k_process_intrinsic_fall','k_temp_intrinsic_fall','k_volt_intrinsic_fall', 'k_process_slope_rise','k_temp_slope_rise','k_volt_slope_rise', 'k_process_slope_fall','k_temp_slope_fall','k_volt_slope_fall', 'k_process_drive_current','k_temp_drive_current','k_volt_drive_current', 'k_process_drive_rise','k_temp_drive_rise','k_volt_drive_rise', 'k_process_drive_fall','k_temp_drive_fall','k_volt_drive_fall', 'k_process_pin_cap','k_temp_pin_cap','k_volt_pin_cap', 'k_process_wire_cap','k_temp_wire_cap','k_volt_wire_cap', 'k_process_pin_res','k_temp_pin_res','k_volt_pin_res', 'k_process_rise_pin_res','k_temp_rise_pin_res','k_volt_rise_pin_res', 'k_process_fall_pin_res','k_temp_fall_pin_res','k_volt_fall_pin_res', 'k_process_wire_res','k_temp_wire_res','k_volt_wire_res', 'k_process_rise_delay_intercept','k_temp_rise_delay_intercept','k_volt_rise_delay_intercept', 'k_process_fall_delay_intercept','k_temp_fall_delay_intercept','k_volt_fall_delay_intercept', 'k_process_cell_rise','k_temp_cell_rise','k_volt_cell_rise', 'k_process_cell_fall','k_temp_cell_fall','k_volt_cell_fall', 'k_process_rise_transition','k_temp_rise_transition','k_volt_rise_transition', 'k_process_fall_transition','k_temp_fall_transition','k_volt_fall_transition', 'k_process_setup_rise','k_temp_setup_rise','k_volt_setup_rise', 'k_process_setup_fall','k_temp_setup_fall','k_volt_setup_fall', 'k_process_hold_rise','k_temp_hold_rise','k_volt_hold_rise', 'k_process_hold_fall','k_temp_hold_fall','k_volt_hold_fall', 'k_process_recovery_rise','k_temp_recovery_rise','k_volt_recovery_rise', 'k_process_recovery_fall','k_temp_recovery_fall','k_volt_recovery_fall', 'k_process_removal_rise','k_temp_removal_rise','k_volt_removal_rise', 'k_process_removal_fall','k_temp_removal_fall','k_volt_removal_fall', 'k_process_nochange_rise','k_temp_nochange_rise','k_volt_nochange_rise', 'k_process_nochange_fall','k_temp_nochange_fall','k_volt_nochange_fall', 'k_process_skew_rise','k_temp_skew_rise','k_volt_skew_rise', 'k_process_skew_fall','k_temp_skew_fall','k_volt_skew_fall', 'k_process_min_pulse_width_low','k_temp_min_pulse_width_low','k_volt_min_pulse_width_low', 'k_process_min_pulse_width_high','k_temp_min_pulse_width_high','k_volt_min_pulse_width_high', 'k_process_min_period','k_temp_min_period','k_volt_min_period', 'k_process_cell_leakage_power','k_temp_cell_leakage_power','k_volt_cell_leakage_power', 'k_process_internal_power','k_temp_internal_power','k_volt_internal_power', ); @ALF_Liberty_Default_Values = ( 'default_output_pin_cap','default_inout_pin_cap','default_input_pin_cap', 'default_wire_load_capacitance','default_wire_load_resistance','default_wire_load_area', 'default_max_transition', 'default_fanout_load', 'default_cell_leakage_power', ); @ALF_LibertyGlobal = ( 'Liberty_PROCESS', 'Liberty_OPERATING_CLASS', 'Liberty_TREE_TYPE', 'Liberty_SCALING_CLASS', ); @ALF_LibertyScaling = ( 'Liberty_SCALING_MODEL', 'Liberty_SCALING_METHOD', ); ### Liberty object processing ### sub ALF_LibertyObjectMatch { local($object,$type,$name,$value) = @_; print("# ALF Data Info: trying to match Liberty object $object ",&ALF_ObjectInfoText($object,'ALF_LibertyType','ALF_LibertyName','ALF_LibertyValue')," against type $type, name $name, and value $value\n") if ($ALF_Debug > 1); local $typematch = $type? ( &StringMatch($type,$ALF_LibertyType{$object}) && ($ALF_Debug < 2 || print("# ALF Data Info:\ttype of object $object matches \47$type\47\n")) ) : 1; local $namematch = defined($name)? ( ($name eq '0')? !$ALF_LibertyName{$object} # object must not have a name && ($ALF_Debug < 2 || print("# ALF Data Info:\tname \47",$ALF_LibertyName{$object},"\47 of Liberty object $object is false\n")) : ($name eq '1')? $ALF_LibertyName{$object} # object must have a name && ($ALF_Debug < 2 || print("# ALF Data Info:\tname \47",$ALF_LibertyName{$object},"\47 of Liberty object $object is true\n")) : &StringMatch(&Unquote($name),&Unquote($ALF_LibertyName{$object})) # object must have a matching name && ($ALF_Debug < 2 || print("# ALF Data Info:\tname \47",$ALF_LibertyName{$object},"\47 of Liberty object $object matches \47$name\47\n")) ) : 1; local $valuematch = defined($value)? ( &StringMatch(&Unquote($value),&Unquote($ALF_LibertyValue{$object})) && ($ALF_Debug < 2 || print("# ALF Data Info:\tvalue \47",$ALF_LibertyValue{$object},"\47 of Liberty object $object matches string \47$value\47\n")) || &ALF_LexicalMatch('number',$value) && &ALF_LexicalMatch('number',$ALF_LibertyValue{$object}) && ($value == $ALF_LibertyValue{$object}) # try numerical match if string match does not work && ($ALF_Debug < 2 || print("# ALF Data Info:\tvalue \47",$ALF_LibertyValue{$object},"\47 of Liberty object $object matches number \47$value\47\n")) ) : 1; $typematch && $namematch && $valuematch; } sub ALF_LibertyObjectQualifierMatch { local($object,%qualifier) = @_; ### returns true if annotations of $object match key-value pairs in %qualifier local @keys = keys %qualifier; print("# ALF Data Info: trying to match Liberty object $object ",&ALF_ObjectInfoText($object,'ALF_LibertyType','ALF_LibertyName','ALF_LibertyValue')," against qualifiers (",join(' ',%qualifier),")\n") if (($ALF_Debug > 1) && ($#keys >= 0)); local $match = 1; foreach $key (@keys) { $match = $match && &ALF_FindMatchingLibertyObject($object,$key,0,$qualifier{$key}); last unless $match; } $match; } sub ALF_FindMatchingLibertyObjects { local($parent,$type,$name,$value,%qualifier) = @_; local @found; foreach $child (&Array($ALF_Children{$parent})) { if (&ALF_LibertyObjectMatch($child,$type,$name,$value) && &ALF_LibertyObjectQualifierMatch($child,%qualifier)) { $found[$#found+1] = $child; print("# ALF Data Info:\tfound Liberty object $child:\t",&ALF_ObjectInfoText($child),"\n") if ($ALF_Debug > 1); } } @found; } sub ALF_FindMatchingLibertyObject { local($parent,$type,$name,$value,%qualifier) = @_; local $found; foreach $child (&Array($ALF_Children{$parent})) { if (&ALF_LibertyObjectMatch($child,$type,$name,$value) && &ALF_LibertyObjectQualifierMatch($child,%qualifier)) { $found = $child; print("# ALF Data Info:\tfound Liberty object $child:\t",&ALF_ObjectInfoText($child),"\n") if ($ALF_Debug > 1); } last if $found; } $found; } ### Liberty data creation ### sub ALF_CreateLibertyTableTemplate { local($library,$arithmetic_model,$template_type,$template_rule) = @_; local @templatename; local %templatename = ( 'power_lut_template', 'power', 'lu_table_template', 'timing', ); local $template = &ALF_CreateObject($library,undef,undef,undef, 'ALF_LibertySyntax','group', 'ALF_LibertyType',$template_type, # 'ALF_LibertyName',join('_',$arithmetic_model,$ALF_Type{$arithmetic_model}), ); $ALF_Children{$template} = &CreateArray(); local $index = 0; local $array = $ALF_Value{&ALF_FindMatchingObject($arithmetic_model,'TABLE')}; local @keys = &Array($ALF_Keys{$array}); local %keytable = &Assoc($ALF_KeyTable{$array}); foreach $key (reverse @keys) { local $libtype = &Eval($template_rule,$key); if (defined($libtype)) { $index += 1; &ALF_CreateLibertyAttribute($template,"variable_$index",$libtype); &ALF_CreateLibertyAttribute($template,"index_$index",$keytable{$key}); #print("ALF_CreateLibertyTableTemplate\talftype=",$ALF_Type{$key},"\tlibtype=$libtype\ttablesize=",&ArraySize($keytable{$key}),"\n"); $templatename[$#templatename+1] = join('_',&ArraySize($keytable{$key}),$ALF_Type{$key}); } else { print("# ALF Data Warning:\ttable dimension $key ",&ALF_ObjectInfoText($key)," cannot be converted to Liberty\n"); } } $ALF_LibertyName{$template} = $templatename{$template_type}.'_'.($#templatename+1).'D_'.join('_X_',@templatename); $template; } sub ALF_CreateLibertyAttribute { local($parent,$libtype,$libval) = @_; local $attribute = &ALF_CreateObject($parent,undef,undef,undef, 'ALF_LibertySyntax',&ArraySize($libval)? 'complex_attribute' : 'simple_attribute', 'ALF_LibertyType',$libtype, 'ALF_LibertyValue',$libval, ); } sub ALF_CreateLibertyTiming { local ($parent_pin,$related_pin,$when,*primary_timing_objects,@other_timing_objects) = @_; local $timing = &ALF_CreateObject($parent_pin,undef,undef,undef, 'ALF_LibertySyntax','group', 'ALF_LibertyType','timing', ); $ALF_Children{$timing} = &CreateArray(); local ($timing_type,$timing_sense) = &ALF_LibertyTimingAnnotations(@primary_timing_objects); local $related_pin_name = &StringMatch($ALF_Type{$related_pin},'GROUP')? join(' ',&Array($ALF_Value{$related_pin})) : $ALF_Name{$related_pin}; &ALF_CreateLibertyAttribute($timing,'timing_type',$timing_type); &ALF_CreateLibertyAttribute($timing,'timing_sense',$timing_sense); &ALF_CreateLibertyAttribute($timing,'related_pin',"\42".$related_pin_name."\42"); &ALF_CreateLibertyAttribute($timing,'when',$when) if defined($when); &AppendArray($ALF_Children{$timing},@primary_timing_objects,@other_timing_objects); &ALF_LibertyAddRelatedOutputPin($timing); $timing; } sub ALF_CreateLibertyInternalPower { local ($parent_pin,$related_pin,$when,*power_objects) = @_; local $internal_power = &ALF_CreateObject($parent_pin,undef,undef,undef, 'ALF_LibertySyntax','group', 'ALF_LibertyType','internal_power', ); $ALF_Children{$internal_power} = &CreateArray(); if ($related_pin) { local $related_pin_name = &StringMatch($ALF_Type{$related_pin},'GROUP')? join(' ',&Array($ALF_Value{$related_pin})) : $ALF_Name{$related_pin}; &ALF_CreateLibertyAttribute($internal_power,'related_pin',"\42".$related_pin_name."\42"); } &ALF_CreateLibertyAttribute($internal_power,'when',$when) if defined($when); &AppendArray($ALF_Children{$internal_power},@power_objects); &ALF_LibertyAddRelatedOutputPin($internal_power); $internal_power; } sub ALF_LibertyAddRelatedOutputPin { local ($timing) = @_; local $pin = $ALF_Name{$ALF_Parent{$timing}}; local $related_output_pin; foreach $object (&Array($ALF_Children{$timing})) { local $header = &ALF_FindMatchingObject($object,'HEADER'); local @cap = defined($header)? &ALF_FindMatchingObjects($header,'CAPACITANCE') : (); foreach $cap (@cap) { local $cap_pin = &ALF_FindMatchingObject($cap,'PIN'); local $cap_pin_name = defined($cap_pin)? $ALF_Value{$cap_pin} : undef; $related_output_pin = $cap_pin_name if (defined($cap_pin_name) && !&StringMatch($cap_pin_name,$pin)); last if $related_output_pin; } last if $related_output_pin; } &ALF_CreateLibertyAttribute($timing,'related_output_pin',"\42$related_output_pin\42") if defined($related_output_pin); $related_output_pin; } 1;