### library preparation ### sub ALF_PrepareLibrary { local ($library) = @_; print("# System Message:\tstarted library preparation\t",&DateTime,"\n"); &ALF_FlattenObject($library); &ALF_CreateCellReferences($library); print("# System Message:\tfinished library preparation\t",&DateTime,"\n"); } sub ALF_CreateCellReferences { local($library) = @_; foreach $cell (&ALF_FindMatchingObjects($library,'CELL')) { local $ref = $ALF_Name{$cell}; unless ($ALF_Object{$ref}) { $ALF_Object{$ref} = $cell; } } } ### create design elements ### sub ALF_CreateCellInstances { local($design,%cell) = @_; local $cell_list = &CreateArray(); foreach $key (keys %cell) { local $ref = $cell{$key}; local $object = $ALF_Object{$ref}; if ($object) { local $cell = &ALF_CopyObject($object,$design,$ref,$key); $ALF_Object{$key} = $cell; &AppendArray($cell_list,$cell); } else { print("# ALF Data Error: reference \47$ref\47 for key \47$key\47 not found in design \47$design\47\n"); } } $cell_list; } sub ALF_CreateNodes { local($design,@node_id) = @_; local $node_list = &CreateArray(); foreach $node_id (@node_id) { local $node = &ALF_CreateNode($design,$node_id); $ALF_Object{$node_id} = $node; &AppendArray($node_list,$node); } $node_list; } sub ALF_CreateNode { local($parent,$name) = @_; local $node = &ALF_CreateObject($parent,'NODE',$name); foreach $type ('ARRIVAL','DELAY','SLEWRATE','CAPACITANCE') { local $model = &ALF_CreateObject($node,$type); local $default = &ALF_CreateObject($model,'DEFAULT',undef,0); foreach $subtype ('RISE','FALL') { local $submodel = &ALF_CreateObject($model,$subtype); $ALF_Record{$submodel} = &CreateArray(); } } $node; } ### create design constraints ### sub ALF_CreateConstraint { local($node,$type,$subtype,$result,%condition) = @_; $node = &ALF_Object($node); local $model = &ALF_FindMatchingObject($node,$type); local $submodel = &ALF_FindMatchingObject($model,$subtype); local $data = &ALF_AppendRecord($ALF_Record{$submodel}); &ALF_UpdateRecord($data,$result,%condition); } ### create connectivity and calculation graph for nodes ### sub ALF_CreateSum { local($model,@nodes) = @_; local $type = $ALF_Type{$model}; foreach $subtype ('RISE','FALL') { local $sum = &ALF_FindMatchingObject($model,$subtype); local @arg; foreach $node (@nodes) { local $arg = &ALF_FindMatchingObject(&ALF_FindMatchingObject($node,$type),$subtype); $arg[$#arg+1] = $arg if defined($arg); } if ($#arg > 0) { local $header = &ALF_CreateObject($sum,'HEADER'); local @sum; foreach $arg (@arg) { local $name = &AutoName; local $addend = &ALF_CreateObject($header,$type,$name); $ALF_Link{$addend} = $arg; $sum[$#sum+1] = $name; } &ALF_CreateObject($sum,'EQUATION',undef,&CreateArray(split(/\s/,join(' + ',@sum)))); } elsif ($#arg == 0) { $ALF_Link{$sum} = $arg[0]; } else { $ALF_Value{$sum} = 0; } } } sub ALF_LinkNodes { local($driver,@receivers) = @_; foreach $type ('ARRIVAL','DELAY','SLEWRATE') { foreach $receiver (@receivers) { local $model = &ALF_FindMatchingObject($receiver,$type); &ALF_CreateSum($model,$driver); } } &ALF_CreateSum(&ALF_FindMatchingObject($driver,'CAPACITANCE'),@receivers); } sub ALF_LinkNodeModel { local($node,$type) = @_; $node = &ALF_Object($node); local $model = &ALF_FindMatchingObject($node,$type); if ($model) { foreach $subtype ('RISE','FALL') { local $submodel = &ALF_FindMatchingObject($model,$subtype); local $record = $ALF_Record{$submodel}; $ALF_EvaluationMethod{$record} = 'sum'; } } } ### Create connectivity and calculation graph for cells ### sub ALF_LinkCell { local($cell,%connect) = @_; $cell = &ALF_Object($cell); print("# ALF Data Info: creating links in cell:\t",&ALF_ObjectInfoText($cell),"\n") if $ALF_Debug; foreach $key (keys %connect) { local $pin = &ALF_FindMatchingObject($cell,'PIN',$key); if (defined($pin)) { $ALF_Link{$pin} = &ALF_Object($connect{$key}); local $pinmodel = &ALF_FindMatchingObject($pin,'CAPACITANCE'); &ALF_LinkPinModel($pinmodel) if $pinmodel; } else { print("# ALF Data Error: no pin named $key found in cell:\t",&ALF_ObjectInfoText($cell),"\n"); } } foreach $vector (&ALF_FindMatchingObjects($cell,'VECTOR')) { print("# ALF Data Info: creating links for models in vector:\t",&ALF_ObjectInfoText($vector),"\n") if $ALF_Debug; local $expression = $ALF_Expression{$vector}; local $models = &CreateArray(); &ALF_SearchForObjects($models,$vector,'ALF_IsFullArithmeticModel'); foreach $model (&Array($models)) { #$ALF_Debug = 1 if &StringMatch($ALF_Type{$model},'DELAY'); print("# ALF Data Info: searching link for model:\t",&ALF_ObjectInfoText($model),"\n") if $ALF_Debug; &ALF_LinkVectorModel($model,$expression); #$ALF_Debug = 0; local $header = &ALF_FindMatchingObject($model,'HEADER'); foreach $arg (&Array($ALF_Children{$header})) { &ALF_LinkVectorModel($arg,$expression); print("# ALF Data Info: searching link for model argument:\t",&ALF_ObjectInfoText($arg),"\n") if $ALF_Debug; } } } } sub ALF_LinkVectorModel { local($model,$expression) = @_; local $is_arg = &StringMatch($ALF_Type{$ALF_Parent{$model}},'HEADER'); local $designation = $is_arg? 'model argument' : 'model'; local ($link,$ref); if (&StringMatch($ALF_Type{$model},'DELAY')) { local ($fromedge,$frompin_name,$toedge,$topin_name) = &ALF_TimingArc($model); local $frompin = &ALF_FindMatchingObject(&ALF_FindMatchingObject($model,'FROM'),'PIN',undef,$frompin_name); local ($fromarrival) = &ALF_LinkRiseFall('ARRIVAL',$fromedge,$frompin); local $topin = &ALF_FindMatchingObject(&ALF_FindMatchingObject($model,'TO'),'PIN',undef,$topin_name); local ($toarrival) = &ALF_LinkRiseFall('ARRIVAL',$toedge,$topin); ($link,$ref) = &ALF_LinkRiseFall('DELAY',$toedge,$topin); &ALF_LinkArrival($link,$fromarrival,$toarrival); } else { local ($edge,$pin_name) = &ALF_TimingEdge($model,$expression); local $pin = &ALF_FindMatchingObject($model,'PIN',undef,$pin_name); ($link,$ref) = &ALF_LinkRiseFall($ALF_Type{$model},$edge,$pin); } if ($ref) { print("# ALF Data Info: pointer to link found for $designation:\t",&ALF_ObjectInfoText($model),"\n") if $ALF_Debug; } if ($link) { if (&StringMatch($ALF_Type{$link},'DEFAULT')) { print("# ALF Data Warning: $designation $model has default link:\t",&ALF_ObjectInfoText($link),"\n"); } else { print("# ALF Data Info: $designation $model has link:\t",&ALF_ObjectInfoText($link),"\n") if $ALF_Debug; } if ($is_arg) { $ALF_Link{$model} = $link; } else { &ALF_AppendRecord($ALF_Record{$link},$model); } } elsif ($ref) { print("# ALF Data Error: $designation $model has no link\n"); } } sub ALF_LinkArrival { local($todelay,$fromarrival,$toarrival) = @_; local $model = &ALF_CreateObject($toarrival,'ARRIVAL'); local $header = &ALF_CreateObject($model,'HEADER'); local $name1 = &AutoName; local $addend1 = &ALF_CreateObject($header,'DELAY',$name1); $ALF_Link{$addend1} = $todelay; local $name2 = &AutoName; local $addend2 = &ALF_CreateObject($header,'ARRIVAL',$name2); $ALF_Link{$addend2} = $fromarrival; &ALF_CreateObject($model,'EQUATION',undef,&CreateArray(split(/\s/,join(' + ',$name1,$name2)))); &ALF_AppendRecord($ALF_Record{$toarrival},$model); } sub ALF_LinkRiseFall { local ($modeltype,$edge,$pin) = @_; local ($node,$model,$link); $node = !defined($pin) ? undef : !defined($ALF_Link{$pin})? undef : $ALF_Link{$ALF_Link{$pin}}; $model = !defined($node) ? undef : &ALF_FindMatchingObject($node,$modeltype); $link = !defined($model)? undef : &ALF_IsRisingEdge ($edge)? &ALF_FindMatchingObject($model,'RISE') : &ALF_IsFallingEdge($edge)? &ALF_FindMatchingObject($model,'FALL') : &ALF_FindMatchingObject($model,'DEFAULT'); ($link,$model); } sub ALF_LinkPinModel { local($pin_model) = @_; local $node = $ALF_Link{$ALF_Parent{$pin_model}}; local $node_model = &ALF_FindMatchingObject($node,$ALF_Type{$pin_model}); foreach $subtype ('RISE','FALL') { local $found_submodel = &ALF_FindMatchingObject($pin_model,$subtype); local $pin_submodel = $found_submodel? $found_submodel : $pin_model; local $node_submodel = &ALF_FindMatchingObject($node_model,$subtype); &ALF_AppendRecord($ALF_Record{$node_submodel},$pin_submodel); print("# ALF Data Info: linking pin model\t",&ALF_ObjectInfoText($pin_submodel),"\n") if $ALF_Debug; print("# ALF Data Info: linked pin model $pin_submodel to node\t",&ALF_ObjectInfoText($node_submodel),"\n") if $ALF_Debug; } } ### analysis engine ### sub ALF_CircuitAnalysis { local ($library,$constraint,$report) = @_; print("# System Message:\tstarted circuit analysis\t",&DateTime,"\n"); local @cell_list = keys %ALF_InstanceReference; local @node_list = &ALF_NodeList(@cell_list); #print("cell_list=(@cell_list)\tnode_list=(@node_list)\n"); die; local $design = &AutoName; &ALF_CreateCellInstances($design,%ALF_InstanceReference); &ALF_CreateNodes($design,@node_list); print("# System Message:\tcreated design elements \t",&DateTime,"\n"); &ALF_LinkObjects($library,$design,'CELL','WIRE'); print("# System Message:\tcreated internal connectivity\t",&DateTime,"\n"); foreach $cell (@cell_list) { $cell = &ALF_Object($cell); local $connect = $ALF_InstanceConnect{$ALF_Name{$cell}}; &ALF_LinkCell($cell,&Assoc($connect)); } foreach $node (@node_list) { $node = &ALF_Object($node); &ALF_LinkNodeModel($node,'CAPACITANCE'); } print("# System Message:\tcreated external connectivity\t",&DateTime,"\n"); local ($method_list,$modeltype_list) = &Eval($report); local $models = &CreateArray(); foreach $modeltype (&Array($modeltype_list)) { foreach $cell (@cell_list) { $cell = &ALF_Object($cell); &ALF_SearchForObjects($models,$cell,'ALF_ObjectMatch',$modeltype); } foreach $node (@node_list) { local $nodemodel = &ALF_FindMatchingObject(&ALF_Object($node),$modeltype); foreach $subtype ('RISE','FALL') { &ALF_SearchForObjects($models,$nodemodel,'ALF_ObjectMatch',$subtype); } } } print("# System Message:\tidentified evaluation targets\t",&DateTime,"\n"); foreach $method (&Array($method_list)) { foreach $key (keys %ALF_Record) { #&ALF_ReportRecord($key); # $ALF_Record{$key} = &CreateArray(); } foreach $key (keys %ALF_Result) { $ALF_Result{$key} = undef; } foreach $key (keys %ALF_ResultList) { $ALF_ResultList{$key} = &CreateArray(); } &Eval($constraint); print("# System Message:\tcreated evaluation constraints\t",&DateTime,"\n"); foreach $model (&Array($models)) { local $id = &ALF_HierarchyInfoText($model,5); #$ALF_Debug = 1; local $result = &ALF_Calculate($model,$method); #$ALF_Debug = 0; print("#\tevaluation result ($method) for model $model: $id = $result\n"); } # foreach $key (keys %ALF_Record) { &ALF_ReportRecord($key); } } print("# System Message:\tfinished circuit analysis\t",&DateTime,"\n"); $design; } 1;