;;; ------------------------------------------------------------------------------------------------------- ;;; Change history: ;;; ;;; Initial version, containing: ;;; - The GUI ;;; - The actual code to find the instances ;;; - Code to create a group with only one pyCell, store pyCell properties to the group ;;; and flatten the content of the group ;;; - Output log code ;;; ------------------------------------------------------------------------------------------------------- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; _WARNING_WARNING_WARNING_WARNING_WARNING_ ;;; ;;; IF YOU OPEN THIS FILE IN NEDIT, THE TABs WILL NOT BE THE SAME AS IN THE SKILL DEVELOPMENT ENVIRONMENT EDITOR (INSIDE VIRTUOSO) ;;; THIS CODE HAS BEEN WRITTEN IN THE BUILD-IN EDITOR OF VIRTUOSO. TO GET THERE: CIW -> TOOLS -> SKILL DEVELOPMENT ENVIRONMENT ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; This is the procedure with which all starts... ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; procedure( flattenPycells() let( ( ( theLibList nil ) ) theLibList = FPCDefineLibList() FPCBuildGui( theLibList ) ;;; Load GUI and continue ) ;;; end let ) ;;; end procedure ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;; ;;; Building the GUI form... procedure( FPCBuildGui( theLibList "l" ) let( () FPCSourceLibrary = hiCreateCyclicField( ?name 'FPCSourceLibrary ?choices theLibList ?prompt "Source library:" ?callback "FPCSourceLibSelectedCB()" ) FPCSourceLibraryLabel1 = hiCreateLabel( ?name 'FPCSourceLibraryLabel1 ?labelText "This is the library with the source of the pycells." ?justification 'left ?enabled t ) FPCOutputFileName = hiCreateStringField( ?name 'FPCOutputFileName ?prompt "Log output file name:" ?value "flattened_pycells.txt" ?defValue "flattened_pycells.txt" ?callback "nil" ?editable t ?enabled t ) FPCOutputFileNameLabel1 = hiCreateLabel( ?name 'FPCOutputFileNameLabel1 ?labelText "Log-file will be opened after run completes." ?justification 'left ?enabled t ) FPCLibsToBrowse = hiCreateListBoxField( ?name 'FPCLibsToBrowse ?choices theLibList ?callback "FPCLibsToBrowseSelectedCB()" ?prompt "Libraries to browse:" ?multipleSelect t ?enabled nil ) FPCCellsToBrowse = hiCreateListBoxField( ?name 'FPCCellsToBrowse ?choices list( "Select libraries to browse..." ) ?callback "FPCCellsToBrowseSelectedCB()" ?prompt "Cells to browse:" ?multipleSelect t ?enabled nil ) FPCSelectAllCells = hiCreateButton( ?name 'FPCSelectAllCells ?buttonText "Select all" ?callback "FPCSelectAllCellsClickedCB()" ?enabled nil ) FPCViewsToBrowse = hiCreateListBoxField( ?name 'FPCViewsToBrowse ?choices list( "Select cells to browse..." ) ?changeCB "FPCViewsToBrowseSelectedCB()" ?prompt "Views to browse:" ?multipleSelect t ?enabled nil ) FPCSelectAllViews = hiCreateButton( ?name 'FPCSelectAllViews ?buttonText "Select all" ?callback "FPCSelectAllViewsClickedCB()" ?enabled nil ) FPCGroupNamePrefix = hiCreateStringField( ?name 'FPCGroupNamePrefix ?prompt "Groupname prefix:" ?value "flat_pycell_" ?defValue "flat_pycell_" ?callback "nil" ?editable nil ?enabled nil ) FPCDryRunOnly = hiCreateToggleField( ?name 'FPCDryRunOnly ?choices list( list( 'dryRun "No changes to database, log-file only." ) ) ?prompt "Dry-run only:" ?value '( t ) ?defValue '( t ) ?enabled nil ) FPCVerboseOutput = hiCreateToggleField( ?name 'FPCVerboseOutput ?choices list( list( 'verbose "Also feedback in CIW if enabled" ) ) ?prompt "Verbose output:" ?value '( nil ) ?defValue '( nil ) ?enabled nil ) ;;;;;;;;;;;;;;;;;;;;;; ;;; Building the form... hiCreateAppForm( ?name 'FPCGuiForm ?formTitle "Flatten pyCells..." ?callback "FPCFlattenPyCellsCB()" ?dontBlock t ?fields list( list( FPCSourceLibrary 10:10 200:30 150 ) list( FPCSourceLibraryLabel1 150:30 290:30 150 ) list( FPCOutputFileName 910:10 440:30 150 ) list( FPCOutputFileNameLabel1 1055:40 295:20 150 ) list( FPCLibsToBrowse 10:90 440:200 150 ) list( FPCCellsToBrowse 460:90 440:200 150 ) list( FPCSelectAllCells 460:110 130:30 150 ) list( FPCViewsToBrowse 910:90 440:200 150 ) list( FPCSelectAllViews 910:110 130:30 150 ) list( FPCGroupNamePrefix 10:290 440:30 150 ) list( FPCDryRunOnly 460:293 440:30 150 ) list( FPCVerboseOutput 910:293 440:30 150 ) ) ;;; end list ?fields ?buttonLayout list( 'OKCancelApply ) ;;; end list ?buttonLayout ?buttonDisabled list( 'OK 'Apply 'Help ) ?unmapAfterCB t ?initialSize 1400:600 ) ;;; end hiCreateAppForm ;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;; ;;; Displaying the form hiDisplayForm( FPCGuiForm 125:125 ) ;;;;;;;;;;;;;;;;;;;;;; ) ;;; end let ) ;;; end procedure FPBuildGui ;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;; ;;; After the source library (the library with the actual pycells) has been selected, this procedure is called. procedure( FPCSourceLibSelectedCB() let( () when( FPCGuiForm~>FPCSourceLibrary~>value FPCGuiForm~>FPCLibsToBrowse~>enabled = t ) ;;; end when ) ;;; end let ) ;;; end procedure FPCSourceLibrarySelected ;;;;;;;;;;;;;;;;;;;;;; ;;; After the libraries to browse have been selected, this procedure is called. procedure( FPCLibsToBrowseSelectedCB() let( () when( FPCGuiForm~>FPCLibsToBrowse~>value FPCGuiForm~>FPCCellsToBrowse~>choices = FCPDefineCellList( FPCGuiForm~>FPCLibsToBrowse~>value ) FPCGuiForm~>FPCCellsToBrowse~>enabled = t FPCGuiForm~>FPCSelectAllCells~>enabled = t ) ;;; end when ) ;;; end let ) ;;; end procedure FPCLibsToBrowseSelectedCB ;;;;;;;;;;;;;;;;;;;;;; ;;; After the clles to browse have been selected, this procedure is called. procedure( FPCSelectAllCellsClickedCB() let( () FPCGuiForm~>FPCCellsToBrowse~>value = FPCGuiForm~>FPCCellsToBrowse~>choices ) ;;; end let ) ;;; end procedure FPCCellsToBrowseSelectedCB ;;;;;;;;;;;;;;;;;;;;;; ;;; After the clles to browse have been selected, this procedure is called. procedure( FPCCellsToBrowseSelectedCB() let( ( ( viewTypeList nil ) ( viewNameList nil ) ) viewTypeList = list( "layout" "maskLayout" "maskLayoutGXL" "maskLayoutXL" ) when( FPCGuiForm~>FPCCellsToBrowse~>value viewNameList = FPCDefineViewList( FPCGuiForm~>FPCLibsToBrowse~>value FPCGuiForm~>FPCCellsToBrowse~>value viewTypeList ) if( !viewNameList then viewNameList = list( "No views in library/libraries..." ) FPCGuiForm~>FPCViewsToBrowse~>enabled = nil FPCGuiForm~>FPCSelectAllViews~>enabled = t else FPCGuiForm~>FPCViewsToBrowse~>enabled = t FPCGuiForm~>FPCSelectAllViews~>enabled = t ) ;;; end if FPCGuiForm~>FPCViewsToBrowse~>choices = viewNameList ) ;;; end when ) ;;; end let ) ;;; end procedure FPCCellsToBrowseSelectedCB ;;;;;;;;;;;;;;;;;;;;;; ;;; After the clles to browse have been selected, this procedure is called. procedure( FPCSelectAllViewsClickedCB() let( () FPCGuiForm~>FPCViewsToBrowse~>value = FPCGuiForm~>FPCViewsToBrowse~>choices ) ;;; end let ) ;;; end procedure FPCCellsToBrowseSelectedCB ;;;;;;;;;;;;;;;;;;;;;; ;;; After the views to browse have been selected, this procedure is called. procedure( FPCViewsToBrowseSelectedCB() let( () FPCGuiForm~>FPCGroupNamePrefix~>enabled = t FPCGuiForm~>FPCGroupNamePrefix~>editable = t FPCGuiForm~>FPCDryRunOnly~>enabled = t FPCGuiForm~>FPCVerboseOutput~>enabled = t hiSetFormButtonEnabled( FPCGuiForm 'OK t ) hiSetFormButtonEnabled( FPCGuiForm 'Apply t ) ) ;;; end let ) ;;; end procedure FPCCellsToBrowseSelectedCB ;;;;;;;;;;;;;;;;;;;;;; ;;; Creating a list of all libraries connected in the library manager. procedure( FPCDefineLibList() let( ( ( theLibList nil ) ( tempLibList nil ) ) tempLibList = ddGetLibList() foreach( libDbId tempLibList theLibList = append( theLibList list( libDbId~>name ) ) ) ;;; end foreach theLibList = ( sort theLibList nil ) ) ;;; end let ) ;;; end procedure FPCDefineLibList ;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;; ;;; List all cells in the selected reference library... procedure( FCPDefineCellList( libList "l" ) let( ( ( cellNameList nil ) ) foreach( lib libList foreach( cell ddGetObj( lib )~>cells if( member( cell~>name cellNameList ) then warn( "- Cells with same name in multiple libraries, first one used. Duplicate: %s - %s\n" lib cell~>name ) cellNameList = cellNameList else cellNameList = append( cellNameList list( cell~>name ) ) ) ;;; end if ) ;;; end foreach cell ) ;;; end foreach lib cellNameList = ( sort cellNameList nil ) ) ;;; end let ) ;;; end procedure FCPDefineCellList ;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;; ;;; Creating a list of all views of all selected cells in the selected libraries to browse. procedure( FPCDefineViewList( libList cellList viewTypeList "lll" ) let( ( ( viewList nil ) ( viewNameList nil ) ( viewType nil ) ( cellsToProcess 0 ) ( cellCount 1 ) ) ;;; Get the number of cells to process, needed to set the totalSteps value of the progressbox... cellsToProcess = length( cellList ) ;;; Create and display the progressbox, unless there are no views... unless( zerop( cellsToProcess ) hiDisplayProgressBox( ?name 'FPCProgressBoxViewnameList ?banner "Processing..." ?text "Processing cells in selected libraries, please wait..." ?totalSteps cellsToProcess ?autoClose t ) ) ;;; end unless hiSetProgressButtonText( FPCProgressBoxViewnameList "Close" ) foreach( lib libList foreach( cell setof( x ddGetObj( lib )~>cells~>name member( x cellList ) ) viewList = ddGetObj( lib cell )~>views~>name foreach( view viewList viewType = dbGetq( FPCOpenCellViewByType( lib cell view nil "r" ) cellViewType ) when( member( viewType viewTypeList ) if( member( view viewNameList ) then viewNameList = viewNameList else viewNameList = append( viewNameList list( view ) ) ) ;;; end if ) ;;; end when ) ;;; end foreach ;;; Update the value of the progressbox, only when there is a progressbox... when( FPCProgressBoxViewnameList hiSetProgress( FPCProgressBoxViewnameList cellCount ) cellCount++ ) ;;; end unless ) ;;; end foreach cell ) ;;; end foreach lib ;;; Make sure that the progressbox reaches 100%... when( FPCProgressBoxViewnameList hiSetProgress( FPCProgressBoxViewnameList cellsToProcess ) ) ;;; end unless viewNameList = ( sort viewNameList nil ) ) ;;; end let ) ;;; end procedure FPCDefineViewList ;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;; ;;; Creating a list of all views of all selected cells in the selected libraries to browse. procedure( FPCFlattenPyCellsCB() let( ( ( sourceLib nil ) ( libList nil ) ( cellList nil ) ( viewList nil ) ( dryRunOnly nil ) ( verbose nil ) ( prefix nil ) ( cellView nil ) ( instanceName nil ) ( cellViewShapeList nil ) ( newCellViewShapeList nil ) ( viewsToProcess 0 ) ( viewCount 1 ) ( detailedInfoList nil ) ( detailedInfo nil ) ( pyCellDefaultList nil ) ( parameterName nil ) ( parameterType nil ) ( parameterValue nil ) ( groupName nil ) ( groupID nil ) ( openViewMode "r" ) ( dryRunPrintString "DRYRUN: " ) ( myPort nil ) ( outputFileName "" ) ( cellViewCount 0 ) ( totalInstanceCount 0 ) ( instanceCount 0 ) ( valid nil ) ) pyCellDefaultList = list( list( "mosType" "string" "nmos" ) list( "sourceLayer" "string" "M1" ) list( "drainLayer" "string" "M1" ) list( "wf" "float" 0.12 ) list( "lf" "float" 0.04 ) list( "sourcext" "float" 0.04 ) list( "drainext" "float" 0.04 ) list( "bulkContact" 'boolean nil ) list( "ruleset" "string" "default" ) ) ;;; end list pyCellDefaults sourceLib = FPCGuiForm~>FPCSourceLibrary~>value libList = FPCGuiForm~>FPCLibsToBrowse~>value cellList = FPCGuiForm~>FPCCellsToBrowse~>value viewList = FPCGuiForm~>FPCViewsToBrowse~>value dryRunOnly = car( FPCGuiForm~>FPCDryRunOnly~>value ) verbose = car( FPCGuiForm~>FPCVerboseOutput~>value ) prefix = FPCGuiForm~>FPCGroupNamePrefix~>value outputFileName = FPCGuiForm~>FPCOutputFileName~>value ;;; Depending on the dryRunOnly option, change the open mode (read only or append?) if( dryRunOnly then openViewMode = "r" dryRunPrintString = "DRYRUN: " else openViewMode = "a" dryRunPrintString = "" ) ;;; end if dryRunOnly ;;; Calculate the number of views to process, needed to set the totalSteps value of the progressbox... foreach( lib libList foreach( cell setof( x ddGetObj( lib )~>cells~>name member( x cellList ) ) foreach( view setof( y ddGetObj( lib cell )~>views~>name member( y viewList ) ) viewsToProcess++ ) ;;; end foreach view ) ;;; end foreach cell ) ;;; end foreach lib ;;; Create and display the progressbox... unless( zerop( viewsToProcess ) hiDisplayProgressBox( ?name 'FPCProgressBoxBatchJob ?banner "Processing..." ?text "Processing cells in selected libraries, please wait..." ?totalSteps viewsToProcess ?autoClose t ) ) ;;; end unless hiSetProgressButtonText( FPCProgressBoxBatchJob "Close" ) ;;; Open the port to the output file... myPort = outfile( outputFileName "w" ) ;;; Create the header of the file fprintf( myPort "Output file of the flatten pycells script.\n" ) fprintf( myPort "--------------------- USER SETTINGS -------------------\n" ) fprintf( myPort "Settings made:\n" ) fprintf( myPort "Source library: %L\n" sourceLib ) fprintf( myPort "Search librar(y/ies): %L\n" libList ) fprintf( myPort "Search cell(s): %L\n" cellList ) fprintf( myPort "Search view(s): %L\n" viewList ) fprintf( myPort "Output file name: %L\n" outputFileName ) fprintf( myPort "Dry-run only: %L\n" dryRunOnly ) fprintf( myPort "Verbose output: %L\n" verbose ) fprintf( myPort "Group prefix: %L\n" prefix ) fprintf( myPort "------------------ PROCESSED CELLS --------------------\n" ) fprintf( myPort "Found cells ( Library | Cell | Name | Instance count ):\n" ) ;;; Loop through the lists of the librries, cells and views, and use this information to open the cellviews. ;;; Loop through the libraries... foreach( lib libList ;;; Loop through the cells in the library that match with a name in the celllist... foreach( cell setof( x ddGetObj( lib )~>cells~>name member( x cellList ) ) ;;; Loop through the views of the cell that match with a name in the viewlist... foreach( view setof( y ddGetObj( lib cell )~>views~>name member( y viewList ) ) ;;; At the start, nothing known about the content of a cell, parameter "valid" is set to "nil" to indicate nothing has been found. valid = nil ;;; Only proceed if this cellview can be opened... when( setq( cellView FPCOpenCellViewByType( lib cell view nil openViewMode ) ) sprintf( detailedInfo "%sCellview opened: %s - %s - %s" dryRunPrintString lib cell view ) when( verbose printf( "\n%s" detailedInfo ) ) detailedInfoList = append( detailedInfoList list( detailedInfo ) ) ;;; Reset the instance counter for this cellview... instanceCount = 0 ;;; Now select all instances from the source library... foreach( instance setof( z cellView~>instances equal( z~>libName sourceLib ) ) instanceName = instance~>name valid = t totalInstanceCount++ instanceCount++ sprintf( detailedInfo "%s Processing instance in cell: %s - %s - %s -> %s" dryRunPrintString lib cell view instanceName ) when( verbose printf( "\n%s" detailedInfo ) ) detailedInfoList = append( detailedInfoList list( detailedInfo ) ) ;;; Create the group for this single instance, only this flattened instance will be added to this group. ;;; Group-name is a concatination of the prefix as specified by the user and the name of the instance. ;;; Since the name of the instance is unique in each cell, no need to create a random number... groupName = strcat( prefix instanceName ) unless( dryRunOnly groupID = dbCreateFigGroup( cellView groupName t instance~>xy "R0" ) ) sprintf( detailedInfo "%s Group created: %s" dryRunPrintString groupName ) when( verbose printf( "\n%s" detailedInfo ) ) detailedInfoList = append( detailedInfoList list( detailedInfo ) ) ;;;Add the parameters to the group... foreach( pyCellDefault pyCellDefaultList parameterName = nthelem( 1 pyCellDefault ) parameterType = nthelem( 2 pyCellDefault ) parameterValue = nthelem( 3 pyCellDefault ) when( dbSearchPropByName( instance parameterName ) parameterValue = dbSearchPropByName( instance parameterName )~>value ) ;;; end when unless( dryRunOnly dbCreateProp( groupID parameterName parameterType parameterValue ) ) sprintf( detailedInfo "%s Parameter added: %s -> %L" dryRunPrintString parameterName parameterValue ) when( verbose printf( "\n%s" detailedInfo ) ) detailedInfoList = append( detailedInfoList list( detailedInfo ) ) ) ;;; end foreach pyCellDefault ;;; This is a work-around till solution found: ;;; Flattening an instance inside a group does not work (the resulting shapes will not be part of the group) ;;; and after the flattening the selection is gone. My work-around: ;;; First, I store the list of shapes of the cellview and flatten the instance which will result in more shapes. ;;; Then I filter-out of the new shape list the new shapes and add those to the group. cellViewShapeList = cellView~>shapes unless( dryRunOnly dbFlattenInst( instance 2 t nil nil ) ) sprintf( detailedInfo "%s Instance flattened: %s" dryRunPrintString instanceName ) when( verbose printf( "\n%s" detailedInfo ) ) detailedInfoList = append( detailedInfoList list( detailedInfo ) ) newCellViewShapeList = cellView~>shapes unless( dryRunOnly foreach( shape setof( newShape newCellViewShapeList !member( newShape cellViewShapeList ) ) dbAddFigToFigGroup( groupID shape ) ) ;;; end foreach shape ) ;;; end unless sprintf( detailedInfo "%s Shapes from flat instance added to group: %s" dryRunPrintString groupName ) when( verbose printf( "\n%s" detailedInfo ) ) detailedInfoList = append( detailedInfoList list( detailedInfo ) ) ) ;;; end foreach instance ;;; Save the changes made, if opened in append mode... if( equal( openViewMode "a" ) then dbSave( cellView ) ) ;;; end if openViewMode ;;; Closing the cellview is not needed but good practice...flatten dbClose( cellView ) when( zerop( instanceCount ) sprintf( detailedInfo "%s No instances from %s found: nothing done" dryRunPrintString sourceLib ) when( verbose printf( "\n%s" detailedInfo ) ) detailedInfoList = append( detailedInfoList list( detailedInfo ) ) ) ;;; end when sprintf( detailedInfo "%sCellview closed: %s - %s - %s" dryRunPrintString lib cell view ) when( verbose printf( "\n%s" detailedInfo ) ) detailedInfoList = append( detailedInfoList list( detailedInfo ) ) ) ;;; end when ;;; Update the value of the progressbox... when( FPCProgressBoxBatchJob hiSetProgress( FPCProgressBoxBatchJob viewCount ) viewCount++ ) ;;; end unless ;;; Of course, only when a cell contains (the right) instances from the source library, the results must be stored. ;;; The parameter "valid" is set when needed, and reset to "nil" for each new cellview. if( valid then cellViewCount++ fprintf( myPort "%s | %s | %s | %d\n" lib cell view instanceCount ) ) ;;; end if valid ) ;;; end foreach view ) ;;; end foreach cell ) ;;; end foreach lib ;;; Make sure that the progressbox reaches 100%... when( FPCProgressBoxBatchJob hiSetProgress( FPCProgressBoxBatchJob viewsToProcess ) ) ;;; end unless ;;; and closing the port... fprintf( myPort "---------------------- SUMMARY ------------------------\n" ) fprintf( myPort "cells found: %d\n" cellViewCount ) fprintf( myPort "pycells found: %d\n" totalInstanceCount ) fprintf( myPort "---------------- DETAILED INFORMATION -----------------\n" ) foreach( detailedInfo detailedInfoList fprintf( myPort "%s\n" detailedInfo ) ) ;;; end foreach fprintf( myPort "-------------------- END OF FILE ----------------------\n" ) close( myPort) myPort = nil ;;; Opening the output file view( outputFileName nil outputFileName t ) ) ;;; end let ) ;;; end procedure FPCDefineViewList ;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;; ;;; Function which is a wrapper around dbOpenCellViewByType ;;; which suppresses any warnings it produces ;;; Original code is from Cadence Support. procedure( FPCOpenCellViewByType( @rest args ) ;;; Define a global variable to store the null port in, to ;;; save reopening it next time unless( boundp( 'FPCNullPort ) && openportp( FPCNullPort ) FPCNullPort = outfile( "/dev/null" ) ) ;;; unless ;;; Be good - force any buffered warning to be displayed - this means ;;; we don't swallow any warning unrelated to opening a cellView. ;;; This is done by creating a new warning (which we'll swallow in a moment) ;;; which forces what is in the buffer to be output. warn("") ;;; use SKILL's dynamic scoping to redefine woport to send all ;;; warnings to /dev/null - and get the final (unprinted) warning ;;; with getWarn() let( ( cv ( woport FPCNullPort ) ) cv = apply( 'dbOpenCellViewByType args ) getWarn() cv ) ;;; end let ) ;;; end procedure FPCOpenCellViewByType ;;;;;;;;;;;;;;;;;;;;;;